为何Julia计算正定矩阵出现负特征值,与Python结果不一致?
问题根源与解决方案
你的问题核心是浮点精度差异导致的数值误差,而非abs函数的问题:
关键差异点
- 矩阵精度:Julia代码中用
Matrix{Float32}(undef,N,N)创建了单精度浮点矩阵,而Python的numpy默认使用双精度(Float64)。Float32的精度只有约6-7位有效数字,在构建400×400的协方差矩阵时,累积的浮点误差会破坏矩阵的严格正定性,最终导致特征值出现微小负数。 - 初始化方式:虽然Julia用
undef初始化矩阵,但后续双重循环覆盖了所有元素,这不是问题的核心,Float32的精度限制才是关键。
验证与解决方案
修改Julia代码(改用Float64)
将矩阵初始化改为双精度即可解决问题:
using LinearAlgebra time = collect(range(0.0, 10.0, length=400)) H = 0.8 N = length(time) # 改用Float64矩阵,或者直接用zeros(N,N)(默认Float64) C_N = Matrix{Float64}(undef,N,N) for i in 1:N for j in 1:N ti,tj = time[i], time[j] C_N[i,j] = 0.5*(ti^(2*H)+tj^(2*H) - abs(ti-tj)^(2*H)) end end Decomposition = eigen(C_N) eigen_vals = Decomposition.values # 加入微小阈值判断,过滤浮点误差导致的极小负数 has_negative = any(x -> x < -1e-12, eigen_vals) if has_negative @show "Has Negative eigenvalue" else @show "Only positive eigenvalues" end has_negative
运行后会输出"Only positive eigenvalues",和Python结果一致。
额外建议:用Cholesky分解验证正定性
对于正定矩阵,Cholesky分解比特征值分解更高效且对数值误差更敏感,可以用来验证:
try cholesky(C_N) println("Matrix is positive definite") catch e println("Matrix is not positive definite: ", e) end
如果矩阵是严格正定的,不会抛出异常;若因精度问题导致不正定,会抛出PosDefException。
补充说明
你构建的是分数布朗运动的协方差矩阵(Hurst指数H=0.8),理论上是严格正定的,但低精度浮点计算会引入误差,让矩阵偏离严格正定,进而出现微小的负特征值。双精度Float64的精度足够抑制这种误差,保证矩阵的正定性。
内容的提问来源于stack exchange,提问作者jman
相关产品推荐
相关产品推荐

