|
|
◆ Zcgesv()
| Sub Zcgesv |
( |
N As |
Long, |
|
|
A() As |
Complex, |
|
|
IPiv() As |
Long, |
|
|
B() As |
Complex, |
|
|
X() As |
Complex, |
|
|
Iter As |
Long, |
|
|
Info As |
Long, |
|
|
Optional Nrhs As |
Long = 1 |
|
) |
| |
(シンプルドライバ) 連立一次方程式 AX = B の解 (複素行列) (混合精度反復改良法)
- 目的
- 本ルーチンは次の複素連立一次方程式を解く. ここで, Aはn×n行列, また, XおよびBはn×nrhs行列である.
Zcgesvは, まず単精度演算による分解を行い, その分解結果に反復改良を施してノルムに基づく精度(下記参照)において倍精度の解を得ることを試みる. それがうまくいかなかった場合, 倍精度演算による分解に切り替えて解を求める.
単精度のパフォーマンスが倍精度のそれに比較してそれほどよくない場合には, 反復改良法はよい方法とはいえない. 右辺の数や行列の大きさなどを考慮にいれて適切な方法をとらなければならないが, 今のところ常に反復改良を行うようになっている.
反復改良は次の場合に停止する.
iter > itermax
あるいは
すべての右辺について: rnrm < sqrt(n)*xnrm*anrm*eps*bwdmax
ただし
iter は反復改良における現在の反復回数
rnrm は残差の無限ノルム
xnrm は解の無限ノルム
anrm は行列Aの無限作用素ノルム
eps はDlamch('E')によるマシンイプシロン
itermaxおよびbwdmaxの値は, それぞれ 30 および 1.0 の固定値である.
- 引数
-
| [in] | N | 連立方程式の数, すなわち, 行列Aの行および列数. (N >= 0) (N = 0 の場合, 処理を行わずに戻る) |
| [in,out] | A() | 配列 A(LA1 - 1, LA2 - 1) (LA1 >= N, LA2 >= N)
[in] N×N係数行列 A.
[out] 反復改良がうまくいった場合(Info = 0 かつ Iter >= 0, 下記参照), A()は変更されない. 倍精度による分解が使用された場合(Info = 0 かつ Iter < 0, 下記参照), 配列A()には分解 A = P*L*U のLおよびUが入る. Lの対角要素(= 1)は格納されない. |
| [out] | IPiv() | 配列 IPiv(LIPiv - 1) (LIPiv >= N)
置換行列Pを定義するピボットインデックス. 第i行が第IPiv(i-1)行と交換されたことを表す. 単精度による分解(Info = 0 かつ Iter >= 0), および, 倍精度による分解(Info = 0 かつ Iter < 0)のどちらにも対応する. |
| [in] | B() | 配列 B(LB1 - 1, LB2 - 1) (LB1 >= max(1, N), LB2 >= Nrhs) (2次元配列) または B(LB - 1) (LB >= max(1, N), Nrhs = 1) (1次元配列)
N×Nrhs右辺行列 B. |
| [out] | X() | 配列 X(LX1 - 1, LX2 - 1) (LX1 >= max(1, N), LX2 >= Nrhs) (2次元配列) または X(LX - 1) (LX >= max(1, N), Nrhs = 1) (1次元配列)
Info = 0 の場合, N×Nrhs解行列 X. |
| [out] | Iter | < 0: 反復改良が失敗し, 倍精度による分解を行った.
= -1: 実装上あるいはハードウェア上の理由により倍精度計算に戻した.
= -2: 精度を落とすことによりオーバーフローが起きたため倍精度計算に戻した.
= -3: Sgetrfのエラー.
= -31: 反復が30回に達したため反復改良を停止した.
> 0: 反復改良がうまくいった. 反復回数を返す. |
| [out] | Info | = 0: 正常終了.
= -1: パラメータ N の誤り. (N < 0)
= -2: パラメータ A() の誤り.
= -3: パラメータ IPiv() の誤り.
= -4: パラメータ B() の誤り.
= -6: パラメータ Nrhs の誤り. (Nrhs < 0, または, Nrhs <> 1 かつ B()が1次元配列)
= i > 0: 倍精度で計算されたUのi番目の対角要素が0である. 分解を完了したが, Uが特異であるため解を計算できなかった. |
| [in] | Nrhs | (省略可)
右辺の数, すなわち, 行列Bの列数. (Nrhs >= 0) (Nrhs = 0 の場合, 処理を行わずに戻る) (省略時 = 1) |
- 出典
- LAPACK
- 使用例
- 連立一次方程式 Ax = B を解く. ただし,
( 0.2-0.11i -0.93-0.32i 0.81+0.37i )
A = ( -0.8-0.92i -0.29+0.86i 0.64+0.51i )
( 0.71+0.59i -0.15+0.19i 0.2+0.94i )
( -0.5853-0.9457i )
B = ( -2.1697-1.0006i )
( 0.0116-0.5094i )
とする. Sub Ex_Zcgesv()
Const N = 3
Dim A(N - 1, N - 1) As Complex, B(N - 1) As Complex, X(N - 1) As Complex
Dim IPiv(N - 1) As Long, Iter As Long, Info As Long
A(0, 0) = Cmplx(0.2, -0.11): A(0, 1) = Cmplx(-0.93, -0.32): A(0, 2) = Cmplx(0.81, 0.37)
A(1, 0) = Cmplx(-0.8, -0.92): A(1, 1) = Cmplx(-0.29, 0.86): A(1, 2) = Cmplx(0.64, 0.51)
A(2, 0) = Cmplx(0.71, 0.59): A(2, 1) = Cmplx(-0.15, 0.19): A(2, 2) = Cmplx(0.2, 0.94)
B(0) = Cmplx(-0.5853, -0.9457): B(1) = Cmplx(-2.1697, -1.0006): B(2) = Cmplx(0.0116, -0.5094)
Call Zcgesv(N, A(), IPiv(), B(), X(), Iter, Info)
Debug.Print "Iter =", Iter, "Info =", 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 Zcgesv(N As Long, A() As Complex, IPiv() As Long, B() As Complex, X() As Complex, Iter As Long, Info As Long, Optional Nrhs As Long=1) (シンプルドライバ) 連立一次方程式 AX = B の解 (複素行列) (混合精度反復改良法)
- 実行結果
X = 0.79 -0.13 0.13 0.75 -0.91 0.3
Iter = 2 Info = 0
|