LAPACK 3.3.0

dstev.f

Go to the documentation of this file.
00001       SUBROUTINE DSTEV( JOBZ, N, D, E, Z, LDZ, WORK, INFO )
00002 *
00003 *  -- LAPACK driver routine (version 3.2) --
00004 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00005 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00006 *     November 2006
00007 *
00008 *     .. Scalar Arguments ..
00009       CHARACTER          JOBZ
00010       INTEGER            INFO, LDZ, N
00011 *     ..
00012 *     .. Array Arguments ..
00013       DOUBLE PRECISION   D( * ), E( * ), WORK( * ), Z( LDZ, * )
00014 *     ..
00015 *
00016 *  Purpose
00017 *  =======
00018 *
00019 *  DSTEV computes all eigenvalues and, optionally, eigenvectors of a
00020 *  real symmetric tridiagonal matrix A.
00021 *
00022 *  Arguments
00023 *  =========
00024 *
00025 *  JOBZ    (input) CHARACTER*1
00026 *          = 'N':  Compute eigenvalues only;
00027 *          = 'V':  Compute eigenvalues and eigenvectors.
00028 *
00029 *  N       (input) INTEGER
00030 *          The order of the matrix.  N >= 0.
00031 *
00032 *  D       (input/output) DOUBLE PRECISION array, dimension (N)
00033 *          On entry, the n diagonal elements of the tridiagonal matrix
00034 *          A.
00035 *          On exit, if INFO = 0, the eigenvalues in ascending order.
00036 *
00037 *  E       (input/output) DOUBLE PRECISION array, dimension (N-1)
00038 *          On entry, the (n-1) subdiagonal elements of the tridiagonal
00039 *          matrix A, stored in elements 1 to N-1 of E.
00040 *          On exit, the contents of E are destroyed.
00041 *
00042 *  Z       (output) DOUBLE PRECISION array, dimension (LDZ, N)
00043 *          If JOBZ = 'V', then if INFO = 0, Z contains the orthonormal
00044 *          eigenvectors of the matrix A, with the i-th column of Z
00045 *          holding the eigenvector associated with D(i).
00046 *          If JOBZ = 'N', then Z is not referenced.
00047 *
00048 *  LDZ     (input) INTEGER
00049 *          The leading dimension of the array Z.  LDZ >= 1, and if
00050 *          JOBZ = 'V', LDZ >= max(1,N).
00051 *
00052 *  WORK    (workspace) DOUBLE PRECISION array, dimension (max(1,2*N-2))
00053 *          If JOBZ = 'N', WORK is not referenced.
00054 *
00055 *  INFO    (output) INTEGER
00056 *          = 0:  successful exit
00057 *          < 0:  if INFO = -i, the i-th argument had an illegal value
00058 *          > 0:  if INFO = i, the algorithm failed to converge; i
00059 *                off-diagonal elements of E did not converge to zero.
00060 *
00061 *  =====================================================================
00062 *
00063 *     .. Parameters ..
00064       DOUBLE PRECISION   ZERO, ONE
00065       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00066 *     ..
00067 *     .. Local Scalars ..
00068       LOGICAL            WANTZ
00069       INTEGER            IMAX, ISCALE
00070       DOUBLE PRECISION   BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA, SMLNUM,
00071      $                   TNRM
00072 *     ..
00073 *     .. External Functions ..
00074       LOGICAL            LSAME
00075       DOUBLE PRECISION   DLAMCH, DLANST
00076       EXTERNAL           LSAME, DLAMCH, DLANST
00077 *     ..
00078 *     .. External Subroutines ..
00079       EXTERNAL           DSCAL, DSTEQR, DSTERF, XERBLA
00080 *     ..
00081 *     .. Intrinsic Functions ..
00082       INTRINSIC          SQRT
00083 *     ..
00084 *     .. Executable Statements ..
00085 *
00086 *     Test the input parameters.
00087 *
00088       WANTZ = LSAME( JOBZ, 'V' )
00089 *
00090       INFO = 0
00091       IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
00092          INFO = -1
00093       ELSE IF( N.LT.0 ) THEN
00094          INFO = -2
00095       ELSE IF( LDZ.LT.1 .OR. ( WANTZ .AND. LDZ.LT.N ) ) THEN
00096          INFO = -6
00097       END IF
00098 *
00099       IF( INFO.NE.0 ) THEN
00100          CALL XERBLA( 'DSTEV ', -INFO )
00101          RETURN
00102       END IF
00103 *
00104 *     Quick return if possible
00105 *
00106       IF( N.EQ.0 )
00107      $   RETURN
00108 *
00109       IF( N.EQ.1 ) THEN
00110          IF( WANTZ )
00111      $      Z( 1, 1 ) = ONE
00112          RETURN
00113       END IF
00114 *
00115 *     Get machine constants.
00116 *
00117       SAFMIN = DLAMCH( 'Safe minimum' )
00118       EPS = DLAMCH( 'Precision' )
00119       SMLNUM = SAFMIN / EPS
00120       BIGNUM = ONE / SMLNUM
00121       RMIN = SQRT( SMLNUM )
00122       RMAX = SQRT( BIGNUM )
00123 *
00124 *     Scale matrix to allowable range, if necessary.
00125 *
00126       ISCALE = 0
00127       TNRM = DLANST( 'M', N, D, E )
00128       IF( TNRM.GT.ZERO .AND. TNRM.LT.RMIN ) THEN
00129          ISCALE = 1
00130          SIGMA = RMIN / TNRM
00131       ELSE IF( TNRM.GT.RMAX ) THEN
00132          ISCALE = 1
00133          SIGMA = RMAX / TNRM
00134       END IF
00135       IF( ISCALE.EQ.1 ) THEN
00136          CALL DSCAL( N, SIGMA, D, 1 )
00137          CALL DSCAL( N-1, SIGMA, E( 1 ), 1 )
00138       END IF
00139 *
00140 *     For eigenvalues only, call DSTERF.  For eigenvalues and
00141 *     eigenvectors, call DSTEQR.
00142 *
00143       IF( .NOT.WANTZ ) THEN
00144          CALL DSTERF( N, D, E, INFO )
00145       ELSE
00146          CALL DSTEQR( 'I', N, D, E, Z, LDZ, WORK, INFO )
00147       END IF
00148 *
00149 *     If matrix was scaled, then rescale eigenvalues appropriately.
00150 *
00151       IF( ISCALE.EQ.1 ) THEN
00152          IF( INFO.EQ.0 ) THEN
00153             IMAX = N
00154          ELSE
00155             IMAX = INFO - 1
00156          END IF
00157          CALL DSCAL( IMAX, ONE / SIGMA, D, 1 )
00158       END IF
00159 *
00160       RETURN
00161 *
00162 *     End of DSTEV
00163 *
00164       END
 All Files Functions