将BOOST稀疏矩阵写入二进制格式的数据文件

时间:2016-12-20 23:08:31

标签: matrix boost sparse-matrix

亲爱的stackoverflow社区:

我对BOOST很陌生,我试图使用其uBLAS库的稀疏矩阵。我遇到的一个问题是,在计算我的稀疏矩阵之后,我想将它存储到二进制文件中,并从其他一些程序中读取该文件并恢复稀疏矩阵。通常我会按以下方式写文件(比如我有一个带有100个浮点数的数组A):

std::ofstream ofsDat("file.dat", std::ofstream::out); 
ofsDat.write((char*)A, sizeof(float)*100);
ofsDat.close(); 

我想知道我是否可以对BOOST稀疏矩阵进行类似的写操作?如果是这样,ofstream :: write的第二个参数应该是什么? (应该是数据块的大小)

2 个答案:

答案 0 :(得分:0)

Boost Sparse Matrix仅存储非零值。矩阵的密集表示没有&A。如果您需要二进制输出,则必须自己构建它。你不需要ios::out,这是理解的。你应该

std::ofstream test( "./file.dat", std::ios::binary );

或ofstream可以/将通过将其视为字符流来破坏您的输出。然后:

#include <iostream>
#include <fstream>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/storage.hpp>

namespace ublas = boost::numeric::ublas;

int main( )
{
    size_t width= 10;
    size_t depth= 10;
    ublas::compressed_matrix< double > m( width, depth );
    m(0, 0) = 9;
    m(1, 0) = 2;
    m(0, 1) = 3;
    m(5, 5) = 7;

    std::ofstream test( "./file.dat", std::ios::binary );
    double zero= 0.0;
    for( int i=0; i < width; ++i )
        for (int j=0; j< depth; ++j )
        {
            double* temp= m.find_element( i, j );
            if( temp )
                test.write( (char*)temp, sizeof( double ) );
            else
                test.write( (char*)&zero, sizeof( double ) );
        }
    test.close( );
}

但是如果不向文件写入更多信息,矩阵必须是已知的宽度和深度。我真的会查看另一端的输入,看看它是否可以用文本文件完成。那你只需要:

test << m;

答案 1 :(得分:0)

经过一些搜索和试验,我找到了一种方法来编写和阅读稀疏矩阵。请注意,我的任务实际上相对简单,因此对于一些更复杂和更通用的目的,我不知道这种粗略方法是否有效。

基本思想是写入ofstream,通过const_iterator迭代boost的稀疏矩阵中的所有非零元素(有关详细信息,请参阅此link)。从ifstream读取时,我使用的是穷人的方法:根据写入格式迭代读入,并插入稀疏矩阵。这是我的测试目的代码:

#include <iostream>
#include <fstream>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/io.hpp>


    int main(int argc, char** argv)
    {
        using std::cerr;
        using std::cout; 
        using std::endl;
        using namespace boost::numeric::ublas;
        typedef compressed_matrix<float, row_major> cMatrix;

        const size_t size = 5;
      const size_t rowInd[5] = { 0, 0, 1, 2, 4 };
      const size_t colInd[5] = { 0, 2, 0, 4, 4 };

        cMatrix sparseMat(size,size);
      for (size_t i=0; i<size; ++i) 
            sparseMat.insert_element(rowInd[i], colInd[i], 1.0);

        cout << sparseMat << endl;

        // Try writing to file
        std::ofstream ofsDat("temp.dat", std::ios::out | std::ios::binary);
        for(cMatrix::const_iterator1 rowIter = sparseMat.begin1(); rowIter != sparseMat.end1(); ++rowIter)  {
            for(cMatrix::const_iterator2 colIter = rowIter.begin(); colIter != rowIter.end(); ++colIter)    {
                ofsDat << " " << colIter.index1() << " " << colIter.index2() << " " << *colIter;
            }       // end for colIter
        }       // end for rowIter
        ofsDat.close();

        cout << "Writing ended, starting to read" << endl;

        // Try reading the file
        cMatrix sparseMat_2(size, size);
        std::ifstream ifsDat("temp.dat", std::ios::in | std::ios::binary);
        size_t rowTemp, colTemp; 
        float valTemp;
        while(!ifsDat.eof())    {
            ifsDat >> rowTemp >> colTemp >> valTemp;
            cout << "row " << rowTemp << " column " << colTemp << " value " << valTemp << endl;
            sparseMat_2.insert_element(rowTemp, colTemp, valTemp);
        }

        cout << sparseMat_2 << endl;

        return 0;
    }

我在数据之间添加了一个空格作为分隔符,我不知道是否有更好的或标准的方法来做到这一点?任何反馈将不胜感激!