Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Matrix and DiagonalMatrix in Eigen3

I want to add elements to the diagonal of a Eigen::MatrixXd object with the Eigen3 library (version 3.3.2).

Both for optimisation and being able to use constness, I want to do this by adding a diagonal matrix to the original, like this

const MatrixXd a(2,2); a << 1, 2, 3, 4;
const VectorXd v(2); v << 10, 20;
const MatrixXd b = a + v.asDiagonal();

But this doesn't work: I get a compiler error about there being no operator+. Adding two MatrixXd does work, so I would expect it to behave for the diagonal specialisation.

Removing the constness doesn't help. Using statically sized matrices makes no difference, so it's not a dynamic-sizing thing. And explicitly constructing a DiagonalMatrix rather than using the DiagonalWrapper returned by asDiagonal() also gives the same error.

Multiplication is well-formed for these types: MatrixXd c = a * v.asDiagonal(); compiles and runs just fine. Am I doing something wrong, or is operator+(Matrix,DiagonalMatrix) just missing from the library?

like image 478
andybuckley Avatar asked Oct 29 '22 06:10

andybuckley


1 Answers

Thanks to @CoryKramer for linking to an equivalent question being asked and answered on the KDE/Eigen forum: https://forum.kde.org/viewtopic.php?f=74&t=136617 Here's a summary for posterity:

"Normal" addition of an Eigen Matrix and either a DiagonalMatrix or DiagonalWrapper isn't a supported operation, while multiplication or compound += addition are fine. += isn't an option if trying to work with const objects, but constructing an explicit Matrix2d from the asDiagonal() call -- why didn't I think of trying that?! -- works nicely:

MatrixXd b = a + Matrix2d(v.asDiagonal());

I guess there are potential performance penalties, which is why this isn't supported without the type construction. But they're unlikely to be worse than the dirty alternative of manually looping over diagonal indices.

like image 178
andybuckley Avatar answered Nov 11 '22 08:11

andybuckley