在 Eigen3 中添加矩阵和对角矩阵

问题描述 投票:0回答:2

我想使用 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)
只是从图书馆中丢失了?

c++ matrix eigen eigen3
2个回答
2
投票

感谢 @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());

我猜这可能会带来潜在的性能损失,这就是为什么在没有类型构造的情况下不支持这一点。但它们不太可能比手动循环对角线索引的肮脏替代方案更糟糕。


0
投票

不幸的是,KDE 论坛帖子不再可用。除了@andybuckley分享的内容之外,这个解决方案的意图可能更明确:

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

此代码使用向量 v 创建一个 DiagonalWrapper,然后使用它构造一个 DenseMatrix,可以根据需要在与其他矩阵的运算中使用。

© www.soinside.com 2019 - 2024. All rights reserved.