EIGEN:稀疏矩阵乘法不产生修剪结果

时间:2017-02-09 17:09:35

标签: visual-studio-2013 sparse-matrix eigen eigen3

我正在使用EIGEN进行稀疏矩阵优化和函数。一切都“正常”,除非在某些情况下,我无法理解这种情况。

事情就是这样:

Matrix A
2 0 0
0 2 0
0 0 2

Matrix B
6 3
0 1
2 8

Result
12 6 
0 2 
4 16 

正如您所看到的,这是正确的结果,而且我总能得到正确的结果。

问题在于被视为“非零”的值。在这种情况下:

SparseMatrix<int, RowMajor> A;
SparseMatrix<int, RowMajor> B;
//Parsing and initializing matrix
SparseMatrix<int, RowMajor> result = A*B;
result.pruned();
cout << result.nonZeros();

nonZeros()的结果是5,这是“正常”情况,因为Result只有5个非零值。 现在,让我们考虑一下这段代码:

SparseMatrix<int, RowMajor> A;
SparseMatrix<int, RowMajor> B;
//Parsing and initializing matrix
SparseMatrix<int, RowMajor> result = (A*B).pruned();
cout << result.nonZeros();

nonZeros()的结果是6.我不明白为什么,这是the documentation上提供的语法。

现在最奇怪的部分是,在非常大的矩阵result = A*B; result.pruned()上有时也会将0保存为nonZero,但是比我使用(A*B).pruned();

时更少

我有三个问题:

  • 为什么result = (A*B).pruned()result=A*B;result.pruned();会针对nonZero值给出不同的结果(而不是有效结果,这两种情况都是正确的)?
  • 为什么产品中的0值有时不被视为零值?
  • 你的结果与我相同吗?

我正在使用Visual Studio Professional 2013和Eigen 3.3.2,使用DEBUG模式并定位WIN32。

感谢您的帮助。

编辑:使用VS2013的稀疏乘法基准,W32的DEBUG /释放模式(有或没有SSE2指令集,两种情况都相同);结果总是正确的,所以我不是在这里粘贴它,它没有带来任何信息。随着:

1 = SparseMatrix<int, RowMajor> resultA = A*B;

2 = SparseMatrix<int, RowMajor> resultB = (A*B);resultB.pruned();

3 = SparseMatrix<int, RowMajor> resultC = (A*B).pruned();

案例1

Matrix A
2 0 0
0 2 0
0 0 2

Matrix B
5 3
0 1
2 8

预期值= 5

1 = 5

2 = 5

3 = 6

案例2 矩阵太大,here是文件

预期值= 0

1 = 1444

2 = 1444

3 = 0

正如您所看到的,根据输入和我调用函数的方式,结果是否优化,并且1,2或3都不适用于每种情况。

EDIT²:问题由ggael解决方案解决(谢谢)。

1 个答案:

答案 0 :(得分:1)

我之前的回答(下面)错了。问题已修复there

  

这是因为你的目标是win32,因此你正在打击   FPU寄存器扩展精度的经典问题。通过   默认情况下,pruned删除严格等于0的条目,但是   对于FPU,可能只有在非零后才变为零   被从寄存器复制到内存。更新编译器标志   要么瞄准SSE2指令集,要么杀死额外的FPU   精度。