This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Filling a sparse matrix from external library

Tags: None
(comma "," separated)
spch1212
Registered Member
Posts
2
Karma
0
OS
Hi,

I am attempting to populate a sparse matrix by using an external library. After poking around in the sources I have come up with the following snippet. It apparently works, but is this indeed the recommended way? The designated routine will accept pointers to the internal arrays (ptr, ind, val below) of a standard CSR matrix and then do its magic ..., I.e. I cannot use .insert(...) without allocating additional storage, which I would be glad to avoid.

The following will generate the matrix from the tutorial page:

Eigen::SparseMatrix<double,Eigen::RowMajor> mat(5,5);
mat.reserve(8);

double* val = mat._valuePtr();
int* ptr = mat._outerIndexPtr();
int* ind = mat._innerIndexPtr();
ptr[0] = 0;
val[0] = 3; ind[0] = 1;
ptr[1] = 1;
val[1] = 22; ind[1] = 0;
val[2] = 17; ind[2] = 4;
ptr[2] = ptr[1] + 2;
val[3] = 7; ind[3] = 0;
val[4] = 5; ind[4] = 1;
val[5] = 1; ind[5] = 3;
ptr[3] = ptr[2] + 3;
ptr[4] = ptr[3] + 0;
val[6] = 14; ind[6] = 2;
val[7] = 8; ind[7] = 4;
ptr[5] = ptr[4] + 2;

mat.resizeNonZeros(8); // essential
// mat.finalize();


Regards,
Daniel
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
depends. if you want to fill a sparse matrix element per element, use the .insert() API. It is simpler and safer. see the tutorial. if you already have the val, ptr, and ind arrays, you can "map" them as an Eigen's SparseMatrix using the MappedSparseMatrix class. there is no doc, but the following should be enough to start:

MappedSparseMatrix<double> mat(int rows, int cols, int nnz, int* outerIndexPtr, int* innerIndexPtr, Scalar* valuePtr);
spch1212
Registered Member
Posts
2
Karma
0
OS
Hello Gael,

Thank you for your answer. In fact, I do not fill the sparse matrix element by element. I have a library that directly fills the preallocated val, ptr, and ind arrays. I would prefer not to rely on MappedSparseMatrix, since I am compiling a library and do not want the user to be obliged to free the arrays. My previous approach works, I think. However it feels hackish as I rely on the reserve(...) method to allocate sufficient memory. Furthermore, the matrix is in some undefined state until resizeNonZeros(...) is called (since the number of nonzeros cannot be determined until then). Clearly, I rely on details of the implementation ...

Well, I guess copying is the only clean solution ...

Thanks for the hints,
daniel
FMD
Registered Member
Posts
25
Karma
0
Hallo Daniel,

possibly copying the mapped matrix in one step to you own instance is faster than filling your own instance in several steps.

regards
Frank
Seb
Registered Member
Posts
99
Karma
0
Hello Gael,

question: Will there be access functions for the internal data buffers in Eigen 3.0 ? I do not see them in the developer's API documentation anymore. When writing efficient bindings, these functions are a very useful tool - it would be a pity if they'll be gone.

Sebastian
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
don't worry, they are still there.


Bookmarks



Who is online

Registered users: abc72656, Bing [Bot], daret, Google [Bot], Sogou [Bot], Yahoo [Bot]