00001 SUBROUTINE SPSTRF( 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 REAL A( LDA, * ), WORK( 2*N )
00014 INTEGER PIV( N )
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
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 REAL ONE, ZERO
00085 PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
00086
00087
00088 REAL AJJ, SSTOP, STEMP
00089 INTEGER I, ITEMP, J, JB, K, NB, PVT
00090 LOGICAL UPPER
00091
00092
00093 REAL SLAMCH
00094 INTEGER ILAENV
00095 LOGICAL LSAME, SISNAN
00096 EXTERNAL SLAMCH, ILAENV, LSAME, SISNAN
00097
00098
00099 EXTERNAL SGEMV, SPSTF2, SSCAL, SSWAP, SSYRK, XERBLA
00100
00101
00102 INTRINSIC MAX, MIN, SQRT, MAXLOC
00103
00104
00105
00106
00107
00108 INFO = 0
00109 UPPER = LSAME( UPLO, 'U' )
00110 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00111 INFO = -1
00112 ELSE IF( N.LT.0 ) THEN
00113 INFO = -2
00114 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00115 INFO = -4
00116 END IF
00117 IF( INFO.NE.0 ) THEN
00118 CALL XERBLA( 'SPSTRF', -INFO )
00119 RETURN
00120 END IF
00121
00122
00123
00124 IF( N.EQ.0 )
00125 $ RETURN
00126
00127
00128
00129 NB = ILAENV( 1, 'SPOTRF', UPLO, N, -1, -1, -1 )
00130 IF( NB.LE.1 .OR. NB.GE.N ) THEN
00131
00132
00133
00134 CALL SPSTF2( UPLO, N, A( 1, 1 ), LDA, PIV, RANK, TOL, WORK,
00135 $ INFO )
00136 GO TO 200
00137
00138 ELSE
00139
00140
00141
00142 DO 100 I = 1, N
00143 PIV( I ) = I
00144 100 CONTINUE
00145
00146
00147
00148 PVT = 1
00149 AJJ = A( PVT, PVT )
00150 DO I = 2, N
00151 IF( A( I, I ).GT.AJJ ) THEN
00152 PVT = I
00153 AJJ = A( PVT, PVT )
00154 END IF
00155 END DO
00156 IF( AJJ.EQ.ZERO.OR.SISNAN( AJJ ) ) THEN
00157 RANK = 0
00158 INFO = 1
00159 GO TO 200
00160 END IF
00161
00162
00163
00164 IF( TOL.LT.ZERO ) THEN
00165 SSTOP = N * SLAMCH( 'Epsilon' ) * AJJ
00166 ELSE
00167 SSTOP = TOL
00168 END IF
00169
00170
00171 IF( UPPER ) THEN
00172
00173
00174
00175 DO 140 K = 1, N, NB
00176
00177
00178
00179 JB = MIN( NB, N-K+1 )
00180
00181
00182
00183
00184 DO 110 I = K, N
00185 WORK( I ) = 0
00186 110 CONTINUE
00187
00188 DO 130 J = K, K + JB - 1
00189
00190
00191
00192
00193
00194 DO 120 I = J, N
00195
00196 IF( J.GT.K ) THEN
00197 WORK( I ) = WORK( I ) + A( J-1, I )**2
00198 END IF
00199 WORK( N+I ) = A( I, I ) - WORK( I )
00200
00201 120 CONTINUE
00202
00203 IF( J.GT.1 ) THEN
00204 ITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )
00205 PVT = ITEMP + J - 1
00206 AJJ = WORK( N+PVT )
00207 IF( AJJ.LE.SSTOP.OR.SISNAN( AJJ ) ) THEN
00208 A( J, J ) = AJJ
00209 GO TO 190
00210 END IF
00211 END IF
00212
00213 IF( J.NE.PVT ) THEN
00214
00215
00216
00217 A( PVT, PVT ) = A( J, J )
00218 CALL SSWAP( J-1, A( 1, J ), 1, A( 1, PVT ), 1 )
00219 IF( PVT.LT.N )
00220 $ CALL SSWAP( N-PVT, A( J, PVT+1 ), LDA,
00221 $ A( PVT, PVT+1 ), LDA )
00222 CALL SSWAP( PVT-J-1, A( J, J+1 ), LDA,
00223 $ A( J+1, PVT ), 1 )
00224
00225
00226
00227 STEMP = WORK( J )
00228 WORK( J ) = WORK( PVT )
00229 WORK( PVT ) = STEMP
00230 ITEMP = PIV( PVT )
00231 PIV( PVT ) = PIV( J )
00232 PIV( J ) = ITEMP
00233 END IF
00234
00235 AJJ = SQRT( AJJ )
00236 A( J, J ) = AJJ
00237
00238
00239
00240 IF( J.LT.N ) THEN
00241 CALL SGEMV( 'Trans', J-K, N-J, -ONE, A( K, J+1 ),
00242 $ LDA, A( K, J ), 1, ONE, A( J, J+1 ),
00243 $ LDA )
00244 CALL SSCAL( N-J, ONE / AJJ, A( J, J+1 ), LDA )
00245 END IF
00246
00247 130 CONTINUE
00248
00249
00250
00251 IF( K+JB.LE.N ) THEN
00252 CALL SSYRK( 'Upper', 'Trans', N-J+1, JB, -ONE,
00253 $ A( K, J ), LDA, ONE, A( J, J ), LDA )
00254 END IF
00255
00256 140 CONTINUE
00257
00258 ELSE
00259
00260
00261
00262 DO 180 K = 1, N, NB
00263
00264
00265
00266 JB = MIN( NB, N-K+1 )
00267
00268
00269
00270
00271 DO 150 I = K, N
00272 WORK( I ) = 0
00273 150 CONTINUE
00274
00275 DO 170 J = K, K + JB - 1
00276
00277
00278
00279
00280
00281 DO 160 I = J, N
00282
00283 IF( J.GT.K ) THEN
00284 WORK( I ) = WORK( I ) + A( I, J-1 )**2
00285 END IF
00286 WORK( N+I ) = A( I, I ) - WORK( I )
00287
00288 160 CONTINUE
00289
00290 IF( J.GT.1 ) THEN
00291 ITEMP = MAXLOC( WORK( (N+J):(2*N) ), 1 )
00292 PVT = ITEMP + J - 1
00293 AJJ = WORK( N+PVT )
00294 IF( AJJ.LE.SSTOP.OR.SISNAN( AJJ ) ) THEN
00295 A( J, J ) = AJJ
00296 GO TO 190
00297 END IF
00298 END IF
00299
00300 IF( J.NE.PVT ) THEN
00301
00302
00303
00304 A( PVT, PVT ) = A( J, J )
00305 CALL SSWAP( J-1, A( J, 1 ), LDA, A( PVT, 1 ), LDA )
00306 IF( PVT.LT.N )
00307 $ CALL SSWAP( N-PVT, A( PVT+1, J ), 1,
00308 $ A( PVT+1, PVT ), 1 )
00309 CALL SSWAP( PVT-J-1, A( J+1, J ), 1, A( PVT, J+1 ),
00310 $ LDA )
00311
00312
00313
00314 STEMP = WORK( J )
00315 WORK( J ) = WORK( PVT )
00316 WORK( PVT ) = STEMP
00317 ITEMP = PIV( PVT )
00318 PIV( PVT ) = PIV( J )
00319 PIV( J ) = ITEMP
00320 END IF
00321
00322 AJJ = SQRT( AJJ )
00323 A( J, J ) = AJJ
00324
00325
00326
00327 IF( J.LT.N ) THEN
00328 CALL SGEMV( 'No Trans', N-J, J-K, -ONE,
00329 $ A( J+1, K ), LDA, A( J, K ), LDA, ONE,
00330 $ A( J+1, J ), 1 )
00331 CALL SSCAL( N-J, ONE / AJJ, A( J+1, J ), 1 )
00332 END IF
00333
00334 170 CONTINUE
00335
00336
00337
00338 IF( K+JB.LE.N ) THEN
00339 CALL SSYRK( 'Lower', 'No Trans', N-J+1, JB, -ONE,
00340 $ A( J, K ), LDA, ONE, A( J, J ), LDA )
00341 END IF
00342
00343 180 CONTINUE
00344
00345 END IF
00346 END IF
00347
00348
00349
00350 RANK = N
00351
00352 GO TO 200
00353 190 CONTINUE
00354
00355
00356
00357
00358 RANK = J - 1
00359 INFO = 1
00360
00361 200 CONTINUE
00362 RETURN
00363
00364
00365
00366 END