158 SUBROUTINE dsytri_3x( UPLO, N, A, LDA, E, IPIV, WORK, NB, INFO )
166 INTEGER INFO, LDA, N, NB
170 DOUBLE PRECISION A( LDA, * ), E( * ), WORK( N+NB+1, * )
176 DOUBLE PRECISION ONE, ZERO
177 parameter( one = 1.0d+0, zero = 0.0d+0 )
181 INTEGER CUT, I, ICOUNT, INVD, IP, K, NNB, J, U11
182 DOUBLE PRECISION AK, AKKP1, AKP1, D, T, U01_I_J, U01_IP1_J,
193 INTRINSIC abs, max, mod
200 upper = lsame( uplo,
'U' )
201 IF( .NOT.upper .AND. .NOT.lsame( uplo,
'L' ) )
THEN
203 ELSE IF( n.LT.0 )
THEN
205 ELSE IF( lda.LT.max( 1, n ) )
THEN
212 CALL xerbla(
'DSYTRI_3X', -info )
221 work( k, 1 ) = e( k )
231 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
239 IF( ipiv( info ).GT.0 .AND. a( info, info ).EQ.zero )
265 CALL dtrtri( uplo,
'U', n, a, lda, info )
271 IF( ipiv( k ).GT.0 )
THEN
273 work( k, invd ) = one / a( k, k )
274 work( k, invd+1 ) = zero
279 akp1 = a( k+1, k+1 ) / t
280 akkp1 = work( k+1, 1 ) / t
281 d = t*( ak*akp1-one )
282 work( k, invd ) = akp1 / d
283 work( k+1, invd+1 ) = ak / d
284 work( k, invd+1 ) = -akkp1 / d
285 work( k+1, invd ) = work( k, invd+1 )
298 IF( cut.LE.nnb )
THEN
303 DO i = cut+1-nnb, cut
304 IF( ipiv( i ).LT.0 ) icount = icount + 1
307 IF( mod( icount, 2 ).EQ.1 ) nnb = nnb + 1
316 work( i, j ) = a( i, cut+j )
323 work( u11+i, i ) = one
325 work( u11+i, j ) = zero
328 work( u11+i, j ) = a( cut+i, cut+j )
336 IF( ipiv( i ).GT.0 )
THEN
338 work( i, j ) = work( i, invd ) * work( i, j )
342 u01_i_j = work( i, j )
343 u01_ip1_j = work( i+1, j )
344 work( i, j ) = work( i, invd ) * u01_i_j
345 $ + work( i, invd+1 ) * u01_ip1_j
346 work( i+1, j ) = work( i+1, invd ) * u01_i_j
347 $ + work( i+1, invd+1 ) * u01_ip1_j
357 DO WHILE ( i.LE.nnb )
358 IF( ipiv( cut+i ).GT.0 )
THEN
360 work( u11+i, j ) = work(cut+i,invd) * work(u11+i,j)
364 u11_i_j = work(u11+i,j)
365 u11_ip1_j = work(u11+i+1,j)
366 work( u11+i, j ) = work(cut+i,invd) * work(u11+i,j)
367 $ + work(cut+i,invd+1) * work(u11+i+1,j)
368 work( u11+i+1, j ) = work(cut+i+1,invd) * u11_i_j
369 $ + work(cut+i+1,invd+1) * u11_ip1_j
378 CALL dtrmm(
'L',
'U',
'T',
'U', nnb, nnb,
379 $ one, a( cut+1, cut+1 ), lda, work( u11+1, 1 ),
384 a( cut+i, cut+j ) = work( u11+i, j )
390 CALL dgemm(
'T',
'N', nnb, nnb, cut, one, a( 1, cut+1 ),
391 $ lda, work, n+nb+1, zero, work(u11+1,1), n+nb+1 )
398 a( cut+i, cut+j ) = a( cut+i, cut+j ) + work(u11+i,j)
404 CALL dtrmm(
'L', uplo,
'T',
'U', cut, nnb,
405 $ one, a, lda, work, n+nb+1 )
412 a( i, cut+j ) = work( i, j )
432 ip = abs( ipiv( i ) )
434 IF (i .LT. ip)
CALL dsyswapr( uplo, n, a, lda, i ,ip )
435 IF (i .GT. ip)
CALL dsyswapr( uplo, n, a, lda, ip ,i )
445 CALL dtrtri( uplo,
'U', n, a, lda, info )
450 DO WHILE ( k .GE. 1 )
451 IF( ipiv( k ).GT.0 )
THEN
453 work( k, invd ) = one / a( k, k )
454 work( k, invd+1 ) = zero
458 ak = a( k-1, k-1 ) / t
460 akkp1 = work( k-1, 1 ) / t
461 d = t*( ak*akp1-one )
462 work( k-1, invd ) = akp1 / d
463 work( k, invd ) = ak / d
464 work( k, invd+1 ) = -akkp1 / d
465 work( k-1, invd+1 ) = work( k, invd+1 )
478 IF( (cut + nnb).GT.n )
THEN
483 DO i = cut + 1, cut+nnb
484 IF ( ipiv( i ).LT.0 ) icount = icount + 1
487 IF( mod( icount, 2 ).EQ.1 ) nnb = nnb + 1
494 work( i, j ) = a( cut+nnb+i, cut+j )
501 work( u11+i, i) = one
503 work( u11+i, j ) = zero
506 work( u11+i, j ) = a( cut+i, cut+j )
514 IF( ipiv( cut+nnb+i ).GT.0 )
THEN
516 work( i, j ) = work( cut+nnb+i, invd) * work( i, j)
521 u01_ip1_j = work(i-1,j)
522 work(i,j)=work(cut+nnb+i,invd)*u01_i_j+
523 $ work(cut+nnb+i,invd+1)*u01_ip1_j
524 work(i-1,j)=work(cut+nnb+i-1,invd+1)*u01_i_j+
525 $ work(cut+nnb+i-1,invd)*u01_ip1_j
536 IF( ipiv( cut+i ).GT.0 )
THEN
538 work( u11+i, j ) = work( cut+i, invd)*work(u11+i,j)
543 u11_i_j = work( u11+i, j )
544 u11_ip1_j = work( u11+i-1, j )
545 work( u11+i, j ) = work(cut+i,invd) * work(u11+i,j)
546 $ + work(cut+i,invd+1) * u11_ip1_j
547 work( u11+i-1, j ) = work(cut+i-1,invd+1) * u11_i_j
548 $ + work(cut+i-1,invd) * u11_ip1_j
557 CALL dtrmm(
'L', uplo,
'T',
'U', nnb, nnb, one,
558 $ a( cut+1, cut+1 ), lda, work( u11+1, 1 ),
564 a( cut+i, cut+j ) = work( u11+i, j )
568 IF( (cut+nnb).LT.n )
THEN
572 CALL dgemm(
'T',
'N', nnb, nnb, n-nnb-cut, one,
573 $ a( cut+nnb+1, cut+1 ), lda, work, n+nb+1,
574 $ zero, work( u11+1, 1 ), n+nb+1 )
581 a( cut+i, cut+j ) = a( cut+i, cut+j )+work(u11+i,j)
587 CALL dtrmm(
'L', uplo,
'T',
'U', n-nnb-cut, nnb, one,
588 $ a( cut+nnb+1, cut+nnb+1 ), lda, work,
595 a( cut+nnb+i, cut+j ) = work( i, j )
605 a( cut+i, cut+j ) = work( u11+i, j )
628 ip = abs( ipiv( i ) )
630 IF (i .LT. ip)
CALL dsyswapr( uplo, n, a, lda, i ,ip )
631 IF (i .GT. ip)
CALL dsyswapr( uplo, n, a, lda, ip ,i )
subroutine xerbla(srname, info)
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dsyswapr(uplo, n, a, lda, i1, i2)
DSYSWAPR applies an elementary permutation on the rows and columns of a symmetric matrix.
subroutine dsytri_3x(uplo, n, a, lda, e, ipiv, work, nb, info)
DSYTRI_3X
subroutine dtrmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
DTRMM
subroutine dtrtri(uplo, diag, n, a, lda, info)
DTRTRI