LAPACK  3.4.1
LAPACK: Linear Algebra PACKage
zhbev.f
Go to the documentation of this file.
00001 *> \brief <b> ZHBEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for OTHER matrices</b>
00002 *
00003 *  =========== DOCUMENTATION ===========
00004 *
00005 * Online html documentation available at 
00006 *            http://www.netlib.org/lapack/explore-html/ 
00007 *
00008 *> \htmlonly
00009 *> Download ZHBEV + dependencies 
00010 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zhbev.f"> 
00011 *> [TGZ]</a> 
00012 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zhbev.f"> 
00013 *> [ZIP]</a> 
00014 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zhbev.f"> 
00015 *> [TXT]</a>
00016 *> \endhtmlonly 
00017 *
00018 *  Definition:
00019 *  ===========
00020 *
00021 *       SUBROUTINE ZHBEV( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,
00022 *                         RWORK, INFO )
00023 * 
00024 *       .. Scalar Arguments ..
00025 *       CHARACTER          JOBZ, UPLO
00026 *       INTEGER            INFO, KD, LDAB, LDZ, N
00027 *       ..
00028 *       .. Array Arguments ..
00029 *       DOUBLE PRECISION   RWORK( * ), W( * )
00030 *       COMPLEX*16         AB( LDAB, * ), WORK( * ), Z( LDZ, * )
00031 *       ..
00032 *  
00033 *
00034 *> \par Purpose:
00035 *  =============
00036 *>
00037 *> \verbatim
00038 *>
00039 *> ZHBEV computes all the eigenvalues and, optionally, eigenvectors of
00040 *> a complex Hermitian band matrix A.
00041 *> \endverbatim
00042 *
00043 *  Arguments:
00044 *  ==========
00045 *
00046 *> \param[in] JOBZ
00047 *> \verbatim
00048 *>          JOBZ is CHARACTER*1
00049 *>          = 'N':  Compute eigenvalues only;
00050 *>          = 'V':  Compute eigenvalues and eigenvectors.
00051 *> \endverbatim
00052 *>
00053 *> \param[in] UPLO
00054 *> \verbatim
00055 *>          UPLO is CHARACTER*1
00056 *>          = 'U':  Upper triangle of A is stored;
00057 *>          = 'L':  Lower triangle of A is stored.
00058 *> \endverbatim
00059 *>
00060 *> \param[in] N
00061 *> \verbatim
00062 *>          N is INTEGER
00063 *>          The order of the matrix A.  N >= 0.
00064 *> \endverbatim
00065 *>
00066 *> \param[in] KD
00067 *> \verbatim
00068 *>          KD is INTEGER
00069 *>          The number of superdiagonals of the matrix A if UPLO = 'U',
00070 *>          or the number of subdiagonals if UPLO = 'L'.  KD >= 0.
00071 *> \endverbatim
00072 *>
00073 *> \param[in,out] AB
00074 *> \verbatim
00075 *>          AB is COMPLEX*16 array, dimension (LDAB, N)
00076 *>          On entry, the upper or lower triangle of the Hermitian band
00077 *>          matrix A, stored in the first KD+1 rows of the array.  The
00078 *>          j-th column of A is stored in the j-th column of the array AB
00079 *>          as follows:
00080 *>          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j;
00081 *>          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd).
00082 *>
00083 *>          On exit, AB is overwritten by values generated during the
00084 *>          reduction to tridiagonal form.  If UPLO = 'U', the first
00085 *>          superdiagonal and the diagonal of the tridiagonal matrix T
00086 *>          are returned in rows KD and KD+1 of AB, and if UPLO = 'L',
00087 *>          the diagonal and first subdiagonal of T are returned in the
00088 *>          first two rows of AB.
00089 *> \endverbatim
00090 *>
00091 *> \param[in] LDAB
00092 *> \verbatim
00093 *>          LDAB is INTEGER
00094 *>          The leading dimension of the array AB.  LDAB >= KD + 1.
00095 *> \endverbatim
00096 *>
00097 *> \param[out] W
00098 *> \verbatim
00099 *>          W is DOUBLE PRECISION array, dimension (N)
00100 *>          If INFO = 0, the eigenvalues in ascending order.
00101 *> \endverbatim
00102 *>
00103 *> \param[out] Z
00104 *> \verbatim
00105 *>          Z is COMPLEX*16 array, dimension (LDZ, N)
00106 *>          If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
00107 *>          eigenvectors of the matrix A, with the i-th column of Z
00108 *>          holding the eigenvector associated with W(i).
00109 *>          If JOBZ = 'N', then Z is not referenced.
00110 *> \endverbatim
00111 *>
00112 *> \param[in] LDZ
00113 *> \verbatim
00114 *>          LDZ is INTEGER
00115 *>          The leading dimension of the array Z.  LDZ >= 1, and if
00116 *>          JOBZ = 'V', LDZ >= max(1,N).
00117 *> \endverbatim
00118 *>
00119 *> \param[out] WORK
00120 *> \verbatim
00121 *>          WORK is COMPLEX*16 array, dimension (N)
00122 *> \endverbatim
00123 *>
00124 *> \param[out] RWORK
00125 *> \verbatim
00126 *>          RWORK is DOUBLE PRECISION array, dimension (max(1,3*N-2))
00127 *> \endverbatim
00128 *>
00129 *> \param[out] INFO
00130 *> \verbatim
00131 *>          INFO is INTEGER
00132 *>          = 0:  successful exit.
00133 *>          < 0:  if INFO = -i, the i-th argument had an illegal value.
00134 *>          > 0:  if INFO = i, the algorithm failed to converge; i
00135 *>                off-diagonal elements of an intermediate tridiagonal
00136 *>                form did not converge to zero.
00137 *> \endverbatim
00138 *
00139 *  Authors:
00140 *  ========
00141 *
00142 *> \author Univ. of Tennessee 
00143 *> \author Univ. of California Berkeley 
00144 *> \author Univ. of Colorado Denver 
00145 *> \author NAG Ltd. 
00146 *
00147 *> \date November 2011
00148 *
00149 *> \ingroup complex16OTHEReigen
00150 *
00151 *  =====================================================================
00152       SUBROUTINE ZHBEV( JOBZ, UPLO, N, KD, AB, LDAB, W, Z, LDZ, WORK,
00153      $                  RWORK, INFO )
00154 *
00155 *  -- LAPACK driver routine (version 3.4.0) --
00156 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00157 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00158 *     November 2011
00159 *
00160 *     .. Scalar Arguments ..
00161       CHARACTER          JOBZ, UPLO
00162       INTEGER            INFO, KD, LDAB, LDZ, N
00163 *     ..
00164 *     .. Array Arguments ..
00165       DOUBLE PRECISION   RWORK( * ), W( * )
00166       COMPLEX*16         AB( LDAB, * ), WORK( * ), Z( LDZ, * )
00167 *     ..
00168 *
00169 *  =====================================================================
00170 *
00171 *     .. Parameters ..
00172       DOUBLE PRECISION   ZERO, ONE
00173       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00174 *     ..
00175 *     .. Local Scalars ..
00176       LOGICAL            LOWER, WANTZ
00177       INTEGER            IINFO, IMAX, INDE, INDRWK, ISCALE
00178       DOUBLE PRECISION   ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
00179      $                   SMLNUM
00180 *     ..
00181 *     .. External Functions ..
00182       LOGICAL            LSAME
00183       DOUBLE PRECISION   DLAMCH, ZLANHB
00184       EXTERNAL           LSAME, DLAMCH, ZLANHB
00185 *     ..
00186 *     .. External Subroutines ..
00187       EXTERNAL           DSCAL, DSTERF, XERBLA, ZHBTRD, ZLASCL, ZSTEQR
00188 *     ..
00189 *     .. Intrinsic Functions ..
00190       INTRINSIC          SQRT
00191 *     ..
00192 *     .. Executable Statements ..
00193 *
00194 *     Test the input parameters.
00195 *
00196       WANTZ = LSAME( JOBZ, 'V' )
00197       LOWER = LSAME( UPLO, 'L' )
00198 *
00199       INFO = 0
00200       IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
00201          INFO = -1
00202       ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
00203          INFO = -2
00204       ELSE IF( N.LT.0 ) THEN
00205          INFO = -3
00206       ELSE IF( KD.LT.0 ) THEN
00207          INFO = -4
00208       ELSE IF( LDAB.LT.KD+1 ) THEN
00209          INFO = -6
00210       ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
00211          INFO = -9
00212       END IF
00213 *
00214       IF( INFO.NE.0 ) THEN
00215          CALL XERBLA( 'ZHBEV ', -INFO )
00216          RETURN
00217       END IF
00218 *
00219 *     Quick return if possible
00220 *
00221       IF( N.EQ.0 )
00222      $   RETURN
00223 *
00224       IF( N.EQ.1 ) THEN
00225          IF( LOWER ) THEN
00226             W( 1 ) = AB( 1, 1 )
00227          ELSE
00228             W( 1 ) = AB( KD+1, 1 )
00229          END IF
00230          IF( WANTZ )
00231      $      Z( 1, 1 ) = ONE
00232          RETURN
00233       END IF
00234 *
00235 *     Get machine constants.
00236 *
00237       SAFMIN = DLAMCH( 'Safe minimum' )
00238       EPS = DLAMCH( 'Precision' )
00239       SMLNUM = SAFMIN / EPS
00240       BIGNUM = ONE / SMLNUM
00241       RMIN = SQRT( SMLNUM )
00242       RMAX = SQRT( BIGNUM )
00243 *
00244 *     Scale matrix to allowable range, if necessary.
00245 *
00246       ANRM = ZLANHB( 'M', UPLO, N, KD, AB, LDAB, RWORK )
00247       ISCALE = 0
00248       IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
00249          ISCALE = 1
00250          SIGMA = RMIN / ANRM
00251       ELSE IF( ANRM.GT.RMAX ) THEN
00252          ISCALE = 1
00253          SIGMA = RMAX / ANRM
00254       END IF
00255       IF( ISCALE.EQ.1 ) THEN
00256          IF( LOWER ) THEN
00257             CALL ZLASCL( 'B', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
00258          ELSE
00259             CALL ZLASCL( 'Q', KD, KD, ONE, SIGMA, N, N, AB, LDAB, INFO )
00260          END IF
00261       END IF
00262 *
00263 *     Call ZHBTRD to reduce Hermitian band matrix to tridiagonal form.
00264 *
00265       INDE = 1
00266       CALL ZHBTRD( JOBZ, UPLO, N, KD, AB, LDAB, W, RWORK( INDE ), Z,
00267      $             LDZ, WORK, IINFO )
00268 *
00269 *     For eigenvalues only, call DSTERF.  For eigenvectors, call ZSTEQR.
00270 *
00271       IF( .NOT.WANTZ ) THEN
00272          CALL DSTERF( N, W, RWORK( INDE ), INFO )
00273       ELSE
00274          INDRWK = INDE + N
00275          CALL ZSTEQR( JOBZ, N, W, RWORK( INDE ), Z, LDZ,
00276      $                RWORK( INDRWK ), INFO )
00277       END IF
00278 *
00279 *     If matrix was scaled, then rescale eigenvalues appropriately.
00280 *
00281       IF( ISCALE.EQ.1 ) THEN
00282          IF( INFO.EQ.0 ) THEN
00283             IMAX = N
00284          ELSE
00285             IMAX = INFO - 1
00286          END IF
00287          CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
00288       END IF
00289 *
00290       RETURN
00291 *
00292 *     End of ZHBEV
00293 *
00294       END
 All Files Functions