概要
本サンプルはFortran言語によりLAPACKルーチンDGEEVXを利用するサンプルプログラムです。
行列のすべての固有値と右固有ベクトルを求めます。
それぞれの固有値と固有ベクトルに対して条件数の推定値と前方誤差限界を求めます。均衡化オプションが使用されます。固有値の条件数を求めるためには左固有ベクトルを求める必要がありますがこの例で表示はされません。
入力データ
(本ルーチンの詳細はDGEEVX のマニュアルページを参照)| このデータをダウンロード |
DGEEVX Example Program Data 4 :Value of N 0.35 0.45 -0.14 -0.17 0.09 0.07 -0.54 0.35 -0.44 -0.33 -0.03 0.17 0.25 -0.32 -0.13 0.11 :End of matrix A
出力結果
(本ルーチンの詳細はDGEEVX のマニュアルページを参照)| この出力例をダウンロード |
DGEEVX Example Program Results
Eigenvalues
Eigenvalue rcond error
1 7.9948E-01 0.9936 -
2 (-9.9412E-02, 4.0079E-01) 0.7027 -
3 (-9.9412E-02,-4.0079E-01) 0.7027 -
4 -1.0066E-01 0.5710 -
Eigenvectors
Eigenvector rcond error
1 6.5509E-01 0.8181 -
5.2363E-01
-5.3622E-01
9.5607E-02
2 (-1.9330E-01, 2.5463E-01) 0.3996 -
( 2.5186E-01,-5.2240E-01)
( 9.7182E-02,-3.0838E-01)
( 6.7595E-01, 0.0000E+00)
3 (-1.9330E-01,-2.5463E-01) 0.3996 -
( 2.5186E-01, 5.2240E-01)
( 9.7182E-02, 3.0838E-01)
( 6.7595E-01,-0.0000E+00)
4 1.2533E-01 0.3125 -
3.3202E-01
5.9384E-01
7.2209E-01
Errors below 10*machine precision are not displayed
ソースコード
(本ルーチンの詳細はDGEEVX のマニュアルページを参照)※本サンプルソースコードのご利用手順は「サンプルのコンパイル及び実行方法」をご参照下さい。
| このソースコードをダウンロード |
Program dgeevx_example
! DGEEVX Example Program Text
! Copyright 2017, Numerical Algorithms Group Ltd. http://www.nag.com
! .. Use Statements ..
Use lapack_interfaces, Only: dgeevx
Use lapack_precision, Only: dp
! .. Implicit None Statement ..
Implicit None
! .. Parameters ..
Integer, Parameter :: nb = 64, nin = 5, nout = 6
! .. Local Scalars ..
Complex (Kind=dp) :: eig
Real (Kind=dp) :: abnrm, eps, tol
Integer :: i, ihi, ilo, info, j, k, lda, ldvl, ldvr, lwork, n
Logical :: pair
! .. Local Arrays ..
Real (Kind=dp), Allocatable :: a(:, :), rconde(:), rcondv(:), scale(:), &
vl(:, :), vr(:, :), wi(:), work(:), wr(:)
Real (Kind=dp) :: dummy(1)
Integer, Allocatable :: iwork(:)
! .. Intrinsic Procedures ..
Intrinsic :: cmplx, epsilon, max, maxloc, nint
! .. Executable Statements ..
Write (nout, *) 'DGEEVX Example Program Results'
! Skip heading in data file
Read (nin, *)
Read (nin, *) n
lda = n
ldvl = n
ldvr = n
lwork = (2+nb)*n
Allocate (a(lda,n), rconde(n), rcondv(n), scale(n), vl(ldvl,n), &
vr(ldvr,n), wi(n), wr(n), iwork(2*n-2))
! Use routine workspace query to get optimal workspace.
lwork = -1
Call dgeevx('Balance', 'Vectors (left)', 'Vectors (right)', &
'Both reciprocal condition numbers', n, a, lda, wr, wi, vl, ldvl, vr, &
ldvr, ilo, ihi, scale, abnrm, rconde, rcondv, dummy, lwork, iwork, &
info)
! Make sure that there is enough workspace for block size nb.
lwork = max((nb+2)*n, nint(dummy(1)))
Allocate (work(lwork))
! Read the matrix A from data file
Read (nin, *)(a(i,1:n), i=1, n)
! Solve the eigenvalue problem
Call dgeevx('Balance', 'Vectors (left)', 'Vectors (right)', &
'Both reciprocal condition numbers', n, a, lda, wr, wi, vl, ldvl, vr, &
ldvr, ilo, ihi, scale, abnrm, rconde, rcondv, work, lwork, iwork, &
info)
If (info==0) Then
! Compute the machine precision
eps = epsilon(1.0E0_dp)
tol = eps*abnrm
pair = .False.
! Print the eigenvalues and vectors, and associated condition
! number and bounds
Write (nout, *)
Write (nout, *) 'Eigenvalues'
Write (nout, *)
Write (nout, *) ' Eigenvalue rcond error'
Do j = 1, n
! Print information on j-th eigenvalue
If (wi(j)==0.0_dp) Then
If (rconde(j)>0.0_dp) Then
If (tol/rconde(j)<10.0_dp*eps) Then
Write (nout, 100) j, wr(j), rconde(j), '-'
Else
Write (nout, 110) j, wr(j), rconde(j), tol/rconde(j)
End If
Else
Write (nout, 110) j, wr(j), rconde(j), 'Inf'
End If
Else
If (rconde(j)>0.0_dp) Then
If (tol/rconde(j)<10.0_dp*eps) Then
Write (nout, 120) j, wr(j), wi(j), rconde(j), '-'
Else
Write (nout, 130) j, wr(j), wi(j), rconde(j), tol/rconde(j)
End If
Else
Write (nout, 120) j, wr(j), wi(j), rconde(j), 'Inf'
End If
End If
End Do
Write (nout, *)
Write (nout, *) 'Eigenvectors'
Write (nout, *)
Write (nout, *) ' Eigenvector rcond error'
Do j = 1, n
! Print information on j-th eigenvector
Write (nout, *)
If (wi(j)==0.0E0_dp) Then
! Make real eigenvectors have positive first entry
If (vr(1,j)<0.0_dp) Then
vr(1:n, j) = -vr(1:n, j)
End If
If (rcondv(j)>0.0_dp) Then
If (tol/rcondv(j)<10.0_dp*eps) Then
Write (nout, 100) j, vr(1, j), rcondv(j), '-'
Else
Write (nout, 110) j, vr(1, j), rcondv(j), tol/rcondv(j)
End If
Else
Write (nout, 110) j, vr(1, j), rcondv(j), 'Inf'
End If
Write (nout, 140) vr(2:n, j)
Else
If (pair) Then
eig = cmplx(vr(1,j-1), -vr(1,j), kind=dp)
Else
! Make largest eigenvector element have positive first entry
work(1:n) = vr(1:n, j)**2 + vr(1:n, j+1)**2
k = maxloc(work(1:n), 1)
If (vr(k,j)<0.0_dp) Then
vr(1:n, j) = -vr(1:n, j)
End If
eig = cmplx(vr(1,j), vr(1,j+1), kind=dp)
End If
If (rcondv(j)>0.0_dp) Then
If (tol/rcondv(j)<10.0_dp*eps) Then
Write (nout, 120) j, eig, rcondv(j), '-'
Else
Write (nout, 130) j, eig, rcondv(j), tol/rcondv(j)
End If
Else
Write (nout, 120) j, eig, rcondv(j), 'Inf'
End If
If (pair) Then
Write (nout, 150)(vr(i,j-1), -vr(i,j), i=2, n)
Else
Write (nout, 150)(vr(i,j), vr(i,j+1), i=2, n)
End If
pair = .Not. pair
End If
End Do
Write (nout, *)
Write (nout, *) 'Errors below 10*machine precision are not displayed'
Else
Write (nout, *)
Write (nout, 160) 'Failure in DGEEVX. INFO = ', info
End If
100 Format (1X, I2, 2X, 1P, E11.4, 14X, 0P, F7.4, 4X, A)
110 Format (1X, I2, 2X, 1P, E11.4, 11X, 0P, F7.4, 1X, 1P, E8.1)
120 Format (1X, I2, 1X, '(', 1P, E11.4, ',', E11.4, ')', 1X, 0P, F7.4, 4X, &
A)
130 Format (1X, I2, 1X, '(', 1P, E11.4, ',', E11.4, ')', 1X, 0P, F7.4, 1X, &
1P, E8.1)
140 Format (1X, 4X, 1P, E11.4)
150 Format (1X, 3X, '(', 1P, E11.4, ',', E11.4, ')')
160 Format (1X, A, I4)
End Program
