2

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アルゴリズムを使用するためにネストされた内部で行ったことを行う方法はありますか?

4

1 に答える 1

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アダプターを raw ストレージの「ビュー」として使用すると、柔軟性が大幅に向上します。

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

私の意見では、これは非常にエレガントです

もちろん、これらは行優先のレイアウトを想定しています。

于 2015-03-27T21:40:45.663 に答える