158 SUBROUTINE zhetri_3x( UPLO, N, A, LDA, E, IPIV, WORK, NB, INFO )
166 INTEGER INFO, LDA, N, NB
170 COMPLEX*16 A( LDA, * ), E( * ), WORK( N+NB+1, * )
177 parameter( one = 1.0d+0 )
178 COMPLEX*16 CONE, CZERO
179 parameter( cone = ( 1.0d+0, 0.0d+0 ),
180 $ czero = ( 0.0d+0, 0.0d+0 ) )
184 INTEGER CUT, I, ICOUNT, INVD, IP, K, NNB, J, U11
185 DOUBLE PRECISION AK, AKP1, T
186 COMPLEX*16 AKKP1, D, U01_I_J, U01_IP1_J, U11_I_J,
197 INTRINSIC abs, dconjg, dble, max
204 upper = lsame( uplo,
'U' )
205 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
207 ELSE IF( n.LT.0 )
THEN
209 ELSE IF( lda.LT.max( 1, n ) )
THEN
216 CALL xerbla(
'ZHETRI_3X', -info )
225 work( k, 1 ) = e( k )
235 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.czero )
243 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.czero )
269 CALL ztrtri( uplo,
'U', n, a, lda, info )
275 IF( ipiv( k ).GT.0 )
THEN
277 work( k, invd ) = one / dble( a( k, k ) )
278 work( k, invd+1 ) = czero
281 t = abs( work( k+1, 1 ) )
282 ak = dble( a( k, k ) ) / t
283 akp1 = dble( a( k+1, k+1 ) ) / t
284 akkp1 = work( k+1, 1 ) / t
285 d = t*( ak*akp1-cone )
286 work( k, invd ) = akp1 / d
287 work( k+1, invd+1 ) = ak / d
288 work( k, invd+1 ) = -akkp1 / d
289 work( k+1, invd ) = dconjg( work( k, invd+1 ) )
302 IF( cut.LE.nnb )
THEN
307 DO i = cut+1-nnb, cut
308 IF( ipiv( i ).LT.0 ) icount = icount + 1
311 IF( mod( icount, 2 ).EQ.1 ) nnb = nnb + 1
320 work( i, j ) = a( i, cut+j )
327 work( u11+i, i ) = cone
329 work( u11+i, j ) = czero
332 work( u11+i, j ) = a( cut+i, cut+j )
340 IF( ipiv( i ).GT.0 )
THEN
342 work( i, j ) = work( i, invd ) * work( i, j )
346 u01_i_j = work( i, j )
347 u01_ip1_j = work( i+1, j )
348 work( i, j ) = work( i, invd ) * u01_i_j
349 $ + work( i, invd+1 ) * u01_ip1_j
350 work( i+1, j ) = work( i+1, invd ) * u01_i_j
351 $ + work( i+1, invd+1 ) * u01_ip1_j
361 DO WHILE ( i.LE.nnb )
362 IF( ipiv( cut+i ).GT.0 )
THEN
364 work( u11+i, j ) = work(cut+i,invd) * work(u11+i,j)
368 u11_i_j = work(u11+i,j)
369 u11_ip1_j = work(u11+i+1,j)
370 work( u11+i, j ) = work(cut+i,invd) * work(u11+i,j)
371 $ + work(cut+i,invd+1) * work(u11+i+1,j)
372 work( u11+i+1, j ) = work(cut+i+1,invd) * u11_i_j
373 $ + work(cut+i+1,invd+1) * u11_ip1_j
382 CALL ztrmm(
'L',
'U',
'C',
'U', nnb, nnb,
383 $ cone, a( cut+1, cut+1 ), lda, work( u11+1, 1 ),
388 a( cut+i, cut+j ) = work( u11+i, j )
394 CALL zgemm(
'C',
'N', nnb, nnb, cut, cone, a( 1, cut+1 ),
395 $ lda, work, n+nb+1, czero, work(u11+1,1),
403 a( cut+i, cut+j ) = a( cut+i, cut+j ) + work(u11+i,j)
409 CALL ztrmm(
'L', uplo,
'C',
'U', cut, nnb,
410 $ cone, a, lda, work, n+nb+1 )
417 a( i, cut+j ) = work( i, j )
437 ip = abs( ipiv( i ) )
439 IF (i .LT. ip)
CALL zheswapr( uplo, n, a, lda, i ,ip )
440 IF (i .GT. ip)
CALL zheswapr( uplo, n, a, lda, ip ,i )
450 CALL ztrtri( uplo,
'U', n, a, lda, info )
455 DO WHILE ( k .GE. 1 )
456 IF( ipiv( k ).GT.0 )
THEN
458 work( k, invd ) = one / dble( a( k, k ) )
459 work( k, invd+1 ) = czero
462 t = abs( work( k-1, 1 ) )
463 ak = dble( a( k-1, k-1 ) ) / t
464 akp1 = dble( a( k, k ) ) / t
465 akkp1 = work( k-1, 1 ) / t
466 d = t*( ak*akp1-cone )
467 work( k-1, invd ) = akp1 / d
468 work( k, invd ) = ak / d
469 work( k, invd+1 ) = -akkp1 / d
470 work( k-1, invd+1 ) = dconjg( work( k, invd+1 ) )
483 IF( (cut + nnb).GT.n )
THEN
488 DO i = cut + 1, cut+nnb
489 IF ( ipiv( i ).LT.0 ) icount = icount + 1
492 IF( mod( icount, 2 ).EQ.1 ) nnb = nnb + 1
499 work( i, j ) = a( cut+nnb+i, cut+j )
506 work( u11+i, i) = cone
508 work( u11+i, j ) = czero
511 work( u11+i, j ) = a( cut+i, cut+j )
519 IF( ipiv( cut+nnb+i ).GT.0 )
THEN
521 work( i, j ) = work( cut+nnb+i, invd) * work( i, j)
526 u01_ip1_j = work(i-1,j)
527 work(i,j)=work(cut+nnb+i,invd)*u01_i_j+
528 $ work(cut+nnb+i,invd+1)*u01_ip1_j
529 work(i-1,j)=work(cut+nnb+i-1,invd+1)*u01_i_j+
530 $ work(cut+nnb+i-1,invd)*u01_ip1_j
541 IF( ipiv( cut+i ).GT.0 )
THEN
543 work( u11+i, j ) = work( cut+i, invd)*work(u11+i,j)
548 u11_i_j = work( u11+i, j )
549 u11_ip1_j = work( u11+i-1, j )
550 work( u11+i, j ) = work(cut+i,invd) * work(u11+i,j)
551 $ + work(cut+i,invd+1) * u11_ip1_j
552 work( u11+i-1, j ) = work(cut+i-1,invd+1) * u11_i_j
553 $ + work(cut+i-1,invd) * u11_ip1_j
562 CALL ztrmm(
'L', uplo,
'C',
'U', nnb, nnb, cone,
563 $ a( cut+1, cut+1 ), lda, work( u11+1, 1 ),
569 a( cut+i, cut+j ) = work( u11+i, j )
573 IF( (cut+nnb).LT.n )
THEN
577 CALL zgemm(
'C',
'N', nnb, nnb, n-nnb-cut, cone,
578 $ a( cut+nnb+1, cut+1 ), lda, work, n+nb+1,
579 $ czero, work( u11+1, 1 ), n+nb+1 )
586 a( cut+i, cut+j ) = a( cut+i, cut+j )+work(u11+i,j)
592 CALL ztrmm(
'L', uplo,
'C',
'U', n-nnb-cut, nnb, cone,
593 $ a( cut+nnb+1, cut+nnb+1 ), lda, work,
600 a( cut+nnb+i, cut+j ) = work( i, j )
610 a( cut+i, cut+j ) = work( u11+i, j )
633 ip = abs( ipiv( i ) )
635 IF (i .LT. ip)
CALL zheswapr( uplo, n, a, lda, i ,ip )
636 IF (i .GT. ip)
CALL zheswapr( uplo, n, a, lda, ip ,i )
subroutine xerbla(srname, info)
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zheswapr(uplo, n, a, lda, i1, i2)
ZHESWAPR applies an elementary permutation on the rows and columns of a Hermitian matrix.
subroutine zhetri_3x(uplo, n, a, lda, e, ipiv, work, nb, info)
ZHETRI_3X
subroutine ztrmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
ZTRMM
subroutine ztrtri(uplo, diag, n, a, lda, info)
ZTRTRI