我一直在 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
Run Code Online (Sandbox Code Playgroud)
我最初的假设是小数位数的差异是导致错误的原因。因此我==
用?
(\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
Run Code Online (Sandbox Code Playgroud)
我已经多次阅读我的代码,我不知所措。我的对角矩阵 ( A_diag
) 中的值似乎与解矩阵相同。此外,将语句设置为近似等于 ( \approx
) 会呈现相同的错误,因此我假设我可以计算出十进制错误。
我的主要问题是:是什么导致了AssertionError
?
不,为了测试相等性,这些点被视为 0。
julia> Diagonal(1:2) == [1 0; 0 2]
true
Run Code Online (Sandbox Code Playgroud)
你的问题是你的数组实际上不相等;-128.49322764802145
不一样-128.493
。(数组的漂亮打印版本会截断浮点数以进行显示,但这不是真正的底层值!)。
[编辑:]
在这种情况下,使用?
( \approx
) 也会失败。原因在文档中解释isapprox()
二元运算符
?
等效于isapprox
使用默认参数,
如果
atol > 0
未指定an ,则rtol
默认为x
or类型的 eps 的平方根y
,以较大者为准(最不精确)。
本质上,这意味着?
将测试近似相等性,?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
Run Code Online (Sandbox Code Playgroud)
由于解矩阵提供六位有效数字的值,另一种替代方法是将值四舍五入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
Run Code Online (Sandbox Code Playgroud)