Re: [eigen] Block sparse matrices and std vector compilation error

[ Thread Index | Date Index | More Archives ]

Thank you for the help Mathieu and Christoph. I have uploaded my gcc compiler to 4.8 and the error indeed does not reproduce. I was compiling with c++11 with the 4.6 gcc version.

I will take your design advice about using Blocks and I will also explain my use case to see if you have any suggestions. My big sparse matrix has a lot of fixed size blocks that are sparse with the same structure and must be updated repeatedly. The blocks are updated through the same function and my hope was to parallelize this by calling the function from different threads using the blocks as an input parameter to the update function.


On Wed, Nov 26, 2014 at 2:59 PM, Christoph Hertzberg <chtz@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:
On 26.11.2014 13:04, Hilario Tomé wrote:
I am interested in storing block sparse matrices in std vectors but get a
compiling error, the error does not happen for dense matrices. I am using
Eigen 3.2.2 with gcc version 4.6.3

Block<> matrices do not have a copy-assignment operator, which is required for std::vector elements in C++03 (not in C++11 anymore), so even for dense matrices you could get undefined behavior (I just checked with g++-4..7 and it appears to work fine).

Block<Matrix> does have an operator= defined, which however, does not copy the Block object itself, but overwrites the values in the referenced matrix. But even though g++ checks for its existence it does not appear to use this anyways. So your case with MatrixXd instead of SparseMatrix<double> does work, but at least for C++03 I would not rely on it to work correctly everywhere.

If you use Block<const MatrixXd> everywhere instead of Block<MatrixXd> then the assignment:
  MatrixXd A;
  Block<const MatrixXd> block = A.block(0,0,5,5);       // (*)
does not work, however this works:
  const MatrixXd A;
  Block<const MatrixXd> block = A.block(0,0,5,5);
Then (for g++) the rest of your program works in C++11 mode, but not in C++03 mode (because Block<const MatrixXd> does not have an assignment operator).

Overall, you might want to reconsider your design. Block objects are somewhat of an internal thing, and the type names might probably change in the future (e.g., SparseMatrix::middleCols(...) could theoretically return a MappedSparseMatrix).


We should probably add a constructor of Block<const X> from Block<X> to make (*) work. OTOH, explicitly storing Block objects is not good style anyways, IMO.

For Block<SparseMatrix> we should probably make it more clear that it does not have an assignment operator at all (implement an operator= which raises a static assertion).
And for Block<*> it would be nice if we could tell the compiler that it is not actually copy-assignable (I'm afraid, there is no easy way to tell this without having C++-concepts (which did not even make it into C++11)).



Dipl.-Inf., Dipl.-Math. Christoph Hertzberg
Cartesium 0.049
Universität Bremen
Enrique-Schmidt-Straße 5
28359 Bremen

Tel: +49 (421) 218-64252


Mail converted by MHonArc 2.6.19+