我使用Math.Net计算大型项目的基本矩阵的确定性。作为我的单元测试的一部分,我遇到了在调试测试时将float
转换为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**
我已阅读this question,但似乎无法解决我的问题。在发布模式而不是调试模式下运行对结果没有影响,它似乎只与附加调试器有关。
发生了什么,我怎样才能减少出现此错误的可能性?
修改
使用Matrix<double>
而不是Matrix<float>
会产生正确的答案。我猜测存在某种精确错误,但我不明白为什么。
答案 0 :(得分:0)
用于计算决定因素的算法通常在数值上不稳定,这就是为什么在可能的情况下最好避免它们(特别是,LAPACK不提供计算决定因素的任何例程)。
我的猜测是Determinant
函数正在调用LU分解例程,并且该调试模式重新排序了一系列计算,导致轻微的扰动将其推到整数边界上。