特征:稀疏矩阵pruned()不会删除阈值以下的条目

时间:2019-03-11 07:22:20

标签: c++ eigen matrix-multiplication eigen3

我想使用Eigen进行稀疏矩阵乘法,其中我希望在每次迭代中都删除低于某个阈值的所有条目。在我看来,Eigen只会删除完全等于零的元素。

我正在运行使用g ++进行编译的Eigen 3.3.7。

#include <Eigen/Sparse>
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
typedef SparseMatrix<double> CscMat;            
typedef SparseMatrix<double,RowMajor> CsrMat;    

int N = 4;
CsrMat S, S2;

MatrixXd D(N, N), D2(N,N);
D << 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16;
D *= 0.1;

S = D.sparseView(0.5);
std::cout << D  << std::endl;
std::cout << S.nonZeros()  << std::endl;

D2 = D;
D2 = (D2.array() < 0.5).select(0, D2);
S2 = D2.sparseView();
std::cout << D  << std::endl;
std::cout << S2.nonZeros() << std::endl;

在上面的S.nonzeros()返回16,而不是像S2.nonzeros()那样预期的12。

输出为:

0.1 0.2 0.3 0.4
0.5 0.6 0.7 0.8
0.9   1 1.1 1.2
1.3 1.4 1.5 1.6
16

  0   0   0   0
0.5 0.6 0.7 0.8
0.9   1 1.1 1.2
1.3 1.4 1.5 1.6
12

2 个答案:

答案 0 :(得分:1)

sparseView的第二个参数是reference。最后,两者的乘积将确定阈值,因此您应该使用以下行:

S = D.sparseView(0.5, 1.0 - std::numeric_limits<double>::epsilon());

获得您想要的东西。

进行评估的实际代码在MathFunctions.h

static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, 
                                     const RealScalar& prec)
{
   return numext::abs(x) <= numext::abs(y) * prec;
}

其中double类型的默认prec是(当前)1e-12

答案 1 :(得分:1)

如果您阅读sparseView的{​​{3}},则会看到第一个参数不是绝对阈值,而是引用非零值(如果是你比较喜欢)。然后,第二个可选参数是相对阈值。这与pruned()的逻辑相同。如果您需要绝对阈值,则可以执行以下操作:

S = D.sparseView(1,0.5);
S = D.sparseView(0.5,1);