SparseMatrix,setZero,数据分配和innerNonZeros:如何有效地将矩阵归零?

时间:2019-05-15 11:00:23

标签: eigen

本征重新分配太多次。

[问题]

setZero不会释放内存-太好了。 setZero将innerNNZ设置为零:这几乎是正确的,因为我想要一个零矩阵。

如果我想在矩阵中分配的位置上设置一个值,则代码将查询innerNNZ以确定没有分配任何内容,然后重新分配所有内容。

显然,出于相同的原因,使用coeffRef()而不是insert()将无济于事。

[背景]

我正在操纵SparseMatrix。 首先,我根据某种模式预分配矩阵。 其次,我打开一个循环到: -将矩阵设置为零 -在其中盖章值 -做一些数学

我想在循环开始时将矩阵清零(我不每次都在同一图案上加盖印记)。 将其设置为零会导致将innerNNZ归零,并且冲压(逐个元素)将生效:浪费大量时间。

[要测试的代码]

int nx = 10;
int ny = nx;
Eigen::VectorXi sizeToReserve(nx);
for(int i = 0; i < nx; i++) 
   sizeToReserve[i] = myOwnBusiness(i);
SparseMatrix<double> mat;
mat.uncompress();
mat.reserve(sizeToReserve);

for(int i = 0; i < nbRun; i++) {
   mat.setZero();
   for(int j = 0; j < nx; j++) {
      for (int k = 0; k < ny; k++) {
         mat.insert(j,k) = aValue(i,j,k);
      }
   }
   // Do fancy stuff
}

我希望mat.insert不会重新分配内存。

[技巧]

我将矩阵缩放为零,以避免接触innerNNZ和externalIndex数组。

1 个答案:

答案 0 :(得分:1)

您可以使用(从docs改编)遍历非零:

for (int k=0; k<mat.outerSize(); ++k)
   for (SparseMatrix<double>::InnerIterator it(mat,k); it; ++it)
      it.valueRef() = 0.0;

另一种选择是将数据指针包装在Eigen::Map<VectorXd>中,并将其用于setZero()

Map<VectorXf>(mat.valuePtr(), mat.nonZeros()).setZero();