XLPack 7.0
XLPack 数値計算ライブラリ (Excel VBA) リファレンスマニュアル
読み取り中…
検索中…
一致する文字列を見つけられません

◆ Dtrevc3()

Sub Dtrevc3 ( Side As  String,
Howmny As  String,
Selct() As  Boolean,
N As  Long,
T() As  Double,
Vl() As  Double,
Vr() As  Double,
Mm As  Long,
M As  Long,
Info As  Long 
)

シュール分解の準三角行列の固有ベクトル

目的
本ルーチンは実上準三角行列 T の一部または全部の右または左固有ベクトルを求める. このタイプの行列は一般実行列のシュール分解 A = Q*T*Q^T (Dhseqr により計算) により生成される.

T の固有値 w に対応する右固有ベクトル x および左固有ベクトル y は次のように定義される.
T*x = w*x, (y^T)*T = w*(y^T)
ここで, y^T はベクトル y の転置を表す. 固有値は本ルーチンに入力されないが, T の対角ブロックより直接読み込まれる.

本ルーチンは T の右および左固有ベクトル x および/または y を返す. あるいは, 入力された行列 Q との積 Q*X および/または Q*Y を返す. Q が行列 A をシュール形 T に変換する直交行列であれば Q*X および Q*Y は A の右および左固有ベクトルである.

本ルーチンは逆変換の Level 3 BLAS 版を使用する.
引数
[in]Side= "R": 右固有ベクトルのみ求める.
= "L": 左固有ベクトルのみ求める.
= "B": 右および左固有ベクトルの両方を求める.
[in]Howmny= "A": すべての右および/または左固有ベクトルを求める.
= "B": Vl() および/または Vr() に入っている行列により逆変換されたすべての右および/または左固有ベクトルを求める.
= "S": 論理型配列 Selct() により指定された一部の右および/または左固有ベクトルを求める.
[in,out]Selct()配列 Selct(LSelct - 1) (LSelct >= N)
Howmny = "S" の場合, Selct() は求める固有ベクトルを指定する.
W(j) が実数固有値の場合, Selct(j) が True であれば対応する実数固有ベクトルが求められる.
W(j) と W(j+1) が複素固有値の実数部と虚数部の場合, Selct(j) あるいは Selct(j+1) のどちらかが True であれば対応する複素固有ベクトルが求められ, 終了時 Selct(j) は True に, また, Selct(j+1) は False に設定される.
Howmny = "A" または "B" の場合, 参照されない.
[in]N行列 A の行および列数. (N >= 0) (N = 0 の場合, 処理を行わずに戻る)
[in]T()配列 T(LT1 - 1, LT2 - 1) (LT1 >= N, LT2 >= N)
シュール正準形の上準三角行列 T.
[in,out]Vl()配列 Vl(LVl1 - 1, LVl2 - 1) (LVl1 >= N, LVl2 >= MM)
[in] Side = "L" または "B" かつ Howmny = "B" の場合, Vl() に N x N 行列 Q を入れる (通常は Dhseqr により返されたシュールベクトルからなる直交行列 Q).
[out] Side = "L" または "B" の場合, Vl() に以下を返す.
Howmny = "A" の場合, T の左固有ベクトルからなる行列 Y.
Howmny = "B" の場合, 行列 Q*Y.
Howmny = "S" の場合, Selct() により指定された T の左固有ベクトルが, 固有値と同じ順に Vl() の列に続けて格納される.
複素固有値に対応する複素固有ベクトルは, 最初は実数部, 2番目は虚数部というように2つの列に続けて格納される.
Side = "R" の場合, 参照されない.
[in,out]Vr()配列 Vr(LVr1 - 1, LVr2 - 1) (LVr1 >= N, LVr2 >= MM)
[in] Side = "R" または "B" かつ Howmny = "B" の場合, Vr() に N x N 行列 Q を入れる (通常は Dhseqr により返されたシュールベクトルからなる直交行列 Q).
[out] Side = "R" または "B" の場合, Vr() に以下を返す.
Howmny = "A" の場合, T の右固有ベクトルからなる行列 X.
Howmny = "B" の場合, 行列 Q*X.
Howmny = "S" の場合, Selct() により指定された T の右固有ベクトルが, 固有値と同じ順に Vr() の列に続けて格納される.
複素固有値に対応する複素固有ベクトルは, 最初は実数部, 2番目は虚数部というように2つの列に続けて格納される.
Side = "L" の場合, 参照されない.
[in]MM配列 Vl() および/または Vr() の列数. (MM >= M)
[out]M配列 Vl() および/または Vr() において実際に固有ベクトルを格納するのに使われた列数.
Howmny = "A" または "B" の場合, M = N と設定される.
選択された実数固有ベクトルはそれぞれ1列を占め, 選択された複素固有ベクトルはそれぞれ2列を占める.
[out]Info= 0: 正常終了.
= -1: パラメータ Side の誤り. (Side <> "R", "L" および "B")
= -2: パラメータ Howmny の誤り. (Howmny <> "A", "B" および "S")
= -3: パラメータ Selct() の誤り.
= -4: パラメータ N の誤り. (N < 0)
= -5: パラメータ T() の誤り.
= -6: パラメータ Vl() の誤り.
= -7: パラメータ Vr() の誤り.
= -8: パラメータ MM の誤り. (MM < M)
詳細
本プログラムで使用されているアルゴリズムは基本的には後退(前進)代入である. 起こりうるオーバーフローに対して強くするためにスケーリングを行う.

