LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dstein.f
Go to the documentation of this file.
1*> \brief \b DSTEIN
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSTEIN + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dstein.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dstein.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dstein.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSTEIN( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK,
20* IWORK, IFAIL, INFO )
21*
22* .. Scalar Arguments ..
23* INTEGER INFO, LDZ, M, N
24* ..
25* .. Array Arguments ..
26* INTEGER IBLOCK( * ), IFAIL( * ), ISPLIT( * ),
27* $ IWORK( * )
28* DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )
29* ..
30*
31*
32*> \par Purpose:
33* =============
34*>
35*> \verbatim
36*>
37*> DSTEIN computes the eigenvectors of a real symmetric tridiagonal
38*> matrix T corresponding to specified eigenvalues, using inverse
39*> iteration.
40*>
41*> The maximum number of iterations allowed for each eigenvector is
42*> specified by an internal parameter MAXITS (currently set to 5).
43*> \endverbatim
44*
45* Arguments:
46* ==========
47*
48*> \param[in] N
49*> \verbatim
50*> N is INTEGER
51*> The order of the matrix. N >= 0.
52*> \endverbatim
53*>
54*> \param[in] D
55*> \verbatim
56*> D is DOUBLE PRECISION array, dimension (N)
57*> The n diagonal elements of the tridiagonal matrix T.
58*> \endverbatim
59*>
60*> \param[in] E
61*> \verbatim
62*> E is DOUBLE PRECISION array, dimension (N-1)
63*> The (n-1) subdiagonal elements of the tridiagonal matrix
64*> T, in elements 1 to N-1.
65*> \endverbatim
66*>
67*> \param[in] M
68*> \verbatim
69*> M is INTEGER
70*> The number of eigenvectors to be found. 0 <= M <= N.
71*> \endverbatim
72*>
73*> \param[in] W
74*> \verbatim
75*> W is DOUBLE PRECISION array, dimension (N)
76*> The first M elements of W contain the eigenvalues for
77*> which eigenvectors are to be computed. The eigenvalues
78*> should be grouped by split-off block and ordered from
79*> smallest to largest within the block. ( The output array
80*> W from DSTEBZ with ORDER = 'B' is expected here. )
81*> \endverbatim
82*>
83*> \param[in] IBLOCK
84*> \verbatim
85*> IBLOCK is INTEGER array, dimension (N)
86*> The submatrix indices associated with the corresponding
87*> eigenvalues in W; IBLOCK(i)=1 if eigenvalue W(i) belongs to
88*> the first submatrix from the top, =2 if W(i) belongs to
89*> the second submatrix, etc. ( The output array IBLOCK
90*> from DSTEBZ is expected here. )
91*> \endverbatim
92*>
93*> \param[in] ISPLIT
94*> \verbatim
95*> ISPLIT is INTEGER array, dimension (N)
96*> The splitting points, at which T breaks up into submatrices.
97*> The first submatrix consists of rows/columns 1 to
98*> ISPLIT( 1 ), the second of rows/columns ISPLIT( 1 )+1
99*> through ISPLIT( 2 ), etc.
100*> ( The output array ISPLIT from DSTEBZ is expected here. )
101*> \endverbatim
102*>
103*> \param[out] Z
104*> \verbatim
105*> Z is DOUBLE PRECISION array, dimension (LDZ, M)
106*> The computed eigenvectors. The eigenvector associated
107*> with the eigenvalue W(i) is stored in the i-th column of
108*> Z. Any vector which fails to converge is set to its current
109*> iterate after MAXITS iterations.
110*> \endverbatim
111*>
112*> \param[in] LDZ
113*> \verbatim
114*> LDZ is INTEGER
115*> The leading dimension of the array Z. LDZ >= max(1,N).
116*> \endverbatim
117*>
118*> \param[out] WORK
119*> \verbatim
120*> WORK is DOUBLE PRECISION array, dimension (5*N)
121*> \endverbatim
122*>
123*> \param[out] IWORK
124*> \verbatim
125*> IWORK is INTEGER array, dimension (N)
126*> \endverbatim
127*>
128*> \param[out] IFAIL
129*> \verbatim
130*> IFAIL is INTEGER array, dimension (M)
131*> On normal exit, all elements of IFAIL are zero.
132*> If one or more eigenvectors fail to converge after
133*> MAXITS iterations, then their indices are stored in
134*> array IFAIL.
135*> \endverbatim
136*>
137*> \param[out] INFO
138*> \verbatim
139*> INFO is INTEGER
140*> = 0: successful exit.
141*> < 0: if INFO = -i, the i-th argument had an illegal value
142*> > 0: if INFO = i, then i eigenvectors failed to converge
143*> in MAXITS iterations. Their indices are stored in
144*> array IFAIL.
145*> \endverbatim
146*
147*> \par Internal Parameters:
148* =========================
149*>
150*> \verbatim
151*> MAXITS INTEGER, default = 5
152*> The maximum number of iterations performed.
153*>
154*> EXTRA INTEGER, default = 2
155*> The number of iterations performed after norm growth
156*> criterion is satisfied, should be at least 1.
157*> \endverbatim
158*
159* Authors:
160* ========
161*
162*> \author Univ. of Tennessee
163*> \author Univ. of California Berkeley
164*> \author Univ. of Colorado Denver
165*> \author NAG Ltd.
166*
167*> \ingroup stein
168*
169* =====================================================================
170 SUBROUTINE dstein( N, D, E, M, W, IBLOCK, ISPLIT, Z, LDZ, WORK,
171 $ IWORK, IFAIL, INFO )
172*
173* -- LAPACK computational routine --
174* -- LAPACK is a software package provided by Univ. of Tennessee, --
175* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
176*
177* .. Scalar Arguments ..
178 INTEGER INFO, LDZ, M, N
179* ..
180* .. Array Arguments ..
181 INTEGER IBLOCK( * ), IFAIL( * ), ISPLIT( * ),
182 $ iwork( * )
183 DOUBLE PRECISION D( * ), E( * ), W( * ), WORK( * ), Z( LDZ, * )
184* ..
185*
186* =====================================================================
187*
188* .. Parameters ..
189 DOUBLE PRECISION ZERO, ONE, TEN, ODM3, ODM1
190 parameter( zero = 0.0d+0, one = 1.0d+0, ten = 1.0d+1,
191 $ odm3 = 1.0d-3, odm1 = 1.0d-1 )
192 INTEGER MAXITS, EXTRA
193 parameter( maxits = 5, extra = 2 )
194* ..
195* .. Local Scalars ..
196 INTEGER B1, BLKSIZ, BN, GPIND, I, IINFO, INDRV1,
197 $ indrv2, indrv3, indrv4, indrv5, its, j, j1,
198 $ jblk, jmax, nblk, nrmchk
199 DOUBLE PRECISION DTPCRT, EPS, EPS1, NRM, ONENRM, ORTOL, PERTOL,
200 $ scl, sep, tol, xj, xjm, ztr
201* ..
202* .. Local Arrays ..
203 INTEGER ISEED( 4 )
204* ..
205* .. External Functions ..
206 INTEGER IDAMAX
207 DOUBLE PRECISION DDOT, DLAMCH, DNRM2
208 EXTERNAL idamax, ddot, dlamch, dnrm2
209* ..
210* .. External Subroutines ..
211 EXTERNAL daxpy, dcopy, dlagtf, dlagts, dlarnv,
212 $ dscal,
213 $ xerbla
214* ..
215* .. Intrinsic Functions ..
216 INTRINSIC abs, max, sqrt
217* ..
218* .. Executable Statements ..
219*
220* Test the input parameters.
221*
222 info = 0
223 DO 10 i = 1, m
224 ifail( i ) = 0
225 10 CONTINUE
226*
227 IF( n.LT.0 ) THEN
228 info = -1
229 ELSE IF( m.LT.0 .OR. m.GT.n ) THEN
230 info = -4
231 ELSE IF( ldz.LT.max( 1, n ) ) THEN
232 info = -9
233 ELSE
234 DO 20 j = 2, m
235 IF( iblock( j ).LT.iblock( j-1 ) ) THEN
236 info = -6
237 GO TO 30
238 END IF
239 IF( iblock( j ).EQ.iblock( j-1 ) .AND. w( j ).LT.w( j-1 ) )
240 $ THEN
241 info = -5
242 GO TO 30
243 END IF
244 20 CONTINUE
245 30 CONTINUE
246 END IF
247*
248 IF( info.NE.0 ) THEN
249 CALL xerbla( 'DSTEIN', -info )
250 RETURN
251 END IF
252*
253* Quick return if possible
254*
255 IF( n.EQ.0 .OR. m.EQ.0 ) THEN
256 RETURN
257 ELSE IF( n.EQ.1 ) THEN
258 z( 1, 1 ) = one
259 RETURN
260 END IF
261*
262* Get machine constants.
263*
264 eps = dlamch( 'Precision' )
265*
266* Initialize seed for random number generator DLARNV.
267*
268 DO 40 i = 1, 4
269 iseed( i ) = 1
270 40 CONTINUE
271*
272* Initialize pointers.
273*
274 indrv1 = 0
275 indrv2 = indrv1 + n
276 indrv3 = indrv2 + n
277 indrv4 = indrv3 + n
278 indrv5 = indrv4 + n
279*
280* Compute eigenvectors of matrix blocks.
281*
282 j1 = 1
283 DO 160 nblk = 1, iblock( m )
284*
285* Find starting and ending indices of block nblk.
286*
287 IF( nblk.EQ.1 ) THEN
288 b1 = 1
289 ELSE
290 b1 = isplit( nblk-1 ) + 1
291 END IF
292 bn = isplit( nblk )
293 blksiz = bn - b1 + 1
294 IF( blksiz.EQ.1 )
295 $ GO TO 60
296 gpind = j1
297*
298* Compute reorthogonalization criterion and stopping criterion.
299*
300 onenrm = abs( d( b1 ) ) + abs( e( b1 ) )
301 onenrm = max( onenrm, abs( d( bn ) )+abs( e( bn-1 ) ) )
302 DO 50 i = b1 + 1, bn - 1
303 onenrm = max( onenrm, abs( d( i ) )+abs( e( i-1 ) )+
304 $ abs( e( i ) ) )
305 50 CONTINUE
306 ortol = odm3*onenrm
307*
308 dtpcrt = sqrt( odm1 / blksiz )
309*
310* Loop through eigenvalues of block nblk.
311*
312 60 CONTINUE
313 jblk = 0
314 DO 150 j = j1, m
315 IF( iblock( j ).NE.nblk ) THEN
316 j1 = j
317 GO TO 160
318 END IF
319 jblk = jblk + 1
320 xj = w( j )
321*
322* Skip all the work if the block size is one.
323*
324 IF( blksiz.EQ.1 ) THEN
325 work( indrv1+1 ) = one
326 GO TO 120
327 END IF
328*
329* If eigenvalues j and j-1 are too close, add a relatively
330* small perturbation.
331*
332 IF( jblk.GT.1 ) THEN
333 eps1 = abs( eps*xj )
334 pertol = ten*eps1
335 sep = xj - xjm
336 IF( sep.LT.pertol )
337 $ xj = xjm + pertol
338 END IF
339*
340 its = 0
341 nrmchk = 0
342*
343* Get random starting vector.
344*
345 CALL dlarnv( 2, iseed, blksiz, work( indrv1+1 ) )
346*
347* Copy the matrix T so it won't be destroyed in factorization.
348*
349 CALL dcopy( blksiz, d( b1 ), 1, work( indrv4+1 ), 1 )
350 CALL dcopy( blksiz-1, e( b1 ), 1, work( indrv2+2 ), 1 )
351 CALL dcopy( blksiz-1, e( b1 ), 1, work( indrv3+1 ), 1 )
352*
353* Compute LU factors with partial pivoting ( PT = LU )
354*
355 tol = zero
356 CALL dlagtf( blksiz, work( indrv4+1 ), xj,
357 $ work( indrv2+2 ),
358 $ work( indrv3+1 ), tol, work( indrv5+1 ), iwork,
359 $ iinfo )
360*
361* Update iteration count.
362*
363 70 CONTINUE
364 its = its + 1
365 IF( its.GT.maxits )
366 $ GO TO 100
367*
368* Normalize and scale the righthand side vector Pb.
369*
370 jmax = idamax( blksiz, work( indrv1+1 ), 1 )
371 scl = blksiz*onenrm*max( eps,
372 $ abs( work( indrv4+blksiz ) ) ) /
373 $ abs( work( indrv1+jmax ) )
374 CALL dscal( blksiz, scl, work( indrv1+1 ), 1 )
375*
376* Solve the system LU = Pb.
377*
378 CALL dlagts( -1, blksiz, work( indrv4+1 ),
379 $ work( indrv2+2 ),
380 $ work( indrv3+1 ), work( indrv5+1 ), iwork,
381 $ work( indrv1+1 ), tol, iinfo )
382*
383* Reorthogonalize by modified Gram-Schmidt if eigenvalues are
384* close enough.
385*
386 IF( jblk.EQ.1 )
387 $ GO TO 90
388 IF( abs( xj-xjm ).GT.ortol )
389 $ gpind = j
390 IF( gpind.NE.j ) THEN
391 DO 80 i = gpind, j - 1
392 ztr = -ddot( blksiz, work( indrv1+1 ), 1, z( b1,
393 $ i ),
394 $ 1 )
395 CALL daxpy( blksiz, ztr, z( b1, i ), 1,
396 $ work( indrv1+1 ), 1 )
397 80 CONTINUE
398 END IF
399*
400* Check the infinity norm of the iterate.
401*
402 90 CONTINUE
403 jmax = idamax( blksiz, work( indrv1+1 ), 1 )
404 nrm = abs( work( indrv1+jmax ) )
405*
406* Continue for additional iterations after norm reaches
407* stopping criterion.
408*
409 IF( nrm.LT.dtpcrt )
410 $ GO TO 70
411 nrmchk = nrmchk + 1
412 IF( nrmchk.LT.extra+1 )
413 $ GO TO 70
414*
415 GO TO 110
416*
417* If stopping criterion was not satisfied, update info and
418* store eigenvector number in array ifail.
419*
420 100 CONTINUE
421 info = info + 1
422 ifail( info ) = j
423*
424* Accept iterate as jth eigenvector.
425*
426 110 CONTINUE
427 scl = one / dnrm2( blksiz, work( indrv1+1 ), 1 )
428 jmax = idamax( blksiz, work( indrv1+1 ), 1 )
429 IF( work( indrv1+jmax ).LT.zero )
430 $ scl = -scl
431 CALL dscal( blksiz, scl, work( indrv1+1 ), 1 )
432 120 CONTINUE
433 DO 130 i = 1, n
434 z( i, j ) = zero
435 130 CONTINUE
436 DO 140 i = 1, blksiz
437 z( b1+i-1, j ) = work( indrv1+i )
438 140 CONTINUE
439*
440* Save the shift to check eigenvalue spacing at next
441* iteration.
442*
443 xjm = xj
444*
445 150 CONTINUE
446 160 CONTINUE
447*
448 RETURN
449*
450* End of DSTEIN
451*
452 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine daxpy(n, da, dx, incx, dy, incy)
DAXPY
Definition daxpy.f:89
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dlagtf(n, a, lambda, b, c, tol, d, in, info)
DLAGTF computes an LU factorization of a matrix T-λI, where T is a general tridiagonal matrix,...
Definition dlagtf.f:154
subroutine dlagts(job, n, a, b, c, d, in, y, tol, info)
DLAGTS solves the system of equations (T-λI)x = y or (T-λI)^Tx = y, where T is a general tridiagonal ...
Definition dlagts.f:161
subroutine dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
Definition dlarnv.f:95
subroutine dscal(n, da, dx, incx)
DSCAL
Definition dscal.f:79
subroutine dstein(n, d, e, m, w, iblock, isplit, z, ldz, work, iwork, ifail, info)
DSTEIN
Definition dstein.f:172