158 SUBROUTINE ssytri_3x( UPLO, N, A, LDA, E, IPIV, WORK, NB, INFO )
166 INTEGER INFO, LDA, N, NB
170 REAL A( LDA, * ), E( * ), WORK( N+NB+1, * )
177 parameter( one = 1.0e+0, zero = 0.0e+0 )
181 INTEGER CUT, I, ICOUNT, INVD, IP, K, NNB, J, U11
182 REAL 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(
'SSYTRI_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 strtri( 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 strmm(
'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 sgemm(
'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 strmm(
'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 ssyswapr( uplo, n, a, lda, i ,ip )
435 IF (i .GT. ip)
CALL ssyswapr( uplo, n, a, lda, ip ,i )
445 CALL strtri( 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 strmm(
'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 sgemm(
'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 strmm(
'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 ssyswapr( uplo, n, a, lda, i ,ip )
631 IF (i .GT. ip)
CALL ssyswapr( uplo, n, a, lda, ip ,i )
subroutine xerbla(srname, info)
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine ssyswapr(uplo, n, a, lda, i1, i2)
SSYSWAPR applies an elementary permutation on the rows and columns of a symmetric matrix.
subroutine ssytri_3x(uplo, n, a, lda, e, ipiv, work, nb, info)
SSYTRI_3X
subroutine strmm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
STRMM
subroutine strtri(uplo, diag, n, a, lda, info)
STRTRI