1 SUBROUTINE DSTEQR
( COMPZ
, N
, D
, E
, Z
, LDZ
, WORK
, INFO
)
3 * -- LAPACK routine
(version
3.1) --
4 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
7 * .. Scalar Arguments
..
11 * .. Array Arguments
..
12 DOUBLE PRECISION D
( * ), E
( * ), WORK
( * ), Z
( LDZ
, * )
18 * DSTEQR computes all eigenvalues and
, optionally
, eigenvectors of a
19 * symmetric tridiagonal matrix using the
implicit QL or QR method
.
20 * The eigenvectors of a full or band symmetric matrix can also be found
21 * if DSYTRD or DSPTRD or DSBTRD has been used
to reduce this matrix
to
27 * COMPZ
(input
) CHARACTER*1
28 * = 'N': Compute eigenvalues only
.
29 * = 'V': Compute eigenvalues and eigenvectors of the original
30 * symmetric matrix
. On entry
, Z must contain the
31 * orthogonal matrix used
to reduce the original matrix
32 * to tridiagonal form
.
33 * = 'I': Compute eigenvalues and eigenvectors of the
34 * tridiagonal matrix
. Z is initialized
to the identity
38 * The order of the matrix
. N
>= 0.
40 * D
(input
/output
) DOUBLE PRECISION array
, dimension (N
)
41 * On entry
, the diagonal elements of the tridiagonal matrix
.
42 * On exit
, if INFO
= 0, the eigenvalues in ascending order
.
44 * E
(input
/output
) DOUBLE PRECISION array
, dimension (N
-1)
45 * On entry
, the
(n
-1) subdiagonal elements of the tridiagonal
47 * On exit
, E has been destroyed
.
49 * Z
(input
/output
) DOUBLE PRECISION array
, dimension (LDZ
, N
)
50 * On entry
, if COMPZ
= 'V', then Z contains the orthogonal
51 * matrix used in the reduction
to tridiagonal form
.
52 * On exit
, if INFO
= 0, then if COMPZ
= 'V', Z contains the
53 * orthonormal eigenvectors of the original symmetric matrix
,
54 * and
if COMPZ
= 'I', Z contains the orthonormal eigenvectors
55 * of the symmetric tridiagonal matrix
.
56 * If COMPZ
= 'N', then Z is not referenced
.
59 * The leading
dimension of the array Z
. LDZ
>= 1, and
if
60 * eigenvectors are desired
, then LDZ
>= max
(1,N
).
62 * WORK
(workspace
) DOUBLE PRECISION array
, dimension (max
(1,2*N
-2))
63 * If COMPZ
= 'N', then WORK is not referenced
.
65 * INFO
(output
) INTEGER
66 * = 0: successful exit
67 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
68 * > 0: the algorithm has failed
to find all the eigenvalues in
69 * a total of
30*N iterations
; if INFO
= i
, then i
70 * elements of E have not converged
to zero
; on exit
, D
71 * and E contain the elements of a symmetric tridiagonal
72 * matrix which is orthogonally similar
to the original
75 * =====================================================================
78 DOUBLE PRECISION ZERO
, ONE
, TWO
, THREE
79 PARAMETER ( ZERO
= 0.0D0
, ONE
= 1.0D0
, TWO
= 2.0D0
,
82 PARAMETER ( MAXIT
= 30 )
85 INTEGER I
, ICOMPZ
, II
, ISCALE
, J
, JTOT
, K
, L
, L1
, LEND
,
86 $ LENDM1
, LENDP1
, LENDSV
, LM1
, LSV
, M
, MM
, MM1
,
88 DOUBLE PRECISION ANORM
, B
, C
, EPS
, EPS2
, F
, G
, P
, R
, RT1
, RT2
,
89 $ S
, SAFMAX
, SAFMIN
, SSFMAX
, SSFMIN
, TST
91 * .. External Functions
..
93 DOUBLE PRECISION DLAMCH
, DLANST
, DLAPY2
94 EXTERNAL LSAME
, DLAMCH
, DLANST
, DLAPY2
96 * .. External Subroutines
..
97 EXTERNAL DLAE2
, DLAEV2
, DLARTG
, DLASCL
, DLASET
, DLASR
,
98 $ DLASRT
, DSWAP
, XERBLA
100 * .. Intrinsic Functions
..
101 INTRINSIC ABS
, MAX
, SIGN
, SQRT
103 * .. Executable Statements
..
105 * Test the input parameters
.
109 IF( LSAME
( COMPZ
, 'N' ) ) THEN
111 ELSE IF( LSAME
( COMPZ
, 'V' ) ) THEN
113 ELSE IF( LSAME
( COMPZ
, 'I' ) ) THEN
118 IF( ICOMPZ
.LT
.0 ) THEN
120 ELSE IF( N
.LT
.0 ) THEN
122 ELSE IF( ( LDZ
.LT
.1 ) .OR
. ( ICOMPZ
.GT
.0 .AND
. LDZ
.LT
.MAX
( 1,
127 CALL XERBLA
( 'DSTEQR', -INFO
)
131 * Quick
return if possible
142 * Determine the unit roundoff and over
/underflow thresholds
.
146 SAFMIN
= DLAMCH
( 'S' )
147 SAFMAX
= ONE
/ SAFMIN
148 SSFMAX
= SQRT
( SAFMAX
) / THREE
149 SSFMIN
= SQRT
( SAFMIN
) / EPS2
151 * Compute the eigenvalues and eigenvectors of the tridiagonal
155 $
CALL DLASET
( 'Full', N
, N
, ZERO
, ONE
, Z
, LDZ
)
160 * Determine where the matrix splits and choose QL or QR iteration
161 * for each block
, according
to whether top or bottom diagonal
162 * element is smaller
.
177 IF( TST
.LE
.( SQRT
( ABS
( D
( M
) ) )*SQRT
( ABS
( D
( M
+
178 $
1 ) ) ) )*EPS
) THEN
195 * Scale submatrix in rows and columns L
to LEND
197 ANORM
= DLANST
( 'I', LEND
-L
+1, D
( L
), E
( L
) )
201 IF( ANORM
.GT
.SSFMAX
) THEN
203 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMAX
, LEND
-L
+1, 1, D
( L
), N
,
205 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMAX
, LEND
-L
, 1, E
( L
), N
,
207 ELSE IF( ANORM
.LT
.SSFMIN
) THEN
209 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMIN
, LEND
-L
+1, 1, D
( L
), N
,
211 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMIN
, LEND
-L
, 1, E
( L
), N
,
215 * Choose between QL and QR iteration
217 IF( ABS
( D
( LEND
) ).LT
.ABS
( D
( L
) ) ) THEN
226 * Look
for small subdiagonal element
.
232 TST
= ABS
( E
( M
) )**2
233 IF( TST
.LE
.( EPS2*ABS
( D
( M
) ) )*ABS
( D
( M
+1 ) )+
247 * If remaining matrix is
2-by
-2, use DLAE2 or SLAEV2
248 * to compute its eigensystem
.
251 IF( ICOMPZ
.GT
.0 ) THEN
252 CALL DLAEV2
( D
( L
), E
( L
), D
( L
+1 ), RT1
, RT2
, C
, S
)
255 CALL DLASR
( 'R', 'V', 'B', N
, 2, WORK
( L
),
256 $ WORK
( N
-1+L
), Z
( 1, L
), LDZ
)
258 CALL DLAE2
( D
( L
), E
( L
), D
( L
+1 ), RT1
, RT2
)
275 G
= ( D
( L
+1 )-P
) / ( TWO*E
( L
) )
277 G
= D
( M
) - P
+ ( E
( L
) / ( G
+SIGN
( R
, G
) ) )
289 CALL DLARTG
( G
, F
, C
, S
, R
)
293 R
= ( D
( I
)-G
)*S
+ TWO*C*B
298 * If eigenvectors are desired
, then save rotations
.
300 IF( ICOMPZ
.GT
.0 ) THEN
307 * If eigenvectors are desired
, then apply saved rotations
.
309 IF( ICOMPZ
.GT
.0 ) THEN
311 CALL DLASR
( 'R', 'V', 'B', N
, MM
, WORK
( L
), WORK
( N
-1+L
),
333 * Look
for small superdiagonal element
.
338 DO 100 M
= L
, LENDP1
, -1
339 TST
= ABS
( E
( M
-1 ) )**2
340 IF( TST
.LE
.( EPS2*ABS
( D
( M
) ) )*ABS
( D
( M
-1 ) )+
354 * If remaining matrix is
2-by
-2, use DLAE2 or SLAEV2
355 * to compute its eigensystem
.
358 IF( ICOMPZ
.GT
.0 ) THEN
359 CALL DLAEV2
( D
( L
-1 ), E
( L
-1 ), D
( L
), RT1
, RT2
, C
, S
)
362 CALL DLASR
( 'R', 'V', 'F', N
, 2, WORK
( M
),
363 $ WORK
( N
-1+M
), Z
( 1, L
-1 ), LDZ
)
365 CALL DLAE2
( D
( L
-1 ), E
( L
-1 ), D
( L
), RT1
, RT2
)
382 G
= ( D
( L
-1 )-P
) / ( TWO*E
( L
-1 ) )
384 G
= D
( M
) - P
+ ( E
( L
-1 ) / ( G
+SIGN
( R
, G
) ) )
396 CALL DLARTG
( G
, F
, C
, S
, R
)
400 R
= ( D
( I
+1 )-G
)*S
+ TWO*C*B
405 * If eigenvectors are desired
, then save rotations
.
407 IF( ICOMPZ
.GT
.0 ) THEN
414 * If eigenvectors are desired
, then apply saved rotations
.
416 IF( ICOMPZ
.GT
.0 ) THEN
418 CALL DLASR
( 'R', 'V', 'F', N
, MM
, WORK
( M
), WORK
( N
-1+M
),
438 * Undo scaling
if necessary
441 IF( ISCALE
.EQ
.1 ) THEN
442 CALL DLASCL
( 'G', 0, 0, SSFMAX
, ANORM
, LENDSV
-LSV
+1, 1,
443 $ D
( LSV
), N
, INFO
)
444 CALL DLASCL
( 'G', 0, 0, SSFMAX
, ANORM
, LENDSV
-LSV
, 1, E
( LSV
),
446 ELSE IF( ISCALE
.EQ
.2 ) THEN
447 CALL DLASCL
( 'G', 0, 0, SSFMIN
, ANORM
, LENDSV
-LSV
+1, 1,
448 $ D
( LSV
), N
, INFO
)
449 CALL DLASCL
( 'G', 0, 0, SSFMIN
, ANORM
, LENDSV
-LSV
, 1, E
( LSV
),
453 * Check
for no convergence
to an eigenvalue after a total
454 * of N*MAXIT iterations
.
464 * Order eigenvalues and eigenvectors
.
467 IF( ICOMPZ
.EQ
.0 ) THEN
471 CALL DLASRT
( 'I', N
, D
, INFO
)
475 * Use Selection Sort
to minimize swaps of eigenvectors
482 IF( D
( J
).LT
.P
) THEN
490 CALL DSWAP
( N
, Z
( 1, I
), 1, Z
( 1, K
), 1 )