将 Eigen::DiagonalMatrix 添加到 Eigen::SparseMatrix 的最有效方法是什么

Ale*_*son 6 c++ sparse-matrix eigen diagonal

我惊讶地发现不可能简单地将 an 添加Eigen::DiagonalMatrix到 an Eigen::SparseMatrix

#include <Eigen/Core>
#include <Eigen/Sparse>

int main()
{
  Eigen::Matrix4d M;
  M<<1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16;
  Eigen::SparseMatrix<double> S = M.sparseView();
  Eigen::DiagonalMatrix<double,Eigen::Dynamic> D = 
    Eigen::VectorXd::LinSpaced(4,1,4).asDiagonal();
  Eigen::SparseMatrix<double> T = D+S;
}
Run Code Online (Sandbox Code Playgroud)

不会编译:

 error: invalid operands to binary expression ('Eigen::DiagonalMatrix<double, Eigen::Dynamic>' and 'Eigen::SparseMatrix<double>')
  Eigen::SparseMatrix<double> T = D+S;
Run Code Online (Sandbox Code Playgroud)

似乎在 Eigen 3.3 中我可以使用:

  T.diagonal() = D.diagonal() + T.diagonal();
Run Code Online (Sandbox Code Playgroud)

但这不适用于较旧(更稳定)的 Eigen 3.2.*:

error: no viable overloaded '='
  T.diagonal() = D.diagonal() + T.diagonal();
Run Code Online (Sandbox Code Playgroud)

我真的必须遍历条目并一一插入吗?

 Eigen::SparseMatrix<double> T = S;
 for(int i = 0;i<T.rows();i++) T.coeffRef(i,i) += D.diagonal()(i);
Run Code Online (Sandbox Code Playgroud)

更新:

看起来你也可以这样做:

Eigen::SparseMatrix<double> T = Eigen::SparseMatrix<double>(D)+S;
Run Code Online (Sandbox Code Playgroud)

我猜这会导致不必要的复制。