【问题标题】:EIGEN : Sparse matrix multiplication not producing a pruned resultEIGEN:稀疏矩阵乘法不产生修剪结果
【发布时间】:2017-02-09 17:09:35
【问题描述】:

我将 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 保存为非零,但比我使用 (A*B).pruned(); 时要少

我有三个问题:

  • 为什么result = (A*B).pruned()result=A*B;result.pruned(); 在非零值方面给出不同的结果(而不是有效的结果,这两种情况都是正确的)?
  • 为什么产品中的 0 值有时不被视为零值?
  • 你的结果和我一样吗?

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

感谢您的帮助。

编辑: VS2013 稀疏乘法的基准,W32 的调试/发布模式(有或没有 SSE2 指令集,两种情况下的结果相同);结果总是正确的,所以我没有在这里粘贴它,它没有带来任何信息。与:

1 = SparseMatrix&lt;int, RowMajor&gt; resultA = A*B;

2 = SparseMatrix&lt;int, RowMajor&gt; resultB = (A*B);resultB.pruned();

3 = SparseMatrix&lt;int, RowMajor&gt; 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 解决方案解决了问题(谢谢)。

【问题讨论】:

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


    【解决方案1】:

    我之前的回答(如下)是错误的。问题已修复there

    这是因为您的目标是 win32,因此您正在点击 FPU 寄存器扩展精度的经典问题。经过 默认情况下,pruned 删除严格等于 0 的条目,但 使用 FPU,可能只有在之后非零才变为零 被从它的寄存器复制到内存。更新编译器标志 以 SSE2 指令集为目标,或终止额外的 FPU 精度。

    【讨论】:

    • 我刚刚将编译器标志更改为 SSE2 指令集,仍然将 0 视为零值。杀死额外的 FPU 精度是什么意思?写转换器之类的东西?我做了一个基准测试,根据结果我不确定这是一个精度问题,因为根据您调用函数的顺序,结果会有所不同。我将在第一篇文章中添加这个。
    • 你是对的。问题在 3.3 和开发分支中修复。
    猜你喜欢
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2023-03-16
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多