固有ベクトルはそれぞれ最大要素の大きさが 1 になるように正規化される. ここで, 複素数 (x, y) の大きさは |x| + |y| とする.
出典
LAPACK
使用例
行列Aの固有値・固有ベクトルを求める. ただし,
( 0.20 -0.11 -0.93 )
A = ( -0.32 0.81 0.37 )
( -0.80 -0.92 -0.29 )
とする.
Dgehrdでヘッセンベルグ形に変換したのち, DhseqrおよびDorghrで固有値およびシュール形を求め, Dtrevc3でシュール形より固有ベクトルを求める.
Sub Ex_Dgehrd_Dhseqr_Dtrevc3()
Const N = 3
Dim A(N - 1, N - 1) As Double, Tau(N - 2) As Double
Dim Wr(N - 1) As Double, Wi(N - 1) As Double, Selct() As Boolean
Dim Vl(N - 1, N - 1) As Double, Vr(N - 1, N - 1) As Double, M As Long
Dim Ilo As Long, Ihi As Long, I As Long, J As Long, Info As Long
A(0, 0) = 0.2: A(0, 1) = -0.11: A(0, 2) = -0.93
A(1, 0) = -0.32: A(1, 1) = 0.81: A(1, 2) = 0.37
A(2, 0) = -0.8: A(2, 1) = -0.92: A(2, 2) = -0.29
Ilo = 1: Ihi = N
Call Dgehrd(N, Ilo, Ihi, A(), Tau(), Info)
If Info <> 0 Then
Debug.Print "Error in Dgehrd: Info =", Info
Exit Sub
End If
For I = 0 To N - 1
For J = 0 To N - 1
Vr(I, J) = A(I, J)
Next
Next
Call Dorghr(N, Ilo, Ihi, Vr(), Tau(), Info)
If Info <> 0 Then
Debug.Print "Error in Dorghr: Info =", Info
Exit Sub
End If
Call Dhseqr("S", "V", N, Ilo, Ihi, A(), Wr(), Wi(), Vr(), Info)
If Info <> 0 Then
Debug.Print "Error in Dhseqr: Info =", Info
Exit Sub
End If
For I = 0 To N - 1
For J = 0 To N - 1
Vl(I, J) = Vr(I, J)
Next
Next
Call Dtrevc3("B", "B", Selct(), N, A(), Vl(), Vr(), N, M, Info)
If Info <> 0 Then
Debug.Print "Error in Dtrevc3: Info =", Info
Exit Sub
End If
Debug.Print "Eigenvalues (r) =", Wr(0), Wr(1), Wr(2)
Debug.Print "Eigenvalues (i) =", Wi(0), Wi(1), Wi(2)
Debug.Print "Eigenvectors (L) ="
Debug.Print Vl(0, 0), Vl(0, 1), Vl(0, 2)
Debug.Print Vl(1, 0), Vl(1, 1), Vl(1, 2)
Debug.Print Vl(2, 0), Vl(2, 1), Vl(2, 2)
Debug.Print "Eigenvectors (R) ="
Debug.Print Vr(0, 0), Vr(0, 1), Vr(0, 2)
Debug.Print Vr(1, 0), Vr(1, 1), Vr(1, 2)
Debug.Print Vr(2, 0), Vr(2, 1), Vr(2, 2)
Debug.Print "M =", M
End Sub
Sub Dgehrd(N As Long, Ilo As Long, Ihi As Long, A() As Double, Tau() As Double, Info As Long)
一般行列の上ヘッセンベルグ形への変換
Sub Dorghr(N As Long, Ilo As Long, Ihi As Long, A() As Double, Tau() As Double, Info As Long)
ヘッセンベルグ形への変換行列の生成
Sub Dtrevc3(Side As String, Howmny As String, Selct() As Boolean, N As Long, T() As Double, Vl() As Double, Vr() As Double, Mm As Long, M As Long, Info As Long)
シュール分解の準三角行列の固有ベクトル
Sub Dhseqr(Job As String, Compz As String, N As Long, Ilo As Long, Ihi As Long, H() As Double, Wr() As Double, Wi() As Double, Z() As Double, Info As Long)
ヘッセンベルグ行列の固有値およびシュール分解 (QR法)
実行結果
Eigenvalues (r) = -0.904130023851345 0.812065011925673 0.812065011925673
Eigenvalues (i) = 0 0.48915757543818 -0.48915757543818
Eigenvectors (L) =
-0.89678255062032 -0.426130142157969 -0.33620818638403
-0.594264184393386 0.381115511928175 -0.618884488071825
-1 0.379151460023587 0.244224395790644
Eigenvectors (R) =
-0.83634228919053 -0.578201236867243 -0.117907376795369
5.97215298924774E-02 0.420188120674838 -0.579811879325162
-1 0.268818029145007 0.450298711668266
M = 3