概要
本サンプルはFortran言語によりLAPACKルーチンZGEESXを利用するサンプルプログラムです。
行列のSchur分解を行います。


入力データ
(本ルーチンの詳細はZGEESX のマニュアルページを参照)1 2 3 4 5 6 7 8
このデータをダウンロード |
ZGEESX Example Program Data 4 :Value of N (-3.97, -5.04) (-4.11, 3.70) (-0.34, 1.01) ( 1.29, -0.86) ( 0.34, -1.50) ( 1.52, -0.43) ( 1.88, -5.38) ( 3.36, 0.65) ( 3.31, -3.85) ( 2.50, 3.45) ( 0.88, -1.08) ( 0.64, -1.48) (-1.10, 0.82) ( 1.81, -1.59) ( 3.25, 1.33) ( 1.57, -3.44) :End of matrix A
出力結果
(本ルーチンの詳細はZGEESX のマニュアルページを参照)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
この出力例をダウンロード |
ZGEESX Example Program Results Matrix A 1 2 3 4 1 (-3.9700,-5.0400) (-4.1100, 3.7000) (-0.3400, 1.0100) ( 1.2900,-0.8600) 2 ( 0.3400,-1.5000) ( 1.5200,-0.4300) ( 1.8800,-5.3800) ( 3.3600, 0.6500) 3 ( 3.3100,-3.8500) ( 2.5000, 3.4500) ( 0.8800,-1.0800) ( 0.6400,-1.4800) 4 (-1.1000, 0.8200) ( 1.8100,-1.5900) ( 3.2500, 1.3300) ( 1.5700,-3.4400) Number of eigenvalues for which SELECT is true = 2 (dimension of invariant subspace) Selected eigenvalues 1 ( 7.9982,-0.9964) 2 ( 3.0023,-3.9998)
ソースコード
(本ルーチンの詳細はZGEESX のマニュアルページを参照)※本サンプルソースコードのご利用手順は「サンプルのコンパイル及び実行方法」をご参照下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
このソースコードをダウンロード |
! ZGEESX Example Program Text ! Copyright 2017, Numerical Algorithms Group Ltd. http://www.nag.com Module zgeesx_mod ! ZGEESX Example Program Module: ! Parameters and User-defined Routines ! .. Use Statements .. Use lapack_precision, Only: dp ! .. Implicit None Statement .. Implicit None ! .. Accessibility Statements .. Private Public :: select ! .. Parameters .. Integer, Parameter, Public :: nb = 64, nin = 5, nout = 6 Logical, Parameter, Public :: check_fac = .True., print_cond = .False. Contains Function select(w) ! Logical function select for use with ZGEESX (ZGEESX) ! Returns the value .TRUE. if the real part of the eigenvalue ! w is positive. ! .. Function Return Value .. Logical :: select ! .. Scalar Arguments .. Complex (Kind=dp), Intent (In) :: w ! .. Intrinsic Procedures .. Intrinsic :: real ! .. Executable Statements .. select = (real(w)>0._dp) Return End Function End Module Program zgeesx_example ! ZGEESX Example Main Program ! .. Use Statements .. Use blas_interfaces, Only: zgemm Use zgeesx_mod, Only: check_fac, nb, nin, nout, print_cond, select Use lapack_example_aux, Only: nagf_file_print_matrix_complex_gen_comp Use lapack_interfaces, Only: zgeesx, zlange Use lapack_precision, Only: dp ! .. Implicit None Statement .. Implicit None ! .. Local Scalars .. Complex (Kind=dp) :: alpha, beta Real (Kind=dp) :: anorm, eps, norm, rconde, rcondv, tol Integer :: i, ifail, info, lda, ldc, ldd, ldvs, lwork, n, sdim ! .. Local Arrays .. Complex (Kind=dp), Allocatable :: a(:, :), c(:, :), d(:, :), vs(:, :), & w(:), work(:) Complex (Kind=dp) :: dummy(1) Real (Kind=dp), Allocatable :: rwork(:) Logical, Allocatable :: bwork(:) Character (1) :: clabs(1), rlabs(1) ! .. Intrinsic Procedures .. Intrinsic :: cmplx, epsilon, max, nint, real ! .. Executable Statements .. Write (nout, *) 'ZGEESX Example Program Results' Write (nout, *) Flush (nout) ! Skip heading in data file Read (nin, *) Read (nin, *) n lda = n ldc = n ldd = n ldvs = n Allocate (a(lda,n), c(ldc,n), d(ldd,n), vs(ldvs,n), w(n), rwork(n), & bwork(n)) ! Use routine workspace query to get optimal workspace. lwork = -1 Call zgeesx('Vectors (Schur)', 'Sort', select, & 'Both reciprocal condition numbers', n, a, lda, sdim, w, vs, ldvs, & rconde, rcondv, dummy, lwork, rwork, bwork, info) ! Make sure that there is enough workspace for block size nb. lwork = max(n*(nb+1+n/2), nint(real(dummy(1)))) Allocate (work(lwork)) ! Read in the matrix A Read (nin, *)(a(i,1:n), i=1, n) ! Copy A into D d(1:n, 1:n) = a(1:n, 1:n) ! Print matrix A ! ifail: behaviour on error exit ! =0 for hard exit, =1 for quiet-soft, =-1 for noisy-soft ifail = 0 Call nagf_file_print_matrix_complex_gen_comp('General', ' ', n, n, a, & lda, 'Bracketed', 'F7.4', 'Matrix A', 'Integer', rlabs, 'Integer', & clabs, 80, 0, ifail) Write (nout, *) Flush (nout) ! Find the Frobenius norm of A anorm = zlange('Frobenius', n, n, a, lda, rwork) ! Find the Schur factorization of A Call zgeesx('Vectors (Schur)', 'Sort', select, & 'Both reciprocal condition numbers', n, a, lda, sdim, w, vs, ldvs, & rconde, rcondv, work, lwork, rwork, bwork, info) If (info/=0 .And. info/=(n+2)) Then Write (nout, 170) 'Failure in ZGEESX. INFO =', info Go To 100 End If If (check_fac) Then ! Compute A - Z*T*Z^H from the factorization of A and store in matrix D alpha = cmplx(1, kind=dp) beta = cmplx(0, kind=dp) Call zgemm('N', 'N', n, n, n, alpha, vs, ldvs, a, lda, beta, c, ldc) alpha = cmplx(-1, kind=dp) beta = cmplx(1, kind=dp) Call zgemm('N', 'C', n, n, n, alpha, c, ldc, vs, ldvs, beta, d, ldd) ! Find norm of matrix D and print warning if it is too large norm = zlange('O', ldd, n, d, ldd, rwork) If (norm>epsilon(1.0E0_dp)**0.5_dp) Then Write (nout, *) 'Norm of A-(Z*T*Z^H) is much greater than 0.' Write (nout, *) 'Schur factorization has failed.' Go To 100 End If End If ! Print solution Write (nout, 110) 'Number of eigenvalues for which SELECT is true = ', & sdim, '(dimension of invariant subspace)' Write (nout, *) ! Print eigenvalues. Write (nout, *) 'Selected eigenvalues' Write (nout, 120)(i, w(i), i=1, sdim) Write (nout, *) If (info==(n+2)) Then Write (nout, 130) '***Note that rounding errors mean ', & 'that leading eigenvalues in the Schur form', & 'no longer satisfy SELECT = .TRUE.' Write (nout, *) End If Flush (nout) If (print_cond) Then ! Print out the reciprocal condition numbers Write (nout, 140) 'Reciprocal of projection norm onto the invariant', & 'subspace for the selected eigenvalues', 'RCONDE = ', rconde Write (nout, *) Write (nout, 150) & 'Reciprocal condition number for the invariant subspace', & 'RCONDV = ', rcondv ! Compute the machine precision eps = epsilon(1.0E0_dp) tol = eps*anorm ! Print out the approximate asymptotic error bound on the ! average absolute error of the selected eigenvalues given by ! eps*norm(A)/RCONDE Write (nout, *) Write (nout, 160) 'Approximate asymptotic error bound for selected ', & 'eigenvalues = ', tol/rconde ! Print out an approximate asymptotic bound on the maximum ! angular error in the computed invariant subspace given by ! eps*norm(A)/RCONDV Write (nout, 160) & 'Approximate asymptotic error bound for the invariant ', & 'subspace = ', tol/rcondv End If 100 Continue 110 Format (1X, A, I4, /, 1X, A) 120 Format (1X, I4, 2X, ' (', F7.4, ',', F7.4, ')', :) 130 Format (1X, 2A, /, 1X, A) 140 Format (1X, A, /, 1X, A, /, 1X, A, 1P, E8.1) 150 Format (1X, A, /, 1X, A, 1P, E8.1) 160 Format (1X, 2A, 1P, E8.1) 170 Format (1X, A, I4) End Program