我在C中使用Eigen库,我试图找到矩阵的行列式.根据我如何初始化矩阵,我会得到不同的结果.
方法一:
MatrixXd a(3, 3);
for (int n = 0; n < 3; n++)
for (int m = 0; m < 3; m++)
a(n,m) = (double) (n + m*m + 2.5)/3;
cout << "Matrix a: " << endl;
cout << a << endl;
cout << "Determinat of matrix a is: " << a.determinant() << endl;
这部分代码打印出来
Matrix a:
0.8333333 1.166667 2.166667
1.166667 1.5 2.5
1.5 1.833333 2.833333
Determinat of matrix a is: -7.401487e-17
方法二:
MatrixXd b(3, 3);
b << 0.8333333, 1.166667, 2.166667,
1.166667, 1.5, 2.5,
1.5, 1.833333, 2.833333;
cout << b;
cout << endl << "Determinant of matrix b is: " << b.determinant();
打印
0.8333333 1.166667 2.166667
1.166667 1.5 2.5
1.5 1.833333 2.833333
Determinant of matrix b is: 2.333331e-07
方法I产生错误的结果,而方法II给出正确的答案.第一种情况出了什么问题? (我正在使用Visual Studio.)提前感谢!
解决方法:
您在此观察到的是计算中的舍入误差.让我这样解释一下:
对于计算机而言,一切都基于二进制数系统,即我们在日常生活中使用的基数10,而不是基数10,计算机用基数2计算,即只有数字0和1.
这不仅适用于整数,也适用于像0.83333这样的实数……
但就像无法写入0.83333的所有数字……,您的计算机无法存储此数字的二进制表示的每个最后一位数 – 因此它必须以某种方式舍入结果.
根据您的初始化方式(通过计算(n m * m 2.5)/ 3或通过读取逗号初始化中的值),结果可能在最后一位数字中略有不同,从而导致不同的结果.
您可以通过比较0.8333333和2.5 / 3来尝试这一点,这可能会返回false.如果您打印数字,您会得到相同的结果,但内部表示略有不同.
但是你应该注意到绝对误差本身很小(小于0.000001),所以你现在不需要担心它.
如果您想要精确的结果,切换到可以准确表示这些值的有理数字类型可能会有所帮助.