如何使 SparseMatrix 保持未压缩状态?

How to keep a SparseMatrix in an uncompressed state?

自 Eigen 3.2 起,DynamicSparseMatrix 已被弃用,只有一个结构 SparseMatrix 可以压缩或不压缩。分离结构的最大好处是能够控制压缩阶段。现在每次操作未压缩的SparseMatrix,都会自动压缩

对于我们的应用程序来说,这是一个问题,因为它大大减慢了我们矩阵的频繁重新初始化。通常,我们求解非线性方程,需要经常更新一个稀疏矩阵A。我们以前用旧的DynamicSparseMatrix格式来做,运行时性能很好:

main {
   SparseMatrix<double> A;
   Loop {
     A=SomeClass.getUpdatedA();
     ....
   }
}

class SomeClass {
public:
  DynamicSparseMatrix<double>& getUpdatedA() { 
    A = Alinear;
    // Add nonlinear contributions calling  
    loop {
      A.coeffRef(row,col) += someNonLinearContribution;
    }
  }  
private:
  // A and A linear are preallocated with enough space to store all our contributions
  DynamicSparseMatrix<double> A, AlinearPart;
}

对于新版本(将 DynamicSparseMatrix 替换为 SparseMatrix),当您调用 getUpdatedA() 时,A 在第一行之后被压缩。压缩后,添加非线性贡献会变慢,因为我们每次都需要重新分配所有内容。

我们曾经提交过 a bug in Eigen-related forum,并且我们收到了来自 ggael 的以下答复:

You can still use DynamicSparseMatrix from <unsupported/Eigen/SparseExtra>. However, it's not officially supported. For a cleaner solution I need more details:
- Does the structure of A change? Or is it fixed?
- If it changes, is it due to the structure of A_linear? Or due to the additional coefficients? Or both?
- Does the structure of A_linear change?

答案如下:
- A 和 A_linear 的结构是固定的。我们的稀疏矩阵需要一个常数模式,因此如果需要保留结构,我们会在稀疏矩阵中标记零项。
- A 和 Alinear 具有不同的结构。

最新版本的Eigen是否引入了官方支持的解决方案?

一个简单的解决方法是用额外的显式零存储 Alinear 以使其与 A 的结构相匹配。这个解决方案甚至应该比当前基于 DynamicSparseMatrix 的解决方案更快,因为在调用 coeffRef() 期间不会发生内存复制:其他条目将已经存在于正确的位置。