我正面临着组装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
答案 0 :(得分:2)
我的猜测是,只要coeffRef
访问的系数已经存在于矩阵中,那么调用coeffRef
应该比从三元组列表重建矩阵更快。
假设您可以直接使用已知结构计算coeffRef
,您可能也会通过使用A.valuesPtr()[A.outerindexPtr()[i]+some_offset] += ...
直接访问基础数据结构来超越some_offset
执行的二进制搜索。
最后,如果您需要更新所有条目,您还可以使用InnerIterator it
按顺序对其进行迭代,并使用it.valueRef() += ...
更新条目。