1 SUBROUTINE DSYEV
( JOBZ
, UPLO
, N
, A
, LDA
, W
, WORK
, LWORK
, INFO
)
3 * -- LAPACK driver routine
(version
3.1) --
4 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
7 * .. Scalar Arguments
..
9 INTEGER INFO
, LDA
, LWORK
, N
11 * .. Array Arguments
..
12 DOUBLE PRECISION A
( LDA
, * ), W
( * ), WORK
( * )
18 * DSYEV computes all eigenvalues and
, optionally
, eigenvectors of a
19 * real symmetric matrix A
.
24 * JOBZ
(input
) CHARACTER*1
25 * = 'N': Compute eigenvalues only
;
26 * = 'V': Compute eigenvalues and eigenvectors
.
28 * UPLO
(input
) CHARACTER*1
29 * = 'U': Upper triangle of A is stored
;
30 * = 'L': Lower triangle of A is stored
.
33 * The order of the matrix A
. N
>= 0.
35 * A
(input
/output
) DOUBLE PRECISION array
, dimension (LDA
, N
)
36 * On entry
, the symmetric matrix A
. If UPLO
= 'U', the
37 * leading N
-by
-N upper triangular part of A contains the
38 * upper triangular part of the matrix A
. If UPLO
= 'L',
39 * the leading N
-by
-N lower triangular part of A contains
40 * the lower triangular part of the matrix A
.
41 * On exit
, if JOBZ
= 'V', then if INFO
= 0, A contains the
42 * orthonormal eigenvectors of the matrix A
.
43 * If JOBZ
= 'N', then on exit the lower triangle
(if UPLO
='L')
44 * or the upper triangle
(if UPLO
='U') of A
, including the
45 * diagonal
, is destroyed
.
48 * The leading
dimension of the array A
. LDA
>= max
(1,N
).
50 * W
(output
) DOUBLE PRECISION array
, dimension (N
)
51 * If INFO
= 0, the eigenvalues in ascending order
.
53 * WORK
(workspace
/output
) DOUBLE PRECISION array
, dimension (MAX
(1,LWORK
))
54 * On exit
, if INFO
= 0, WORK
(1) returns the optimal LWORK
.
56 * LWORK
(input
) INTEGER
57 * The length of the array WORK
. LWORK
>= max
(1,3*N
-1).
58 * For optimal efficiency
, LWORK
>= (NB
+2)*N
,
59 * where NB is the blocksize
for DSYTRD returned by ILAENV
.
61 * If LWORK
= -1, then a workspace query is assumed
; the routine
62 * only calculates the optimal size of the WORK array
, returns
63 * this value as the first entry of the WORK array
, and no error
64 * message related
to LWORK is issued by XERBLA
.
66 * INFO
(output
) INTEGER
67 * = 0: successful exit
68 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
69 * > 0: if INFO
= i
, the algorithm failed
to converge
; i
70 * off
-diagonal elements of an intermediate tridiagonal
71 * form did not converge
to zero
.
73 * =====================================================================
76 DOUBLE PRECISION ZERO
, ONE
77 PARAMETER ( ZERO
= 0.0D0
, ONE
= 1.0D0
)
80 LOGICAL LOWER
, LQUERY
, WANTZ
81 INTEGER IINFO
, IMAX
, INDE
, INDTAU
, INDWRK
, ISCALE
,
83 DOUBLE PRECISION ANRM
, BIGNUM
, EPS
, RMAX
, RMIN
, SAFMIN
, SIGMA
,
86 * .. External Functions
..
89 DOUBLE PRECISION DLAMCH
, DLANSY
90 EXTERNAL LSAME
, ILAENV
, DLAMCH
, DLANSY
92 * .. External Subroutines
..
93 EXTERNAL DLASCL
, DORGTR
, DSCAL
, DSTEQR
, DSTERF
, DSYTRD
,
96 * .. Intrinsic Functions
..
99 * .. Executable Statements
..
101 * Test the input parameters
.
103 WANTZ
= LSAME
( JOBZ
, 'V' )
104 LOWER
= LSAME
( UPLO
, 'L' )
105 LQUERY
= ( LWORK
.EQ
.-1 )
108 IF( .NOT
.( WANTZ
.OR
. LSAME
( JOBZ
, 'N' ) ) ) THEN
110 ELSE IF( .NOT
.( LOWER
.OR
. LSAME
( UPLO
, 'U' ) ) ) THEN
112 ELSE IF( N
.LT
.0 ) THEN
114 ELSE IF( LDA
.LT
.MAX
( 1, N
) ) THEN
119 NB
= ILAENV
( 1, 'DSYTRD', UPLO
, N
, -1, -1, -1 )
120 LWKOPT
= MAX
( 1, ( NB
+2 )*N
)
123 IF( LWORK
.LT
.MAX
( 1, 3*N
-1 ) .AND
. .NOT
.LQUERY
)
128 CALL XERBLA
( 'DSYEV ', -INFO
)
130 ELSE IF( LQUERY
) THEN
134 * Quick
return if possible
148 * Get machine constants
.
150 SAFMIN
= DLAMCH
( 'Safe minimum' )
151 EPS
= DLAMCH
( 'Precision' )
152 SMLNUM
= SAFMIN
/ EPS
153 BIGNUM
= ONE
/ SMLNUM
154 RMIN
= SQRT
( SMLNUM
)
155 RMAX
= SQRT
( BIGNUM
)
157 * Scale matrix
to allowable range
, if necessary
.
159 ANRM
= DLANSY
( 'M', UPLO
, N
, A
, LDA
, WORK
)
161 IF( ANRM
.GT
.ZERO
.AND
. ANRM
.LT
.RMIN
) THEN
164 ELSE IF( ANRM
.GT
.RMAX
) THEN
169 $
CALL DLASCL
( UPLO
, 0, 0, ONE
, SIGMA
, N
, N
, A
, LDA
, INFO
)
171 * Call DSYTRD
to reduce symmetric matrix
to tridiagonal form
.
176 LLWORK
= LWORK
- INDWRK
+ 1
177 CALL DSYTRD
( UPLO
, N
, A
, LDA
, W
, WORK
( INDE
), WORK
( INDTAU
),
178 $ WORK
( INDWRK
), LLWORK
, IINFO
)
180 * For eigenvalues only
, call DSTERF
. For eigenvectors
, first
call
181 * DORGTR
to generate the orthogonal matrix
, then call DSTEQR
.
183 IF( .NOT
.WANTZ
) THEN
184 CALL DSTERF
( N
, W
, WORK
( INDE
), INFO
)
186 CALL DORGTR
( UPLO
, N
, A
, LDA
, WORK
( INDTAU
), WORK
( INDWRK
),
188 CALL DSTEQR
( JOBZ
, N
, W
, WORK
( INDE
), A
, LDA
, WORK
( INDTAU
),
192 * If matrix was scaled
, then rescale eigenvalues appropriately
.
194 IF( ISCALE
.EQ
.1 ) THEN
200 CALL DSCAL
( IMAX
, ONE
/ SIGMA
, W
, 1 )
203 * Set WORK
(1) to optimal workspace size
.