C ++ - MATLAB:逐块更新稀疏矩阵

时间:2017-03-02 08:45:10

标签: c++ matlab sparse-matrix eigen

这里的Matlab代码

 N = 4096;
 x       =   linspace(-1,1,N);     
 A = sparse(100000,100000); 
 index = 1:32;

 A(index,index)    =   kernel(x(index),x(index));
  //kernel here outputs a 32 x 32 matrix 

我必须将MATLAB代码转换为C ++,但我坚持使用稀疏函数,我尝试使用:

 N=4096;
 Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(N,-1,1); 
 Eigen::SparseMatrix<double> A(Asize,Asize);
 A.block(1,1,index.size(), index.size()) = Kernel();

但SparseMatrix将阻止作为只读功能,因此无法用于更新矩阵。

另一点:

我已经阅读了Eigen文档并检查了不同形式的SparseMatrix声明:

 typedef Eigen::Triplet<double> T;
 std::vector<T>tripleList;
 tripleList.reserve(nnz);

 for(...)
 {
  // ...
  tripletList.push_back(T(i,j,v_ij));   //?? what are these values?
  }
 A.setFromTriplets(tripleList.begin(), tripleList.end());

但是我不明白nnz应该是什么值,它应该是我从Matlab代码得到的值以及我应该通过for循环得到什么值?它们是随机的,如果矩阵大小太大,我如何选择“推动值”。

另外,最后一个问题仍然存在,声明后的稀疏矩阵将如何逐块更新?

1 个答案:

答案 0 :(得分:3)

通常,特征稀疏矩阵块是常量。此规则的例外是例如列主要矩阵中的m.col(i)或主要矩阵中的.row(i)

至于你的第二点,nnz是非零的数量。通过指定矩阵在开始时需要保留多少个非零,可以最小化构造稀疏矩阵时所需的重新分配/复制的数量。请参阅documentation。另请注意,如果您知道每列中需要多少元素,other overload非常有用。 关于for循环,假设您有三个数组:columnIndicesrowIndicesvalues,所有数组都为nnz。你的for循环看起来像:

for(int i = 0; i < nnz; i++)
{
    tripletList.push_back(T(columnIndices[i], rowIndices[i], values[i]));
}

或者,您可以计算for循环中每个三元组的值。