在 Julia 中断言对角化向量时,是什么导致“AssertionError”?
What causes `AssertionError` when asserting a diagonalized vector in Julia?
我一直在做一些 exercises in julia,我目前正在尝试 @assert
一个向量,该向量已经对角化为一个矩阵,与练习笔记本中给出的“解矩阵”相对应。但是,在根据提供的解决方案断言我的代码时,我得到了 AssertionError
。我的代码示例:
julia> using LinearAlgebra
julia> A =
[
140 97 74 168 131
97 106 89 131 36
74 89 152 144 71
168 131 144 54 142
131 36 71 142 36
]
5×5 Matrix{Int64}:
140 97 74 168 131
97 106 89 131 36
74 89 152 144 71
168 131 144 54 142
131 36 71 142 36
julia> A_eigv = eigen(A).values
5-element Vector{Float64}:
-128.49322764802145
-55.887784553057
42.752167279318854
87.16111477514494
542.4677301466137
julia> A_diag = Diagonal(A_eigv)
5×5 Diagonal{Float64, Vector{Float64}}:
-128.493 ⋅ ⋅ ⋅ ⋅
⋅ -55.8878 ⋅ ⋅ ⋅
⋅ ⋅ 42.7522 ⋅ ⋅
⋅ ⋅ ⋅ 87.1611 ⋅
⋅ ⋅ ⋅ ⋅ 542.468
julia> @assert A_diag == [-128.493 0.0 0.0 0.0 0.0;
0.0 -55.8878 0.0 0.0 0.0;
0.0 0.0 42.7522 0.0 0.0;
0.0 0.0 0.0 87.1611 0.0;
0.0 0.0 0.0 0.0 542.468]
AssertionError: A_diag == [-128.493 0.0 0.0 0.0 0.0; 0.0 -55.8878 0.0 0.0 0.0; 0.0 0.0 42.7522 0.0 0.0; 0.0 0.0 0.0 87.1611 0.0; 0.0 0.0 0.0 0.0 542.468]
Stacktrace:
[1] top-level scope
@ In[90]:1
[2] eval
@ ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
我最初的假设是小数位数的差异是错误的原因。因此,我将 ==
替换为 ≈
(\approx
)。但是,如下面的代码示例所示,错误仍然存在:
julia> @assert A_diag ≈ #\approx
[-128.493 0.0 0.0 0.0 0.0;
0.0 -55.8878 0.0 0.0 0.0;
0.0 0.0 42.7522 0.0 0.0;
0.0 0.0 0.0 87.1611 0.0;
0.0 0.0 0.0 0.0 542.468]
AssertionError: A_diag ≈ [-128.493 0.0 0.0 0.0 0.0; 0.0 -55.8878 0.0 0.0 0.0; 0.0 0.0 42.7522 0.0 0.0; 0.0 0.0 0.0 87.1611 0.0; 0.0 0.0 0.0 0.0 542.468]
Stacktrace:
[1] top-level scope
@ In[97]:1
[2] eval
@ ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
我已经多次通读我的代码了,我不知所措。我的对角矩阵 (A_diag
) 中的值似乎与解矩阵相同。此外,将语句设置为近似等于 (\approx
) 会呈现相同的错误,因此我假设我可以算出小数错误。
我的主要问题是:是什么导致了 AssertionError
?
不,为了测试相等性,这些点被视为 0。
julia> Diagonal(1:2) == [1 0; 0 2]
true
你的问题是你的数组实际上不相等; -128.49322764802145
与 -128.493
不同。 (数组的漂亮打印版本截断了浮点数以供显示,但这不是真正的基础值!)。
[编辑:]
使用≈
(\approx
) 在这种情况下也会失败。 isapprox()
的文档中解释了这样做的原因
The binary operator ≈
is equivalent to isapprox
with the default arguments,
if an atol > 0
is not specified, rtol
defaults to the square root of eps of the type of x
or y
, whichever is bigger (least precise).
本质上,这意味着 ≈
将测试近似相等,相对容差 √eps()
大约等于 1.5e-8,或 0.0000015%。这个容忍度太低了,增加容忍度会解决这个问题。例如:
# Option 1: Absolute tolerance. Set to a reasonable max deviation:
julia> isapprox(A_diag, sol_mat, atol = 1e-3)
true
# Option 2: Relative tolerance. Setting rtol = 1e-n, n is the number of significant digits in either matrices will work in most cases.
julia> isapprox(A_diag, sol_mat, rtol = 1e-6)
true
由于解矩阵提供了六位有效数字的值,另一种替代方法是将 A_diag
中的值四舍五入到这个数字 og 数字并测试是否相等。例如:
julia> round.(A_diag, RoundNearestTiesUp, sigdigits=6) ==
[-128.493 0.0 0.0 0.0 0.0;
0.0 -55.8878 0.0 0.0 0.0;
0.0 0.0 42.7522 0.0 0.0;
0.0 0.0 0.0 87.1611 0.0;
0.0 0.0 0.0 0.0 542.468]
true
我一直在做一些 exercises in julia,我目前正在尝试 @assert
一个向量,该向量已经对角化为一个矩阵,与练习笔记本中给出的“解矩阵”相对应。但是,在根据提供的解决方案断言我的代码时,我得到了 AssertionError
。我的代码示例:
julia> using LinearAlgebra
julia> A =
[
140 97 74 168 131
97 106 89 131 36
74 89 152 144 71
168 131 144 54 142
131 36 71 142 36
]
5×5 Matrix{Int64}:
140 97 74 168 131
97 106 89 131 36
74 89 152 144 71
168 131 144 54 142
131 36 71 142 36
julia> A_eigv = eigen(A).values
5-element Vector{Float64}:
-128.49322764802145
-55.887784553057
42.752167279318854
87.16111477514494
542.4677301466137
julia> A_diag = Diagonal(A_eigv)
5×5 Diagonal{Float64, Vector{Float64}}:
-128.493 ⋅ ⋅ ⋅ ⋅
⋅ -55.8878 ⋅ ⋅ ⋅
⋅ ⋅ 42.7522 ⋅ ⋅
⋅ ⋅ ⋅ 87.1611 ⋅
⋅ ⋅ ⋅ ⋅ 542.468
julia> @assert A_diag == [-128.493 0.0 0.0 0.0 0.0;
0.0 -55.8878 0.0 0.0 0.0;
0.0 0.0 42.7522 0.0 0.0;
0.0 0.0 0.0 87.1611 0.0;
0.0 0.0 0.0 0.0 542.468]
AssertionError: A_diag == [-128.493 0.0 0.0 0.0 0.0; 0.0 -55.8878 0.0 0.0 0.0; 0.0 0.0 42.7522 0.0 0.0; 0.0 0.0 0.0 87.1611 0.0; 0.0 0.0 0.0 0.0 542.468]
Stacktrace:
[1] top-level scope
@ In[90]:1
[2] eval
@ ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
我最初的假设是小数位数的差异是错误的原因。因此,我将 ==
替换为 ≈
(\approx
)。但是,如下面的代码示例所示,错误仍然存在:
julia> @assert A_diag ≈ #\approx
[-128.493 0.0 0.0 0.0 0.0;
0.0 -55.8878 0.0 0.0 0.0;
0.0 0.0 42.7522 0.0 0.0;
0.0 0.0 0.0 87.1611 0.0;
0.0 0.0 0.0 0.0 542.468]
AssertionError: A_diag ≈ [-128.493 0.0 0.0 0.0 0.0; 0.0 -55.8878 0.0 0.0 0.0; 0.0 0.0 42.7522 0.0 0.0; 0.0 0.0 0.0 87.1611 0.0; 0.0 0.0 0.0 0.0 542.468]
Stacktrace:
[1] top-level scope
@ In[97]:1
[2] eval
@ ./boot.jl:360 [inlined]
[3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
我已经多次通读我的代码了,我不知所措。我的对角矩阵 (A_diag
) 中的值似乎与解矩阵相同。此外,将语句设置为近似等于 (\approx
) 会呈现相同的错误,因此我假设我可以算出小数错误。
我的主要问题是:是什么导致了 AssertionError
?
不,为了测试相等性,这些点被视为 0。
julia> Diagonal(1:2) == [1 0; 0 2]
true
你的问题是你的数组实际上不相等; -128.49322764802145
与 -128.493
不同。 (数组的漂亮打印版本截断了浮点数以供显示,但这不是真正的基础值!)。
[编辑:]
使用≈
(\approx
) 在这种情况下也会失败。 isapprox()
The binary operator
≈
is equivalent toisapprox
with the default arguments,
if an
atol > 0
is not specified,rtol
defaults to the square root of eps of the type ofx
ory
, whichever is bigger (least precise).
本质上,这意味着 ≈
将测试近似相等,相对容差 √eps()
大约等于 1.5e-8,或 0.0000015%。这个容忍度太低了,增加容忍度会解决这个问题。例如:
# Option 1: Absolute tolerance. Set to a reasonable max deviation:
julia> isapprox(A_diag, sol_mat, atol = 1e-3)
true
# Option 2: Relative tolerance. Setting rtol = 1e-n, n is the number of significant digits in either matrices will work in most cases.
julia> isapprox(A_diag, sol_mat, rtol = 1e-6)
true
由于解矩阵提供了六位有效数字的值,另一种替代方法是将 A_diag
中的值四舍五入到这个数字 og 数字并测试是否相等。例如:
julia> round.(A_diag, RoundNearestTiesUp, sigdigits=6) ==
[-128.493 0.0 0.0 0.0 0.0;
0.0 -55.8878 0.0 0.0 0.0;
0.0 0.0 42.7522 0.0 0.0;
0.0 0.0 0.0 87.1611 0.0;
0.0 0.0 0.0 0.0 542.468]
true