0

我正在使用 Math.Net 来计算大型项目的基本矩阵的确定性。作为单元测试的一部分,我在调试测试时遇到了将 a 转换float为 an不同的问题。int似乎附加调试器会在没有它的情况下产生不同的运行结果。

using System;
using MathNet.Numerics.LinearAlgebra;

public class Test
{
    public static void Main(string[] args)
    {
        Matrix<float> a = Matrix<float>.Build.Dense(2, 2, new float[] { 10, 19, 25, 10 });

        Console.WriteLine("Det {0}", a.Determinant());
        Console.WriteLine("Det Int {0}", (int)a.Determinant());
        Console.WriteLine("Det Trunc {0}", Math.Truncate(a.Determinant()));
        Console.WriteLine("Det Floor {0}", Math.Floor(a.Determinant()));
    }
}

正常运行测试时,我得到以下结果:

Det -375
Det Int -374
Det Trunc -374
Det Floor -375

但是,在调试代码时,我得到了这个:

Det -375
Det Int **-375**
Det Trunc **-375**
Det Floor **-376**

我已经阅读了这个问题,但它似乎并没有解决我的问题。在发布模式而不是调试模式下运行对结果没有影响,它似乎只与附加调试器有关。

发生了什么事,我怎样才能减少这个错误的可能性?

编辑: 使用Matrix<double>而不是Matrix<float>产生正确的答案。我猜有某种精度错误,但我不明白为什么

4

1 回答 1

0

计算行列式的算法通常在数值上不稳定,这就是为什么如果可能最好避免使用它们的原因(值得注意的是,LAPACK 不提供任何计算行列式的例程)。

我的猜测是该Determinant函数正在调用 LU 分解例程,并且该调试模式重新排序了一系列计算,导致轻微的扰动将其推过整数边界。

于 2014-12-09T12:50:42.917 回答