我想使用 Eigen3 库(版本 3.3.2)将元素添加到 Eigen::MatrixXd 对象的对角线上。
为了优化和能够使用常量,我想通过向原始矩阵添加对角矩阵来实现这一点,就像这样
const MatrixXd a(2,2); a << 1, 2, 3, 4;
const VectorXd v(2); v << 10, 20;
const MatrixXd b = a + v.asDiagonal();
但这不起作用:我收到一个关于没有
operator+
的编译器错误。添加两个 MatrixXd
确实有效,所以我希望它能够针对对角线专业化。
删除常量没有帮助。使用静态大小的矩阵没有什么区别,所以它不是动态大小的事情。并且显式构造
DiagonalMatrix
而不是使用 DiagonalWrapper
返回的 asDiagonal()
也会给出相同的错误。
乘法对于这些类型来说格式良好:
MatrixXd c = a * v.asDiagonal();
编译和运行得很好。我做错了什么吗,或者 operator+(Matrix,DiagonalMatrix)
只是从图书馆中丢失了?
感谢 @CoryKramer 链接到 KDE/Eigen 论坛上提出和回答的等效问题:https://forum.kde.org/viewtopic.php?f=74&t=136617 以下是供后代使用的摘要:
不支持特征
Matrix
和 DiagonalMatrix
或 DiagonalWrapper
的“正常”加法运算,而乘法或复合 +=
加法则可以。如果尝试使用 const 对象,则 +=
不是一个选项,而是从 Matrix2d
调用构造显式 asDiagonal()
——为什么我没有想到尝试这样做? -- 效果很好:
MatrixXd b = a + Matrix2d(v.asDiagonal());
我猜这可能会带来潜在的性能损失,这就是为什么在没有类型构造的情况下不支持这一点。但它们不太可能比手动循环对角线索引的肮脏替代方案更糟糕。
不幸的是,KDE 论坛帖子不再可用。除了@andybuckley分享的内容之外,这个解决方案的意图可能更明确:
MatrixXd b = a + v.asDiagonal().toDenseMatrix();
此代码使用向量 v 创建一个 DiagonalWrapper,然后使用它构造一个 DenseMatrix,可以根据需要在与其他矩阵的运算中使用。