LAPACK 3.12.0
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ zhetf2_rook()

subroutine zhetf2_rook ( character  uplo,
integer  n,
complex*16, dimension( lda, * )  a,
integer  lda,
integer, dimension( * )  ipiv,
integer  info 
)

ZHETF2_ROOK computes the factorization of a complex Hermitian indefinite matrix using the bounded Bunch-Kaufman ("rook") diagonal pivoting method (unblocked algorithm).

Download ZHETF2_ROOK + dependencies [TGZ] [ZIP] [TXT]

Purpose:
 ZHETF2_ROOK computes the factorization of a complex Hermitian matrix A
 using the bounded Bunch-Kaufman ("rook") diagonal pivoting method:

    A = U*D*U**H  or  A = L*D*L**H

 where U (or L) is a product of permutation and unit upper (lower)
 triangular matrices, U**H is the conjugate transpose of U, and D is
 Hermitian and block diagonal with 1-by-1 and 2-by-2 diagonal blocks.

 This is the unblocked version of the algorithm, calling Level 2 BLAS.
Parameters
[in]UPLO
          UPLO is CHARACTER*1
          Specifies whether the upper or lower triangular part of the
          Hermitian matrix A is stored:
          = 'U':  Upper triangular
          = 'L':  Lower triangular
[in]N
          N is INTEGER
          The order of the matrix A.  N >= 0.
[in,out]A
          A is COMPLEX*16 array, dimension (LDA,N)
          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading
          n-by-n upper triangular part of A contains the upper
          triangular part of the matrix A, and the strictly lower
          triangular part of A is not referenced.  If UPLO = 'L', the
          leading n-by-n lower triangular part of A contains the lower
          triangular part of the matrix A, and the strictly upper
          triangular part of A is not referenced.

          On exit, the block diagonal matrix D and the multipliers used
          to obtain the factor U or L (see below for further details).
[in]LDA
          LDA is INTEGER
          The leading dimension of the array A.  LDA >= max(1,N).
[out]IPIV
          IPIV is INTEGER array, dimension (N)
          Details of the interchanges and the block structure of D.

          If UPLO = 'U':
             If IPIV(k) > 0, then rows and columns k and IPIV(k) were
             interchanged and D(k,k) is a 1-by-1 diagonal block.

             If IPIV(k) < 0 and IPIV(k-1) < 0, then rows and
             columns k and -IPIV(k) were interchanged and rows and
             columns k-1 and -IPIV(k-1) were inerchaged,
             D(k-1:k,k-1:k) is a 2-by-2 diagonal block.

          If UPLO = 'L':
             If IPIV(k) > 0, then rows and columns k and IPIV(k)
             were interchanged and D(k,k) is a 1-by-1 diagonal block.

             If IPIV(k) < 0 and IPIV(k+1) < 0, then rows and
             columns k and -IPIV(k) were interchanged and rows and
             columns k+1 and -IPIV(k+1) were inerchaged,
             D(k:k+1,k:k+1) is a 2-by-2 diagonal block.
[out]INFO
          INFO is INTEGER
          = 0: successful exit
          < 0: if INFO = -k, the k-th argument had an illegal value
          > 0: if INFO = k, D(k,k) is exactly zero.  The factorization
               has been completed, but the block diagonal matrix D is
               exactly singular, and division by zero will occur if it
               is used to solve a system of equations.
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Further Details:
  If UPLO = 'U', then A = U*D*U**H, where
     U = P(n)*U(n)* ... *P(k)U(k)* ...,
  i.e., U is a product of terms P(k)*U(k), where k decreases from n to
  1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
  and 2-by-2 diagonal blocks D(k).  P(k) is a permutation matrix as
  defined by IPIV(k), and U(k) is a unit upper triangular matrix, such
  that if the diagonal block D(k) is of order s (s = 1 or 2), then

             (   I    v    0   )   k-s
     U(k) =  (   0    I    0   )   s
             (   0    0    I   )   n-k
                k-s   s   n-k

  If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k).
  If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k),
  and A(k,k), and v overwrites A(1:k-2,k-1:k).

  If UPLO = 'L', then A = L*D*L**H, where
     L = P(1)*L(1)* ... *P(k)*L(k)* ...,
  i.e., L is a product of terms P(k)*L(k), where k increases from 1 to
  n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1
  and 2-by-2 diagonal blocks D(k).  P(k) is a permutation matrix as
  defined by IPIV(k), and L(k) is a unit lower triangular matrix, such
  that if the diagonal block D(k) is of order s (s = 1 or 2), then

             (   I    0     0   )  k-1
     L(k) =  (   0    I     0   )  s
             (   0    v     I   )  n-k-s+1
                k-1   s  n-k-s+1

  If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k).
  If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k),
  and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1).
