Question

I'm using C++ with the armadillo library. When I print a vector or matrix, there is always included a line-break after the vector/matrix, even when using .raw_print(). Is there any simple way of disabling this behaviour?

Minimal example:

#include <iostream>
#include <armadillo>

using namespace std;
using namespace arma;

int main() {
    rowvec a;
    a << 0 << 1 << 2;
    cout << a;
    a.print();
    a.raw_print();

    mat b;
    b << 0 << 1 << 2 << endr
      << 3 << 4 << 5 << endr
      << 6 << 7 << 8;
    cout << b;
    b.print();
    b.raw_print();
}

I'm compiling and running on linux, using GCC version 4.4.6

g++ test.cpp -o test -larmadillo
Was it helpful?

Solution

The .print() function in Armadillo is designed to do "pretty-printing". The .raw_print() function reduces the amount of pretty-printing (ie. it doesn't change the representation of numbers to scientific format), but still prints newlines.

If these functions had any less functionality, they would provide no added value over simply looping through the elements and dumping them to a user stream (such as cout). As such, the solution is simply to do the printing yourself, through a function such as:

inline
void
my_print(const mat& X)
  {
  for(uword i=0; i < X.n_elem ++i) { cout << X(i) << ' '; }
  }

If you want a minimal amount of pretty-printing where there are newlines at the end of each row (except the last one), try this:

inline
void
my_print(const mat& X)
  {
  for(uword row=0; row < X.n_rows; ++row)
    {
    for(uword col=0; col < X.n_cols; ++col) { cout << X(row,col) << ' '; }

    // determine when to print newlines
    if( row != (X.n_rows-1) ) { cout << '\n'; }
    }
  }

Note that the above code only prints the mat type (which is a typedef for Mat < double > ) and derived types such as vec and rowvec. If you want to print any templated Mat < T > type (and the derived types Col < T > and Row < T >), try the following:

template<typename eT>
inline
void
my_print(const Mat<eT>& X)
  {
  for(uword row=0; row < X.n_rows; ++row)
    {
    for(uword col=0; col < X.n_cols; ++col) { cout << X(row,col) << ' '; }

    // determine when to print newlines
    if( row != (X.n_rows-1) ) { cout << '\n'; }
    }
  }

Furthermore, if you want to be able to print any Armadillo matrix expression (eg. A+B), try this:

template<typename T1>
inline
void
my_print(const Base<typename T1::elem_type,T1>& expr)
  {
  const Mat<typename T1::elem_type> X(expr);  // forcefully evaluate expression

  for(uword row=0; row < X.n_rows; ++row)
    {
    for(uword col=0; col < X.n_cols; ++col) { cout << X(row,col) << ' '; }

    // determine when to print newlines
    if( row != (X.n_rows-1) ) { cout << '\n'; }
    }
  }

Note that the above code will make a copy of a matrix if the expression is simply a single matrix. If efficiency is required, template metaprogramming is required to avoid the copy, which is beyond the scope of the original question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top