|
|
◆ Zgssvd()
| Sub Zgssvd |
( |
Jobv As |
String, |
|
|
Jobu As |
String, |
|
|
M As |
Long, |
|
|
N As |
Long, |
|
|
Val() As |
Complex, |
|
|
Ptr() As |
Long, |
|
|
Ind() As |
Long, |
|
|
Which As |
String, |
|
|
Nev As |
Long, |
|
|
Ncv As |
Long, |
|
|
S() As |
Double, |
|
|
V() As |
Complex, |
|
|
U() As |
Complex, |
|
|
Optional Info As |
Long, |
|
|
Optional Nconv As |
Long, |
|
|
Optional Niter As |
Long, |
|
|
Optional Base As |
Long = -1, |
|
|
Optional Format As |
Long = 0, |
|
|
Optional Maxiter As |
Long = 300, |
|
|
Optional Tol As |
Double = 0 |
|
) |
| |
特異値分解 (SVD) (複素疎行列) (リスタート付きアーノルディ法 (IRAM)) (Arpack) (ドライバ)
- 目的
- 行列 A の特異値(s)と対応する右特異ベクトル(v)を, 次の対称固有値問題を解くことによって求める. A は M x N 複素疎行列である. 必要であれば, 左特異ベクトルも u = A*v/s によって求められる.
疎行列 A は CSC または CSR 形式で格納されているものとする.
対称固有値問題は, Arpack ルーチン Zsaupd および Zseupd を使用し, リスタート付きアーノルディ法 (Implicitly restarted Arnoldi method (IRAM)) により解く.
- 引数
-
| [in] | Jobv | = 'N': 右特異ベクトルを計算しない.
= 'V': 右特異ベクトルを計算する. |
| [in] | Jobu | = 'N': 左特異ベクトルを計算しない.
= 'V': 左特異ベクトルを計算する. (Jobv も 'V' でなければならない.) |
| [in] | M | 行列の行数. (M >= 0) (M = 0 の場合, 処理を行わずに戻る) |
| [in] | N | 行列の列数. (N >= 0) (N = 0 の場合, 処理を行わずに戻る) |
| [in] | Val() | 配列 Val(LVal - 1) (LVal >= Nnz)
入力行列の非ゼロ要素の値. (Nnz は非ゼロ要素数) |
| [in] | Ptr() | 配列 Ptr(LPtr - 1) (LPtr >= N + 1
入力行列の列ポインタ(CSC形式の場合)または行ポインタ(CSR形式の場合). |
| [in] | Ind() | 配列 Ind(LInd - 1) (LInd >= Nnz)
入力行列の行インデクス(CSC形式の場合)または列インデクス(CSR形式の場合). (Nnz は非ゼロ要素数) |
| [in] | Which | = "LM": 絶対値最大のものから Nev 個の固有値を求める.
= "SM": 絶対値最小のものから Nev 個の固有値を求める.
= "LR": 実数部が最大のものから Nev 個の固有値を求める.
= "SR": 実数部が最小のものから Nev 個の固有値を求める.
= "LI": 虚数部が最大のものから Nev 個の固有値を求める.
= "SI": 虚数部が最小のものから Nev 個の固有値を求める. |
| [in] | Nev | 求める特異値の数. (0 < Nev < N) |
| [in] | Ncv | 各反復において生成されるアーノルディ基底ベクトルの数. (Nev < Ncv <= N) (Ncv >= 2*Nev が推奨される) |
| [out] | S() | 配列 S(LS - 1) (LS >= Nev)
A の特異値を返す. |
| [out] | V() | 配列 V(LV1 - 1, LV2 - 1) (LV1 >= N, LV2 >= Nev)
Nev本の右特異ベクトル. Jobv = 'N' の場合, 参照されない. |
| [out] | U() | 配列 U(LU1 - 1, LU2 - 1) (LU1 >= M, LU2 >= Nev)
Nev本の左特異ベクトル. Jobu = 'N' の場合, 参照されない. |
| [out] | Info | リターンコード.
= 0: 正常終了.
< 0: (-Info)番目の入力パラメータの誤り.
= 1: 最大反復回数に達した.
= 3: リスタート付きアーノルディ反復中にシフト値が適用できなかった. Ncv を Nev に比較して大きくすると改善するかもしれない (Ncv >= 2*Nev が推奨される).
= 11: 初期残差ベクトルが 0 である.
= 12: アーノルディ分解に失敗した.
= 13: LAPACK ルーチンで固有値の計算に失敗した.
= 14: Znaupd は十分な精度の固有値を得られなかった.
= 15 〜 17: 内部処理エラー. |
| [out] | Nconv | (省略可)
収束条件を満たしたリッツ値の数. |
| [out] | Niter | (省略可)
アーノルディ反復回数. |
| [in] | Base | (省略可)
Ptr() および Ind() のインデクス形式.
= 0: 0-ベース(C形式): 開始インデクス値が 0.
= 1: 1-ベース(Fortran形式): 開始インデクス値が 1.
(省略時: Ptr(0) = 1 であれば 1, そうでなければ 0 とみなす) |
| [in] | Format | (省略可)
行列の格納形式. (省略時 = 0)
= 0: CSR 形式.
= 1: CSC 形式. |
| [in] | Maxiter | (省略可)
アーノルディ反復の最大回数. (MaxIter > 0) (省略時 = 300) |
| [in] | Tol | (省略可)
停止基準: リッツ値の最大相対誤差. (省略時 = 0)
Tol <= 0 の場合, マシン精度とみなす. |
- 使用例
- 行列 A の大きい方から2個の特異値およびその特異ベクトルを求める. ただし,
( 0.20-0.11i -0.93-0.32i 0.81+0.37i )
A = ( -0.80-0.92i -0.29+0.86i 0.64+0.51i )
( 0.71+0.59i -0.15+0.19i 0.20+0.94i )
とする. Sub Ex_Zgssvd()
Const M = 3, N = 3, Nnz = M * N, Ncv = 3, Nev = 2
Dim A(Nnz - 1) As Complex, Ia(M) As Long, Ja(Nnz - 1) As Long
Dim S(Nev - 1) As Double, V(N - 1, Nev - 1) As Complex, U(M - 1, Nev - 1) As Complex
Dim Nconv As Long, Niter As Long, Info As Long, J As Long
A(0) = Cmplx(0.2, -0.11): A(1) = Cmplx(-0.93, -0.32): A(2) = Cmplx(0.81, 0.37): A(3) = Cmplx(-0.8, -0.92): A(4) = Cmplx(-0.29, 0.86): A(5) = Cmplx(0.64, 0.51): A(6) = Cmplx(0.71, 0.59): A(7) = Cmplx(-0.15, 0.19): A(8) = Cmplx(0.2, 0.94)
Ia(0) = 0: Ia(1) = 3: Ia(2) = 6: Ia(3) = 9
Ja(0) = 0: Ja(1) = 1: Ja(2) = 2: Ja(3) = 0: Ja(4) = 1: Ja(5) = 2: Ja(6) = 0: Ja(7) = 1: Ja(8) = 2
Call Zgssvd("V", "V", M, N, A(), Ia(), Ja(), "LM", Nev, Ncv, S(), V(), U(), Info, Nconv)
Debug.Print "S ="
Debug.Print S(0), S(1)
Debug.Print "U ="
Debug.Print "V ="
Debug.Print "Nconv =" + Str(Nconv) + ", Info =" + Str(Info)
End Sub
Function Cmplx(R As Double, Optional I As Double=0) As Complex 複素数の作成
Function Cimag(A As Complex) As Double 複素数の虚数部
Function Creal(A As Complex) As Double 複素数の実数部
Sub Zgssvd(Jobv As String, Jobu As String, M As Long, N As Long, Val() As Complex, Ptr() As Long, Ind() As Long, Which As String, Nev As Long, Ncv As Long, S() As Double, V() As Complex, U() As Complex, Optional Info As Long, Optional Nconv As Long, Optional Niter As Long, Optional Base As Long=-1, Optional Format As Long=0, Optional Maxiter As Long=300, Optional Tol As Double=0) 特異値分解 (SVD) (複素疎行列) (リスタート付きアーノルディ法 (IRAM)) (Arpack) (ドライバ)
- 実行結果
S =
2.07084030821889 1.23513084760163
U =
-0.499319835042685 -0.128907878805375 0.30744761793176 -0.106085551503547
-0.524690775955828 0.515849447652865 5.03089827914885E-02 0.63070250085819
-0.196074791420937 -0.392703545014794 0.700599777834659 5.53636247911296E-02
V =
-0.246963110991103 -0.550132820535747 -1.39614130074507E-02 -0.663671631033324
0.510037572083399 0.172828125992991 0.146757535786758 -0.138078610579205
-0.450648051781491 0.378512283728743 0.611917923700831 -0.37986579571262
Nconv = 2, Info = 0
|