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

◆ zheevr_2stage()

subroutine zheevr_2stage ( character jobz,
character range,
character uplo,
integer n,
complex*16, dimension( lda, * ) a,
integer lda,
double precision vl,
double precision vu,
integer il,
integer iu,
double precision abstol,
integer m,
double precision, dimension( * ) w,
complex*16, dimension( ldz, * ) z,
integer ldz,
integer, dimension( * ) isuppz,
complex*16, dimension( * ) work,
integer lwork,
double precision, dimension( * ) rwork,
integer lrwork,
integer, dimension( * ) iwork,
integer liwork,
integer info )

ZHEEVR_2STAGE computes the eigenvalues and, optionally, the left and/or right eigenvectors for HE matrices

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

Purpose:
!>
!> ZHEEVR_2STAGE computes selected eigenvalues and, optionally, eigenvectors
!> of a complex Hermitian matrix A using the 2stage technique for
!> the reduction to tridiagonal.  Eigenvalues and eigenvectors can
!> be selected by specifying either a range of values or a range of
!> indices for the desired eigenvalues.
!>
!> ZHEEVR_2STAGE first reduces the matrix A to tridiagonal form T with a call
!> to ZHETRD.  Then, whenever possible, ZHEEVR_2STAGE calls ZSTEMR to compute
!> eigenspectrum using Relatively Robust Representations.  ZSTEMR
!> computes eigenvalues by the dqds algorithm, while orthogonal
!> eigenvectors are computed from various  L D L^T representations
!> (also known as Relatively Robust Representations). Gram-Schmidt
!> orthogonalization is avoided as far as possible. More specifically,
!> the various steps of the algorithm are as follows.
!>
!> For each unreduced block (submatrix) of T,
!>    (a) Compute T - sigma I  = L D L^T, so that L and D
!>        define all the wanted eigenvalues to high relative accuracy.
!>        This means that small relative changes in the entries of D and L
!>        cause only small relative changes in the eigenvalues and
!>        eigenvectors. The standard (unfactored) representation of the
!>        tridiagonal matrix T does not have this property in general.
!>    (b) Compute the eigenvalues to suitable accuracy.
!>        If the eigenvectors are desired, the algorithm attains full
!>        accuracy of the computed eigenvalues only right before
!>        the corresponding vectors have to be computed, see steps c) and d).
!>    (c) For each cluster of close eigenvalues, select a new
!>        shift close to the cluster, find a new factorization, and refine
!>        the shifted eigenvalues to suitable accuracy.
!>    (d) For each eigenvalue with a large enough relative separation compute
!>        the corresponding eigenvector by forming a rank revealing twisted
!>        factorization. Go back to (c) for any clusters that remain.
!>
!> The desired accuracy of the output can be specified by the input
!> parameter ABSTOL.
!>
!> For more details, see ZSTEMR's documentation and:
!> - Inderjit S. Dhillon and Beresford N. Parlett: 
!>   Linear Algebra and its Applications, 387(1), pp. 1-28, August 2004.
!> - Inderjit Dhillon and Beresford Parlett:  SIAM Journal on Matrix Analysis and Applications, Vol. 25,
!>   2004.  Also LAPACK Working Note 154.
!> - Inderjit Dhillon: ,
!>   Computer Science Division Technical Report No. UCB/CSD-97-971,
!>   UC Berkeley, May 1997.
!>
!>
!> Note 1 : ZHEEVR_2STAGE calls ZSTEMR when the full spectrum is requested
!> on machines which conform to the ieee-754 floating point standard.
!> ZHEEVR_2STAGE calls DSTEBZ and ZSTEIN on non-ieee machines and
!> when partial spectrum requests are made.
!>
!> Normal execution of ZSTEMR may create NaNs and infinities and
!> hence may abort due to a floating point exception in environments
!> which do not handle NaNs and infinities in the ieee standard default
!> manner.
!> 
Parameters
[in]JOBZ
!>          JOBZ is CHARACTER*1
!>          = 'N':  Compute eigenvalues only;
!>          = 'V':  Compute eigenvalues and eigenvectors.
!>                  Not available in this release.
!> 
[in]RANGE
!>          RANGE is CHARACTER*1
!>          = 'A': all eigenvalues will be found.
!>          = 'V': all eigenvalues in the half-open interval (VL,VU]
!>                 will be found.
!>          = 'I': the IL-th through IU-th eigenvalues will be found.
!>          For RANGE = 'V' or 'I' and IU - IL < N - 1, DSTEBZ and
!>          ZSTEIN are called
!> 
[in]UPLO
!>          UPLO is CHARACTER*1
!>          = 'U':  Upper triangle of A is stored;
!>          = 'L':  Lower triangle of A is stored.
!> 
[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.  If UPLO = 'L',
!>          the leading N-by-N lower triangular part of A contains
!>          the lower triangular part of the matrix A.
!>          On exit, the lower triangle (if UPLO='L') or the upper
!>          triangle (if UPLO='U') of A, including the diagonal, is
!>          destroyed.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,N).
!> 
[in]VL
!>          VL is DOUBLE PRECISION
!>          If RANGE='V', the lower bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]VU
!>          VU is DOUBLE PRECISION
!>          If RANGE='V', the upper bound of the interval to
!>          be searched for eigenvalues. VL < VU.
!>          Not referenced if RANGE = 'A' or 'I'.
!> 
[in]IL
!>          IL is INTEGER
!>          If RANGE='I', the index of the
!>          smallest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]IU
!>          IU is INTEGER
!>          If RANGE='I', the index of the
!>          largest eigenvalue to be returned.
!>          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0.
!>          Not referenced if RANGE = 'A' or 'V'.
!> 
[in]ABSTOL
!>          ABSTOL is DOUBLE PRECISION
!>          The absolute error tolerance for the eigenvalues.
!>          An approximate eigenvalue is accepted as converged
!>          when it is determined to lie in an interval [a,b]
!>          of width less than or equal to
!>
!>                  ABSTOL + EPS *   max( |a|,|b| ) ,
!>
!>          where EPS is the machine precision.  If ABSTOL is less than
!>          or equal to zero, then  EPS*|T|  will be used in its place,
!>          where |T| is the 1-norm of the tridiagonal matrix obtained
!>          by reducing A to tridiagonal form.
!>
!>          See  by Demmel and
!>          Kahan, LAPACK Working Note #3.
!>
!>          If high relative accuracy is important, set ABSTOL to
!>          DLAMCH( 'Safe minimum' ).  Doing so will guarantee that
!>          eigenvalues are computed to high relative accuracy when
!>          possible in future releases.  The current code does not
!>          make any guarantees about high relative accuracy, but
!>          future releases will. See J. Barlow and J. Demmel,
!>          , LAPACK Working Note #7, for a discussion
!>          of which matrices define their eigenvalues to high relative
!>          accuracy.
!> 
[out]M
!>          M is INTEGER
!>          The total number of eigenvalues found.  0 <= M <= N.
!>          If RANGE = 'A', M = N, and if RANGE = 'I', M = IU-IL+1.
!> 
[out]W
!>          W is DOUBLE PRECISION array, dimension (N)
!>          The first M elements contain the selected eigenvalues in
!>          ascending order.
!> 
[out]Z
!>          Z is COMPLEX*16 array, dimension (LDZ, max(1,M))
!>          If JOBZ = 'V', then if INFO = 0, the first M columns of Z
!>          contain the orthonormal eigenvectors of the matrix A
!>          corresponding to the selected eigenvalues, with the i-th
!>          column of Z holding the eigenvector associated with W(i).
!>          If JOBZ = 'N', then Z is not referenced.
!>          Note: the user must ensure that at least max(1,M) columns are
!>          supplied in the array Z; if RANGE = 'V', the exact value of M
!>          is not known in advance and an upper bound must be used.
!> 
[in]LDZ
!>          LDZ is INTEGER
!>          The leading dimension of the array Z.  LDZ >= 1, and if
!>          JOBZ = 'V', LDZ >= max(1,N).
!> 
[out]ISUPPZ
!>          ISUPPZ is INTEGER array, dimension ( 2*max(1,M) )
!>          The support of the eigenvectors in Z, i.e., the indices
!>          indicating the nonzero elements in Z. The i-th eigenvector
!>          is nonzero only in elements ISUPPZ( 2*i-1 ) through
!>          ISUPPZ( 2*i ). This is an output of ZSTEMR (tridiagonal
!>          matrix). The support of the eigenvectors of A is typically
!>          1:N because of the unitary transformations applied by ZUNMTR.
!>          Implemented only for RANGE = 'A' or 'I' and IU - IL = N - 1
!> 
[out]WORK
!>          WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.
!>          If N <= 1,               LWORK must be at least 1.
!>          If JOBZ = 'N' and N > 1, LWORK must be queried.
!>                                   LWORK = MAX(1, 26*N, dimension) where
!>                                   dimension = max(stage1,stage2) + (KD+1)*N + N
!>                                             = N*KD + N*max(KD+1,FACTOPTNB)
!>                                               + max(2*KD*KD, KD*NTHREADS)
!>                                               + (KD+1)*N + N
!>                                   where KD is the blocking size of the reduction,
!>                                   FACTOPTNB is the blocking used by the QR or LQ
!>                                   algorithm, usually FACTOPTNB=128 is a good choice
!>                                   NTHREADS is the number of threads used when
!>                                   openMP compilation is enabled, otherwise =1.
!>          If JOBZ = 'V' and N > 1, LWORK must be queried. Not yet available
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal sizes of the WORK, RWORK and
!>          IWORK arrays, returns these values as the first entries of
!>          the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]RWORK
!>          RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
!>          On exit, if INFO = 0, RWORK(1) returns the optimal
!>          (and minimal) LRWORK.
!> 
[in]LRWORK
!>          LRWORK is INTEGER
!>          The length of the array RWORK.
!>          If N <= 1, LRWORK >= 1, else LRWORK >= 24*N.
!>
!>          If LRWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension (MAX(1,LIWORK))
!>          On exit, if INFO = 0, IWORK(1) returns the optimal
!>          (and minimal) LIWORK.
!> 
[in]LIWORK
!>          LIWORK is INTEGER
!>          The dimension of the array IWORK.
!>          If N <= 1, LIWORK >= 1, else LIWORK >= 10*N.
!>
!>          If LIWORK = -1, then a workspace query is assumed; the
!>          routine only calculates the optimal sizes of the WORK, RWORK
!>          and IWORK arrays, returns these values as the first entries
!>          of the WORK, RWORK and IWORK arrays, and no error message
!>          related to LWORK or LRWORK or LIWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  Internal error
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Inderjit Dhillon, IBM Almaden, USA \n
Osni Marques, LBNL/NERSC, USA \n
Ken Stanley, Computer Science Division, University of
  California at Berkeley, USA \n
