Julia中的矩阵乘法逆舍入误差

时间:2015-10-01 00:22:17

标签: matrix precision julia matrix-multiplication matrix-inverse

for(int x = 1; x <= 100; x++) {
    cout << x << " ";
    if ((x%10)==0) cout << endl;
}

为什么结果位于左上角julia> A = [1 2; 3 4] 2x2 Array{Int64,2}: 1 2 3 4 julia> A * inv(A) 2x2 Array{Float64,2}: 1.0 0.0 8.88178e-16 1.0 而非8.88178e-16,如右上角?如何执行操作以便得到0.0作为结果。

有没有办法根据需要显示结果,但实际上象素地执行矩阵运算,就像在muPad或其他一些符号评估器中一样?

1 个答案:

答案 0 :(得分:4)

如评论中所述,最好的方法是使用Rational类型。 E.x.,A = Rational{Int}[1 2;3 4],以您想要的格式使用A*float(inv(A))获取输出。致@mschauer的信用。

为了详细说明,通常在计算中使用的浮点数具有有限的精度,并且不能表示所有实数。因此,使用浮点数操作时会出现这些错误。有关此问题的详细信息,请参阅注释中的链接。

然而,Julia可以很容易地定义其他数字类型,并根据需要对它们进行操作。其中一个是有理数字类型,它可以精确地表示分数。我们可以创建数组作为有理数:

julia> A = Rational{Int}[1 2;3 4] 2x2 Array{Rational{Int64},2}: 1//1 2//1 3//1 4//1

然后,对此数组的操作将返回完全合理的结果

julia> A*(inv(A)) 2x2 Array{Rational{Int64},2}: 1//1 0//1 0//1 1//1

如果我们希望结果为浮点数,则可以在计算结束时转换它们。

julia> float(A*(inv(A))) 2x2 Array{Float64,2}: 1.0 0.0 0.0 1.0

请务必注意,默认情况下使用浮点数的原因是性能。 CPU已经过优化,可以对浮点数进行操作,并且使用上述的有理数将会慢得多。然而,Julia为您提供了工具,让您可以根据自己的需要自行做出选择。