|
DGEEV/ZGEEV (CLAPACK) |
DGEEV/ZGEEV
一般行列(n行n列の非対称行列)の固有値と左右の固有ベクトルを求める。ちなみに、高校課程で習うのは右固有ベクトル。
<関数>
dgeev_( char *jobvl, char *jobvr, integer *n, doublereal *a,
integer *lda, doublereal *wr, doublereal *wi, doublereal *vl,
integer *ldvl, doublereal *vr, integer *ldvr, doublereal *work,
integer *lwork, integer *info);
<引数>
char jobvl - (input) 左固有ベクトルを計算するかしないかのフラグ
='N' 行列[A]の左固有ベクトルを計算しない。
='V' 行列[A]の左固有ベクトルを計算する。
char jobvr - (input) 右固有ベクトルを計算するかしないかのフラグ
='N' 行列[A]の右固有ベクトルを計算しない。
='V' 行列[A]の右固有ベクトルを計算する。
long int n - (input) 正方行列[A]の次数。(n≧0) ここで、行列Aはn行n列である。
double a - (input/output) 配列形式はa[lda×n]。
(input) n行n列の行列[A]。
(output) 行列[A]は計算過程で上書きされる。
long int lda - (input) 行列Aの第一次元(のメモリ格納数)。lda≧max(1,n) つまり、1〜nの中で一番大きい数よりも、ldaが大きくなければならない。
通常はlda=nで良い。
double wr - (output) 次元数nの配列。計算された固有値の実部が入る。(dgeevのみ)
double wi - (output) 次元数nの配列。計算された固有値の虚部が入る。複素共役対の場合は虚部が正の方が先に入る。(dgeevのみ)
double w - (output) 次元数nの配列。固有値が入る。(zgeevのみ)
double vl - (output) 次元数(ldvl×n)の配列。
jobvl = 'V': 左固有ベクトルが列毎に固有値と同じ順番で格納される。
jobvl = 'N': vlは参照されない。
<DGEEVの詳細説明>
j(j=0〜n-1)番目の固有値が実数のとき、j番目の固有ベクトルは配列vlのldvl×j+1〜ldvl×(j+1)番に格納される。
j番目とj+1番目の固有値が複素共役対のとき、固有ベクトルuj,uj+1は次のようになる。
uj = Re(vl[][j])+Im(vl[][j+1])
uj+1 = Re(vl[][j])-Im(vl[][j+1])
つまり、実数部はldvl×j+1〜ldvl×(j+1)に入り、虚数部はldvl×(j+1)+1〜ldvl×((j+1)+1)に入る。
<ZGEEVの詳細説明>
j(j=0〜n-1)番目の固有ベクトルは配列vlのldvl×j+1〜ldvl×(j+1)番に格納される。
long int ldvl - (intput) 配列vlの第一次元(のメモリ格納数)。jbovl = 'N'のときldvl≧1、jbovl = 'V'のときldvl≧n。
double vr - (output) 次元数(ldvr×n)の配列。
jobvr = 'V': 右固有ベクトルが列毎に固有値と同じ順番で格納される。
jobvr = 'N': vrは参照されない。
<DGEEVの詳細説明>
j(j=0〜n-1)番目の固有値が実数のとき、j番目の固有ベクトルは配列vlのldvr×j+1〜ldvr×(j+1)番に格納される。
j番目とj+1番目の固有値が複素共役対のとき、固有ベクトルuj,uj+1は次のようになる。
uj = Re(vr[][j])+Im(vr[][j+1])
uj+1 = Re(vr[][j])-Im(vr[][j+1])
つまり、実数部はldvr×j+1〜ldvr×(j+1)に入り、虚数部はldvr×(j+1)+1〜ldvr×((j+1)+1)に入る。
<ZGEEVの詳細説明>
j(j=0〜n-1)番目の固有ベクトルは配列vrのldvr×j+1〜ldvr×(j+1)番に格納される。
long int ldvr - (input) 配列vrの第一次元(のメモリ格納数)。jbovr = 'N'のときldvr≧1、jbovr = 'V'のときldvr≧n。
double work - (output) 次元数lworkの配列。info = 0のとき、work[0]は最適なlworkが入る。
long int lwork - (input) 配列workの大きさを表す。
(DGEEVでは)基本的にはlwork≧max(1,3*n)で、jobvl='V'または jobvr='V'のときにはlwork≧max(1,4*n)とする。
(ZGEEVでは)基本的にはlwork≧max(1,2*n)とする。
いずれにしろ、計算性能を向上させるにはlworkを大きくとればよい。
補足:lwork = -1とすると、work配列の最適な大きさだけを計算し、work[0]に最適なlworkを格納する。
double rwork - (work) <ZGEEVのみある>次元数2*nの配列。
long int info - (output)
info = 0: 正常終了
info < 0: info = -i ならば、i番目の引数の値が間違えていることを示す。
info > 0: QR法によって全ての固有値を計算できなかった。固有ベクトルは計算されていない。dgeevの場合はwrとwrに、zgeevの場合にはw配列のi+1〜n番要素に収束した固有値が格納される。
コンパイル時にmathライブラリをリンクする必要性あり。
の右固有値を求める。
|
#include <stdio.h> #define N 3 double A[N*N]; double wr[N]; double wi[N]; double vl[1*N]; double vr[N*N]; double work[4*N]; int main(void) { static long int i; char jobvl = 'N'; char jobvr ='V'; static long int n=N,lda=N,ldvl=1,ldvr=N,lwork=4*N,info; A[0]=6.;A[1]=-1.;A[2]=5.; A[3]=-3.;A[4]=2.;A[5]=-3.; A[6]=-7.;A[7]=1.;A[8]=-6.; dgeev_( &jobvl, &jobvr, &n, A, &lda, wr, wi, vl, &ldvl, vr, &ldvr, work, &lwork, &info); for(i=0;i<N;++i) printf("%lf\n",wr[i]); return 0; } |
Copyright (C) 2001 Keisuke ABE. All Rights Reserved.