将标量添加到Eigen :: SparseMatrix的每个非零条目

Enr*_*rba 2 c++ sparse-matrix eigen

我有一个巨大的Eigen::SparseMatrix,我想在矩阵中的非零条目中添加一个标量.

也就是说,如果我有一个矩阵A,其值_表示0稀疏矩阵中的一个条目,即它从未插入.

    1 _ 2
A = _ 3 _
    4 5 6
Run Code Online (Sandbox Code Playgroud)

我想做点什么,A += 1然后到达

    2 _ 3
A = _ 4 _
    5 6 7
Run Code Online (Sandbox Code Playgroud)

零条目不受影响的地方.

有没有有效的方法来做到这一点?

m79*_*13d 5

我知道三种不同的方法:

  1. 使用a循环遍历所有非零值 InnerIterator

    for (int k=0; k<A.outerSize(); ++k)
      for (SparseMatrix<double>::InnerIterator it(A,k); it; ++it)
        it.valueRef() += 1;
    
    Run Code Online (Sandbox Code Playgroud)

    这是一种通用方法,适用于所有情况,但可能比其他方法慢.

  2. 使用coeffs运算符获取包含所有非零元素的1D向量

    A.makeCompressed();
    A.coeffs() += 1;
    
    Run Code Online (Sandbox Code Playgroud)

    如果矩阵已经是压缩形式或者您需要压缩格式,则此方法可能更快.

  3. 使用访问原始数据 valuePtr

    typedef Map<const Array<double,Dynamic,1> > CoeffMap;
    CoeffMap coeffs(A.valuePtr(), A.outerIndexPtr()[A.outerSize()]);
    coeffs += 1;
    
    Run Code Online (Sandbox Code Playgroud)

    这种方法可能是最快的方法,但也是最棘手的方法,并且由于对未初始化的数据执行浮动基本操作,在某些机器上可能更慢(参见chtz的注释).如果A是压缩格式,则此方法等同于方法2.

请注意,我没有对不同方法进行基准测试.性能信息纯粹基于直觉.如果你想这样做,一定要使用真正大小的矩阵.