1 SUBROUTINE DSTEIN
( 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
( * ), Z
( LDZ
, * )
20 * DSTEIN computes the eigenvectors of a
real symmetric tridiagonal
21 * matrix T corresponding
to specified eigenvalues
, using inverse
24 * The maximum number of iterations allowed
for each eigenvector is
25 * specified by an internal
parameter MAXITS
(currently set
to 5).
31 * The order of the matrix
. N
>= 0.
33 * D
(input
) DOUBLE PRECISION array
, dimension (N
)
34 * The n diagonal elements of the tridiagonal matrix T
.
36 * E
(input
) DOUBLE PRECISION array
, dimension (N
-1)
37 * The
(n
-1) subdiagonal elements of the tridiagonal matrix
38 * T
, in elements
1 to N
-1.
41 * The number of eigenvectors
to be found
. 0 <= M
<= N
.
43 * W
(input
) DOUBLE PRECISION array
, dimension (N
)
44 * The first M elements of W contain the eigenvalues
for
45 * which eigenvectors are
to be computed
. The eigenvalues
46 * should be grouped by split
-off block and ordered from
47 * smallest
to largest within the block
. ( The output array
48 * W from DSTEBZ with ORDER
= 'B' is expected here
. )
50 * IBLOCK
(input
) INTEGER array
, dimension (N
)
51 * The submatrix indices associated with the corresponding
52 * eigenvalues in W
; IBLOCK
(i
)=1 if eigenvalue W
(i
) belongs
to
53 * the first submatrix from the top
, =2 if W
(i
) belongs
to
54 * the second submatrix
, etc
. ( The output array IBLOCK
55 * from DSTEBZ is expected here
. )
57 * ISPLIT
(input
) INTEGER array
, dimension (N
)
58 * The splitting points
, at which T breaks up into submatrices
.
59 * The first submatrix consists of rows
/columns
1 to
60 * ISPLIT
( 1 ), the second of rows
/columns ISPLIT
( 1 )+1
61 * through ISPLIT
( 2 ), etc
.
62 * ( The output array ISPLIT from DSTEBZ is expected here
. )
64 * Z
(output
) DOUBLE PRECISION array
, dimension (LDZ
, M
)
65 * The computed eigenvectors
. The eigenvector associated
66 * with the eigenvalue W
(i
) is stored in the i
-th column of
67 * Z
. Any vector which fails
to converge is set
to its current
68 * iterate after MAXITS iterations
.
71 * The leading
dimension of the array Z
. LDZ
>= max
(1,N
).
73 * WORK
(workspace
) DOUBLE PRECISION array
, dimension (5*N
)
75 * IWORK
(workspace
) INTEGER array
, dimension (N
)
77 * IFAIL
(output
) INTEGER array
, dimension (M
)
78 * On normal exit
, all elements of IFAIL are zero
.
79 * If one or more eigenvectors fail
to converge after
80 * MAXITS iterations
, then their indices are stored in
83 * INFO
(output
) INTEGER
84 * = 0: successful exit
.
85 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
86 * > 0: if INFO
= i
, then i eigenvectors failed
to converge
87 * in MAXITS iterations
. Their indices are stored in
93 * MAXITS
INTEGER, default = 5
94 * The maximum number of iterations performed
.
96 * EXTRA
INTEGER, default = 2
97 * The number of iterations performed after norm growth
98 * criterion is satisfied
, should be at least
1.
100 * =====================================================================
103 DOUBLE PRECISION ZERO
, ONE
, TEN
, ODM3
, ODM1
104 PARAMETER ( ZERO
= 0.0D
+0, ONE
= 1.0D
+0, TEN
= 1.0D
+1,
105 $ ODM3
= 1.0D
-3, ODM1
= 1.0D
-1 )
106 INTEGER MAXITS
, EXTRA
107 PARAMETER ( MAXITS
= 5, EXTRA
= 2 )
109 * .. Local Scalars
..
110 INTEGER B1
, BLKSIZ
, BN
, GPIND
, I
, IINFO
, INDRV1
,
111 $ INDRV2
, INDRV3
, INDRV4
, INDRV5
, ITS
, J
, J1
,
112 $ JBLK
, JMAX
, NBLK
, NRMCHK
113 DOUBLE PRECISION DTPCRT
, EPS
, EPS1
, NRM
, ONENRM
, ORTOL
, PERTOL
,
114 $ SCL
, SEP
, TOL
, XJ
, XJM
, ZTR
119 * .. External Functions
..
121 DOUBLE PRECISION DASUM
, DDOT
, DLAMCH
, DNRM2
122 EXTERNAL IDAMAX
, DASUM
, DDOT
, DLAMCH
, DNRM2
124 * .. External Subroutines
..
125 EXTERNAL DAXPY
, DCOPY
, DLAGTF
, DLAGTS
, DLARNV
, DSCAL
,
128 * .. Intrinsic Functions
..
129 INTRINSIC ABS
, MAX
, SQRT
131 * .. Executable Statements
..
133 * Test the input parameters
.
142 ELSE IF( M
.LT
.0 .OR
. M
.GT
.N
) THEN
144 ELSE IF( LDZ
.LT
.MAX
( 1, N
) ) THEN
148 IF( IBLOCK
( J
).LT
.IBLOCK
( J
-1 ) ) THEN
152 IF( IBLOCK
( J
).EQ
.IBLOCK
( J
-1 ) .AND
. W
( J
).LT
.W
( J
-1 ) )
162 CALL XERBLA
( 'DSTEIN', -INFO
)
166 * Quick
return if possible
168 IF( N
.EQ
.0 .OR
. M
.EQ
.0 ) THEN
170 ELSE IF( N
.EQ
.1 ) THEN
175 * Get machine constants
.
177 EPS
= DLAMCH
( 'Precision' )
179 * Initialize seed
for random number generator DLARNV
.
185 * Initialize pointers
.
193 * Compute eigenvectors of matrix blocks
.
196 DO 160 NBLK
= 1, IBLOCK
( M
)
198 * Find starting and ending indices of block nblk
.
203 B1
= ISPLIT
( NBLK
-1 ) + 1
211 * Compute reorthogonalization criterion and stopping criterion
.
213 ONENRM
= ABS
( D
( B1
) ) + ABS
( E
( B1
) )
214 ONENRM
= MAX
( ONENRM
, ABS
( D
( BN
) )+ABS
( E
( BN
-1 ) ) )
215 DO 50 I
= B1
+ 1, BN
- 1
216 ONENRM
= MAX
( ONENRM
, ABS
( D
( I
) )+ABS
( E
( I
-1 ) )+
221 DTPCRT
= SQRT
( ODM1
/ BLKSIZ
)
223 * Loop through eigenvalues of block nblk
.
228 IF( IBLOCK
( J
).NE
.NBLK
) THEN
235 * Skip all the work
if the block size is one
.
237 IF( BLKSIZ
.EQ
.1 ) THEN
238 WORK
( INDRV1
+1 ) = ONE
242 * If eigenvalues j and j
-1 are too close
, add a relatively
243 * small perturbation
.
256 * Get random starting vector
.
258 CALL DLARNV
( 2, ISEED
, BLKSIZ
, WORK
( INDRV1
+1 ) )
260 * Copy the matrix T so it won
't be destroyed in factorization.
262 CALL DCOPY( BLKSIZ, D( B1 ), 1, WORK( INDRV4+1 ), 1 )
263 CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV2+2 ), 1 )
264 CALL DCOPY( BLKSIZ-1, E( B1 ), 1, WORK( INDRV3+1 ), 1 )
266 * Compute LU factors with partial pivoting ( PT = LU )
269 CALL DLAGTF( BLKSIZ, WORK( INDRV4+1 ), XJ, WORK( INDRV2+2 ),
270 $ WORK( INDRV3+1 ), TOL, WORK( INDRV5+1 ), IWORK,
273 * Update iteration count.
280 * Normalize and scale the righthand side vector Pb.
282 SCL = BLKSIZ*ONENRM*MAX( EPS,
283 $ ABS( WORK( INDRV4+BLKSIZ ) ) ) /
284 $ DASUM( BLKSIZ, WORK( INDRV1+1 ), 1 )
285 CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )
287 * Solve the system LU = Pb.
289 CALL DLAGTS( -1, BLKSIZ, WORK( INDRV4+1 ), WORK( INDRV2+2 ),
290 $ WORK( INDRV3+1 ), WORK( INDRV5+1 ), IWORK,
291 $ WORK( INDRV1+1 ), TOL, IINFO )
293 * Reorthogonalize by modified Gram-Schmidt if eigenvalues are
298 IF( ABS( XJ-XJM ).GT.ORTOL )
300 IF( GPIND.NE.J ) THEN
301 DO 80 I = GPIND, J - 1
302 ZTR = -DDOT( BLKSIZ, WORK( INDRV1+1 ), 1, Z( B1, I ),
304 CALL DAXPY( BLKSIZ, ZTR, Z( B1, I ), 1,
305 $ WORK( INDRV1+1 ), 1 )
309 * Check the infinity norm of the iterate.
312 JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )
313 NRM = ABS( WORK( INDRV1+JMAX ) )
315 * Continue for additional iterations after norm reaches
316 * stopping criterion.
321 IF( NRMCHK.LT.EXTRA+1 )
326 * If stopping criterion was not satisfied, update info and
327 * store eigenvector number in array ifail.
333 * Accept iterate as jth eigenvector.
336 SCL = ONE / DNRM2( BLKSIZ, WORK( INDRV1+1 ), 1 )
337 JMAX = IDAMAX( BLKSIZ, WORK( INDRV1+1 ), 1 )
338 IF( WORK( INDRV1+JMAX ).LT.ZERO )
340 CALL DSCAL( BLKSIZ, SCL, WORK( INDRV1+1 ), 1 )
346 Z( B1+I-1, J ) = WORK( INDRV1+I )
349 * Save the shift to check eigenvalue spacing at next