特征:修改稀疏矩阵'三元组列表,而不是使用coeffRef

时间:2017-06-06 07:16:51

标签: c++ eigen

我正面临着组装Eigen::SparseMatrix的问题。实际上,它涉及有限元系统矩阵,通过循环元素和积分点来组装。下面我提出了更抽象的问题。

我首先构建一个三元组列表来初始化矩阵(如Eigen documentation中所述)。然后,我使用coeffRef在并发循环中执行汇编(参见下面的示例)。问题涉及coeffRef"执行二进制搜索"这一事实,而我确切知道每个项目在三元组列表中的位置(T下方)。更具体地说:

  • 修改三元组列表以避免coeffRef是否更有效,代价是必须重新初始化稀疏矩阵?

  • 如果想要修改三元组列表中的值,是否有比

    更优雅的东西
    T[i] = Trip(T[i].row(),T[i].col(),T[i].value()+X);
    

我意识到答案可能在很大程度上取决于矩阵的带宽(即搜索的成本),但可能会有一些关于此的通用事项。

实施例

#include <iostream>
#include <Eigen/Sparse>

typedef Eigen::SparseMatrix<double> SpMat;
typedef Eigen::Triplet     <double> Trip;

int main(void)
{
  size_t N = 100;

  SpMat A(N,N);

  std::vector<Trip> T;
  T.reserve(3*N);

  for ( size_t i=0; i<N; ++i )
  {
    if ( i==0   ) T.push_back(Trip(i,i  ,-1.0));
    else          T.push_back(Trip(i,i-1,-1.0));

    T.push_back(Trip(i,i,+2.0));

    if ( i==N-1 ) T.push_back(Trip(i,0  ,-1.0));
    else          T.push_back(Trip(i,i+1,-1.0));
  }

  A.setFromTriplets(T.begin(),T.end());

  for ( size_t i=0; i<N; ++i )
    A.coeffRef(i,i) += static_cast<double>(i);

  return 0;
}

使用例如编译:

clang++ -I/usr/local/include/eigen3 test.cpp

1 个答案:

答案 0 :(得分:2)

我的猜测是,只要coeffRef访问的系数已经存在于矩阵中,那么调用coeffRef应该比从三元组列表重建矩阵更快。

假设您可以直接使用已知结构计算coeffRef,您可能也会通过使用A.valuesPtr()[A.outerindexPtr()[i]+some_offset] += ...直接访问基础数据结构来超越some_offset执行的二进制搜索。

最后,如果您需要更新所有条目,您还可以使用InnerIterator it按顺序对其进行迭代,并使用it.valueRef() += ...更新条目。