1 SUBROUTINE ZSTEIN
( N
, D
, E
, M
, W
, IBLOCK
, ISPLIT
, Z
, LDZ
, WORK
,
4 * -- LAPACK routine
(version
3.1) --
5 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
8 * .. Scalar Arguments
..
9 INTEGER INFO
, LDZ
, M
, N
11 * .. Array Arguments
..
12 INTEGER IBLOCK
( * ), IFAIL
( * ), ISPLIT
( * ),
14 DOUBLE PRECISION D
( * ), E
( * ), W
( * ), WORK
( * )
15 COMPLEX*16 Z
( LDZ
, * )
21 * ZSTEIN computes the eigenvectors of a
real symmetric tridiagonal
22 * matrix T corresponding
to specified eigenvalues
, using inverse
25 * The maximum number of iterations allowed
for each eigenvector is
26 * specified by an internal
parameter MAXITS
(currently set
to 5).
28 * Although the eigenvectors are
real, they are stored in a
complex
29 * array
, which may be passed
to ZUNMTR or ZUPMTR
for back
30 * transformation
to the eigenvectors of a
complex Hermitian matrix
31 * which was reduced
to tridiagonal form
.
38 * The order of the matrix
. N
>= 0.
40 * D
(input
) DOUBLE PRECISION array
, dimension (N
)
41 * The n diagonal elements of the tridiagonal matrix T
.
43 * E
(input
) DOUBLE PRECISION array
, dimension (N
-1)
44 * The
(n
-1) subdiagonal elements of the tridiagonal matrix
45 * T
, stored in elements
1 to N
-1.
48 * The number of eigenvectors
to be found
. 0 <= M
<= N
.
50 * W
(input
) DOUBLE PRECISION array
, dimension (N
)
51 * The first M elements of W contain the eigenvalues
for
52 * which eigenvectors are
to be computed
. The eigenvalues
53 * should be grouped by split
-off block and ordered from
54 * smallest
to largest within the block
. ( The output array
55 * W from DSTEBZ with ORDER
= 'B' is expected here
. )
57 * IBLOCK
(input
) INTEGER array
, dimension (N
)
58 * The submatrix indices associated with the corresponding
59 * eigenvalues in W
; IBLOCK
(i
)=1 if eigenvalue W
(i
) belongs
to
60 * the first submatrix from the top
, =2 if W
(i
) belongs
to
61 * the second submatrix
, etc
. ( The output array IBLOCK
62 * from DSTEBZ is expected here
. )
64 * ISPLIT
(input
) INTEGER array
, dimension (N
)
65 * The splitting points
, at which T breaks up into submatrices
.
66 * The first submatrix consists of rows
/columns
1 to
67 * ISPLIT
( 1 ), the second of rows
/columns ISPLIT
( 1 )+1
68 * through ISPLIT
( 2 ), etc
.
69 * ( The output array ISPLIT from DSTEBZ is expected here
. )
71 * Z
(output
) COMPLEX*16 array
, dimension (LDZ
, M
)
72 * The computed eigenvectors
. The eigenvector associated
73 * with the eigenvalue W
(i
) is stored in the i
-th column of
74 * Z
. Any vector which fails
to converge is set
to its current
75 * iterate after MAXITS iterations
.
76 * The imaginary parts of the eigenvectors are set
to zero
.
79 * The leading
dimension of the array Z
. LDZ
>= max
(1,N
).
81 * WORK
(workspace
) DOUBLE PRECISION array
, dimension (5*N
)
83 * IWORK
(workspace
) INTEGER array
, dimension (N
)
85 * IFAIL
(output
) INTEGER array
, dimension (M
)
86 * On normal exit
, all elements of IFAIL are zero
.
87 * If one or more eigenvectors fail
to converge after
88 * MAXITS iterations
, then their indices are stored in
91 * INFO
(output
) INTEGER
92 * = 0: successful exit
93 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
94 * > 0: if INFO
= i
, then i eigenvectors failed
to converge
95 * in MAXITS iterations
. Their indices are stored in
101 * MAXITS
INTEGER, default = 5
102 * The maximum number of iterations performed
.
104 * EXTRA
INTEGER, default = 2
105 * The number of iterations performed after norm growth
106 * criterion is satisfied
, should be at least
1.
108 * =====================================================================
111 COMPLEX*16 CZERO
, CONE
112 PARAMETER ( CZERO
= ( 0.0D
+0, 0.0D
+0 ),
113 $ CONE
= ( 1.0D
+0, 0.0D
+0 ) )
114 DOUBLE PRECISION ZERO
, ONE
, TEN
, ODM3
, ODM1
115 PARAMETER ( ZERO
= 0.0D
+0, ONE
= 1.0D
+0, TEN
= 1.0D
+1,
116 $ ODM3
= 1.0D
-3, ODM1
= 1.0D
-1 )
117 INTEGER MAXITS
, EXTRA
118 PARAMETER ( MAXITS
= 5, EXTRA
= 2 )
120 * .. Local Scalars
..
121 INTEGER B1
, BLKSIZ
, BN
, GPIND
, I
, IINFO
, INDRV1
,
122 $ INDRV2
, INDRV3
, INDRV4
, INDRV5
, ITS
, J
, J1
,
123 $ JBLK
, JMAX
, JR
, NBLK
, NRMCHK
124 DOUBLE PRECISION DTPCRT
, EPS
, EPS1
, NRM
, ONENRM
, ORTOL
, PERTOL
,
125 $ SCL
, SEP
, TOL
, XJ
, XJM
, ZTR
130 * .. External Functions
..
132 DOUBLE PRECISION DASUM
, DLAMCH
, DNRM2
133 EXTERNAL IDAMAX
, DASUM
, DLAMCH
, DNRM2
135 * .. External Subroutines
..
136 EXTERNAL DCOPY
, DLAGTF
, DLAGTS
, DLARNV
, DSCAL
, XERBLA
138 * .. Intrinsic Functions
..
139 INTRINSIC ABS
, DBLE
, DCMPLX
, MAX
, SQRT
141 * .. Executable Statements
..
143 * Test the input parameters
.
152 ELSE IF( M
.LT
.0 .OR
. M
.GT
.N
) THEN
154 ELSE IF( LDZ
.LT
.MAX
( 1, N
) ) THEN
158 IF( IBLOCK
( J
).LT
.IBLOCK
( J
-1 ) ) THEN
162 IF( IBLOCK
( J
).EQ
.IBLOCK
( J
-1 ) .AND
. W
( J
).LT
.W
( J
-1 ) )
172 CALL XERBLA
( 'ZSTEIN', -INFO
)
176 * Quick
return if possible
178 IF( N
.EQ
.0 .OR
. M
.EQ
.0 ) THEN
180 ELSE IF( N
.EQ
.1 ) THEN
185 * Get machine constants
.
187 EPS
= DLAMCH
( 'Precision' )
189 * Initialize seed
for random number generator DLARNV
.
195 * Initialize pointers
.
203 * Compute eigenvectors of matrix blocks
.
206 DO 180 NBLK
= 1, IBLOCK
( M
)
208 * Find starting and ending indices of block nblk
.
213 B1
= ISPLIT
( NBLK
-1 ) + 1
221 * Compute reorthogonalization criterion and stopping criterion
.
223 ONENRM
= ABS
( D
( B1
) ) + ABS
( E
( B1
) )
224 ONENRM
= MAX
( ONENRM
, ABS
( D
( BN
) )+ABS
( E
( BN
-1 ) ) )
225 DO 50 I
= B1
+ 1, BN
- 1
226 ONENRM
= MAX
( ONENRM
, ABS
( D
( I
) )+ABS
( E
( I
-1 ) )+
231 DTPCRT
= SQRT
( ODM1
/ BLKSIZ
)
233 * Loop through eigenvalues of block nblk
.
238 IF( IBLOCK
( J
).NE
.NBLK
) THEN
245 * Skip all the work
if the block size is one
.
247 IF( BLKSIZ
.EQ
.1 ) THEN
248 WORK
( INDRV1
+1 ) = ONE
252 * If eigenvalues j and j
-1 are too close
, add a relatively
253 * small perturbation
.
266 * Get random starting vector
.
268 CALL DLARNV
( 2, ISEED
, BLKSIZ
, WORK
( INDRV1
+1 ) )
270 * Copy the matrix T so it won
't be destroyed in factorization.
272 CALL DCOPY( BLKSIZ, D( B1 ), 1, WORK( INDRV4+1 ), 1 )
273 CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV2+2 ), 1 )
274 CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV3+1 ), 1 )
276 * Compute LU factors with partial pivoting ( PT = LU )
279 CALL DLAGTF( BLKSIZ, WORK( INDRV4+1 ), XJ, WORK( INDRV2+2 ),
280 $ WORK( INDRV3+1 ), TOL, WORK( INDRV5+1 ), IWORK,
283 * Update iteration count.
290 * Normalize and scale the righthand side vector Pb.
292 SCL = BLKSIZ*ONENRM*MAX( EPS,
293 $ ABS( WORK( INDRV4+BLKSIZ ) ) ) /
294 $ DASUM( BLKSIZ, WORK( INDRV1+1 ), 1 )
295 CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )
297 * Solve the system LU = Pb.
299 CALL DLAGTS( -1, BLKSIZ, WORK( INDRV4+1 ), WORK( INDRV2+2 ),
300 $ WORK( INDRV3+1 ), WORK( INDRV5+1 ), IWORK,
301 $ WORK( INDRV1+1 ), TOL, IINFO )
303 * Reorthogonalize by modified Gram-Schmidt if eigenvalues are
308 IF( ABS( XJ-XJM ).GT.ORTOL )
310 IF( GPIND.NE.J ) THEN
311 DO 100 I = GPIND, J - 1
314 ZTR = ZTR + WORK( INDRV1+JR )*
315 $ DBLE( Z( B1-1+JR, I ) )
318 WORK( INDRV1+JR ) = WORK( INDRV1+JR ) -
319 $ ZTR*DBLE( Z( B1-1+JR, I ) )
324 * Check the infinity norm of the iterate.
327 JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )
328 NRM = ABS( WORK( INDRV1+JMAX ) )
330 * Continue for additional iterations after norm reaches
331 * stopping criterion.
336 IF( NRMCHK.LT.EXTRA+1 )
341 * If stopping criterion was not satisfied, update info and
342 * store eigenvector number in array ifail.
348 * Accept iterate as jth eigenvector.
351 SCL = ONE / DNRM2( BLKSIZ, WORK( INDRV1+1 ), 1 )
352 JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )
353 IF( WORK( INDRV1+JMAX ).LT.ZERO )
355 CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )
361 Z( B1+I-1, J ) = DCMPLX( WORK( INDRV1+I ), ZERO )
364 * Save the shift to check eigenvalue spacing at next