142
143
144
145
146
147
148 DOUBLE PRECISION TOL
149 INTEGER INFO, LDA, N, RANK
150 CHARACTER UPLO
151
152
153 DOUBLE PRECISION A( LDA, * ), WORK( 2*N )
154 INTEGER PIV( N )
155
156
157
158
159
160 DOUBLE PRECISION ONE, ZERO
161 parameter( one = 1.0d+0, zero = 0.0d+0 )
162
163
164 DOUBLE PRECISION AJJ, DSTOP, DTEMP
165 INTEGER I, ITEMP, J, JB, K, NB, PVT
166 LOGICAL UPPER
167
168
169 DOUBLE PRECISION DLAMCH
170 INTEGER ILAENV
171 LOGICAL LSAME, DISNAN
173
174
176
177
178 INTRINSIC max, min, sqrt, maxloc
179
180
181
182
183
184 info = 0
185 upper =
lsame( uplo,
'U' )
186 IF( .NOT.upper .AND. .NOT.
lsame( uplo,
'L' ) )
THEN
187 info = -1
188 ELSE IF( n.LT.0 ) THEN
189 info = -2
190 ELSE IF( lda.LT.max( 1, n ) ) THEN
191 info = -4
192 END IF
193 IF( info.NE.0 ) THEN
194 CALL xerbla(
'DPSTRF', -info )
195 RETURN
196 END IF
197
198
199
200 IF( n.EQ.0 )
201 $ RETURN
202
203
204
205 nb =
ilaenv( 1,
'DPOTRF', uplo, n, -1, -1, -1 )
206 IF( nb.LE.1 .OR. nb.GE.n ) THEN
207
208
209
210 CALL dpstf2( uplo, n, a( 1, 1 ), lda, piv, rank, tol, work,
211 $ info )
212 GO TO 200
213
214 ELSE
215
216
217
218 DO 100 i = 1, n
219 piv( i ) = i
220 100 CONTINUE
221
222
223
224 pvt = 1
225 ajj = a( pvt, pvt )
226 DO i = 2, n
227 IF( a( i, i ).GT.ajj ) THEN
228 pvt = i
229 ajj = a( pvt, pvt )
230 END IF
231 END DO
232 IF( ajj.LE.zero.OR.
disnan( ajj ) )
THEN
233 rank = 0
234 info = 1
235 GO TO 200
236 END IF
237
238
239
240 IF( tol.LT.zero ) THEN
241 dstop = n *
dlamch(
'Epsilon' ) * ajj
242 ELSE
243 dstop = tol
244 END IF
245
246
247 IF( upper ) THEN
248
249
250
251 DO 140 k = 1, n, nb
252
253
254
255 jb = min( nb, n-k+1 )
256
257
258
259
260 DO 110 i = k, n
261 work( i ) = 0
262 110 CONTINUE
263
264 DO 130 j = k, k + jb - 1
265
266
267
268
269
270 DO 120 i = j, n
271
272 IF( j.GT.k ) THEN
273 work( i ) = work( i ) + a( j-1, i )**2
274 END IF
275 work( n+i ) = a( i, i ) - work( i )
276
277 120 CONTINUE
278
279 IF( j.GT.1 ) THEN
280 itemp = maxloc( work( (n+j):(2*n) ), 1 )
281 pvt = itemp + j - 1
282 ajj = work( n+pvt )
283 IF( ajj.LE.dstop.OR.
disnan( ajj ) )
THEN
284 a( j, j ) = ajj
285 GO TO 190
286 END IF
287 END IF
288
289 IF( j.NE.pvt ) THEN
290
291
292
293 a( pvt, pvt ) = a( j, j )
294 CALL dswap( j-1, a( 1, j ), 1, a( 1, pvt ), 1 )
295 IF( pvt.LT.n )
296 $
CALL dswap( n-pvt, a( j, pvt+1 ), lda,
297 $ a( pvt, pvt+1 ), lda )
298 CALL dswap( pvt-j-1, a( j, j+1 ), lda,
299 $ a( j+1, pvt ), 1 )
300
301
302
303 dtemp = work( j )
304 work( j ) = work( pvt )
305 work( pvt ) = dtemp
306 itemp = piv( pvt )
307 piv( pvt ) = piv( j )
308 piv( j ) = itemp
309 END IF
310
311 ajj = sqrt( ajj )
312 a( j, j ) = ajj
313
314
315
316 IF( j.LT.n ) THEN
317 CALL dgemv(
'Trans', j-k, n-j, -one, a( k, j+1 ),
318 $ lda, a( k, j ), 1, one, a( j, j+1 ),
319 $ lda )
320 CALL dscal( n-j, one / ajj, a( j, j+1 ), lda )
321 END IF
322
323 130 CONTINUE
324
325
326
327 IF( k+jb.LE.n ) THEN
328 CALL dsyrk(
'Upper',
'Trans', n-j+1, jb, -one,
329 $ a( k, j ), lda, one, a( j, j ), lda )
330 END IF
331
332 140 CONTINUE
333
334 ELSE
335
336
337
338 DO 180 k = 1, n, nb
339
340
341
342 jb = min( nb, n-k+1 )
343
344
345
346
347 DO 150 i = k, n
348 work( i ) = 0
349 150 CONTINUE
350
351 DO 170 j = k, k + jb - 1
352
353
354
355
356
357 DO 160 i = j, n
358
359 IF( j.GT.k ) THEN
360 work( i ) = work( i ) + a( i, j-1 )**2
361 END IF
362 work( n+i ) = a( i, i ) - work( i )
363
364 160 CONTINUE
365
366 IF( j.GT.1 ) THEN
367 itemp = maxloc( work( (n+j):(2*n) ), 1 )
368 pvt = itemp + j - 1
369 ajj = work( n+pvt )
370 IF( ajj.LE.dstop.OR.
disnan( ajj ) )
THEN
371 a( j, j ) = ajj
372 GO TO 190
373 END IF
374 END IF
375
376 IF( j.NE.pvt ) THEN
377
378
379
380 a( pvt, pvt ) = a( j, j )
381 CALL dswap( j-1, a( j, 1 ), lda, a( pvt, 1 ), lda )
382 IF( pvt.LT.n )
383 $
CALL dswap( n-pvt, a( pvt+1, j ), 1,
384 $ a( pvt+1, pvt ), 1 )
385 CALL dswap( pvt-j-1, a( j+1, j ), 1, a( pvt, j+1 ),
386 $ lda )
387
388
389
390 dtemp = work( j )
391 work( j ) = work( pvt )
392 work( pvt ) = dtemp
393 itemp = piv( pvt )
394 piv( pvt ) = piv( j )
395 piv( j ) = itemp
396 END IF
397
398 ajj = sqrt( ajj )
399 a( j, j ) = ajj
400
401
402
403 IF( j.LT.n ) THEN
404 CALL dgemv(
'No Trans', n-j, j-k, -one,
405 $ a( j+1, k ), lda, a( j, k ), lda, one,
406 $ a( j+1, j ), 1 )
407 CALL dscal( n-j, one / ajj, a( j+1, j ), 1 )
408 END IF
409
410 170 CONTINUE
411
412
413
414 IF( k+jb.LE.n ) THEN
415 CALL dsyrk(
'Lower',
'No Trans', n-j+1, jb, -one,
416 $ a( j, k ), lda, one, a( j, j ), lda )
417 END IF
418
419 180 CONTINUE
420
421 END IF
422 END IF
423
424
425
426 rank = n
427
428 GO TO 200
429 190 CONTINUE
430
431
432
433
434 rank = j - 1
435 info = 1
436
437 200 CONTINUE
438 RETURN
439
440
441
subroutine xerbla(srname, info)
subroutine dgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
DGEMV
subroutine dsyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
DSYRK
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
logical function disnan(din)
DISNAN tests input for NaN.
double precision function dlamch(cmach)
DLAMCH
logical function lsame(ca, cb)
LSAME
subroutine dpstf2(uplo, n, a, lda, piv, rank, tol, work, info)
DPSTF2 computes the Cholesky factorization with complete pivoting of a real symmetric positive semide...
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dswap(n, dx, incx, dy, incy)
DSWAP