Запись UBL-матрицы Boost в текстовый файл

У меня есть матрица Boost Ublas, и я хочу напечатать ее содержимое в текстовый файл. У меня есть следующая реализация, и она работает.

#include <iostream>
using namespace std;
#include "boost\numeric\ublas\matrix.hpp"typedef boost::numeric::ublas::matrix<float> matrix;
#include <algorithm>
#include <iterator>
#include <fstream>

int main()
{
fill(m1.begin2(), m1.begin2() + 400 * 500, 3.3);

ofstream dat("file.txt");
for (auto i = 0; i < 400 ; i++) {
for (auto j = 0; j < 500; j++) {
dat << m1(i, j) << "\t"; // Must seperate with Tab
}
dat << endl; // Must write on New line
}

Я хочу написать этот код без использования вложенных циклов for. Я попробовал API ostreambuf_iterator следующим образом

copy(m1.begin2(), m1.begin2() + 500 * 400, ostream_iterator<float>(dat, "\n")); // Can only new line everything

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

2

Решение

Мне нравится Boost Spirit Karma для такого рода небольших задач форматирования / генерации.

Прямой подход

Если вы не против конечных вкладок в каждой строке, вот

Жить на Колиру

matrix m1(4, 5);
std::fill(m1.data().begin(), m1.data().end(), 1);

using namespace boost::spirit::karma;
std::ofstream("file.txt") << format_delimited(columns(m1.size2()) [auto_], '\t', m1.data()) << "\n";

Печать

1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →
1.0 → 1.0 → 1.0 → 1.0 → 1.0 →

С помощью multi_array Посмотреть

Вы получаете гораздо больше гибкости при использовании const_multi_array_ref Адаптер как «просмотр» в вашем сыром хранилище:

Жить на Колиру

std::ofstream("file.txt") << format(auto_ % '\t' % eol,
boost::const_multi_array_ref<float, 2>(&*m1.data().begin(), boost::extents[4][5]));

Это приводит к тому же, но не имеет конечных вкладок в каждой строке:

1.0 → 1.0 → 1.0 → 1.0 → 1.0
1.0 → 1.0 → 1.0 → 1.0 → 1.0
1.0 → 1.0 → 1.0 → 1.0 → 1.0
1.0 → 1.0 → 1.0 → 1.0 → 1.0

Обновить Сделайте его более читабельным и менее подверженным ошибкам с помощью вспомогательной функции:

template <typename T> boost::const_multi_array_ref<T, 2> make_view(boost::numeric::ublas::matrix<T> const& m) {
return  boost::const_multi_array_ref<T,2> (
&*m.data().begin(),
boost::extents[m.size1()][m.size2()]
);
}

Так становится просто

Жить на Колиру

std::cout << format(auto_ % '\t' % eol, make_view(m1)) << "\n";

Который очень элегантно, по-моему

Заметка Конечно, они предполагают макет ряда строк.

4

Другие решения


По вопросам рекламы [email protected]