Finally after some search and trials, I found a way to do this writing and reading sparse matrix. Note that my task is actually relatively simple, so for some more complicated and more general purpose, I do not know if this crude method will work or not.
The basic idea is write into ofstream
, by iterating over all non-zero elements in the boost's sparse matrix, via a const_iterator (see this link for more details). And when read from ifstream
, I am using a poor man's method: iteratively read in according to the writing format, and insert into the sparse matrix. Here is my code for my test purpose:
#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;
}
I added a space in between the data as separators, I don't know if there's a better, or standard way to do this? Any feedback will be appreciated!