00001 SUBROUTINE ZPSTF2( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )
00002
00003
00004
00005
00006
00007
00008 DOUBLE PRECISION TOL
00009 INTEGER INFO, LDA, N, RANK
00010 CHARACTER UPLO
00011
00012
00013 COMPLEX*16 A( LDA, * )
00014 DOUBLE PRECISION WORK( 2*N )
00015 INTEGER PIV( N )
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
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 DOUBLE PRECISION ONE, ZERO
00086 PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
00087 COMPLEX*16 CONE
00088 PARAMETER ( CONE = ( 1.0D+0, 0.0D+0 ) )
00089
00090
00091 COMPLEX*16 ZTEMP
00092 DOUBLE PRECISION AJJ, DSTOP, DTEMP
00093 INTEGER I, ITEMP, J, PVT
00094 LOGICAL UPPER
00095
00096
00097 DOUBLE PRECISION DLAMCH
00098 LOGICAL LSAME, DISNAN
00099 EXTERNAL DLAMCH, LSAME, DISNAN
00100
00101
00102 EXTERNAL ZDSCAL, ZGEMV, ZLACGV, ZSWAP, XERBLA
00103
00104
00105 INTRINSIC DBLE, DCONJG, MAX, SQRT
00106
00107
00108
00109
00110
00111 INFO = 0
00112 UPPER = LSAME( UPLO, 'U' )
00113 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00114 INFO = -1
00115 ELSE IF( N.LT.0 ) THEN
00116 INFO = -2
00117 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00118 INFO = -4
00119 END IF
00120 IF( INFO.NE.0 ) THEN
00121 CALL XERBLA( 'ZPSTF2', -INFO )
00122 RETURN
00123 END IF
00124
00125
00126
00127 IF( N.EQ.0 )
00128 $ RETURN
00129
00130
00131
00132 DO 100 I = 1, N
00133 PIV( I ) = I
00134 100 CONTINUE
00135
00136
00137
00138 DO 110 I = 1, N
00139 WORK( I ) = DBLE( A( I, I ) )
00140 110 CONTINUE
00141 PVT = MAXLOC( WORK( 1:N ), 1 )
00142 AJJ = DBLE( A( PVT, PVT ) )
00143 IF( AJJ.EQ.ZERO.OR.DISNAN( AJJ ) ) THEN
00144 RANK = 0
00145 INFO = 1
00146 GO TO 200
00147 END IF
00148
00149
00150
00151 IF( TOL.LT.ZERO ) THEN
00152 DSTOP = N * DLAMCH( 'Epsilon' ) * AJJ
00153 ELSE
00154 DSTOP = TOL
00155 END IF
00156
00157
00158
00159 DO 120 I = 1, N
00160 WORK( I ) = 0
00161 120 CONTINUE
00162
00163 IF( UPPER ) THEN
00164
00165
00166
00167 DO 150 J = 1, N
00168
00169
00170
00171
00172
00173 DO 130 I = J, N
00174
00175 IF( J.GT.1 ) THEN
00176 WORK( I ) = WORK( I ) +
00177 $ DBLE( DCONJG( A( J-1, I ) )*
00178 $ A( J-1, I ) )
00179 END IF
00180 WORK( N+I ) = DBLE( A( I, I ) ) - WORK( I )
00181
00182 130 CONTINUE
00183
00184 IF( J.GT.1 ) THEN
00185 ITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )
00186 PVT = ITEMP + J - 1
00187 AJJ = WORK( N+PVT )
00188 IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THEN
00189 A( J, J ) = AJJ
00190 GO TO 190
00191 END IF
00192 END IF
00193
00194 IF( J.NE.PVT ) THEN
00195
00196
00197
00198 A( PVT, PVT ) = A( J, J )
00199 CALL ZSWAP( J-1, A( 1, J ), 1, A( 1, PVT ), 1 )
00200 IF( PVT.LT.N )
00201 $ CALL ZSWAP( N-PVT, A( J, PVT+1 ), LDA,
00202 $ A( PVT, PVT+1 ), LDA )
00203 DO 140 I = J + 1, PVT - 1
00204 ZTEMP = DCONJG( A( J, I ) )
00205 A( J, I ) = DCONJG( A( I, PVT ) )
00206 A( I, PVT ) = ZTEMP
00207 140 CONTINUE
00208 A( J, PVT ) = DCONJG( A( J, PVT ) )
00209
00210
00211
00212 DTEMP = WORK( J )
00213 WORK( J ) = WORK( PVT )
00214 WORK( PVT ) = DTEMP
00215 ITEMP = PIV( PVT )
00216 PIV( PVT ) = PIV( J )
00217 PIV( J ) = ITEMP
00218 END IF
00219
00220 AJJ = SQRT( AJJ )
00221 A( J, J ) = AJJ
00222
00223
00224
00225 IF( J.LT.N ) THEN
00226 CALL ZLACGV( J-1, A( 1, J ), 1 )
00227 CALL ZGEMV( 'Trans', J-1, N-J, -CONE, A( 1, J+1 ), LDA,
00228 $ A( 1, J ), 1, CONE, A( J, J+1 ), LDA )
00229 CALL ZLACGV( J-1, A( 1, J ), 1 )
00230 CALL ZDSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
00231 END IF
00232
00233 150 CONTINUE
00234
00235 ELSE
00236
00237
00238
00239 DO 180 J = 1, N
00240
00241
00242
00243
00244
00245 DO 160 I = J, N
00246
00247 IF( J.GT.1 ) THEN
00248 WORK( I ) = WORK( I ) +
00249 $ DBLE( DCONJG( A( I, J-1 ) )*
00250 $ A( I, J-1 ) )
00251 END IF
00252 WORK( N+I ) = DBLE( A( I, I ) ) - WORK( I )
00253
00254 160 CONTINUE
00255
00256 IF( J.GT.1 ) THEN
00257 ITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )
00258 PVT = ITEMP + J - 1
00259 AJJ = WORK( N+PVT )
00260 IF( AJJ.LE.DSTOP.OR.DISNAN( AJJ ) ) THEN
00261 A( J, J ) = AJJ
00262 GO TO 190
00263 END IF
00264 END IF
00265
00266 IF( J.NE.PVT ) THEN
00267
00268
00269
00270 A( PVT, PVT ) = A( J, J )
00271 CALL ZSWAP( J-1, A( J, 1 ), LDA, A( PVT, 1 ), LDA )
00272 IF( PVT.LT.N )
00273 $ CALL ZSWAP( N-PVT, A( PVT+1, J ), 1, A( PVT+1, PVT ),
00274 $ 1 )
00275 DO 170 I = J + 1, PVT - 1
00276 ZTEMP = DCONJG( A( I, J ) )
00277 A( I, J ) = DCONJG( A( PVT, I ) )
00278 A( PVT, I ) = ZTEMP
00279 170 CONTINUE
00280 A( PVT, J ) = DCONJG( A( PVT, J ) )
00281
00282
00283
00284 DTEMP = WORK( J )
00285 WORK( J ) = WORK( PVT )
00286 WORK( PVT ) = DTEMP
00287 ITEMP = PIV( PVT )
00288 PIV( PVT ) = PIV( J )
00289 PIV( J ) = ITEMP
00290 END IF
00291
00292 AJJ = SQRT( AJJ )
00293 A( J, J ) = AJJ
00294
00295
00296
00297 IF( J.LT.N ) THEN
00298 CALL ZLACGV( J-1, A( J, 1 ), LDA )
00299 CALL ZGEMV( 'No Trans', N-J, J-1, -CONE, A( J+1, 1 ),
00300 $ LDA, A( J, 1 ), LDA, CONE, A( J+1, J ), 1 )
00301 CALL ZLACGV( J-1, A( J, 1 ), LDA )
00302 CALL ZDSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
00303 END IF
00304
00305 180 CONTINUE
00306
00307 END IF
00308
00309
00310
00311 RANK = N
00312
00313 GO TO 200
00314 190 CONTINUE
00315
00316
00317
00318
00319 RANK = J - 1
00320 INFO = 1
00321
00322 200 CONTINUE
00323 RETURN
00324
00325
00326
00327 END