Julia 中的复数计算,奇怪的结果?

xsn*_*snk 1 types linear-algebra julia

我正在 Julia 中做一些简单的线性代数练习。

以下是变量的定义方式

H = (1/sqrt(2)) * [1.0 + 0.0im 1.0 + 0.0im; 1.0 + 0.0im -1.0 + 0.0im;]
X = [0.0im 1.0 + 0.0im; 1.0 + 0.0im 0.0im;]
Run Code Online (Sandbox Code Playgroud)

H 计算为

 2×2 Array{Complex{Float64},2}:
 0.707107+0.0im   0.707107+0.0im
 0.707107+0.0im  -0.707107+0.0im
Run Code Online (Sandbox Code Playgroud)

X计算为

 2×2 Array{Complex{Float64},2}:
 0.0+0.0im  1.0+0.0im
 1.0+0.0im  0.0+0.0im
Run Code Online (Sandbox Code Playgroud)

单位矩阵定义为 I = [1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im;]

现在,这两个X * X以及H * H回报

2×2 Array{Complex{Float64},2}:
1.0+0.0im  0.0+0.0im
0.0+0.0im  1.0+0.0im
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。但

I == X * X # returns true

I == H * H # returns false
Run Code Online (Sandbox Code Playgroud)

X * X - I 返回

 2×2 Array{Complex{Float64},2}:
 0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,而对 H 做同样的事情

  2×2 Array{Complex{Float64},2}:
 -2.22045e-16+0.0im           0.0+0.0im
          0.0+0.0im  -2.22045e-16+0.0im
Run Code Online (Sandbox Code Playgroud)

我对朱莉娅很陌生。为什么会这样?

小智 5

这是因为sqrt(2)是一个浮点数,因此(sqrt(2)*sqrt(2))不等于 2。

解决此问题的一种方法是为代数数定义一种新类型,如您在AlgebracNumbers.jl所见

例子:

sqrt(AlgebracNumber(2))^2 == 2
Run Code Online (Sandbox Code Playgroud)

  • 也许值得指出的是,除非您正在做一些非常特殊的事情,否则您不需要担心浮点“不精确性”,并且使用浮点数就足够了,无需使用像“AlgebracNumber”这样的特殊数字类型。算法不应该对这样的事情敏感,而是重写代码来使用,例如近似比较而不是绝对比较等。 (6认同)