\brief DSYEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices
=========== DOCUMENTATION ===========
Online html documentation available at http://www.netlib.org/lapack/explore-html/
\htmlonly Download DSYEV + dependencies [TGZ] [ZIP] [TXT] \endhtmlonly
Definition: ===========
SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
.. Scalar Arguments ..
CHARACTER JOBZ, UPLO
INTEGER INFO, LDA, LWORK, N
..
.. Array Arguments ..
DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
..
\par Purpose: =============
\verbatim
DSYEV computes all eigenvalues and, optionally, eigenvectors of a real symmetric matrix A. \endverbatim
Arguments: ==========
\param[in] JOBZ \verbatim JOBZ is CHARACTER*1 = 'N': Compute eigenvalues only; = 'V': Compute eigenvalues and eigenvectors. \endverbatim
\param[in] UPLO \verbatim UPLO is CHARACTER*1 = 'U': Upper triangle of A is stored; = 'L': Lower triangle of A is stored. \endverbatim
\param[in] N \verbatim N is INTEGER The order of the matrix A. N >= 0. \endverbatim
\param[in,out] A \verbatim A is DOUBLE PRECISION array, dimension (LDA, N) On entry, the symmetric 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, if JOBZ = 'V', then if INFO = 0, A contains the orthonormal eigenvectors of the matrix A. If JOBZ = 'N', then on exit the lower triangle (if UPLO='L') or the upper triangle (if UPLO='U') of A, including the diagonal, is destroyed. \endverbatim
\param[in] LDA \verbatim LDA is INTEGER The leading dimension of the array A. LDA >= max(1,N). \endverbatim
\param[out] W \verbatim W is DOUBLE PRECISION array, dimension (N) If INFO = 0, the eigenvalues in ascending order. \endverbatim
\param[out] WORK \verbatim WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) On exit, if INFO = 0, WORK(1) returns the optimal LWORK. \endverbatim
\param[in] LWORK \verbatim LWORK is INTEGER The length of the array WORK. LWORK >= max(1,3N-1). For optimal efficiency, LWORK >= (NB+2)N, where NB is the blocksize for DSYTRD returned by ILAENV.
If LWORK = -1, then a workspace query is assumed; the routine only calculates the optimal size of the WORK array, returns this value as the first entry of the WORK array, and no error message related to LWORK is issued by XERBLA.
\endverbatim
\param[out] INFO \verbatim INFO is INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value > 0: if INFO = i, the algorithm failed to converge; i off-diagonal elements of an intermediate tridiagonal form did not converge to zero. \endverbatim
Authors: ========
\author Univ. of Tennessee \author Univ. of California Berkeley \author Univ. of Colorado Denver \author NAG Ltd.
\date December 2016
\ingroup doubleSYeigen
!*> \brief <b> DSYEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices</b> !* !* =========== DOCUMENTATION =========== !* !* Online html documentation available at !* http://www.netlib.org/lapack/explore-html/ !* !*> \htmlonly !*> Download DSYEV + dependencies !*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyev.f"> !*> [TGZ]</a> !*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyev.f"> !*> [ZIP]</a> !*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyev.f"> !*> [TXT]</a> !*> \endhtmlonly !* !* Definition: !* =========== !* !* SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO ) !* !* .. Scalar Arguments .. !* CHARACTER JOBZ, UPLO !* INTEGER INFO, LDA, LWORK, N !* .. !* .. Array Arguments .. !* DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ) !* .. !* !* !*> \par Purpose: !* ============= !*> !*> \verbatim !*> !*> DSYEV computes all eigenvalues and, optionally, eigenvectors of a !*> real symmetric matrix A. !*> \endverbatim !* !* Arguments: !* ========== !* !*> \param[in] JOBZ !*> \verbatim !*> JOBZ is CHARACTER*1 !*> = 'N': Compute eigenvalues only; !*> = 'V': Compute eigenvalues and eigenvectors. !*> \endverbatim !*> !*> \param[in] UPLO !*> \verbatim !*> UPLO is CHARACTER*1 !*> = 'U': Upper triangle of A is stored; !*> = 'L': Lower triangle of A is stored. !*> \endverbatim !*> !*> \param[in] N !*> \verbatim !*> N is INTEGER !*> The order of the matrix A. N >= 0. !*> \endverbatim !*> !*> \param[in,out] A !*> \verbatim !*> A is DOUBLE PRECISION array, dimension (LDA, N) !*> On entry, the symmetric 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, if JOBZ = 'V', then if INFO = 0, A contains the !*> orthonormal eigenvectors of the matrix A. !*> If JOBZ = 'N', then on exit the lower triangle (if UPLO='L') !*> or the upper triangle (if UPLO='U') of A, including the !*> diagonal, is destroyed. !*> \endverbatim !*> !*> \param[in] LDA !*> \verbatim !*> LDA is INTEGER !*> The leading dimension of the array A. LDA >= max(1,N). !*> \endverbatim !*> !*> \param[out] W !*> \verbatim !*> W is DOUBLE PRECISION array, dimension (N) !*> If INFO = 0, the eigenvalues in ascending order. !*> \endverbatim !*> !*> \param[out] WORK !*> \verbatim !*> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) !*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK. !*> \endverbatim !*> !*> \param[in] LWORK !*> \verbatim !*> LWORK is INTEGER !*> The length of the array WORK. LWORK >= max(1,3*N-1). !*> For optimal efficiency, LWORK >= (NB+2)*N, !*> where NB is the blocksize for DSYTRD returned by ILAENV. !*> !*> If LWORK = -1, then a workspace query is assumed; the routine !*> only calculates the optimal size of the WORK array, returns !*> this value as the first entry of the WORK array, and no error !*> message related to LWORK is issued by XERBLA. !*> \endverbatim !*> !*> \param[out] INFO !*> \verbatim !*> INFO is INTEGER !*> = 0: successful exit !*> < 0: if INFO = -i, the i-th argument had an illegal value !*> > 0: if INFO = i, the algorithm failed to converge; i !*> off-diagonal elements of an intermediate tridiagonal !*> form did not converge to zero. !*> \endverbatim !* !* Authors: !* ======== !* !*> \author Univ. of Tennessee !*> \author Univ. of California Berkeley !*> \author Univ. of Colorado Denver !*> \author NAG Ltd. !* !*> \date December 2016 !* !*> \ingroup doubleSYeigen !* module DSYEV_PF ! - added module statement ! changed .f to .f90 interface DSYEV module procedure DSYEV_PF end interface contains !* ===================================================================== SUBROUTINE DSYEV_PF( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO ) !* !* -- LAPACK driver routine (version 3.7.0) -- !* -- LAPACK is a software package provided by Univ. of Tennessee, -- !* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- !* December 2016 !* !* .. Scalar Arguments .. CHARACTER(1),intent(in) JOBZ, UPLO INTEGER INFO, LDA, LWORK, N !* .. !* .. Array Arguments .. DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ) !* .. !* !* ===================================================================== !* !* .. Parameters .. DOUBLE PRECISION ZERO, ONE PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) !* .. !* .. Local Scalars .. LOGICAL LOWER, LQUERY, WANTZ INTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,& LLWORK, LWKOPT, NB DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,& SMLNUM !* .. !* .. External Functions .. LOGICAL LSAME INTEGER ILAENV DOUBLE PRECISION DLAMCH, DLANSY EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY !* .. !* .. External Subroutines .. EXTERNAL DLASCL, DORGTR, DSCAL, DSTEQR, DSTERF, DSYTRD,& XERBLA !* .. !* .. Intrinsic Functions .. INTRINSIC MAX, SQRT !* .. !* .. Executable Statements .. !* !* Test the input parameters. !* WANTZ = LSAME( JOBZ, 'V' ) LOWER = LSAME( UPLO, 'L' ) LQUERY = ( LWORK.EQ.-1 ) !* INFO = 0 IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN INFO = -1 ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN INFO = -2 ELSE IF( N.LT.0 ) THEN INFO = -3 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN INFO = -5 END IF !* IF( INFO.EQ.0 ) THEN NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 ) LWKOPT = MAX( 1, ( NB+2 )*N ) WORK( 1 ) = LWKOPT !* IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )& INFO = -8 END IF !* IF( INFO.NE.0 ) THEN CALL XERBLA( 'DSYEV ', -INFO ) RETURN ELSE IF( LQUERY ) THEN RETURN END IF !* !* Quick return if possible !* IF( N.EQ.0 ) THEN RETURN END IF !* IF( N.EQ.1 ) THEN W( 1 ) = A( 1, 1 ) WORK( 1 ) = 2 IF( WANTZ )& A( 1, 1 ) = ONE RETURN END IF !* !* Get machine constants. !* SAFMIN = DLAMCH( 'Safe minimum' ) EPS = DLAMCH( 'Precision' ) SMLNUM = SAFMIN / EPS BIGNUM = ONE / SMLNUM RMIN = SQRT( SMLNUM ) RMAX = SQRT( BIGNUM ) !* !* Scale matrix to allowable range, if necessary. !* ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK ) ISCALE = 0 IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN ISCALE = 1 SIGMA = RMIN / ANRM ELSE IF( ANRM.GT.RMAX ) THEN ISCALE = 1 SIGMA = RMAX / ANRM END IF IF( ISCALE.EQ.1 )& CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO ) !* !* Call DSYTRD to reduce symmetric matrix to tridiagonal form. !* INDE = 1 INDTAU = INDE + N INDWRK = INDTAU + N LLWORK = LWORK - INDWRK + 1 CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),& WORK( INDWRK ), LLWORK, IINFO ) !* !* For eigenvalues only, call DSTERF. For eigenvectors, first call !* DORGTR to generate the orthogonal matrix, then call DSTEQR. !* IF( .NOT.WANTZ ) THEN CALL DSTERF( N, W, WORK( INDE ), INFO ) ELSE CALL DORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),& LLWORK, IINFO ) CALL DSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),& INFO ) END IF !* !* If matrix was scaled, then rescale eigenvalues appropriately. !* IF( ISCALE.EQ.1 ) THEN IF( INFO.EQ.0 ) THEN IMAX = N ELSE IMAX = INFO - 1 END IF CALL DSCAL( IMAX, ONE / SIGMA, W, 1 ) END IF !* !* Set WORK(1) to optimal workspace size. !* WORK( 1 ) = LWKOPT !* RETURN !* !* End of DSYEV !* END SUBROUTINE end module DSYEV_PF