선형 시스템의 랴푸노프 스펙트럼
정리
행렬 에 대해 다음과 같은 벡터필드가 선형 미분방정식으로 주어져 있다고 하자.
만약 가 대칭행렬 이면, 이 시스템의 랴푸노프 스펙트럼은 의 고유값과 같다.
- 여기서 는 행렬 의 전치행렬이다.
설명
julia> A = [-.2 -.3; -.3 -.7]
2×2 Matrix{Float64}:
-0.2 -0.3
-0.3 -0.7
julia> @showprogress for t in 0:h:tend
# v, _ = RK4(T_A, v_[end])
# push!(v_, v)
U, V = gram_schmidt(U)
λ += V |> eachcol .|> norm .|> log
isinteger(t) && push!(λ_, λ / t)
U = RK4(A, U, h)
end
Progress: 100%|█████████████████████| Time: 0:00:05
구체적인 예로써 위와 같은 행렬 로 주어진 선형 시스템에서 랴푸노프 스펙트럼을 계산해보자.
julia> λ / (tend)
2-element Vector{Float64}:
-0.05958668545713238
-0.8404133145577668
julia> eigen((A + A')/2).values
2-element Vector{Float64}:
-0.8405124837953326
-0.0594875162046673
수치 계산 결과를 비교해보면 이론적인 예측치와 상당히 유사하게 계산되는 것을 확인할 수 있다.
이렇게 쉬운 시스템의 랴푸노프 스펙트럼을 굳이 계산하는 의미는 코드의 검증에 있다. 보통의 복잡한 시스템과 달리 선형 시스템은 이론적으로 랴푸노프 스펙트럼을 계산할 수 있어서, RK4 및 그램 슈미트 직교화 혹은 QR 분해와 그 순서가 정확한지 확인할 수 있는 예시가 되는 것이다.
증명 1
변분 방정식: 의 자코비안 행렬 에 대해 다음을 변분 방정식variational equation이라 한다. 여기서 행렬함수 의 초기 조건은 항등행렬 로 둔다. … 기하적으로, 는 원래 시스템의 에서 조금 움직인 로 변하는동안 그 탄젠트 벡터 자체가 어떻게 작용하는지를 보여준다고 생각할 수 있다.
위와 같이 정의된 를 랴푸노프 스펙트럼Lyapunov spectrum이라 하거나, 위와 같이 정의된 행렬 의 고유값 에 로그를 취한 를 랴푸노프 스펙트럼이라 한다.
은 선형 미분방정식이므로 그 자코비안 역시 가 되어 원래 시스템의 변분 방정식은 항등행렬인 초기값 에 대해 이고 그 정확한 해는 가 된다. 랴푸노프 스펙트럼의 정의에 따라 다음을 얻는다.
행렬의 지수와 로그: 만약 두 행렬 가 를 만족하면, 다음이 성립한다. 특히 의 고유값 와 의 고유값 에 대해 다음의 따름정리를 얻을 수 있다.
는 실수 엔트리만을 가지므로 에르미트 행렬이고, 그 고유값은 실수이므로 과 의 모든 고유값도 실수다. 고유값이 실수라는 것은 이들의 편각이 이라는 것이므로 행렬 로그 가 성리해서 다음을 얻는다.
■
코드
다음은 줄리아를 통해 실제로 랴푸노프 스펙트럼을 계산한 결과다.
using ProgressMeter, LinearAlgebra
function gram_schmidt(J)
N = size(J, 1)
U, V = deepcopy(J), deepcopy(J)
U[:,1] = V[:,1] / norm(V[:,1])
for j in 2:N
for jp in 1:(j-1)
V[:,j] -= (J[:,j]'U[:,jp])*U[:,jp]
end
U[:,j] = V[:,j] / norm(V[:,j])
end
return U, V
end
function RK4(J::AbstractMatrix, U::AbstractMatrix, dt=1e-2)
V1 = J*U
V2 = J*(U + (dt/2)*V1)
V3 = J*(U + (dt/2)*V2)
V4 = J*(U + dt*V3)
return U + (dt/6)*(V1 + 2V2 + 2V3 + V4)
end
A = [-.2 -.3; -.3 -.7]
# T_A(v) = A*v
U = I(2)
λ = zeros(2); λ_ = [λ]
# v = [10, 10.0]; v_ = [v]
h = 1e-3; tend = 1000
@showprogress for t in 0:h:tend
# v, _ = RK4(T_A, v_[end])
# push!(v_, v)
U, V = gram_schmidt(U)
λ += V |> eachcol .|> norm .|> log
isinteger(t) && push!(λ_, λ / t)
U = RK4(A, U, h)
end
λ / (tend)
eigen((A + A')/2).values
using Plots
plot(xlims = [1, 100], xlabel = "t", legend = :right)
scatter!(0:10:1001, first.(λ_[1:10:end]), label = "λ1", msw = 0)
scatter!(0:10:1001, last.(λ_[1:10:end]), label = "λ2", msw = 0)
hline!(eigen((A + A')/2).values, color = :black, label = "Theoretical")