代码之家  ›  专栏  ›  技术社区  ›  The Vivandiere

将Boost ublas矩阵写入文本文件

  •  2
  • The Vivandiere  · 技术社区  · 9 年前

    我有一个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_interator API,如下所示

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

    然而,正如您所看到的,连续的元素都是在新的行上编写的,我无法像嵌套for循环那样实现排序类型。有没有一种方法可以像我在嵌套中那样使用STL算法?

    1 回复  |  直到 9 年前
        1
  •  4
  •   sehe    9 年前

    我喜欢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 适配器作为原始存储的“视图”:

    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
    

    使现代化 使用helper函数使其可读性更强,不易出错:

    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";
    

    哪个是 非常优雅 ,在我看来

    笔记 当然,这些都采用行主要布局。

    推荐文章