`Complex{Float128}`及更高精度矩阵怎么求特征值问题?

我想计算:

\lambda v=Mv + e^{i \lambda t}u

这个方程。其中, v,u 分别为未知、已知列向量。 \lambda,t 为未知、已知数。 M 为已知复数矩阵。

整个是特征方程的变体——右边多了一个和特征值有关的振荡项。

我没有找到解它的好方法。只给出了牛顿迭代的方案。但是计算精度成了问题。

Q1: 对于这个方程,有数学好的大佬有解法吗?或者有直接的包吗?


我希望用更高精度计算。但是LinearAlgebraeigen不支持Complex{BigFloat}

Q2Complex{BigFloat}有求特征值、特征向量的包吗?它精度还蛮高的。

然后看到英文论坛差不多的问题,人家推荐Float128。我就试了试这个包 JuliaMath/Quadmath.jl: Float128 and libquadmath for the Julia language (github.com)Float128和这个包 JuliaMath/DoubleFloats.jl: math with more good bits (github.com)Double64

但是,我发现:

julia > sizeof(Float128(1))
16
julia > sizeof(Double64(1))
16

Q3:俩不是一样大吗?DoubleFloats说的这句话没看懂,求大佬解释:

Float128s have 6 more significant bits than Double64s, and a much wider exponent range (Double64s exponents have the same range as Float64s).

最后,Complex{Float128}我试过了,没法求特征值问题。比如我提供一个矩阵:

M = Complex{Float128}.([1.0 2.0 3.0 4.0 5.0; 2.0 1.0 2.0 3.0 4.0; 3.0 2.0 1.0 2.0 3.0; 4.0 3.0 2.0 1.0 2.0; 5.0 4.0 3.0 2.0 1.0])

它用ArpackeigsLinearAlgebraeigenKrylovKiteigsolve都会报错。那么:
Q4Complex{Float128}的矩阵怎么求特征值和特征向量呢。

或许你应该这样做:

using LinearAlgebra
setprecision(128)
m=Complex{BigFloat}[1 0;0 1]
eigen(m)

谢谢大佬,差点把我大脑干烧了:BigFloat我应该是最早就尝试过的。

试了试,BigFloat好像矩阵一复杂就不能算。

julia> M = ComplexF64[1.0 2.0; 3.0 4.]; eigen(M)
Eigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}}
values:
2-element Vector{ComplexF64}:
 -0.3722813232690143 + 0.0im
   5.372281323269014 + 0.0im
vectors:
2×2 Matrix{ComplexF64}:
  0.824565+0.0im  0.415974+0.0im
 -0.565767-0.0im  0.909377+0.0im

julia> M = Complex{BigFloat}[1.0 2.0; 3.0 4.]; eigen(M)
ERROR: MethodError: no method matching eigen!(::Matrix{Complex{BigFloat}}; permute=true, scale=true, sortby=LinearAlgebra.eigsortby)
Closest candidates are:
  eigen!(::SymTridiagonal{var"#s814", V} where {var"#s814"<:Union{Float32, Float64}, V<:AbstractVector{var"#s814"}}) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\tridiag.jl:280 got unsupported keyword arguments "permute", "scale", "sortby"
  eigen!(::SymTridiagonal{var"#s814", V} where {var"#s814"<:Union{Float32, Float64}, V<:AbstractVector{var"#s814"}}, ::UnitRange) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\tridiag.jl:283 got unsupported keyword arguments "permute", "scale", "sortby"
  eigen!(::SymTridiagonal{var"#s814", V} where {var"#s814"<:Union{Float32, Float64}, V<:AbstractVector{var"#s814"}}, ::Real, ::Real) at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\tridiag.jl:288 got unsupported keyword arguments "permute", "scale", "sortby"
  ...
Stacktrace:
 [1] eigen(A::Matrix{Complex{BigFloat}}; permute::Bool, scale::Bool, sortby::typeof(LinearAlgebra.eigsortby))
   @ LinearAlgebra C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\eigen.jl:237
 [2] eigen(A::Matrix{Complex{BigFloat}})
   @ LinearAlgebra C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\LinearAlgebra\src\eigen.jl:235
 [3] top-level scope
   @ REPL[17]:1

BigFloat仅仅对角可以。

julia> M = Complex{BigFloat}[1.0 0.0; 0.0 4.]; eigen(M)
Eigen{Complex{BigFloat}, Complex{BigFloat}, Matrix{Complex{BigFloat}}, Vector{Complex{BigFloat}}}
values:
2-element Vector{Complex{BigFloat}}:
 1.0 + 0.0im
 4.0 + 0.0im
vectors:
2×2 Matrix{Complex{BigFloat}}:
 1.0+0.0im  0.0+0.0im
 0.0+0.0im  1.0+0.0im

我不知道你的问题在哪里,不过我的电脑上是可以求解的,但速度很慢:

using LinearAlgebra
setprecision(128)#全局设置BigFloat运算精度
m=rand(Complex{BigFloat},100,100)
eigen(m)

我的julia版本是1.10.0.
或许你需要重启一下julia,重新运行程序

另外,你也可以参考一下其他的多精度运算包, 如DoubleFloats.jl