ホーム > 数値計算ソフトウェア > ライブラリ > LAPACK > CLAPACK > ルーチンの仕様 >

 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.