Reputation: 53
Does Eigen support element insertion into a sparse matrix if the size is not known?
I have a stream of data coming in, and I am attempting to store that sparsely, but I don't know the maximum value of the indices (row/column) of the data ahead of time (I can guess, but not guarantee). Looking at Eigen's insert code, it has an assertion (1130, SparseMatrix.h) that the index that you wish to insert into is <=rows(), <=cols().
Do I really need to wait until I have all the data before I can start using Eigen's sparse matrix code? The design I would have to go for then would require me to wait for all the data, then scanto find the maximum index, which is not ideal for my application. I curently don't need the full matrix to start working - an limited one with the currently available data would be fine.
Please don't close this question unless you have an answer, the linked answer was for dense matrices, not sparse ones, which have different internal storage...
I'm also looking for information on the case where matrix size is not immediately available at run-time, rather than at compile time, and olny for sparse.
Upvotes: 0
Views: 385
Reputation: 3250
The recommendation is still to store the values into a intermediate triplets container and build the sparse matrix at the end. If you don't want to read all the stream... then just read first nnn triplets until your desired condition and then use setFromTriplets() with the partial list of triplets.
But, if you still don't want to read the full matrix to start working, you can guess a size for your matrix and make it grow in case you read a value that can not be stored in your current size using conservativeResize().
#include <Eigen/Sparse>
#include <iostream>
Eigen::SparseMatrix<double> mat;
mat.resize(100,100); //Initial size guess. Could be 1, 10, 1000, etc...
fstream inputStream ("filename.txt", "r"):
while(inputStream)
{
//Read position and value from stream
unsigned i, j;
double v;
inputStream >> i >> j >> v;
//check current size of the matrix and make it grow if necessary
if ( (i >= mat.rows()) || (j >= mat.cols()) )
mat.conservativeResize(std::max(i+1, mat.rows()), std::max(j+1, mat.cols()) );
//store the value in matrix
mat.coeffRef(i,j) = v;
//Insert here your condition to break before of read all the stream
if (mat.nonZeros() > 150 )
break;
}
//Do some clean-up in case you think is necessary
mat.makeCompressed();
Upvotes: 2