将Boost ublas矩阵写入文本文件

时间:2015-03-27 19:10:01

标签: c++ c++11 boost stl boost-ublas

我有一个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循环的情况下编写此代码。我尝试了ostreambuf_iterator API,如下所示

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

但是,正如您所看到的,连续元素是在新行上编写的,而我无法像嵌套for循环那样实现排序类型。有没有办法在嵌套中使用STL算法做我所做的事情?

1 个答案:

答案 0 :(得分:4)

我喜欢Boost Spirit Karma这些小格式化/生成器任务。

直接进场

如果您不介意每行的尾随标签,请点击此处

<强> Live On Coliru

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适配器作为&#34;视图&#34;时,您可以获得更大的灵活性。在原始存储上:

<强> Live On Coliru

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

所以它变得只是

<强> Live On Coliru

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

非常优雅

  

注意当然这些假设是行主要布局。