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

[SOLVED] Bug when storing Eigen2 objects in STL vectors

Tags: None
(comma "," separated)
Seb
Registered Member
Posts
99
Karma
0
I precompute some objects which are stored in std::vectors (of dense and sparse matrices). Using Eigen2 I encounter the following errors:
Code: Select all
   material.setPrecomputedMatrices().resize(2); // std::vector
   material.setPrecomputedMatrices()[def_Cmat0].swap(Dmat);
   material.setPrecomputedMatrices()[def_Cmat_stab] = 0.5*material.setPrecomputedMatrices()[def_Cmat0];

Dmat is of type Matrix6d...
Error:
Code: Select all
Core/Assign.h:404: Derived& Eigen::MatrixBase::lazyAssign(const Eigen::MatrixBase&) [with OtherDerived = Eigen::CwiseUnaryOp, Eigen::Matrix >, Derived = Eigen::Matrix]: Assertion `rows() == other.rows() && cols() == other.cols()' failed.

The exception is thrown at the last line, the first was ok.

It seems that one can not change the matrix dimensions after calling the constructor for the first time. swap() seems to override this. I wonder if this should be made possible, since I can not store Eigen2 objects using vector[i]=Matrix; or push_back(Matrix);


When filling a vector with SparseMatrix objects, I encounter a segfault at vector_of_sparsematrix.resize(3);
Valgrind says: Source and destination overlap in memcpy(0x0, 0x0, 4)

One problem is that vector_of_sparsematrix.resize(3); does not compile since there is no public default constructor. Therefore, I derived SparseMatrix and added one that called SparseMatrix(0,0)

Btw: When changing the default constructor to SparseMatrix(1,1), no error seems to appear. Output over std::cout verifies that input and output objects are identical for sparse matrices. But still I wonder what happens to the matrix dimensions, if SparseMatrix is supposed to behave like Matrix regarding changing dimensions after creation...


I tried the last published beta and the svn version from yesterday.

Last edited by bjacob on Fri Jan 09, 2009 8:02 pm, edited 1 time in total.
User avatar
bjacob
Registered Member
Posts
658
Karma
3
The problem when you do std::vector is that std::vector calls the default constructor of MatrixXd, which constructs an uninitialized matrix (no array allocated).

In Eigen, the only thing you can do with an uninitialized matrix is to initialize it by calling .set(.....) on it.

Fortunately, the resize() method of std::vector takes a second parameter allowing to set the default value of elements of the vector. So here you could call:

Code: Select all
material.setPrecomputedMatrices().resize(2, MatrixXd(1,1));


of course that's not 100% optimal as that means that your matrix gets allocated a first time and then reallocated when you store a meaningful matrix in it.

So instead what you can do is keep the current form, and then call .set() on the vector elements.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
Seb
Registered Member
Posts
99
Karma
0
That's it - I didn't know of set().

Also, the hint with the 2nd parameter for std::vector.resize() is very helpful. It gives me the chance to use SparseMatrix without subclassing.

Thanks!
User avatar
bjacob
Registered Member
Posts
658
Karma
3
Today there was a big change: the set() method is no more; instead, operator= will resize (and initialize) the matrix as needed.

So the first approach that you tried, should now work.


Join us on Eigen's IRC channel: #eigen on irc.freenode.net
Have a serious interest in Eigen? Then join the mailing list!
Seb
Registered Member
Posts
99
Karma
0
Ah, thanks. I expected something like this - the different usage of dense and sparse objects was a real source of bugs. Very well, it is gone...


Bookmarks



Who is online

Registered users: Bing [Bot], Evergrowing, Google [Bot], rblackwell