Contributors:
  November 2013,  Igor Kozachenko,
                  Computer Science Division,
                  University of California, Berkeley

  September 2007, Sven Hammarling, Nicholas J. Higham, Craig Lucas,
                  School of Mathematics,
                  University of Manchester

  01-01-96 - Based on modifications by
    J. Lewis, Boeing Computer Services Company
    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA

Definition at line 193 of file zhetf2_rook.f.

194*
195* -- LAPACK computational routine --
196* -- LAPACK is a software package provided by Univ. of Tennessee, --
197* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
198*
199* .. Scalar Arguments ..
200 CHARACTER UPLO
201 INTEGER INFO, LDA, N
202* ..
203* .. Array Arguments ..
204 INTEGER IPIV( * )
205 COMPLEX*16 A( LDA, * )
206* ..
207*
208* ======================================================================
209*
210* .. Parameters ..
211 DOUBLE PRECISION ZERO, ONE
212 parameter( zero = 0.0d+0, one = 1.0d+0 )
213 DOUBLE PRECISION EIGHT, SEVTEN
214 parameter( eight = 8.0d+0, sevten = 17.0d+0 )
215* ..
216* .. Local Scalars ..
217 LOGICAL DONE, UPPER
218 INTEGER I, II, IMAX, ITEMP, J, JMAX, K, KK, KP, KSTEP,
219 $ P
220 DOUBLE PRECISION ABSAKK, ALPHA, COLMAX, D, D11, D22, R1, DTEMP,
221 $ ROWMAX, TT, SFMIN
222 COMPLEX*16 D12, D21, T, WK, WKM1, WKP1, Z
223* ..
224* .. External Functions ..
225*
226 LOGICAL LSAME
227 INTEGER IZAMAX
228 DOUBLE PRECISION DLAMCH, DLAPY2
229 EXTERNAL lsame, izamax, dlamch, dlapy2
230* ..
231* .. External Subroutines ..
232 EXTERNAL xerbla, zdscal, zher, zswap
233* ..
234* .. Intrinsic Functions ..
235 INTRINSIC abs, dble, dcmplx, dconjg, dimag, max, sqrt
236* ..
237* .. Statement Functions ..
238 DOUBLE PRECISION CABS1
239* ..
240* .. Statement Function definitions ..
241 cabs1( z ) = abs( dble( z ) ) + abs( dimag( z ) )
242* ..
243* .. Executable Statements ..
244*
245* Test the input parameters.
246*
247 info = 0
248 upper = lsame( uplo, 'U' )
249 IF( .NOT.upper .AND. .NOT.lsame( uplo, 'L' ) ) THEN
250 info = -1
251 ELSE IF( n.LT.0 ) THEN
252 info = -2
253 ELSE IF( lda.LT.max( 1, n ) ) THEN
254 info = -4
255 END IF
256 IF( info.NE.0 ) THEN
257 CALL xerbla( 'ZHETF2_ROOK', -info )
258 RETURN
259 END IF
260*
261* Initialize ALPHA for use in choosing pivot block size.
262*
263 alpha = ( one+sqrt( sevten ) ) / eight
264*
265* Compute machine safe minimum
266*
267 sfmin = dlamch( 'S' )
268*
269 IF( upper ) THEN
270*
271* Factorize A as U*D*U**H using the upper triangle of A
272*
273* K is the main loop index, decreasing from N to 1 in steps of
274* 1 or 2
275*
276 k = n
277 10 CONTINUE
278*
279* If K < 1, exit from loop
280*
281 IF( k.LT.1 )
282 $ GO TO 70
283 kstep = 1
284 p = k
285*
286* Determine rows and columns to be interchanged and whether
287* a 1-by-1 or 2-by-2 pivot block will be used
288*
289 absakk = abs( dble( a( k, k ) ) )
290*
291* IMAX is the row-index of the largest off-diagonal element in
292* column K, and COLMAX is its absolute value.
293* Determine both COLMAX and IMAX.
294*
295 IF( k.GT.1 ) THEN
296 imax = izamax( k-1, a( 1, k ), 1 )
297 colmax = cabs1( a( imax, k ) )
298 ELSE
299 colmax = zero
300 END IF
301*
302 IF( ( max( absakk, colmax ).EQ.zero ) ) THEN
303*
304* Column K is zero or underflow: set INFO and continue
305*
306 IF( info.EQ.0 )
307 $ info = k
308 kp = k
309 a( k, k ) = dble( a( k, k ) )
310 ELSE
311*
312* ============================================================
313*
314* BEGIN pivot search
315*
316* Case(1)
317* Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX
318* (used to handle NaN and Inf)
319*
320 IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
321*
322* no interchange, use 1-by-1 pivot block
323*
324 kp = k
325*
326 ELSE
327*
328 done = .false.
329*
330* Loop until pivot found
331*
332 12 CONTINUE
333*
334* BEGIN pivot search loop body
335*
336*
337* JMAX is the column-index of the largest off-diagonal
338* element in row IMAX, and ROWMAX is its absolute value.
339* Determine both ROWMAX and JMAX.
340*
341 IF( imax.NE.k ) THEN
342 jmax = imax + izamax( k-imax, a( imax, imax+1 ),
343 $ lda )
344 rowmax = cabs1( a( imax, jmax ) )
345 ELSE
346 rowmax = zero
347 END IF
348*
349 IF( imax.GT.1 ) THEN
350 itemp = izamax( imax-1, a( 1, imax ), 1 )
351 dtemp = cabs1( a( itemp, imax ) )
352 IF( dtemp.GT.rowmax ) THEN
353 rowmax = dtemp
354 jmax = itemp
355 END IF
356 END IF
357*
358* Case(2)
359* Equivalent to testing for
360* ABS( DBLE( W( IMAX,KW-1 ) ) ).GE.ALPHA*ROWMAX
361* (used to handle NaN and Inf)
362*
363 IF( .NOT.( abs( dble( a( imax, imax ) ) )
364 $ .LT.alpha*rowmax ) ) THEN
365*
366* interchange rows and columns K and IMAX,
367* use 1-by-1 pivot block
368*
369 kp = imax
370 done = .true.
371*
372* Case(3)
373* Equivalent to testing for ROWMAX.EQ.COLMAX,
374* (used to handle NaN and Inf)
375*
376 ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
377 $ THEN
378*
379* interchange rows and columns K-1 and IMAX,
380* use 2-by-2 pivot block
381*
382 kp = imax
383 kstep = 2
384 done = .true.
385*
386* Case(4)
387 ELSE
388*
389* Pivot not found: set params and repeat
390*
391 p = imax
392 colmax = rowmax
393 imax = jmax
394 END IF
395*
396* END pivot search loop body
397*
398 IF( .NOT.done ) GOTO 12
399*
400 END IF
401*
402* END pivot search
403*
404* ============================================================
405*
406* KK is the column of A where pivoting step stopped
407*
408 kk = k - kstep + 1
409*
410* For only a 2x2 pivot, interchange rows and columns K and P
411* in the leading submatrix A(1:k,1:k)
412*
413 IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
414* (1) Swap columnar parts
415 IF( p.GT.1 )
416 $ CALL zswap( p-1, a( 1, k ), 1, a( 1, p ), 1 )
417* (2) Swap and conjugate middle parts
418 DO 14 j = p + 1, k - 1
419 t = dconjg( a( j, k ) )
420 a( j, k ) = dconjg( a( p, j ) )
421 a( p, j ) = t
422 14 CONTINUE
423* (3) Swap and conjugate corner elements at row-col intersection
424 a( p, k ) = dconjg( a( p, k ) )
425* (4) Swap diagonal elements at row-col intersection
426 r1 = dble( a( k, k ) )
427 a( k, k ) = dble( a( p, p ) )
428 a( p, p ) = r1
429 END IF
430*
431* For both 1x1 and 2x2 pivots, interchange rows and
432* columns KK and KP in the leading submatrix A(1:k,1:k)
433*
434 IF( kp.NE.kk ) THEN
435* (1) Swap columnar parts
436 IF( kp.GT.1 )
437 $ CALL zswap( kp-1, a( 1, kk ), 1, a( 1, kp ), 1 )
438* (2) Swap and conjugate middle parts
439 DO 15 j = kp + 1, kk - 1
440 t = dconjg( a( j, kk ) )
441 a( j, kk ) = dconjg( a( kp, j ) )
442 a( kp, j ) = t
443 15 CONTINUE
444* (3) Swap and conjugate corner elements at row-col intersection
445 a( kp, kk ) = dconjg( a( kp, kk ) )
446* (4) Swap diagonal elements at row-col intersection
447 r1 = dble( a( kk, kk ) )
448 a( kk, kk ) = dble( a( kp, kp ) )
449 a( kp, kp ) = r1
450*
451 IF( kstep.EQ.2 ) THEN
452* (*) Make sure that diagonal element of pivot is real
453 a( k, k ) = dble( a( k, k ) )
454* (5) Swap row elements
455 t = a( k-1, k )
456 a( k-1, k ) = a( kp, k )
457 a( kp, k ) = t
458 END IF
459 ELSE
460* (*) Make sure that diagonal element of pivot is real
461 a( k, k ) = dble( a( k, k ) )
462 IF( kstep.EQ.2 )
463 $ a( k-1, k-1 ) = dble( a( k-1, k-1 ) )
464 END IF
465*
466* Update the leading submatrix
467*
468 IF( kstep.EQ.1 ) THEN
469*
470* 1-by-1 pivot block D(k): column k now holds
471*
472* W(k) = U(k)*D(k)
473*
474* where U(k) is the k-th column of U
475*
476 IF( k.GT.1 ) THEN
477*
478* Perform a rank-1 update of A(1:k-1,1:k-1) and
479* store U(k) in column k
480*
481 IF( abs( dble( a( k, k ) ) ).GE.sfmin ) THEN
482*
483* Perform a rank-1 update of A(1:k-1,1:k-1) as
484* A := A - U(k)*D(k)*U(k)**T
485* = A - W(k)*1/D(k)*W(k)**T
486*
487 d11 = one / dble( a( k, k ) )
488 CALL zher( uplo, k-1, -d11, a( 1, k ), 1, a, lda )
489*
490* Store U(k) in column k
491*
492 CALL zdscal( k-1, d11, a( 1, k ), 1 )
493 ELSE
494*
495* Store L(k) in column K
496*
497 d11 = dble( a( k, k ) )
498 DO 16 ii = 1, k - 1
499 a( ii, k ) = a( ii, k ) / d11
500 16 CONTINUE
501*
502* Perform a rank-1 update of A(k+1:n,k+1:n) as
503* A := A - U(k)*D(k)*U(k)**T
504* = A - W(k)*(1/D(k))*W(k)**T
505* = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T
506*
507 CALL zher( uplo, k-1, -d11, a( 1, k ), 1, a, lda )
508 END IF
509 END IF
510*
511 ELSE
512*
513* 2-by-2 pivot block D(k): columns k and k-1 now hold
514*
515* ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k)
516*
517* where U(k) and U(k-1) are the k-th and (k-1)-th columns
518* of U
519*
520* Perform a rank-2 update of A(1:k-2,1:k-2) as
521*
522* A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )**T
523* = A - ( ( A(k-1)A(k) )*inv(D(k)) ) * ( A(k-1)A(k) )**T
524*
525* and store L(k) and L(k+1) in columns k and k+1
526*
527 IF( k.GT.2 ) THEN
528* D = |A12|
529 d = dlapy2( dble( a( k-1, k ) ),
530 $ dimag( a( k-1, k ) ) )
531 d11 = dble( a( k, k ) / d )
532 d22 = dble( a( k-1, k-1 ) / d )
533 d12 = a( k-1, k ) / d
534 tt = one / ( d11*d22-one )
535*
536 DO 30 j = k - 2, 1, -1
537*
538* Compute D21 * ( W(k)W(k+1) ) * inv(D(k)) for row J
539*
540 wkm1 = tt*( d11*a( j, k-1 )-dconjg( d12 )*
541 $ a( j, k ) )
542 wk = tt*( d22*a( j, k )-d12*a( j, k-1 ) )
543*
544* Perform a rank-2 update of A(1:k-2,1:k-2)
545*
546 DO 20 i = j, 1, -1
547 a( i, j ) = a( i, j ) -
548 $ ( a( i, k ) / d )*dconjg( wk ) -
549 $ ( a( i, k-1 ) / d )*dconjg( wkm1 )
550 20 CONTINUE
551*
552* Store U(k) and U(k-1) in cols k and k-1 for row J
553*
554 a( j, k ) = wk / d
555 a( j, k-1 ) = wkm1 / d
556* (*) Make sure that diagonal element of pivot is real
557 a( j, j ) = dcmplx( dble( a( j, j ) ), zero )
558*
559 30 CONTINUE
560*
561 END IF
562*
563 END IF
564*
565 END IF
566*
567* Store details of the interchanges in IPIV
568*
569 IF( kstep.EQ.1 ) THEN
570 ipiv( k ) = kp
571 ELSE
572 ipiv( k ) = -p
573 ipiv( k-1 ) = -kp
574 END IF
575*
576* Decrease K and return to the start of the main loop
577*
578 k = k - kstep
579 GO TO 10
580*
581 ELSE
582*
583* Factorize A as L*D*L**H using the lower triangle of A
584*
585* K is the main loop index, increasing from 1 to N in steps of
586* 1 or 2
587*
588 k = 1
589 40 CONTINUE
590*
591* If K > N, exit from loop
592*
593 IF( k.GT.n )
594 $ GO TO 70
595 kstep = 1
596 p = k
597*
598* Determine rows and columns to be interchanged and whether
599* a 1-by-1 or 2-by-2 pivot block will be used
600*
601 absakk = abs( dble( a( k, k ) ) )
602*
603* IMAX is the row-index of the largest off-diagonal element in
604* column K, and COLMAX is its absolute value.
605* Determine both COLMAX and IMAX.
606*
607 IF( k.LT.n ) THEN
608 imax = k + izamax( n-k, a( k+1, k ), 1 )
609 colmax = cabs1( a( imax, k ) )
610 ELSE
611 colmax = zero
612 END IF
613*
614 IF( max( absakk, colmax ).EQ.zero ) THEN
615*
616* Column K is zero or underflow: set INFO and continue
617*
618 IF( info.EQ.0 )
619 $ info = k
620 kp = k
621 a( k, k ) = dble( a( k, k ) )
622 ELSE
623*
624* ============================================================
625*
626* BEGIN pivot search
627*
628* Case(1)
629* Equivalent to testing for ABSAKK.GE.ALPHA*COLMAX
630* (used to handle NaN and Inf)
631*
632 IF( .NOT.( absakk.LT.alpha*colmax ) ) THEN
633*
634* no interchange, use 1-by-1 pivot block
635*
636 kp = k
637*
638 ELSE
639*
640 done = .false.
641*
642* Loop until pivot found
643*
644 42 CONTINUE
645*
646* BEGIN pivot search loop body
647*
648*
649* JMAX is the column-index of the largest off-diagonal
650* element in row IMAX, and ROWMAX is its absolute value.
651* Determine both ROWMAX and JMAX.
652*
653 IF( imax.NE.k ) THEN
654 jmax = k - 1 + izamax( imax-k, a( imax, k ), lda )
655 rowmax = cabs1( a( imax, jmax ) )
656 ELSE
657 rowmax = zero
658 END IF
659*
660 IF( imax.LT.n ) THEN
661 itemp = imax + izamax( n-imax, a( imax+1, imax ),
662 $ 1 )
663 dtemp = cabs1( a( itemp, imax ) )
664 IF( dtemp.GT.rowmax ) THEN
665 rowmax = dtemp
666 jmax = itemp
667 END IF
668 END IF
669*
670* Case(2)
671* Equivalent to testing for
672* ABS( DBLE( W( IMAX,KW-1 ) ) ).GE.ALPHA*ROWMAX
673* (used to handle NaN and Inf)
674*
675 IF( .NOT.( abs( dble( a( imax, imax ) ) )
676 $ .LT.alpha*rowmax ) ) THEN
677*
678* interchange rows and columns K and IMAX,
679* use 1-by-1 pivot block
680*
681 kp = imax
682 done = .true.
683*
684* Case(3)
685* Equivalent to testing for ROWMAX.EQ.COLMAX,
686* (used to handle NaN and Inf)
687*
688 ELSE IF( ( p.EQ.jmax ) .OR. ( rowmax.LE.colmax ) )
689 $ THEN
690*
691* interchange rows and columns K+1 and IMAX,
692* use 2-by-2 pivot block
693*
694 kp = imax
695 kstep = 2
696 done = .true.
697*
698* Case(4)
699 ELSE
700*
701* Pivot not found: set params and repeat
702*
703 p = imax
704 colmax = rowmax
705 imax = jmax
706 END IF
707*
708*
709* END pivot search loop body
710*
711 IF( .NOT.done ) GOTO 42
712*
713 END IF
714*
715* END pivot search
716*
717* ============================================================
718*
719* KK is the column of A where pivoting step stopped
720*
721 kk = k + kstep - 1
722*
723* For only a 2x2 pivot, interchange rows and columns K and P
724* in the trailing submatrix A(k:n,k:n)
725*
726 IF( ( kstep.EQ.2 ) .AND. ( p.NE.k ) ) THEN
727* (1) Swap columnar parts
728 IF( p.LT.n )
729 $ CALL zswap( n-p, a( p+1, k ), 1, a( p+1, p ), 1 )
730* (2) Swap and conjugate middle parts
731 DO 44 j = k + 1, p - 1
732 t = dconjg( a( j, k ) )
733 a( j, k ) = dconjg( a( p, j ) )
734 a( p, j ) = t
735 44 CONTINUE
736* (3) Swap and conjugate corner elements at row-col intersection
737 a( p, k ) = dconjg( a( p, k ) )
738* (4) Swap diagonal elements at row-col intersection
739 r1 = dble( a( k, k ) )
740 a( k, k ) = dble( a( p, p ) )
741 a( p, p ) = r1
742 END IF
743*
744* For both 1x1 and 2x2 pivots, interchange rows and
745* columns KK and KP in the trailing submatrix A(k:n,k:n)
746*
747 IF( kp.NE.kk ) THEN
748* (1) Swap columnar parts
749 IF( kp.LT.n )
750 $ CALL zswap( n-kp, a( kp+1, kk ), 1, a( kp+1, kp ), 1 )
751* (2) Swap and conjugate middle parts
752 DO 45 j = kk + 1, kp - 1
753 t = dconjg( a( j, kk ) )
754 a( j, kk ) = dconjg( a( kp, j ) )
755 a( kp, j ) = t
756 45 CONTINUE
757* (3) Swap and conjugate corner elements at row-col intersection
758 a( kp, kk ) = dconjg( a( kp, kk ) )
759* (4) Swap diagonal elements at row-col intersection
760 r1 = dble( a( kk, kk ) )
761 a( kk, kk ) = dble( a( kp, kp ) )
762 a( kp, kp ) = r1
763*
764 IF( kstep.EQ.2 ) THEN
765* (*) Make sure that diagonal element of pivot is real
766 a( k, k ) = dble( a( k, k ) )
767* (5) Swap row elements
768 t = a( k+1, k )
769 a( k+1, k ) = a( kp, k )
770 a( kp, k ) = t
771 END IF
772 ELSE
773* (*) Make sure that diagonal element of pivot is real
774 a( k, k ) = dble( a( k, k ) )
775 IF( kstep.EQ.2 )
776 $ a( k+1, k+1 ) = dble( a( k+1, k+1 ) )
777 END IF
778*
779* Update the trailing submatrix
780*
781 IF( kstep.EQ.1 ) THEN
782*
783* 1-by-1 pivot block D(k): column k of A now holds
784*
785* W(k) = L(k)*D(k),
786*
787* where L(k) is the k-th column of L
788*
789 IF( k.LT.n ) THEN
790*
791* Perform a rank-1 update of A(k+1:n,k+1:n) and
792* store L(k) in column k
793*
794* Handle division by a small number
795*
796 IF( abs( dble( a( k, k ) ) ).GE.sfmin ) THEN
797*
798* Perform a rank-1 update of A(k+1:n,k+1:n) as
799* A := A - L(k)*D(k)*L(k)**T
800* = A - W(k)*(1/D(k))*W(k)**T
801*
802 d11 = one / dble( a( k, k ) )
803 CALL zher( uplo, n-k, -d11, a( k+1, k ), 1,
804 $ a( k+1, k+1 ), lda )
805*
806* Store L(k) in column k
807*
808 CALL zdscal( n-k, d11, a( k+1, k ), 1 )
809 ELSE
810*
811* Store L(k) in column k
812*
813 d11 = dble( a( k, k ) )
814 DO 46 ii = k + 1, n
815 a( ii, k ) = a( ii, k ) / d11
816 46 CONTINUE
817*
818* Perform a rank-1 update of A(k+1:n,k+1:n) as
819* A := A - L(k)*D(k)*L(k)**T
820* = A - W(k)*(1/D(k))*W(k)**T
821* = A - (W(k)/D(k))*(D(k))*(W(k)/D(K))**T
822*
823 CALL zher( uplo, n-k, -d11, a( k+1, k ), 1,
824 $ a( k+1, k+1 ), lda )
825 END IF
826 END IF
827*
828 ELSE
829*
830* 2-by-2 pivot block D(k): columns k and k+1 now hold
831*
832* ( W(k) W(k+1) ) = ( L(k) L(k+1) )*D(k)
833*
834* where L(k) and L(k+1) are the k-th and (k+1)-th columns
835* of L
836*
837*
838* Perform a rank-2 update of A(k+2:n,k+2:n) as
839*
840* A := A - ( L(k) L(k+1) ) * D(k) * ( L(k) L(k+1) )**T
841* = A - ( ( A(k)A(k+1) )*inv(D(k) ) * ( A(k)A(k+1) )**T
842*
843* and store L(k) and L(k+1) in columns k and k+1
844*
845 IF( k.LT.n-1 ) THEN
846* D = |A21|
847 d = dlapy2( dble( a( k+1, k ) ),
848 $ dimag( a( k+1, k ) ) )
849 d11 = dble( a( k+1, k+1 ) ) / d
850 d22 = dble( a( k, k ) ) / d
851 d21 = a( k+1, k ) / d
852 tt = one / ( d11*d22-one )
853*
854 DO 60 j = k + 2, n
855*
856* Compute D21 * ( W(k)W(k+1) ) * inv(D(k)) for row J
857*
858 wk = tt*( d11*a( j, k )-d21*a( j, k+1 ) )
859 wkp1 = tt*( d22*a( j, k+1 )-dconjg( d21 )*
860 $ a( j, k ) )
861*
862* Perform a rank-2 update of A(k+2:n,k+2:n)
863*
864 DO 50 i = j, n
865 a( i, j ) = a( i, j ) -
866 $ ( a( i, k ) / d )*dconjg( wk ) -
867 $ ( a( i, k+1 ) / d )*dconjg( wkp1 )
868 50 CONTINUE
869*
870* Store L(k) and L(k+1) in cols k and k+1 for row J
871*
872 a( j, k ) = wk / d
873 a( j, k+1 ) = wkp1 / d
874* (*) Make sure that diagonal element of pivot is real
875 a( j, j ) = dcmplx( dble( a( j, j ) ), zero )
876*
877 60 CONTINUE
878*
879 END IF
880*
881 END IF
882*
883 END IF
884*
885* Store details of the interchanges in IPIV
886*
887 IF( kstep.EQ.1 ) THEN
888 ipiv( k ) = kp
889 ELSE
890 ipiv( k ) = -p
891 ipiv( k+1 ) = -kp
892 END IF
893*
894* Increase K and return to the start of the main loop
895*
896 k = k + kstep
897 GO TO 40
898*
899 END IF
900*
901 70 CONTINUE
902*
903 RETURN
904*
905* End of ZHETF2_ROOK
906*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zher(uplo, n, alpha, x, incx, a, lda)
ZHER
Definition zher.f:135
integer function izamax(n, zx, incx)
IZAMAX
Definition izamax.f:71
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
double precision function dlapy2(x, y)
DLAPY2 returns sqrt(x2+y2).
Definition dlapy2.f:63
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine zdscal(n, da, zx, incx)
ZDSCAL
Definition zdscal.f:78
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81
Here is the call graph for this function:
Here is the caller graph for this function: