Отключить разрыв строки после печати вектора/матрицы броненосца (C++)

Я использую C++ с библиотекой броненосца. Когда я печатаю вектор или матрицу, после вектора/матрицы всегда включается разрыв строки, даже при использовании .raw_print(). Есть ли простой способ отключить это поведение?

Минимальный пример:

#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();
}

Я компилирую и запускаю Linux, используя GCC версии 4.4.6.

g++ test.cpp -o test -larmadillo

person Filip S.    schedule 31.01.2013    source источник
comment
Я мало что знаю об этом, но похоже, что разрыв строки присущ типу rowvec   -  person SShaheen    schedule 31.01.2013
comment
Это также видно при печати матриц, которые я редактировал в примере.   -  person Filip S.    schedule 31.01.2013


Ответы (1)


Функция .print() в Armadillo предназначен для "красивой печати". Функция .raw_print() уменьшает количество красивой печати (т. е. не изменяет представление чисел в научном формате), но по-прежнему печатает новые строки.

Если бы эти функции имели меньшую функциональность, они не давали бы дополнительных преимуществ по сравнению с простым циклическим просмотром элементов и выгрузкой их в пользовательский поток (например, cout). Таким образом, решение состоит в том, чтобы просто выполнить печать самостоятельно с помощью такой функции, как:

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

Если вы хотите минимальное количество красивой печати, когда в конце каждой строки (кроме последней) есть символы новой строки, попробуйте следующее:

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'; }
    }
  }

Обратите внимание, что приведенный выше код выводит только тип mat (который является typedef для Mat ‹ double > ) и производные типы, такие как vec и rowvec. Если вы хотите напечатать любой шаблонный тип Mat ‹ T > (и производные типы Col ‹ T > и Row ‹ T >), попробуйте следующее:

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'; }
    }
  }

Кроме того, если вы хотите иметь возможность напечатать любое матричное выражение Armadillo (например, A + B), попробуйте следующее:

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'; }
    }
  }

Обратите внимание, что приведенный выше код создаст копию матрицы, если выражение представляет собой просто одну матрицу. Если требуется эффективность, требуется метапрограммирование шаблона, чтобы избежать копирования, что выходит за рамки исходного вопроса.

person mtall    schedule 01.02.2013
comment
Спасибо! Я думаю, нет простого способа сделать то, что я хочу, поэтому ваше решение выглядит хорошо. Одна из моих проблем заключается в том, что я хочу напечатать матрицу в файл, который должен иметь определенное форматирование, но, думаю, мне придется сделать это вручную. - person Filip S.; 01.02.2013