Jason Riedy, Computer Science Division, University of
  California at Berkeley, USA \n
Further Details:
!>
!>  All details about the 2stage techniques are available in:
!>
!>  Azzam Haidar, Hatem Ltaief, and Jack Dongarra.
!>  Parallel reduction to condensed forms for symmetric eigenvalue problems
!>  using aggregated fine-grained and memory-aware kernels. In Proceedings
!>  of 2011 International Conference for High Performance Computing,
!>  Networking, Storage and Analysis (SC '11), New York, NY, USA,
!>  Article 8 , 11 pages.
!>  http://doi.acm.org/10.1145/2063384.2063394
!>
!>  A. Haidar, J. Kurzak, P. Luszczek, 2013.
!>  An improved parallel singular value algorithm and its implementation
!>  for multicore hardware, In Proceedings of 2013 International Conference
!>  for High Performance Computing, Networking, Storage and Analysis (SC '13).
!>  Denver, Colorado, USA, 2013.
!>  Article 90, 12 pages.
!>  http://doi.acm.org/10.1145/2503210.2503292
!>
!>  A. Haidar, R. Solca, S. Tomov, T. Schulthess and J. Dongarra.
!>  A novel hybrid CPU-GPU generalized eigensolver for electronic structure
!>  calculations based on fine-grained memory aware tasks.
!>  International Journal of High Performance Computing Applications.
!>  Volume 28 Issue 2, Pages 196-209, May 2014.
!>  http://hpc.sagepub.com/content/28/2/196
!>
!> 

Definition at line 403 of file zheevr_2stage.f.

407*
408 IMPLICIT NONE
409*
410* -- LAPACK driver routine --
411* -- LAPACK is a software package provided by Univ. of Tennessee, --
412* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
413*
414* .. Scalar Arguments ..
415 CHARACTER JOBZ, RANGE, UPLO
416 INTEGER IL, INFO, IU, LDA, LDZ, LIWORK, LRWORK, LWORK,
417 $ M, N
418 DOUBLE PRECISION ABSTOL, VL, VU
419* ..
420* .. Array Arguments ..
421 INTEGER ISUPPZ( * ), IWORK( * )
422 DOUBLE PRECISION RWORK( * ), W( * )
423 COMPLEX*16 A( LDA, * ), WORK( * ), Z( LDZ, * )
424* ..
425*
426* =====================================================================
427*
428* .. Parameters ..
429 DOUBLE PRECISION ZERO, ONE, TWO
430 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
431* ..
432* .. Local Scalars ..
433 LOGICAL ALLEIG, INDEIG, LOWER, LQUERY, TEST, VALEIG,
434 $ WANTZ, TRYRAC
435 CHARACTER ORDER
436 INTEGER I, IEEEOK, IINFO, IMAX, INDIBL, INDIFL, INDISP,
437 $ INDIWO, INDRD, INDRDD, INDRE, INDREE, INDRWK,
438 $ INDTAU, INDWK, INDWKN, ISCALE, ITMP1, J, JJ,
439 $ LIWMIN, LLWORK, LLRWORK, LLWRKN, LRWMIN,
440 $ LWMIN, NSPLIT, LHTRD, LWTRD, KD, IB, INDHOUS
441 DOUBLE PRECISION ABSTLL, ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN,
442 $ SIGMA, SMLNUM, TMP1, VLL, VUU
443* ..
444* .. External Functions ..
445 LOGICAL LSAME
446 INTEGER ILAENV, ILAENV2STAGE
447 DOUBLE PRECISION DLAMCH, ZLANSY
448 EXTERNAL lsame, dlamch, zlansy, ilaenv,
450* ..
451* .. External Subroutines ..
452 EXTERNAL dcopy, dscal, dstebz, dsterf, xerbla,
453 $ zdscal,
455* ..
456* .. Intrinsic Functions ..
457 INTRINSIC dble, max, min, sqrt
458* ..
459* .. Executable Statements ..
460*
461* Test the input parameters.
462*
463 ieeeok = ilaenv( 10, 'ZHEEVR', 'N', 1, 2, 3, 4 )
464*
465 lower = lsame( uplo, 'L' )
466 wantz = lsame( jobz, 'V' )
467 alleig = lsame( range, 'A' )
468 valeig = lsame( range, 'V' )
469 indeig = lsame( range, 'I' )
470*
471 lquery = ( ( lwork.EQ.-1 ) .OR. ( lrwork.EQ.-1 ) .OR.
472 $ ( liwork.EQ.-1 ) )
473*
474 kd = ilaenv2stage( 1, 'ZHETRD_2STAGE', jobz, n, -1, -1,
475 $ -1 )
476 ib = ilaenv2stage( 2, 'ZHETRD_2STAGE', jobz, n, kd, -1,
477 $ -1 )
478 lhtrd = ilaenv2stage( 3, 'ZHETRD_2STAGE', jobz, n, kd, ib,
479 $ -1 )
480 lwtrd = ilaenv2stage( 4, 'ZHETRD_2STAGE', jobz, n, kd, ib,
481 $ -1 )
482*
483 IF( n.LE.1 ) THEN
484 lwmin = 1
485 lrwmin = 1
486 liwmin = 1
487 ELSE
488 lwmin = n + lhtrd + lwtrd
489 lrwmin = 24*n
490 liwmin = 10*n
491 END IF
492*
493 info = 0
494 IF( .NOT.( lsame( jobz, 'N' ) ) ) THEN
495 info = -1
496 ELSE IF( .NOT.( alleig .OR. valeig .OR. indeig ) ) THEN
497 info = -2
498 ELSE IF( .NOT.( lower .OR. lsame( uplo, 'U' ) ) ) THEN
499 info = -3
500 ELSE IF( n.LT.0 ) THEN
501 info = -4
502 ELSE IF( lda.LT.max( 1, n ) ) THEN
503 info = -6
504 ELSE
505 IF( valeig ) THEN
506 IF( n.GT.0 .AND. vu.LE.vl )
507 $ info = -8
508 ELSE IF( indeig ) THEN
509 IF( il.LT.1 .OR. il.GT.max( 1, n ) ) THEN
510 info = -9
511 ELSE IF( iu.LT.min( n, il ) .OR. iu.GT.n ) THEN
512 info = -10
513 END IF
514 END IF
515 END IF
516 IF( info.EQ.0 ) THEN
517 IF( ldz.LT.1 .OR. ( wantz .AND. ldz.LT.n ) ) THEN
518 info = -15
519 END IF
520 END IF
521*
522 IF( info.EQ.0 ) THEN
523 work( 1 ) = lwmin
524 rwork( 1 ) = real( lrwmin )
525 iwork( 1 ) = liwmin
526*
527 IF( lwork.LT.lwmin .AND. .NOT.lquery ) THEN
528 info = -18
529 ELSE IF( lrwork.LT.lrwmin .AND. .NOT.lquery ) THEN
530 info = -20
531 ELSE IF( liwork.LT.liwmin .AND. .NOT.lquery ) THEN
532 info = -22
533 END IF
534 END IF
535*
536 IF( info.NE.0 ) THEN
537 CALL xerbla( 'ZHEEVR_2STAGE', -info )
538 RETURN
539 ELSE IF( lquery ) THEN
540 RETURN
541 END IF
542*
543* Quick return if possible
544*
545 m = 0
546 IF( n.EQ.0 ) THEN
547 work( 1 ) = 1
548 RETURN
549 END IF
550*
551 IF( n.EQ.1 ) THEN
552 work( 1 ) = 1
553 IF( alleig .OR. indeig ) THEN
554 m = 1
555 w( 1 ) = dble( a( 1, 1 ) )
556 ELSE
557 IF( vl.LT.dble( a( 1, 1 ) ) .AND. vu.GE.dble( a( 1, 1 ) ) )
558 $ THEN
559 m = 1
560 w( 1 ) = dble( a( 1, 1 ) )
561 END IF
562 END IF
563 IF( wantz ) THEN
564 z( 1, 1 ) = one
565 isuppz( 1 ) = 1
566 isuppz( 2 ) = 1
567 END IF
568 RETURN
569 END IF
570*
571* Get machine constants.
572*
573 safmin = dlamch( 'Safe minimum' )
574 eps = dlamch( 'Precision' )
575 smlnum = safmin / eps
576 bignum = one / smlnum
577 rmin = sqrt( smlnum )
578 rmax = min( sqrt( bignum ), one / sqrt( sqrt( safmin ) ) )
579*
580* Scale matrix to allowable range, if necessary.
581*
582 iscale = 0
583 abstll = abstol
584 IF (valeig) THEN
585 vll = vl
586 vuu = vu
587 END IF
588 anrm = zlansy( 'M', uplo, n, a, lda, rwork )
589 IF( anrm.GT.zero .AND. anrm.LT.rmin ) THEN
590 iscale = 1
591 sigma = rmin / anrm
592 ELSE IF( anrm.GT.rmax ) THEN
593 iscale = 1
594 sigma = rmax / anrm
595 END IF
596 IF( iscale.EQ.1 ) THEN
597 IF( lower ) THEN
598 DO 10 j = 1, n
599 CALL zdscal( n-j+1, sigma, a( j, j ), 1 )
600 10 CONTINUE
601 ELSE
602 DO 20 j = 1, n
603 CALL zdscal( j, sigma, a( 1, j ), 1 )
604 20 CONTINUE
605 END IF
606 IF( abstol.GT.0 )
607 $ abstll = abstol*sigma
608 IF( valeig ) THEN
609 vll = vl*sigma
610 vuu = vu*sigma
611 END IF
612 END IF
613
614* Initialize indices into workspaces. Note: The IWORK indices are
615* used only if DSTERF or ZSTEMR fail.
616
617* WORK(INDTAU:INDTAU+N-1) stores the complex scalar factors of the
618* elementary reflectors used in ZHETRD.
619 indtau = 1
620* INDWK is the starting offset of the remaining complex workspace,
621* and LLWORK is the remaining complex workspace size.
622 indhous = indtau + n
623 indwk = indhous + lhtrd
624 llwork = lwork - indwk + 1
625
626* RWORK(INDRD:INDRD+N-1) stores the real tridiagonal's diagonal
627* entries.
628 indrd = 1
629* RWORK(INDRE:INDRE+N-1) stores the off-diagonal entries of the
630* tridiagonal matrix from ZHETRD.
631 indre = indrd + n
632* RWORK(INDRDD:INDRDD+N-1) is a copy of the diagonal entries over
633* -written by ZSTEMR (the DSTERF path copies the diagonal to W).
634 indrdd = indre + n
635* RWORK(INDREE:INDREE+N-1) is a copy of the off-diagonal entries over
636* -written while computing the eigenvalues in DSTERF and ZSTEMR.
637 indree = indrdd + n
638* INDRWK is the starting offset of the left-over real workspace, and
639* LLRWORK is the remaining workspace size.
640 indrwk = indree + n
641 llrwork = lrwork - indrwk + 1
642
643* IWORK(INDIBL:INDIBL+M-1) corresponds to IBLOCK in DSTEBZ and
644* stores the block indices of each of the M<=N eigenvalues.
645 indibl = 1
646* IWORK(INDISP:INDISP+NSPLIT-1) corresponds to ISPLIT in DSTEBZ and
647* stores the starting and finishing indices of each block.
648 indisp = indibl + n
649* IWORK(INDIFL:INDIFL+N-1) stores the indices of eigenvectors
650* that corresponding to eigenvectors that fail to converge in
651* ZSTEIN. This information is discarded; if any fail, the driver
652* returns INFO > 0.
653 indifl = indisp + n
654* INDIWO is the offset of the remaining integer workspace.
655 indiwo = indifl + n
656
657*
658* Call ZHETRD_2STAGE to reduce Hermitian matrix to tridiagonal form.
659*
660 CALL zhetrd_2stage( jobz, uplo, n, a, lda, rwork( indrd ),
661 $ rwork( indre ), work( indtau ),
662 $ work( indhous ), lhtrd,
663 $ work( indwk ), llwork, iinfo )
664*
665* If all eigenvalues are desired
666* then call DSTERF or ZSTEMR and ZUNMTR.
667*
668 test = .false.
669 IF( indeig ) THEN
670 IF( il.EQ.1 .AND. iu.EQ.n ) THEN
671 test = .true.
672 END IF
673 END IF
674 IF( ( alleig.OR.test ) .AND. ( ieeeok.EQ.1 ) ) THEN
675 IF( .NOT.wantz ) THEN
676 CALL dcopy( n, rwork( indrd ), 1, w, 1 )
677 CALL dcopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
678 CALL dsterf( n, w, rwork( indree ), info )
679 ELSE
680 CALL dcopy( n-1, rwork( indre ), 1, rwork( indree ), 1 )
681 CALL dcopy( n, rwork( indrd ), 1, rwork( indrdd ), 1 )
682*
683 IF (abstol .LE. two*n*eps) THEN
684 tryrac = .true.
685 ELSE
686 tryrac = .false.
687 END IF
688 CALL zstemr( jobz, 'A', n, rwork( indrdd ),
689 $ rwork( indree ), vl, vu, il, iu, m, w,
690 $ z, ldz, n, isuppz, tryrac,
691 $ rwork( indrwk ), llrwork,
692 $ iwork, liwork, info )
693*
694* Apply unitary matrix used in reduction to tridiagonal
695* form to eigenvectors returned by ZSTEMR.
696*
697 IF( wantz .AND. info.EQ.0 ) THEN
698 indwkn = indwk
699 llwrkn = lwork - indwkn + 1
700 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda,
701 $ work( indtau ), z, ldz, work( indwkn ),
702 $ llwrkn, iinfo )
703 END IF
704 END IF
705*
706*
707 IF( info.EQ.0 ) THEN
708 m = n
709 GO TO 30
710 END IF
711 info = 0
712 END IF
713*
714* Otherwise, call DSTEBZ and, if eigenvectors are desired, ZSTEIN.
715* Also call DSTEBZ and ZSTEIN if ZSTEMR fails.
716*
717 IF( wantz ) THEN
718 order = 'B'
719 ELSE
720 order = 'E'
721 END IF
722
723 CALL dstebz( range, order, n, vll, vuu, il, iu, abstll,
724 $ rwork( indrd ), rwork( indre ), m, nsplit, w,
725 $ iwork( indibl ), iwork( indisp ), rwork( indrwk ),
726 $ iwork( indiwo ), info )
727*
728 IF( wantz ) THEN
729 CALL zstein( n, rwork( indrd ), rwork( indre ), m, w,
730 $ iwork( indibl ), iwork( indisp ), z, ldz,
731 $ rwork( indrwk ), iwork( indiwo ), iwork( indifl ),
732 $ info )
733*
734* Apply unitary matrix used in reduction to tridiagonal
735* form to eigenvectors returned by ZSTEIN.
736*
737 indwkn = indwk
738 llwrkn = lwork - indwkn + 1
739 CALL zunmtr( 'L', uplo, 'N', n, m, a, lda, work( indtau ),
740 $ z,
741 $ ldz, work( indwkn ), llwrkn, iinfo )
742 END IF
743*
744* If matrix was scaled, then rescale eigenvalues appropriately.
745*
746 30 CONTINUE
747 IF( iscale.EQ.1 ) THEN
748 IF( info.EQ.0 ) THEN
749 imax = m
750 ELSE
751 imax = info - 1
752 END IF
753 CALL dscal( imax, one / sigma, w, 1 )
754 END IF
755*
756* If eigenvalues are not in order, then sort them, along with
757* eigenvectors.
758*
759 IF( wantz ) THEN
760 DO 50 j = 1, m - 1
761 i = 0
762 tmp1 = w( j )
763 DO 40 jj = j + 1, m
764 IF( w( jj ).LT.tmp1 ) THEN
765 i = jj
766 tmp1 = w( jj )
767 END IF
768 40 CONTINUE
769*
770 IF( i.NE.0 ) THEN
771 itmp1 = iwork( indibl+i-1 )
772 w( i ) = w( j )
773 iwork( indibl+i-1 ) = iwork( indibl+j-1 )
774 w( j ) = tmp1
775 iwork( indibl+j-1 ) = itmp1
776 CALL zswap( n, z( 1, i ), 1, z( 1, j ), 1 )
777 END IF
778 50 CONTINUE
779 END IF
780*
781* Set WORK(1) to optimal workspace size.
782*
783 work( 1 ) = lwmin
784 rwork( 1 ) = real( lrwmin )
785 iwork( 1 ) = liwmin
786*
787 RETURN
788*
789* End of ZHEEVR_2STAGE
790*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine zhetrd_2stage(vect, uplo, n, a, lda, d, e, tau, hous2, lhous2, work, lwork, info)
ZHETRD_2STAGE
integer function ilaenv2stage(ispec, name, opts, n1, n2, n3, n4)
ILAENV2STAGE
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
double precision function zlansy(norm, uplo, n, a, lda, work)
ZLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition zlansy.f:121
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
subroutine zdscal(n, da, zx, incx)
ZDSCAL
Definition zdscal.f:78
subroutine dstebz(range, order, n, vl, vu, il, iu, abstol, d, e, m, nsplit, w, iblock, isplit, work, iwork, info)
DSTEBZ
Definition dstebz.f:272
subroutine zstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
ZSTEIN
Definition zstein.f:180
subroutine zstemr(jobz, range, n, d, e, vl, vu, il, iu, m, w, z, ldz, nzc, isuppz, tryrac, work, lwork, iwork, liwork, info)
ZSTEMR
Definition zstemr.f:337
subroutine dsterf(n, d, e, info)
DSTERF
Definition dsterf.f:84
subroutine zswap(n, zx, incx, zy, incy)
ZSWAP
Definition zswap.f:81
subroutine zunmtr(side, uplo, trans, m, n, a, lda, tau, c, ldc, work, lwork, info)
ZUNMTR
Definition zunmtr.f:170
Here is the call graph for this function:
Here is the caller graph for this function: