Annotation of rpl/lapack/lapack/dsyev.f, revision 1.8
1.8 ! bertrand 1: *> \brief <b> DSYEV computes the eigenvalues and, optionally, the left and/or right eigenvectors for SY matrices</b>
! 2: *
! 3: * =========== DOCUMENTATION ===========
! 4: *
! 5: * Online html documentation available at
! 6: * http://www.netlib.org/lapack/explore-html/
! 7: *
! 8: *> \htmlonly
! 9: *> Download DSYEV + dependencies
! 10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyev.f">
! 11: *> [TGZ]</a>
! 12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyev.f">
! 13: *> [ZIP]</a>
! 14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyev.f">
! 15: *> [TXT]</a>
! 16: *> \endhtmlonly
! 17: *
! 18: * Definition:
! 19: * ===========
! 20: *
! 21: * SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
! 22: *
! 23: * .. Scalar Arguments ..
! 24: * CHARACTER JOBZ, UPLO
! 25: * INTEGER INFO, LDA, LWORK, N
! 26: * ..
! 27: * .. Array Arguments ..
! 28: * DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
! 29: * ..
! 30: *
! 31: *
! 32: *> \par Purpose:
! 33: * =============
! 34: *>
! 35: *> \verbatim
! 36: *>
! 37: *> DSYEV computes all eigenvalues and, optionally, eigenvectors of a
! 38: *> real symmetric matrix A.
! 39: *> \endverbatim
! 40: *
! 41: * Arguments:
! 42: * ==========
! 43: *
! 44: *> \param[in] JOBZ
! 45: *> \verbatim
! 46: *> JOBZ is CHARACTER*1
! 47: *> = 'N': Compute eigenvalues only;
! 48: *> = 'V': Compute eigenvalues and eigenvectors.
! 49: *> \endverbatim
! 50: *>
! 51: *> \param[in] UPLO
! 52: *> \verbatim
! 53: *> UPLO is CHARACTER*1
! 54: *> = 'U': Upper triangle of A is stored;
! 55: *> = 'L': Lower triangle of A is stored.
! 56: *> \endverbatim
! 57: *>
! 58: *> \param[in] N
! 59: *> \verbatim
! 60: *> N is INTEGER
! 61: *> The order of the matrix A. N >= 0.
! 62: *> \endverbatim
! 63: *>
! 64: *> \param[in,out] A
! 65: *> \verbatim
! 66: *> A is DOUBLE PRECISION array, dimension (LDA, N)
! 67: *> On entry, the symmetric matrix A. If UPLO = 'U', the
! 68: *> leading N-by-N upper triangular part of A contains the
! 69: *> upper triangular part of the matrix A. If UPLO = 'L',
! 70: *> the leading N-by-N lower triangular part of A contains
! 71: *> the lower triangular part of the matrix A.
! 72: *> On exit, if JOBZ = 'V', then if INFO = 0, A contains the
! 73: *> orthonormal eigenvectors of the matrix A.
! 74: *> If JOBZ = 'N', then on exit the lower triangle (if UPLO='L')
! 75: *> or the upper triangle (if UPLO='U') of A, including the
! 76: *> diagonal, is destroyed.
! 77: *> \endverbatim
! 78: *>
! 79: *> \param[in] LDA
! 80: *> \verbatim
! 81: *> LDA is INTEGER
! 82: *> The leading dimension of the array A. LDA >= max(1,N).
! 83: *> \endverbatim
! 84: *>
! 85: *> \param[out] W
! 86: *> \verbatim
! 87: *> W is DOUBLE PRECISION array, dimension (N)
! 88: *> If INFO = 0, the eigenvalues in ascending order.
! 89: *> \endverbatim
! 90: *>
! 91: *> \param[out] WORK
! 92: *> \verbatim
! 93: *> WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK))
! 94: *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
! 95: *> \endverbatim
! 96: *>
! 97: *> \param[in] LWORK
! 98: *> \verbatim
! 99: *> LWORK is INTEGER
! 100: *> The length of the array WORK. LWORK >= max(1,3*N-1).
! 101: *> For optimal efficiency, LWORK >= (NB+2)*N,
! 102: *> where NB is the blocksize for DSYTRD returned by ILAENV.
! 103: *>
! 104: *> If LWORK = -1, then a workspace query is assumed; the routine
! 105: *> only calculates the optimal size of the WORK array, returns
! 106: *> this value as the first entry of the WORK array, and no error
! 107: *> message related to LWORK is issued by XERBLA.
! 108: *> \endverbatim
! 109: *>
! 110: *> \param[out] INFO
! 111: *> \verbatim
! 112: *> INFO is INTEGER
! 113: *> = 0: successful exit
! 114: *> < 0: if INFO = -i, the i-th argument had an illegal value
! 115: *> > 0: if INFO = i, the algorithm failed to converge; i
! 116: *> off-diagonal elements of an intermediate tridiagonal
! 117: *> form did not converge to zero.
! 118: *> \endverbatim
! 119: *
! 120: * Authors:
! 121: * ========
! 122: *
! 123: *> \author Univ. of Tennessee
! 124: *> \author Univ. of California Berkeley
! 125: *> \author Univ. of Colorado Denver
! 126: *> \author NAG Ltd.
! 127: *
! 128: *> \date November 2011
! 129: *
! 130: *> \ingroup doubleSYeigen
! 131: *
! 132: * =====================================================================
1.1 bertrand 133: SUBROUTINE DSYEV( JOBZ, UPLO, N, A, LDA, W, WORK, LWORK, INFO )
134: *
1.8 ! bertrand 135: * -- LAPACK driver routine (version 3.4.0) --
1.1 bertrand 136: * -- LAPACK is a software package provided by Univ. of Tennessee, --
137: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
1.8 ! bertrand 138: * November 2011
1.1 bertrand 139: *
140: * .. Scalar Arguments ..
141: CHARACTER JOBZ, UPLO
142: INTEGER INFO, LDA, LWORK, N
143: * ..
144: * .. Array Arguments ..
145: DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * )
146: * ..
147: *
148: * =====================================================================
149: *
150: * .. Parameters ..
151: DOUBLE PRECISION ZERO, ONE
152: PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
153: * ..
154: * .. Local Scalars ..
155: LOGICAL LOWER, LQUERY, WANTZ
156: INTEGER IINFO, IMAX, INDE, INDTAU, INDWRK, ISCALE,
157: $ LLWORK, LWKOPT, NB
158: DOUBLE PRECISION ANRM, BIGNUM, EPS, RMAX, RMIN, SAFMIN, SIGMA,
159: $ SMLNUM
160: * ..
161: * .. External Functions ..
162: LOGICAL LSAME
163: INTEGER ILAENV
164: DOUBLE PRECISION DLAMCH, DLANSY
165: EXTERNAL LSAME, ILAENV, DLAMCH, DLANSY
166: * ..
167: * .. External Subroutines ..
168: EXTERNAL DLASCL, DORGTR, DSCAL, DSTEQR, DSTERF, DSYTRD,
169: $ XERBLA
170: * ..
171: * .. Intrinsic Functions ..
172: INTRINSIC MAX, SQRT
173: * ..
174: * .. Executable Statements ..
175: *
176: * Test the input parameters.
177: *
178: WANTZ = LSAME( JOBZ, 'V' )
179: LOWER = LSAME( UPLO, 'L' )
180: LQUERY = ( LWORK.EQ.-1 )
181: *
182: INFO = 0
183: IF( .NOT.( WANTZ .OR. LSAME( JOBZ, 'N' ) ) ) THEN
184: INFO = -1
185: ELSE IF( .NOT.( LOWER .OR. LSAME( UPLO, 'U' ) ) ) THEN
186: INFO = -2
187: ELSE IF( N.LT.0 ) THEN
188: INFO = -3
189: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
190: INFO = -5
191: END IF
192: *
193: IF( INFO.EQ.0 ) THEN
194: NB = ILAENV( 1, 'DSYTRD', UPLO, N, -1, -1, -1 )
195: LWKOPT = MAX( 1, ( NB+2 )*N )
196: WORK( 1 ) = LWKOPT
197: *
198: IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )
199: $ INFO = -8
200: END IF
201: *
202: IF( INFO.NE.0 ) THEN
203: CALL XERBLA( 'DSYEV ', -INFO )
204: RETURN
205: ELSE IF( LQUERY ) THEN
206: RETURN
207: END IF
208: *
209: * Quick return if possible
210: *
211: IF( N.EQ.0 ) THEN
212: RETURN
213: END IF
214: *
215: IF( N.EQ.1 ) THEN
216: W( 1 ) = A( 1, 1 )
217: WORK( 1 ) = 2
218: IF( WANTZ )
219: $ A( 1, 1 ) = ONE
220: RETURN
221: END IF
222: *
223: * Get machine constants.
224: *
225: SAFMIN = DLAMCH( 'Safe minimum' )
226: EPS = DLAMCH( 'Precision' )
227: SMLNUM = SAFMIN / EPS
228: BIGNUM = ONE / SMLNUM
229: RMIN = SQRT( SMLNUM )
230: RMAX = SQRT( BIGNUM )
231: *
232: * Scale matrix to allowable range, if necessary.
233: *
234: ANRM = DLANSY( 'M', UPLO, N, A, LDA, WORK )
235: ISCALE = 0
236: IF( ANRM.GT.ZERO .AND. ANRM.LT.RMIN ) THEN
237: ISCALE = 1
238: SIGMA = RMIN / ANRM
239: ELSE IF( ANRM.GT.RMAX ) THEN
240: ISCALE = 1
241: SIGMA = RMAX / ANRM
242: END IF
243: IF( ISCALE.EQ.1 )
244: $ CALL DLASCL( UPLO, 0, 0, ONE, SIGMA, N, N, A, LDA, INFO )
245: *
246: * Call DSYTRD to reduce symmetric matrix to tridiagonal form.
247: *
248: INDE = 1
249: INDTAU = INDE + N
250: INDWRK = INDTAU + N
251: LLWORK = LWORK - INDWRK + 1
252: CALL DSYTRD( UPLO, N, A, LDA, W, WORK( INDE ), WORK( INDTAU ),
253: $ WORK( INDWRK ), LLWORK, IINFO )
254: *
255: * For eigenvalues only, call DSTERF. For eigenvectors, first call
256: * DORGTR to generate the orthogonal matrix, then call DSTEQR.
257: *
258: IF( .NOT.WANTZ ) THEN
259: CALL DSTERF( N, W, WORK( INDE ), INFO )
260: ELSE
261: CALL DORGTR( UPLO, N, A, LDA, WORK( INDTAU ), WORK( INDWRK ),
262: $ LLWORK, IINFO )
263: CALL DSTEQR( JOBZ, N, W, WORK( INDE ), A, LDA, WORK( INDTAU ),
264: $ INFO )
265: END IF
266: *
267: * If matrix was scaled, then rescale eigenvalues appropriately.
268: *
269: IF( ISCALE.EQ.1 ) THEN
270: IF( INFO.EQ.0 ) THEN
271: IMAX = N
272: ELSE
273: IMAX = INFO - 1
274: END IF
275: CALL DSCAL( IMAX, ONE / SIGMA, W, 1 )
276: END IF
277: *
278: * Set WORK(1) to optimal workspace size.
279: *
280: WORK( 1 ) = LWKOPT
281: *
282: RETURN
283: *
284: * End of DSYEV
285: *
286: END
CVSweb interface <joel.bertrand@systella.fr>