00001 SUBROUTINE CGETRI( N, A, LDA, IPIV, WORK, LWORK, INFO )
00002
00003
00004
00005
00006
00007
00008
00009 INTEGER INFO, LDA, LWORK, N
00010
00011
00012 INTEGER IPIV( * )
00013 COMPLEX A( LDA, * ), WORK( * )
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 COMPLEX ZERO, ONE
00066 PARAMETER ( ZERO = ( 0.0E+0, 0.0E+0 ),
00067 $ ONE = ( 1.0E+0, 0.0E+0 ) )
00068
00069
00070 LOGICAL LQUERY
00071 INTEGER I, IWS, J, JB, JJ, JP, LDWORK, LWKOPT, NB,
00072 $ NBMIN, NN
00073
00074
00075 INTEGER ILAENV
00076 EXTERNAL ILAENV
00077
00078
00079 EXTERNAL CGEMM, CGEMV, CSWAP, CTRSM, CTRTRI, XERBLA
00080
00081
00082 INTRINSIC MAX, MIN
00083
00084
00085
00086
00087
00088 INFO = 0
00089 NB = ILAENV( 1, 'CGETRI', ' ', N, -1, -1, -1 )
00090 LWKOPT = N*NB
00091 WORK( 1 ) = LWKOPT
00092 LQUERY = ( LWORK.EQ.-1 )
00093 IF( N.LT.0 ) THEN
00094 INFO = -1
00095 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00096 INFO = -3
00097 ELSE IF( LWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
00098 INFO = -6
00099 END IF
00100 IF( INFO.NE.0 ) THEN
00101 CALL XERBLA( 'CGETRI', -INFO )
00102 RETURN
00103 ELSE IF( LQUERY ) THEN
00104 RETURN
00105 END IF
00106
00107
00108
00109 IF( N.EQ.0 )
00110 $ RETURN
00111
00112
00113
00114
00115 CALL CTRTRI( 'Upper', 'Non-unit', N, A, LDA, INFO )
00116 IF( INFO.GT.0 )
00117 $ RETURN
00118
00119 NBMIN = 2
00120 LDWORK = N
00121 IF( NB.GT.1 .AND. NB.LT.N ) THEN
00122 IWS = MAX( LDWORK*NB, 1 )
00123 IF( LWORK.LT.IWS ) THEN
00124 NB = LWORK / LDWORK
00125 NBMIN = MAX( 2, ILAENV( 2, 'CGETRI', ' ', N, -1, -1, -1 ) )
00126 END IF
00127 ELSE
00128 IWS = N
00129 END IF
00130
00131
00132
00133 IF( NB.LT.NBMIN .OR. NB.GE.N ) THEN
00134
00135
00136
00137 DO 20 J = N, 1, -1
00138
00139
00140
00141 DO 10 I = J + 1, N
00142 WORK( I ) = A( I, J )
00143 A( I, J ) = ZERO
00144 10 CONTINUE
00145
00146
00147
00148 IF( J.LT.N )
00149 $ CALL CGEMV( 'No transpose', N, N-J, -ONE, A( 1, J+1 ),
00150 $ LDA, WORK( J+1 ), 1, ONE, A( 1, J ), 1 )
00151 20 CONTINUE
00152 ELSE
00153
00154
00155
00156 NN = ( ( N-1 ) / NB )*NB + 1
00157 DO 50 J = NN, 1, -NB
00158 JB = MIN( NB, N-J+1 )
00159
00160
00161
00162
00163 DO 40 JJ = J, J + JB - 1
00164 DO 30 I = JJ + 1, N
00165 WORK( I+( JJ-J )*LDWORK ) = A( I, JJ )
00166 A( I, JJ ) = ZERO
00167 30 CONTINUE
00168 40 CONTINUE
00169
00170
00171
00172 IF( J+JB.LE.N )
00173 $ CALL CGEMM( 'No transpose', 'No transpose', N, JB,
00174 $ N-J-JB+1, -ONE, A( 1, J+JB ), LDA,
00175 $ WORK( J+JB ), LDWORK, ONE, A( 1, J ), LDA )
00176 CALL CTRSM( 'Right', 'Lower', 'No transpose', 'Unit', N, JB,
00177 $ ONE, WORK( J ), LDWORK, A( 1, J ), LDA )
00178 50 CONTINUE
00179 END IF
00180
00181
00182
00183 DO 60 J = N - 1, 1, -1
00184 JP = IPIV( J )
00185 IF( JP.NE.J )
00186 $ CALL CSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
00187 60 CONTINUE
00188
00189 WORK( 1 ) = IWS
00190 RETURN
00191
00192
00193
00194 END