141
142
143
144
145
146
147 REAL TOL
148 INTEGER INFO, LDA, N, RANK
149 CHARACTER UPLO
150
151
152 COMPLEX A( LDA, * )
153 REAL WORK( 2*N )
154 INTEGER PIV( N )
155
156
157
158
159
160 REAL ONE, ZERO
161 parameter( one = 1.0e+0, zero = 0.0e+0 )
162 COMPLEX CONE
163 parameter( cone = ( 1.0e+0, 0.0e+0 ) )
164
165
166 COMPLEX CTEMP
167 REAL AJJ, SSTOP, STEMP
168 INTEGER I, ITEMP, J, JB, K, NB, PVT
169 LOGICAL UPPER
170
171
172 REAL SLAMCH
173 INTEGER ILAENV
174 LOGICAL LSAME, SISNAN
176
177
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 = real( 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,
327 $ j+1 ),
328 $ lda, a( k, j ), 1, cone, a( j, j+1 ),
329 $ lda )
330 CALL clacgv( j-1, a( 1, j ), 1 )
331 CALL csscal( n-j, one / ajj, a( j, j+1 ), lda )
332 END IF
333
334 150 CONTINUE
335
336
337
338 IF( k+jb.LE.n ) THEN
339 CALL cherk(
'Upper',
'Conj Trans', n-j+1, jb, -one,
340 $ a( k, j ), lda, one, a( j, j ), lda )
341 END IF
342
343 160 CONTINUE
344
345 ELSE
346
347
348
349 DO 210 k = 1, n, nb
350
351
352
353 jb = min( nb, n-k+1 )
354
355
356
357
358 DO 170 i = k, n
359 work( i ) = 0
360 170 CONTINUE
361
362 DO 200 j = k, k + jb - 1
363
364
365
366
367
368 DO 180 i = j, n
369
370 IF( j.GT.k ) THEN
371 work( i ) = work( i ) +
372 $ real( conjg( a( i, j-1 ) )*
373 $ a( i, j-1 ) )
374 END IF
375 work( n+i ) = real( a( i, i ) ) - work( i )
376
377 180 CONTINUE
378
379 IF( j.GT.1 ) THEN
380 itemp = maxloc( work( (n+j):(2*n) ), 1 )
381 pvt = itemp + j - 1
382 ajj = work( n+pvt )
383 IF( ajj.LE.sstop.OR.
sisnan( ajj ) )
THEN
384 a( j, j ) = ajj
385 GO TO 220
386 END IF
387 END IF
388
389 IF( j.NE.pvt ) THEN
390
391
392
393 a( pvt, pvt ) = a( j, j )
394 CALL cswap( j-1, a( j, 1 ), lda, a( pvt, 1 ),
395 $ lda )
396 IF( pvt.LT.n )
397 $
CALL cswap( n-pvt, a( pvt+1, j ), 1,
398 $ a( pvt+1, pvt ), 1 )
399 DO 190 i = j + 1, pvt - 1
400 ctemp = conjg( a( i, j ) )
401 a( i, j ) = conjg( a( pvt, i ) )
402 a( pvt, i ) = ctemp
403 190 CONTINUE
404 a( pvt, j ) = conjg( a( pvt, j ) )
405
406
407
408 stemp = work( j )
409 work( j ) = work( pvt )
410 work( pvt ) = stemp
411 itemp = piv( pvt )
412 piv( pvt ) = piv( j )
413 piv( j ) = itemp
414 END IF
415
416 ajj = sqrt( ajj )
417 a( j, j ) = ajj
418
419
420
421 IF( j.LT.n ) THEN
422 CALL clacgv( j-1, a( j, 1 ), lda )
423 CALL cgemv(
'No Trans', n-j, j-k, -cone,
424 $ a( j+1, k ), lda, a( j, k ), lda, cone,
425 $ a( j+1, j ), 1 )
426 CALL clacgv( j-1, a( j, 1 ), lda )
427 CALL csscal( n-j, one / ajj, a( j+1, j ), 1 )
428 END IF
429
430 200 CONTINUE
431
432
433
434 IF( k+jb.LE.n ) THEN
435 CALL cherk(
'Lower',
'No Trans', n-j+1, jb, -one,
436 $ a( j, k ), lda, one, a( j, j ), lda )
437 END IF
438
439 210 CONTINUE
440
441 END IF
442 END IF
443
444
445
446 rank = n
447
448 GO TO 230
449 220 CONTINUE
450
451
452
453
454 rank = j - 1
455 info = 1
456
457 230 CONTINUE
458 RETURN
459
460
461
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