1 SUBROUTINE ZSTEQR
( 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
( * )
13 COMPLEX*16 Z
( LDZ
, * )
19 * ZSTEQR computes all eigenvalues and
, optionally
, eigenvectors of a
20 * symmetric tridiagonal matrix using the
implicit QL or QR method
.
21 * The eigenvectors of a full or band
complex Hermitian matrix can also
22 * be found
if ZHETRD or ZHPTRD or ZHBTRD has been used
to reduce this
23 * matrix
to tridiagonal form
.
28 * COMPZ
(input
) CHARACTER*1
29 * = 'N': Compute eigenvalues only
.
30 * = 'V': Compute eigenvalues and eigenvectors of the original
31 * Hermitian matrix
. On entry
, Z must contain the
32 * unitary matrix used
to reduce the original matrix
33 * to tridiagonal form
.
34 * = 'I': Compute eigenvalues and eigenvectors of the
35 * tridiagonal matrix
. Z is initialized
to the identity
39 * The order of the matrix
. N
>= 0.
41 * D
(input
/output
) DOUBLE PRECISION array
, dimension (N
)
42 * On entry
, the diagonal elements of the tridiagonal matrix
.
43 * On exit
, if INFO
= 0, the eigenvalues in ascending order
.
45 * E
(input
/output
) DOUBLE PRECISION array
, dimension (N
-1)
46 * On entry
, the
(n
-1) subdiagonal elements of the tridiagonal
48 * On exit
, E has been destroyed
.
50 * Z
(input
/output
) COMPLEX*16 array
, dimension (LDZ
, N
)
51 * On entry
, if COMPZ
= 'V', then Z contains the unitary
52 * matrix used in the reduction
to tridiagonal form
.
53 * On exit
, if INFO
= 0, then if COMPZ
= 'V', Z contains the
54 * orthonormal eigenvectors of the original Hermitian matrix
,
55 * and
if COMPZ
= 'I', Z contains the orthonormal eigenvectors
56 * of the symmetric tridiagonal matrix
.
57 * If COMPZ
= 'N', then Z is not referenced
.
60 * The leading
dimension of the array Z
. LDZ
>= 1, and
if
61 * eigenvectors are desired
, then LDZ
>= max
(1,N
).
63 * WORK
(workspace
) DOUBLE PRECISION array
, dimension (max
(1,2*N
-2))
64 * If COMPZ
= 'N', then WORK is not referenced
.
66 * INFO
(output
) INTEGER
67 * = 0: successful exit
68 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
69 * > 0: the algorithm has failed
to find all the eigenvalues in
70 * a total of
30*N iterations
; if INFO
= i
, then i
71 * elements of E have not converged
to zero
; on exit
, D
72 * and E contain the elements of a symmetric tridiagonal
73 * matrix which is unitarily similar
to the original
76 * =====================================================================
79 DOUBLE PRECISION ZERO
, ONE
, TWO
, THREE
80 PARAMETER ( ZERO
= 0.0D0
, ONE
= 1.0D0
, TWO
= 2.0D0
,
82 COMPLEX*16 CZERO
, CONE
83 PARAMETER ( CZERO
= ( 0.0D0
, 0.0D0
),
84 $ CONE
= ( 1.0D0
, 0.0D0
) )
86 PARAMETER ( MAXIT
= 30 )
89 INTEGER I
, ICOMPZ
, II
, ISCALE
, J
, JTOT
, K
, L
, L1
, LEND
,
90 $ LENDM1
, LENDP1
, LENDSV
, LM1
, LSV
, M
, MM
, MM1
,
92 DOUBLE PRECISION ANORM
, B
, C
, EPS
, EPS2
, F
, G
, P
, R
, RT1
, RT2
,
93 $ S
, SAFMAX
, SAFMIN
, SSFMAX
, SSFMIN
, TST
95 * .. External Functions
..
97 DOUBLE PRECISION DLAMCH
, DLANST
, DLAPY2
98 EXTERNAL LSAME
, DLAMCH
, DLANST
, DLAPY2
100 * .. External Subroutines
..
101 EXTERNAL DLAE2
, DLAEV2
, DLARTG
, DLASCL
, DLASRT
, XERBLA
,
102 $ ZLASET
, ZLASR
, ZSWAP
104 * .. Intrinsic Functions
..
105 INTRINSIC ABS
, MAX
, SIGN
, SQRT
107 * .. Executable Statements
..
109 * Test the input parameters
.
113 IF( LSAME
( COMPZ
, 'N' ) ) THEN
115 ELSE IF( LSAME
( COMPZ
, 'V' ) ) THEN
117 ELSE IF( LSAME
( COMPZ
, 'I' ) ) THEN
122 IF( ICOMPZ
.LT
.0 ) THEN
124 ELSE IF( N
.LT
.0 ) THEN
126 ELSE IF( ( LDZ
.LT
.1 ) .OR
. ( ICOMPZ
.GT
.0 .AND
. LDZ
.LT
.MAX
( 1,
131 CALL XERBLA
( 'ZSTEQR', -INFO
)
135 * Quick
return if possible
146 * Determine the unit roundoff and over
/underflow thresholds
.
150 SAFMIN
= DLAMCH
( 'S' )
151 SAFMAX
= ONE
/ SAFMIN
152 SSFMAX
= SQRT
( SAFMAX
) / THREE
153 SSFMIN
= SQRT
( SAFMIN
) / EPS2
155 * Compute the eigenvalues and eigenvectors of the tridiagonal
159 $
CALL ZLASET
( 'Full', N
, N
, CZERO
, CONE
, Z
, LDZ
)
164 * Determine where the matrix splits and choose QL or QR iteration
165 * for each block
, according
to whether top or bottom diagonal
166 * element is smaller
.
181 IF( TST
.LE
.( SQRT
( ABS
( D
( M
) ) )*SQRT
( ABS
( D
( M
+
182 $
1 ) ) ) )*EPS
) THEN
199 * Scale submatrix in rows and columns L
to LEND
201 ANORM
= DLANST
( 'I', LEND
-L
+1, D
( L
), E
( L
) )
205 IF( ANORM
.GT
.SSFMAX
) THEN
207 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMAX
, LEND
-L
+1, 1, D
( L
), N
,
209 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMAX
, LEND
-L
, 1, E
( L
), N
,
211 ELSE IF( ANORM
.LT
.SSFMIN
) THEN
213 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMIN
, LEND
-L
+1, 1, D
( L
), N
,
215 CALL DLASCL
( 'G', 0, 0, ANORM
, SSFMIN
, LEND
-L
, 1, E
( L
), N
,
219 * Choose between QL and QR iteration
221 IF( ABS
( D
( LEND
) ).LT
.ABS
( D
( L
) ) ) THEN
230 * Look
for small subdiagonal element
.
236 TST
= ABS
( E
( M
) )**2
237 IF( TST
.LE
.( EPS2*ABS
( D
( M
) ) )*ABS
( D
( M
+1 ) )+
251 * If remaining matrix is
2-by
-2, use DLAE2 or SLAEV2
252 * to compute its eigensystem
.
255 IF( ICOMPZ
.GT
.0 ) THEN
256 CALL DLAEV2
( D
( L
), E
( L
), D
( L
+1 ), RT1
, RT2
, C
, S
)
259 CALL ZLASR
( 'R', 'V', 'B', N
, 2, WORK
( L
),
260 $ WORK
( N
-1+L
), Z
( 1, L
), LDZ
)
262 CALL DLAE2
( D
( L
), E
( L
), D
( L
+1 ), RT1
, RT2
)
279 G
= ( D
( L
+1 )-P
) / ( TWO*E
( L
) )
281 G
= D
( M
) - P
+ ( E
( L
) / ( G
+SIGN
( R
, G
) ) )
293 CALL DLARTG
( G
, F
, C
, S
, R
)
297 R
= ( D
( I
)-G
)*S
+ TWO*C*B
302 * If eigenvectors are desired
, then save rotations
.
304 IF( ICOMPZ
.GT
.0 ) THEN
311 * If eigenvectors are desired
, then apply saved rotations
.
313 IF( ICOMPZ
.GT
.0 ) THEN
315 CALL ZLASR
( 'R', 'V', 'B', N
, MM
, WORK
( L
), WORK
( N
-1+L
),
337 * Look
for small superdiagonal element
.
342 DO 100 M
= L
, LENDP1
, -1
343 TST
= ABS
( E
( M
-1 ) )**2
344 IF( TST
.LE
.( EPS2*ABS
( D
( M
) ) )*ABS
( D
( M
-1 ) )+
358 * If remaining matrix is
2-by
-2, use DLAE2 or SLAEV2
359 * to compute its eigensystem
.
362 IF( ICOMPZ
.GT
.0 ) THEN
363 CALL DLAEV2
( D
( L
-1 ), E
( L
-1 ), D
( L
), RT1
, RT2
, C
, S
)
366 CALL ZLASR
( 'R', 'V', 'F', N
, 2, WORK
( M
),
367 $ WORK
( N
-1+M
), Z
( 1, L
-1 ), LDZ
)
369 CALL DLAE2
( D
( L
-1 ), E
( L
-1 ), D
( L
), RT1
, RT2
)
386 G
= ( D
( L
-1 )-P
) / ( TWO*E
( L
-1 ) )
388 G
= D
( M
) - P
+ ( E
( L
-1 ) / ( G
+SIGN
( R
, G
) ) )
400 CALL DLARTG
( G
, F
, C
, S
, R
)
404 R
= ( D
( I
+1 )-G
)*S
+ TWO*C*B
409 * If eigenvectors are desired
, then save rotations
.
411 IF( ICOMPZ
.GT
.0 ) THEN
418 * If eigenvectors are desired
, then apply saved rotations
.
420 IF( ICOMPZ
.GT
.0 ) THEN
422 CALL ZLASR
( 'R', 'V', 'F', N
, MM
, WORK
( M
), WORK
( N
-1+M
),
442 * Undo scaling
if necessary
445 IF( ISCALE
.EQ
.1 ) THEN
446 CALL DLASCL
( 'G', 0, 0, SSFMAX
, ANORM
, LENDSV
-LSV
+1, 1,
447 $ D
( LSV
), N
, INFO
)
448 CALL DLASCL
( 'G', 0, 0, SSFMAX
, ANORM
, LENDSV
-LSV
, 1, E
( LSV
),
450 ELSE IF( ISCALE
.EQ
.2 ) THEN
451 CALL DLASCL
( 'G', 0, 0, SSFMIN
, ANORM
, LENDSV
-LSV
+1, 1,
452 $ D
( LSV
), N
, INFO
)
453 CALL DLASCL
( 'G', 0, 0, SSFMIN
, ANORM
, LENDSV
-LSV
, 1, E
( LSV
),
457 * Check
for no convergence
to an eigenvalue after a total
458 * of N*MAXIT iterations
.
460 IF( JTOT
.EQ
.NMAXIT
) THEN
469 * Order eigenvalues and eigenvectors
.
472 IF( ICOMPZ
.EQ
.0 ) THEN
476 CALL DLASRT
( 'I', N
, D
, INFO
)
480 * Use Selection Sort
to minimize swaps of eigenvectors
487 IF( D
( J
).LT
.P
) THEN
495 CALL ZSWAP
( N
, Z
( 1, I
), 1, Z
( 1, K
), 1 )