LAPACK  3.4.1
LAPACK: Linear Algebra PACKage
ssyev.f
Go to the documentation of this file.
00001 *> \brief <b> SSYEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY 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 SSYEV + dependencies 
00010 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssyev.f"> 
00011 *> [TGZ]</a> 
00012 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssyev.f"> 
00013 *> [ZIP]</a> 
00014 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssyev.f"> 
00015 *> [TXT]</a>
00016 *> \endhtmlonly 
00017 *
00018 *  Definition:
00019 *  ===========
00020 *
00021 *       SUBROUTINE SSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
00022 * 
00023 *       .. Scalar Arguments ..
00024 *       CHARACTER          JOBZ, UPLO
00025 *       INTEGER            INFO, LDA, LWORK, N
00026 *       ..
00027 *       .. Array Arguments ..
00028 *       REAL               A( LDA, * ), W( * ), WORK( * )
00029 *       ..
00030 *  
00031 *
00032 *> \par Purpose:
00033 *  =============
00034 *>
00035 *> \verbatim
00036 *>
00037 *> SSYEV computes all eigenvalues and, optionally, eigenvectors of a
00038 *> real symmetric matrix A.
00039 *> \endverbatim
00040 *
00041 *  Arguments:
00042 *  ==========
00043 *
00044 *> \param[in] JOBZ
00045 *> \verbatim
00046 *>          JOBZ is CHARACTER*1
00047 *>          = 'N':  Compute eigenvalues only;
00048 *>          = 'V':  Compute eigenvalues and eigenvectors.
00049 *> \endverbatim
00050 *>
00051 *> \param[in] UPLO
00052 *> \verbatim
00053 *>          UPLO is CHARACTER*1
00054 *>          = 'U':  Upper triangle of A is stored;
00055 *>          = 'L':  Lower triangle of A is stored.
00056 *> \endverbatim
00057 *>
00058 *> \param[in] N
00059 *> \verbatim
00060 *>          N is INTEGER
00061 *>          The order of the matrix A.  N >= 0.
00062 *> \endverbatim
00063 *>
00064 *> \param[in,out] A
00065 *> \verbatim
00066 *>          A is REAL array, dimension (LDA, N)
00067 *>          On entry, the symmetric matrix A.  If UPLO = 'U', the
00068 *>          leading N-by-N upper triangular part of A contains the
00069 *>          upper triangular part of the matrix A.  If UPLO = 'L',
00070 *>          the leading N-by-N lower triangular part of A contains
00071 *>          the lower triangular part of the matrix A.
00072 *>          On exit, if JOBZ = 'V', then if INFO = 0, A contains the
00073 *>          orthonormal eigenvectors of the matrix A.
00074 *>          If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
00075 *>          or the upper triangle (if UPLO='U') of A, including the
00076 *>          diagonal, is destroyed.
00077 *> \endverbatim
00078 *>
00079 *> \param[in] LDA
00080 *> \verbatim
00081 *>          LDA is INTEGER
00082 *>          The leading dimension of the array A.  LDA >= max(1,N).
00083 *> \endverbatim
00084 *>
00085 *> \param[out] W
00086 *> \verbatim
00087 *>          W is REAL array, dimension (N)
00088 *>          If INFO = 0, the eigenvalues in ascending order.
00089 *> \endverbatim
00090 *>
00091 *> \param[out] WORK
00092 *> \verbatim
00093 *>          WORK is REAL array, dimension (MAX(1,LWORK))
00094 *>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
00095 *> \endverbatim
00096 *>
00097 *> \param[in] LWORK
00098 *> \verbatim
00099 *>          LWORK is INTEGER
00100 *>          The length of the array WORK.  LWORK >= max(1,3*N-1).
00101 *>          For optimal efficiency, LWORK >= (NB+2)*N,
00102 *>          where NB is the blocksize for SSYTRD returned by ILAENV.
00103 *>
00104 *>          If LWORK = -1, then a workspace query is assumed; the routine
00105 *>          only calculates the optimal size of the WORK array, returns
00106 *>          this value as the first entry of the WORK array, and no error
00107 *>          message related to LWORK is issued by XERBLA.
00108 *> \endverbatim
00109 *>
00110 *> \param[out] INFO
00111 *> \verbatim
00112 *>          INFO is INTEGER
00113 *>          = 0:  successful exit
00114 *>          < 0:  if INFO = -i, the i-th argument had an illegal value
00115 *>          > 0:  if INFO = i, the algorithm failed to converge; i
00116 *>                off-diagonal elements of an intermediate tridiagonal
00117 *>                form did not converge to zero.
00118 *> \endverbatim
00119 *
00120 *  Authors:
00121 *  ========
00122 *
00123 *> \author Univ. of Tennessee 
00124 *> \author Univ. of California Berkeley 
00125 *> \author Univ. of Colorado Denver 
00126 *> \author NAG Ltd. 
00127 *
00128 *> \date November 2011
00129 *
00130 *> \ingroup realSYeigen
00131 *
00132 *  =====================================================================
00133       SUBROUTINE SSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
00134 *
00135 *  -- LAPACK driver routine (version 3.4.0) --
00136 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00137 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00138 *     November 2011
00139 *
00140 *     .. Scalar Arguments ..
00141       CHARACTER          JOBZ, UPLO
00142       INTEGER            INFO, LDA, LWORK, N
00143 *     ..
00144 *     .. Array Arguments ..
00145       REAL               A( LDA, * ), W( * ), WORK( * )
00146 *     ..
00147 *
00148 *  =====================================================================
00149 *
00150 *     .. Parameters ..
00151       REAL               ZERO, ONE
00152       PARAMETER          ( ZERO = 0.0E0, ONE = 1.0E0 )
00153 *     ..
00154 *     .. Local Scalars ..
00155       LOGICAL            LOWER, LQUERY, WANTZ
00156       INTEGER            IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
00157      $                   LLWORK, LWKOPT, NB
00158       REAL               ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
00159      $                   SMLNUM
00160 *     ..
00161 *     .. External Functions ..
00162       LOGICAL            LSAME
00163       INTEGER            ILAENV
00164       REAL               SLAMCH, SLANSY
00165       EXTERNAL           ILAENV, LSAME, SLAMCH, SLANSY
00166 *     ..
00167 *     .. External Subroutines ..
00168       EXTERNAL           SLASCL, SORGTR, SSCAL, SSTEQR, SSTERF, SSYTRD,
00169      $                   XERBLA
00170 *     ..
00171 *     .. Intrinsic Functions ..
00172       INTRINSIC          MAX, SQRT
00173 *     ..
00174 *     .. Executable Statements ..
00175 *
00176 *     Test the input parameters.
00177 *
00178       WANTZ = LSAME( JOBZ, 'V' )
00179       LOWER = LSAME( UPLO, 'L' )
00180       LQUERY = ( LWORK.EQ.-1 )
00181 *
00182       INFO = 0
00183       IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
00184          INFO = -1
00185       ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
00186          INFO = -2
00187       ELSE IF( N.LT.0 ) THEN
00188          INFO = -3
00189       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00190          INFO = -5
00191       END IF
00192 *
00193       IF( INFO.EQ.0 ) THEN
00194          NB = ILAENV( 1, 'SSYTRD', UPLO, N, -1, -1, -1 )
00195          LWKOPT = MAX( 1, ( NB+2 )*N )
00196          WORK( 1 ) = LWKOPT
00197 *
00198          IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )
00199      $      INFO = -8
00200       END IF
00201 *
00202       IF( INFO.NE.0 ) THEN
00203          CALL XERBLA( 'SSYEV ', -INFO )
00204          RETURN
00205       ELSE IF( LQUERY ) THEN
00206          RETURN
00207       END IF
00208 *
00209 *     Quick return if possible
00210 *
00211       IF( N.EQ.0 ) THEN
00212          RETURN
00213       END IF
00214 *
00215       IF( N.EQ.1 ) THEN
00216          W( 1 ) = A( 1, 1 )
00217          WORK( 1 ) = 2
00218          IF( WANTZ )
00219      $      A( 1, 1 ) = ONE
00220          RETURN
00221       END IF
00222 *
00223 *     Get machine constants.
00224 *
00225       SAFMIN = SLAMCH( 'Safe minimum' )
00226       EPS = SLAMCH( 'Precision' )
00227       SMLNUM = SAFMIN / EPS
00228       BIGNUM = ONE / SMLNUM
00229       RMIN = SQRT( SMLNUM )
00230       RMAX = SQRT( BIGNUM )
00231 *
00232 *     Scale matrix to allowable range, if necessary.
00233 *
00234       ANRM = SLANSY( 'M', UPLO, N, A, LDA, WORK )
00235       ISCALE = 0
00236       IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
00237          ISCALE = 1
00238          SIGMA = RMIN / ANRM
00239       ELSE IF( ANRM.GT.RMAX ) THEN
00240          ISCALE = 1
00241          SIGMA = RMAX / ANRM
00242       END IF
00243       IF( ISCALE.EQ.1 )
00244      $   CALL SLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
00245 *
00246 *     Call SSYTRD to reduce symmetric matrix to tridiagonal form.
00247 *
00248       INDE = 1
00249       INDTAU = INDE + N
00250       INDWRK = INDTAU + N
00251       LLWORK = LWORK - INDWRK + 1
00252       CALL SSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),
00253      $             WORK( INDWRK ), LLWORK, IINFO )
00254 *
00255 *     For eigenvalues only, call SSTERF.  For eigenvectors, first call
00256 *     SORGTR to generate the orthogonal matrix, then call SSTEQR.
00257 *
00258       IF( .NOT.WANTZ ) THEN
00259          CALL SSTERF( N, W, WORK( INDE ), INFO )
00260       ELSE
00261          CALL SORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
00262      $                LLWORK, IINFO )
00263          CALL SSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),
00264      $                INFO )
00265       END IF
00266 *
00267 *     If matrix was scaled, then rescale eigenvalues appropriately.
00268 *
00269       IF( ISCALE.EQ.1 ) THEN
00270          IF( INFO.EQ.0 ) THEN
00271             IMAX = N
00272          ELSE
00273             IMAX = INFO - 1
00274          END IF
00275          CALL SSCAL( IMAX, ONE / SIGMA, W, 1 )
00276       END IF
00277 *
00278 *     Set WORK(1) to optimal workspace size.
00279 *
00280       WORK( 1 ) = LWKOPT
00281 *
00282       RETURN
00283 *
00284 *     End of SSYEV
00285 *
00286       END
 All Files Functions