133
  134
  135
  136
  137
  138      IMPLICIT NONE
  139
  140
  141      CHARACTER    UPLO
  142      INTEGER      N, LDA, LWORK, INFO
  143
  144
  145      INTEGER      IPIV( * )
  146      COMPLEX*16   A( LDA, * ), WORK( * )
  147
  148
  149
  150
  151      COMPLEX*16   ZERO, ONE
  152      parameter( zero = (0.0d+0, 0.0d+0), one = (1.0d+0, 0.0d+0) )
  153
  154
  155      LOGICAL      LQUERY, UPPER
  156      INTEGER      J, LWKMIN, LWKOPT
  157      INTEGER      NB, MJ, NJ, K1, K2, J1, J2, J3, JB
  158      COMPLEX*16   ALPHA
  159
  160
  161      LOGICAL      LSAME
  162      INTEGER      ILAENV
  164
  165
  168
  169
  170      INTRINSIC    dble, dconjg, max
  171
  172
  173
  174
  175
  176      nb = 
ilaenv( 1, 
'ZHETRF_AA', uplo, n, -1, -1, -1 )
 
  177
  178
  179
  180      info = 0
  181      upper = 
lsame( uplo, 
'U' )
 
  182      lquery = ( lwork.EQ.-1 )
  183      IF( n.LE.1 ) THEN
  184         lwkmin = 1
  185         lwkopt = 1
  186      ELSE
  187         lwkmin = 2*n
  188         lwkopt = (nb+1)*n
  189      END IF
  190
  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      ELSE IF( lwork.LT.lwkmin .AND. .NOT.lquery ) THEN
  198         info = -7
  199      END IF
  200
  201      IF( info.EQ.0 ) THEN
  202         work( 1 ) = lwkopt
  203      END IF
  204
  205      IF( info.NE.0 ) THEN
  206         CALL xerbla( 
'ZHETRF_AA', -info )
 
  207         RETURN
  208      ELSE IF( lquery ) THEN
  209         RETURN
  210      END IF
  211
  212
  213
  214      IF( n.EQ.0 ) THEN
  215          RETURN
  216      ENDIF
  217      ipiv( 1 ) = 1
  218      IF( n.EQ.1 ) THEN
  219         a( 1, 1 ) = dble( a( 1, 1 ) )
  220         RETURN
  221      END IF
  222
  223
  224
  225      IF( lwork.LT.((1+nb)*n) ) THEN
  226         nb = ( lwork-n ) / n
  227      END IF
  228
  229      IF( upper ) THEN
  230
  231
  232
  233
  234
  235
  236
  237         CALL zcopy( n, a( 1, 1 ), lda, work( 1 ), 1 )
 
  238
  239
  240
  241
  242
  243         j = 0
  244 10      CONTINUE
  245         IF( j.GE.n )
  246     $      GO TO 20
  247
  248
  249
  250
  251
  252
  253
  254
  255         j1 = j + 1
  256         jb = min( n-j1+1, nb )
  257         k1 = max(1, j)-j
  258
  259
  260
  262     $                      a( max(1, j), j+1 ), lda,
  263     $                      ipiv( j+1 ), work, n, work( n*nb+1 ) )
  264
  265
  266
  267         DO j2 = j+2, min(n, j+jb+1)
  268            ipiv( j2 ) = ipiv( j2 ) + j
  269            IF( (j2.NE.ipiv(j2)) .AND. ((j1-k1).GT.2) ) THEN
  270               CALL zswap( j1-k1-2, a( 1, j2 ), 1,
 
  271     $                              a( 1, ipiv(j2) ), 1 )
  272            END IF
  273         END DO
  274         j = j + jb
  275
  276
  277
  278
  279
  280         IF( j.LT.n ) THEN
  281
  282
  283
  284            IF( j1.GT.1 .OR. jb.GT.1 ) THEN
  285
  286
  287
  288               alpha = dconjg( a( j, j+1 ) )
  289               a( j, j+1 ) = one
  290               CALL zcopy( n-j, a( j-1, j+1 ), lda,
 
  291     $                          work( (j+1-j1+1)+jb*n ), 1 )
  292               CALL zscal( n-j, alpha, work( (j+1-j1+1)+jb*n ), 1 )
 
  293
  294
  295
  296
  297
  298               IF( j1.GT.1 ) THEN
  299
  300
  301
  302                  k2 = 1
  303               ELSE
  304
  305
  306
  307                  k2 = 0
  308
  309
  310
  311                  jb = jb - 1
  312               END IF
  313
  314               DO j2 = j+1, n, nb
  315                  nj = min( nb, n-j2+1 )
  316
  317
  318
  319                  j3 = j2
  320                  DO mj = nj-1, 1, -1
  321                     CALL zgemm( 
'Conjugate transpose', 
'Transpose',
 
  322     $                            1, mj, jb+1,
  323     $                           -one, a( j1-k2, j3 ), lda,
  324     $                                 work( (j3-j1+1)+k1*n ), n,
  325     $                            one, a( j3, j3 ), lda )
  326                     j3 = j3 + 1
  327                  END DO
  328
  329
  330
  331                  CALL zgemm( 
'Conjugate transpose', 
'Transpose',
 
  332     $                        nj, n-j3+1, jb+1,
  333     $                       -one, a( j1-k2, j2 ), lda,
  334     $                             work( (j3-j1+1)+k1*n ), n,
  335     $                        one, a( j2, j3 ), lda )
  336               END DO
  337
  338
  339
  340               a( j, j+1 ) = dconjg( alpha )
  341            END IF
  342
  343
  344
  345            CALL zcopy( n-j, a( j+1, j+1 ), lda, work( 1 ), 1 )
 
  346         END IF
  347         GO TO 10
  348      ELSE
  349
  350
  351
  352
  353
  354
  355
  356
  357         CALL zcopy( n, a( 1, 1 ), 1, work( 1 ), 1 )
 
  358
  359
  360
  361
  362
  363         j = 0
  364 11      CONTINUE
  365         IF( j.GE.n )
  366     $      GO TO 20
  367
  368
  369
  370
  371
  372
  373
  374
  375         j1 = j+1
  376         jb = min( n-j1+1, nb )
  377         k1 = max(1, j)-j
  378
  379
  380
  382     $                      a( j+1, max(1, j) ), lda,
  383     $                      ipiv( j+1 ), work, n, work( n*nb+1 ) )
  384
  385
  386
  387         DO j2 = j+2, min(n, j+jb+1)
  388            ipiv( j2 ) = ipiv( j2 ) + j
  389            IF( (j2.NE.ipiv(j2)) .AND. ((j1-k1).GT.2) ) THEN
  390               CALL zswap( j1-k1-2, a( j2, 1 ), lda,
 
  391     $                              a( ipiv(j2), 1 ), lda )
  392            END IF
  393         END DO
  394         j = j + jb
  395
  396
  397
  398
  399
  400         IF( j.LT.n ) THEN
  401
  402
  403
  404            IF( j1.GT.1 .OR. jb.GT.1 ) THEN
  405
  406
  407
  408               alpha = dconjg( a( j+1, j ) )
  409               a( j+1, j ) = one
  410               CALL zcopy( n-j, a( j+1, j-1 ), 1,
 
  411     $                          work( (j+1-j1+1)+jb*n ), 1 )
  412               CALL zscal( n-j, alpha, work( (j+1-j1+1)+jb*n ), 1 )
 
  413
  414
  415
  416
  417
  418               IF( j1.GT.1 ) THEN
  419
  420
  421
  422                  k2 = 1
  423               ELSE
  424
  425
  426
  427                  k2 = 0
  428
  429
  430
  431                  jb = jb - 1
  432               END IF
  433
  434               DO j2 = j+1, n, nb
  435                  nj = min( nb, n-j2+1 )
  436
  437
  438
  439                  j3 = j2
  440                  DO mj = nj-1, 1, -1
  441                     CALL zgemm( 
'No transpose',
 
  442     $                           'Conjugate transpose',
  443     $                           mj, 1, jb+1,
  444     $                          -one, work( (j3-j1+1)+k1*n ), n,
  445     $                                a( j3, j1-k2 ), lda,
  446     $                           one, a( j3, j3 ), lda )
  447                     j3 = j3 + 1
  448                  END DO
  449
  450
  451
  452                  CALL zgemm( 
'No transpose', 
'Conjugate transpose',
 
  453     $                        n-j3+1, nj, jb+1,
  454     $                       -one, work( (j3-j1+1)+k1*n ), n,
  455     $                             a( j2, j1-k2 ), lda,
  456     $                        one, a( j3, j2 ), lda )
  457               END DO
  458
  459
  460
  461               a( j+1, j ) = dconjg( alpha )
  462            END IF
  463
  464
  465
  466            CALL zcopy( n-j, a( j+1, j+1 ), 1, work( 1 ), 1 )
 
  467         END IF
  468         GO TO 11
  469      END IF
  470
  471   20 CONTINUE
  472      work( 1 ) = lwkopt
  473      RETURN
  474
  475
  476
subroutine xerbla(srname, info)
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine zlahef_aa(uplo, j1, m, nb, a, lda, ipiv, h, ldh, work)
ZLAHEF_AA
logical function lsame(ca, cb)
LSAME
subroutine zscal(n, za, zx, incx)
ZSCAL
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP