logo

線形システムのリアプノフスペクトル 📂動力学

線形システムのリアプノフスペクトル

定理

行列 ARn×nA \in \mathbb{R}^{n \times n} に対して次のようなベクトル場線形微分方程式で与えられているとする。 x˙=Ax,xRn \dot{\mathbf{x}} = A \mathbf{x} \qquad , \mathbf{x} \in \mathbb{R}^{n}

もし AA対称行列であるなら、このシステムのリャプノフスペクトラム12(A+AT){\frac{ 1 }{ 2 }} \left( A + A^{T} \right)固有値と等しい。


  • ここで ATA^{T} は行列 AA転置行列である。

説明

A=[0.20.30.20.7] A = \begin{bmatrix} -0.2 & -0.3 \\ -0.2 & -0.7 \end{bmatrix}

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

具体的な例として上記のような行列 A=ATA = A^{T} で与えられた線形システムのリャプノフスペクトラムを計算してみよう。

julia> λ / (tend)
2-element Vector{Float64}:
 -0.05958668545713238
 -0.8404133145577668

julia> eigen((A + A')/2).values
2-element Vector{Float64}:
 -0.8405124837953326
 -0.0594875162046673

数値計算の結果を比較すると、理論的な予測値と非常に類似して計算されることを確認できる。

lyapunov.png

このような簡単なシステムのリャプノフスペクトラムをわざわざ計算する意味はコードの検証にある。普通の複雑なシステムとは異なり、線形システムは理論的にリャプノフスペクトラムを計算できるため、RK4グラムシュミット直交化またはQR分解とその順序が正しいかを確認できる例示となる。

証明 1

リャプノフスペクトラムの定義:

変分方程式: ffヤコビ行列 JJ に対して、次を変分方程式variational equationとする。 Y˙=JY \dot{Y} = J Y ここで行列関数 Y=Y(t)Rn×nY = Y(t) \in \mathbb{R}^{n \times n} の初期条件は単位行列 Y(0)=IY(0) = I とする。 … 幾何学的に、YY は元のシステムの x(0)x(0) から少し動いた x(t)x(t) に変わる間にその接ベクトル自体がどのように作用するかを示すと考えられる。

λk:=limtlog[(Y(t,v)vv)1/t] \lambda_{k} := \lim_{t \to \infty} \log \left[ \left( {\frac{ \left\| Y(t, v) v \right\| }{ \left\| v \right\| }} \right)^{1/t} \right] 上のように定義された {λ1,,λn}\left\{ \lambda_{1} , \cdots , \lambda_{n} \right\}リャプノフスペクトラムLyapunov spectrumと呼ぶか、 Λv:=limt[Y(t)Y(t)]1/2t \Lambda_{v} := \lim_{t \to \infty} \left[ Y(t)^{\ast} Y(t) \right]^{1/2t} 上のように定義された行列 Λv\Lambda_{v}固有値 μ1,,μn\mu_{1} , \cdots , \mu_{n}対数を取った λk:=logμk\lambda_{k} := \log \mu_{k} をリャプノフスペクトラムと呼ぶ。

x˙=Ax\dot{\mathbf{x}} = A \mathbf{x} は線形微分方程式であるため、そのヤコビ行列 JJ もまた J=AJ = A となり、元のシステムの変分方程式単位行列の初期値 Y=InY = I_{n} に対して Y˙=AY\dot{Y} = A Y であり、その正確な解は Y(t)=eAtY(t) = e^{A t} となる。リャプノフスペクトラムの定義に従い次を得る。 loglimt[Y(t)TY(t)]1/2t=limtlog[Y(t)TY(t)]1/2t=limt12tlog[Y(t)TY(t)]=limt12tlog[eATteAt] \begin{align*} & \log \lim_{t \to \infty} \left[ Y(t)^{T} Y(t) \right]^{1/2t} \\ =& \lim_{t \to \infty} \log \left[ Y(t)^{T} Y(t) \right]^{1/2t} \\ =& \lim_{t \to \infty} {\frac{ 1 }{ 2t }} \log \left[ Y(t)^{T} Y(t) \right] \\ =& \lim_{t \to \infty} {\frac{ 1 }{ 2t }} \log \left[ e^{A^{T} t} e^{A t} \right] \end{align*}

行列の指数と対数: もし二つの行列 A,BCn×nA, B \in \mathbb{C}^{n \times n}AB=BAAB = BA を満たすならば、次が成立する。 logAB=logA+logB2πiU(logA+logB) \log AB = \log A + \log B - 2 \pi i \mathcal{U} \left( \log A + \log B \right) 特に AA固有値 μk\mu_{k}BB の固有値 νk\nu_{k} に対して次の従属定理を得られる。 logAB=logA+logB    k=1,,n:argμk+argνk(π,π] \log AB = \log A + \log B \iff \forall k = 1 , \cdots , n : \arg \mu_{k} + \arg \nu_{k} \in ( - \pi , \pi ]

ARn×nA \in \mathbb{R}^{n \times n} は実数エントリのみを持つためエルミート行列であり、その固有値は実数であるため eATte^{A^{T} t}eAte^{A t} のすべての固有値も実数である。固有値が実数であるということはこれらの偏角00 であることを意味するため、行列対数 logAB=logA+logB\log A B = \log A + \log B が成立して次を得る。 limt12tlog[eATteAt]=limt12t[logeATt+logeAt]=limt12t[ATt+At]=12[AT+A] \begin{align*} & \lim_{t \to \infty} {\frac{ 1 }{ 2t }} \log \left[ e^{A^{T} t} e^{A t} \right] \\ =& \lim_{t \to \infty} {\frac{ 1 }{ 2t }} \left[ \log e^{A^{T} t} + \log e^{A t} \right] \\ =& \lim_{t \to \infty} {\frac{ 1 }{ 2t }} \left[ A^{T} t + A t \right] \\ =& {\frac{ 1 }{ 2 }} \left[ A^{T} + A \right] \end{align*}

コード

次はジュリアを使って実際にリャプノフスペクトラムを計算した結果である。

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")