C++ 特征矩阵中稀疏矩阵运算的预分配内存

C++ 特征矩阵中稀疏矩阵运算的预分配内存,c++,sparse-matrix,eigen,C++,Sparse Matrix,Eigen,我正在使用Eigen(确切地说是一个优化器)编写一个程序,它有一个“热循环”,我希望尽可能避免内存分配 当使用Egeng/Dense时,我能够通过提前计算和预分配所需的所有工作空间的大小,在构造函数中执行所有内存分配(明智地使用.noalias()和inplace LLT分解) 我想对代码的本征/稀疏变量做一些类似的事情(在可能的范围内)。构造函数将要求用户为所有数据提供稀疏模式,我可以使用这些数据来确定我需要的所有后续矩阵(包括工作空间)的大小和稀疏模式。我需要执行4种操作: 稀疏矩阵向量积

我正在使用Eigen(确切地说是一个优化器)编写一个程序,它有一个“热循环”,我希望尽可能避免内存分配

当使用Egeng/Dense时,我能够通过提前计算和预分配所需的所有工作空间的大小,在构造函数中执行所有内存分配(明智地使用.noalias()和inplace LLT分解)

我想对代码的本征/稀疏变量做一些类似的事情(在可能的范围内)。构造函数将要求用户为所有数据提供稀疏模式,我可以使用这些数据来确定我需要的所有后续矩阵(包括工作空间)的大小和稀疏模式。我需要执行4种操作:

  • 稀疏矩阵向量积
  • Cholesky分解
  • 形式为E=H+A'*B*A的Schur补,其中B是对角矩阵,H,A是一般稀疏矩阵
  • 我目前的理解如下:

    • 对于矩阵向量积,我可以使用x.noalias()=A*y(A是稀疏的,x,y密集向量),没有问题
    • 我可以通过用显式零填充来执行矩阵加法,例如。,。这主要适用于像B=A+sI这样的操作,其中A是稀疏的,sI是恒等式的标量倍数。我可以确保主对角线包含在B的稀疏模式中,并在循环中执行加法
    • 截至2017年,没有办法避免在稀疏矩阵产品中进行临时分配,例如,C=A*B(),而且我还没有看到任何用于稀疏矩阵的内置函数,因此我必须咬紧牙关,接受临时创建
    • 出于许可的原因,我使用了一个eigen external LDL的因式分解包,它允许我基于符号分析阶段进行预分配

    有人能提出一种快速的方法来组织Schur计算E=H+a'*B*a吗?(利用我事先知道它的稀疏结构)

    这是一个开放的特性请求有一段时间了:,如果有人对此有可行的解决方案,欢迎提供:)注意,
    Eigen::SimplicialLDLT
    现在是MPL2,它也可以基于符号分解预分配,只需调用
    analyzePattern(a)
    一次,然后
    分解(A)
    。如果你知道
    A'*A
    的结构,你可以尝试循环它的非零,对于每个非零
    (i,j)
    ,计算它为
    (A.innerVector(i).cwiseProduct(b).dot(A.innerVector(j))
    ,使用
    b
    一个密集向量存储b的对角线。这应该是非常有效的,但我不能100%肯定这会比分配快。根据@ggael的建议,我解决了以下问题:
    for(int i=1,k=0;i这是一个开放的特性请求已有一段时间了:,如果有人对此有可行的解决方案,欢迎贡献:)注意,
    Eigen::SimplicialLDLT
    现在是MPL2,它也可以基于符号分解预分配,只需调用
    analyzePattern(a)
    一次,然后
    factorize(a)
    。如果您知道
    A'*A
    的结构,您可以尝试在其非零上循环,对于每个非零
    (i,j)
    ,将其计算为
    (A.innerVector(i).cwiseProduct(b).dot(A.innerVector(j))
    ,使用
    b
    一个密集向量存储b的对角线。这应该是非常有效的,但我不能100%肯定这会比分配更快。根据@ggael的建议,我解决了以下问题:
    for(int I=1,k=0;I