将标量添加到 Eigen::SparseMatrix 的每个非零条目
Add scalar to every non-zero entry of an Eigen::SparseMatrix
我有一个巨大的 Eigen::SparseMatrix
,我想向矩阵中的非零项添加一个标量。
也就是说,如果我有一个矩阵 A
,其值 _
表示稀疏矩阵中的一个 0
条目,即它从未被插入。
1 _ 2
A = _ 3 _
4 5 6
我想做类似 A += 1
的事情并到达
2 _ 3
A = _ 4 _
5 6 7
其中零条目不受影响。
有什么有效的方法吗?
我知道三种不同的方法:
Loop over all the non-zero values using an InnerIterator
for (int k=0; k<A.outerSize(); ++k)
for (SparseMatrix<double>::InnerIterator it(A,k); it; ++it)
it.valueRef() += 1;
这是一种通用方法,适用于所有情况,但可能比其他方法慢。
使用coeffs
运算符得到包含所有非零元素的一维向量
A.makeCompressed();
A.coeffs() += 1;
如果矩阵已经是压缩格式或者您需要压缩格式,此方法可能会更快。
使用valuePtr
访问原始数据
typedef Map<const Array<double,Dynamic,1> > CoeffMap;
CoeffMap coeffs(A.valuePtr(), A.outerIndexPtr()[A.outerSize()]);
coeffs += 1;
这种方法可能是最快的方法,但也是最棘手的方法,并且由于对未初始化的数据执行浮动基础操作,在某些机器上可能会更慢(参见 chtz 的评论)。如果A
是压缩格式,此方法等同于方法2。
请注意,我没有对不同的方法进行基准测试。性能信息完全基于直觉。如果你想这样做,一定要使用真实大小的矩阵。
作为@m7913d 的第二个回答的补充:coeffs()
是处理系数式数学函数的一个非常有用的函数。 Eigen 文档只提供了基于稠密矩阵的数学计算 -> https://eigen.tuxfamily.org/dox/group__CoeffwiseMathFunctions.html
例如,您可以这样做:
A.coeffs() = A.coeffs.exp();
我有一个巨大的 Eigen::SparseMatrix
,我想向矩阵中的非零项添加一个标量。
也就是说,如果我有一个矩阵 A
,其值 _
表示稀疏矩阵中的一个 0
条目,即它从未被插入。
1 _ 2
A = _ 3 _
4 5 6
我想做类似 A += 1
的事情并到达
2 _ 3
A = _ 4 _
5 6 7
其中零条目不受影响。
有什么有效的方法吗?
我知道三种不同的方法:
Loop over all the non-zero values using an
InnerIterator
for (int k=0; k<A.outerSize(); ++k) for (SparseMatrix<double>::InnerIterator it(A,k); it; ++it) it.valueRef() += 1;
这是一种通用方法,适用于所有情况,但可能比其他方法慢。
使用
coeffs
运算符得到包含所有非零元素的一维向量A.makeCompressed(); A.coeffs() += 1;
如果矩阵已经是压缩格式或者您需要压缩格式,此方法可能会更快。
使用
访问原始数据valuePtr
typedef Map<const Array<double,Dynamic,1> > CoeffMap; CoeffMap coeffs(A.valuePtr(), A.outerIndexPtr()[A.outerSize()]); coeffs += 1;
这种方法可能是最快的方法,但也是最棘手的方法,并且由于对未初始化的数据执行浮动基础操作,在某些机器上可能会更慢(参见 chtz 的评论)。如果
A
是压缩格式,此方法等同于方法2。
请注意,我没有对不同的方法进行基准测试。性能信息完全基于直觉。如果你想这样做,一定要使用真实大小的矩阵。
作为@m7913d 的第二个回答的补充:coeffs()
是处理系数式数学函数的一个非常有用的函数。 Eigen 文档只提供了基于稠密矩阵的数学计算 -> https://eigen.tuxfamily.org/dox/group__CoeffwiseMathFunctions.html
例如,您可以这样做:
A.coeffs() = A.coeffs.exp();