00001 SUBROUTINE CPSTF2( UPLO, N, A, LDA, PIV, RANK, TOL, WORK, INFO )
00002
00003
00004
00005
00006
00007
00008 REAL TOL
00009 INTEGER INFO, LDA, N, RANK
00010 CHARACTER UPLO
00011
00012
00013 COMPLEX A( LDA, * )
00014 REAL 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 REAL ONE, ZERO
00086 PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
00087 COMPLEX CONE
00088 PARAMETER ( CONE = ( 1.0E+0, 0.0E+0 ) )
00089
00090
00091 COMPLEX CTEMP
00092 REAL AJJ, SSTOP, STEMP
00093 INTEGER I, ITEMP, J, PVT
00094 LOGICAL UPPER
00095
00096
00097 REAL SLAMCH
00098 LOGICAL LSAME, SISNAN
00099 EXTERNAL SLAMCH, LSAME, SISNAN
00100
00101
00102 EXTERNAL CGEMV, CLACGV, CSSCAL, CSWAP, XERBLA
00103
00104
00105 INTRINSIC CONJG, MAX, REAL, 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( 'CPSTF2', -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 ) = REAL( A( I, I ) )
00140 110 CONTINUE
00141 PVT = MAXLOC( WORK( 1:N ), 1 )
00142 AJJ = REAL ( A( PVT, PVT ) )
00143 IF( AJJ.EQ.ZERO.OR.SISNAN( 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 SSTOP = N * SLAMCH( 'Epsilon' ) * AJJ
00153 ELSE
00154 SSTOP = 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 $ REAL( CONJG( A( J-1, I ) )*
00178 $ A( J-1, I ) )
00179 END IF
00180 WORK( N+I ) = REAL( 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.SSTOP.OR.SISNAN( 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 CSWAP( J-1, A( 1, J ), 1, A( 1, PVT ), 1 )
00200 IF( PVT.LT.N )
00201 $ CALL CSWAP( N-PVT, A( J, PVT+1 ), LDA,
00202 $ A( PVT, PVT+1 ), LDA )
00203 DO 140 I = J + 1, PVT - 1
00204 CTEMP = CONJG( A( J, I ) )
00205 A( J, I ) = CONJG( A( I, PVT ) )
00206 A( I, PVT ) = CTEMP
00207 140 CONTINUE
00208 A( J, PVT ) = CONJG( A( J, PVT ) )
00209
00210
00211
00212 STEMP = WORK( J )
00213 WORK( J ) = WORK( PVT )
00214 WORK( PVT ) = STEMP
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 CLACGV( J-1, A( 1, J ), 1 )
00227 CALL CGEMV( 'Trans', J-1, N-J, -CONE, A( 1, J+1 ), LDA,
00228 $ A( 1, J ), 1, CONE, A( J, J+1 ), LDA )
00229 CALL CLACGV( J-1, A( 1, J ), 1 )
00230 CALL CSSCAL( 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 $ REAL( CONJG( A( I, J-1 ) )*
00250 $ A( I, J-1 ) )
00251 END IF
00252 WORK( N+I ) = REAL( 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.SSTOP.OR.SISNAN( 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 CSWAP( J-1, A( J, 1 ), LDA, A( PVT, 1 ), LDA )
00272 IF( PVT.LT.N )
00273 $ CALL CSWAP( N-PVT, A( PVT+1, J ), 1, A( PVT+1, PVT ),
00274 $ 1 )
00275 DO 170 I = J + 1, PVT - 1
00276 CTEMP = CONJG( A( I, J ) )
00277 A( I, J ) = CONJG( A( PVT, I ) )
00278 A( PVT, I ) = CTEMP
00279 170 CONTINUE
00280 A( PVT, J ) = CONJG( A( PVT, J ) )
00281
00282
00283
00284 STEMP = WORK( J )
00285 WORK( J ) = WORK( PVT )
00286 WORK( PVT ) = STEMP
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 CLACGV( J-1, A( J, 1 ), LDA )
00299 CALL CGEMV( '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 CLACGV( J-1, A( J, 1 ), LDA )
00302 CALL CSSCAL( 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