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