LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
dsteqr.f
Go to the documentation of this file.
1*> \brief \b DSTEQR
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download DSTEQR + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsteqr.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsteqr.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsteqr.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE DSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
20*
21* .. Scalar Arguments ..
22* CHARACTER COMPZ
23* INTEGER INFO, LDZ, N
24* ..
25* .. Array Arguments ..
26* DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
27* ..
28*
29*
30*> \par Purpose:
31* =============
32*>
33*> \verbatim
34*>
35*> DSTEQR computes all eigenvalues and, optionally, eigenvectors of a
36*> symmetric tridiagonal matrix using the implicit QL or QR method.
37*> The eigenvectors of a full or band symmetric matrix can also be found
38*> if DSYTRD or DSPTRD or DSBTRD has been used to reduce this matrix to
39*> tridiagonal form.
40*> \endverbatim
41*
42* Arguments:
43* ==========
44*
45*> \param[in] COMPZ
46*> \verbatim
47*> COMPZ is CHARACTER*1
48*> = 'N': Compute eigenvalues only.
49*> = 'V': Compute eigenvalues and eigenvectors of the original
50*> symmetric matrix. On entry, Z must contain the
51*> orthogonal matrix used to reduce the original matrix
52*> to tridiagonal form.
53*> = 'I': Compute eigenvalues and eigenvectors of the
54*> tridiagonal matrix. Z is initialized to the identity
55*> matrix.
56*> \endverbatim
57*>
58*> \param[in] N
59*> \verbatim
60*> N is INTEGER
61*> The order of the matrix. N >= 0.
62*> \endverbatim
63*>
64*> \param[in,out] D
65*> \verbatim
66*> D is DOUBLE PRECISION array, dimension (N)
67*> On entry, the diagonal elements of the tridiagonal matrix.
68*> On exit, if INFO = 0, the eigenvalues in ascending order.
69*> \endverbatim
70*>
71*> \param[in,out] E
72*> \verbatim
73*> E is DOUBLE PRECISION array, dimension (N-1)
74*> On entry, the (n-1) subdiagonal elements of the tridiagonal
75*> matrix.
76*> On exit, E has been destroyed.
77*> \endverbatim
78*>
79*> \param[in,out] Z
80*> \verbatim
81*> Z is DOUBLE PRECISION array, dimension (LDZ, N)
82*> On entry, if COMPZ = 'V', then Z contains the orthogonal
83*> matrix used in the reduction to tridiagonal form.
84*> On exit, if INFO = 0, then if COMPZ = 'V', Z contains the
85*> orthonormal eigenvectors of the original symmetric matrix,
86*> and if COMPZ = 'I', Z contains the orthonormal eigenvectors
87*> of the symmetric tridiagonal matrix.
88*> If COMPZ = 'N', then Z is not referenced.
89*> \endverbatim
90*>
91*> \param[in] LDZ
92*> \verbatim
93*> LDZ is INTEGER
94*> The leading dimension of the array Z. LDZ >= 1, and if
95*> eigenvectors are desired, then LDZ >= max(1,N).
96*> \endverbatim
97*>
98*> \param[out] WORK
99*> \verbatim
100*> WORK is DOUBLE PRECISION array, dimension (max(1,2*N-2))
101*> If COMPZ = 'N', then WORK is not referenced.
102*> \endverbatim
103*>
104*> \param[out] INFO
105*> \verbatim
106*> INFO is INTEGER
107*> = 0: successful exit
108*> < 0: if INFO = -i, the i-th argument had an illegal value
109*> > 0: the algorithm has failed to find all the eigenvalues in
110*> a total of 30*N iterations; if INFO = i, then i
111*> elements of E have not converged to zero; on exit, D
112*> and E contain the elements of a symmetric tridiagonal
113*> matrix which is orthogonally similar to the original
114*> matrix.
115*> \endverbatim
116*
117* Authors:
118* ========
119*
120*> \author Univ. of Tennessee
121*> \author Univ. of California Berkeley
122*> \author Univ. of Colorado Denver
123*> \author NAG Ltd.
124*
125*> \ingroup steqr
126*
127* =====================================================================
128 SUBROUTINE dsteqr( COMPZ, N, D, E, Z, LDZ, WORK, INFO )
129*
130* -- LAPACK computational routine --
131* -- LAPACK is a software package provided by Univ. of Tennessee, --
132* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
133*
134* .. Scalar Arguments ..
135 CHARACTER COMPZ
136 INTEGER INFO, LDZ, N
137* ..
138* .. Array Arguments ..
139 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
140* ..
141*
142* =====================================================================
143*
144* .. Parameters ..
145 DOUBLE PRECISION ZERO, ONE, TWO, THREE
146 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0,
147 $ three = 3.0d0 )
148 INTEGER MAXIT
149 parameter( maxit = 30 )
150* ..
151* .. Local Scalars ..
152 INTEGER I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
153 $ LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
154 $ NM1, NMAXIT
155 DOUBLE PRECISION ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
156 $ S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
157* ..
158* .. External Functions ..
159 LOGICAL LSAME
160 DOUBLE PRECISION DLAMCH, DLANST, DLAPY2
161 EXTERNAL lsame, dlamch, dlanst, dlapy2
162* ..
163* .. External Subroutines ..
164 EXTERNAL dlae2, dlaev2, dlartg, dlascl, dlaset,
165 $ dlasr,
167* ..
168* .. Intrinsic Functions ..
169 INTRINSIC abs, max, sign, sqrt
170* ..
171* .. Executable Statements ..
172*
173* Test the input parameters.
174*
175 info = 0
176*
177 IF( lsame( compz, 'N' ) ) THEN
178 icompz = 0
179 ELSE IF( lsame( compz, 'V' ) ) THEN
180 icompz = 1
181 ELSE IF( lsame( compz, 'I' ) ) THEN
182 icompz = 2
183 ELSE
184 icompz = -1
185 END IF
186 IF( icompz.LT.0 ) THEN
187 info = -1
188 ELSE IF( n.LT.0 ) THEN
189 info = -2
190 ELSE IF( ( ldz.LT.1 ) .OR. ( icompz.GT.0 .AND. ldz.LT.max( 1,
191 $ n ) ) ) THEN
192 info = -6
193 END IF
194 IF( info.NE.0 ) THEN
195 CALL xerbla( 'DSTEQR', -info )
196 RETURN
197 END IF
198*
199* Quick return if possible
200*
201 IF( n.EQ.0 )
202 $ RETURN
203*
204 IF( n.EQ.1 ) THEN
205 IF( icompz.EQ.2 )
206 $ z( 1, 1 ) = one
207 RETURN
208 END IF
209*
210* Determine the unit roundoff and over/underflow thresholds.
211*
212 eps = dlamch( 'E' )
213 eps2 = eps**2
214 safmin = dlamch( 'S' )
215 safmax = one / safmin
216 ssfmax = sqrt( safmax ) / three
217 ssfmin = sqrt( safmin ) / eps2
218*
219* Compute the eigenvalues and eigenvectors of the tridiagonal
220* matrix.
221*
222 IF( icompz.EQ.2 )
223 $ CALL dlaset( 'Full', n, n, zero, one, z, ldz )
224*
225 nmaxit = n*maxit
226 jtot = 0
227*
228* Determine where the matrix splits and choose QL or QR iteration
229* for each block, according to whether top or bottom diagonal
230* element is smaller.
231*
232 l1 = 1
233 nm1 = n - 1
234*
235 10 CONTINUE
236 IF( l1.GT.n )
237 $ GO TO 160
238 IF( l1.GT.1 )
239 $ e( l1-1 ) = zero
240 IF( l1.LE.nm1 ) THEN
241 DO 20 m = l1, nm1
242 tst = abs( e( m ) )
243 IF( tst.EQ.zero )
244 $ GO TO 30
245 IF( tst.LE.( sqrt( abs( d( m ) ) )*sqrt( abs( d( m+
246 $ 1 ) ) ) )*eps ) THEN
247 e( m ) = zero
248 GO TO 30
249 END IF
250 20 CONTINUE
251 END IF
252 m = n
253*
254 30 CONTINUE
255 l = l1
256 lsv = l
257 lend = m
258 lendsv = lend
259 l1 = m + 1
260 IF( lend.EQ.l )
261 $ GO TO 10
262*
263* Scale submatrix in rows and columns L to LEND
264*
265 anorm = dlanst( 'M', lend-l+1, d( l ), e( l ) )
266 iscale = 0
267 IF( anorm.EQ.zero )
268 $ GO TO 10
269 IF( anorm.GT.ssfmax ) THEN
270 iscale = 1
271 CALL dlascl( 'G', 0, 0, anorm, ssfmax, lend-l+1, 1, d( l ),
272 $ n,
273 $ info )
274 CALL dlascl( 'G', 0, 0, anorm, ssfmax, lend-l, 1, e( l ), n,
275 $ info )
276 ELSE IF( anorm.LT.ssfmin ) THEN
277 iscale = 2
278 CALL dlascl( 'G', 0, 0, anorm, ssfmin, lend-l+1, 1, d( l ),
279 $ n,
280 $ info )
281 CALL dlascl( 'G', 0, 0, anorm, ssfmin, lend-l, 1, e( l ), n,
282 $ info )
283 END IF
284*
285* Choose between QL and QR iteration
286*
287 IF( abs( d( lend ) ).LT.abs( d( l ) ) ) THEN
288 lend = lsv
289 l = lendsv
290 END IF
291*
292 IF( lend.GT.l ) THEN
293*
294* QL Iteration
295*
296* Look for small subdiagonal element.
297*
298 40 CONTINUE
299 IF( l.NE.lend ) THEN
300 lendm1 = lend - 1
301 DO 50 m = l, lendm1
302 tst = abs( e( m ) )**2
303 IF( tst.LE.( eps2*abs( d( m ) ) )*abs( d( m+1 ) )+
304 $ safmin )GO TO 60
305 50 CONTINUE
306 END IF
307*
308 m = lend
309*
310 60 CONTINUE
311 IF( m.LT.lend )
312 $ e( m ) = zero
313 p = d( l )
314 IF( m.EQ.l )
315 $ GO TO 80
316*
317* If remaining matrix is 2-by-2, use DLAE2 or SLAEV2
318* to compute its eigensystem.
319*
320 IF( m.EQ.l+1 ) THEN
321 IF( icompz.GT.0 ) THEN
322 CALL dlaev2( d( l ), e( l ), d( l+1 ), rt1, rt2, c,
323 $ s )
324 work( l ) = c
325 work( n-1+l ) = s
326 CALL dlasr( 'R', 'V', 'B', n, 2, work( l ),
327 $ work( n-1+l ), z( 1, l ), ldz )
328 ELSE
329 CALL dlae2( d( l ), e( l ), d( l+1 ), rt1, rt2 )
330 END IF
331 d( l ) = rt1
332 d( l+1 ) = rt2
333 e( l ) = zero
334 l = l + 2
335 IF( l.LE.lend )
336 $ GO TO 40
337 GO TO 140
338 END IF
339*
340 IF( jtot.EQ.nmaxit )
341 $ GO TO 140
342 jtot = jtot + 1
343*
344* Form shift.
345*
346 g = ( d( l+1 )-p ) / ( two*e( l ) )
347 r = dlapy2( g, one )
348 g = d( m ) - p + ( e( l ) / ( g+sign( r, g ) ) )
349*
350 s = one
351 c = one
352 p = zero
353*
354* Inner loop
355*
356 mm1 = m - 1
357 DO 70 i = mm1, l, -1
358 f = s*e( i )
359 b = c*e( i )
360 CALL dlartg( g, f, c, s, r )
361 IF( i.NE.m-1 )
362 $ e( i+1 ) = r
363 g = d( i+1 ) - p
364 r = ( d( i )-g )*s + two*c*b
365 p = s*r
366 d( i+1 ) = g + p
367 g = c*r - b
368*
369* If eigenvectors are desired, then save rotations.
370*
371 IF( icompz.GT.0 ) THEN
372 work( i ) = c
373 work( n-1+i ) = -s
374 END IF
375*
376 70 CONTINUE
377*
378* If eigenvectors are desired, then apply saved rotations.
379*
380 IF( icompz.GT.0 ) THEN
381 mm = m - l + 1
382 CALL dlasr( 'R', 'V', 'B', n, mm, work( l ),
383 $ work( n-1+l ),
384 $ z( 1, l ), ldz )
385 END IF
386*
387 d( l ) = d( l ) - p
388 e( l ) = g
389 GO TO 40
390*
391* Eigenvalue found.
392*
393 80 CONTINUE
394 d( l ) = p
395*
396 l = l + 1
397 IF( l.LE.lend )
398 $ GO TO 40
399 GO TO 140
400*
401 ELSE
402*
403* QR Iteration
404*
405* Look for small superdiagonal element.
406*
407 90 CONTINUE
408 IF( l.NE.lend ) THEN
409 lendp1 = lend + 1
410 DO 100 m = l, lendp1, -1
411 tst = abs( e( m-1 ) )**2
412 IF( tst.LE.( eps2*abs( d( m ) ) )*abs( d( m-1 ) )+
413 $ safmin )GO TO 110
414 100 CONTINUE
415 END IF
416*
417 m = lend
418*
419 110 CONTINUE
420 IF( m.GT.lend )
421 $ e( m-1 ) = zero
422 p = d( l )
423 IF( m.EQ.l )
424 $ GO TO 130
425*
426* If remaining matrix is 2-by-2, use DLAE2 or SLAEV2
427* to compute its eigensystem.
428*
429 IF( m.EQ.l-1 ) THEN
430 IF( icompz.GT.0 ) THEN
431 CALL dlaev2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2, c,
432 $ s )
433 work( m ) = c
434 work( n-1+m ) = s
435 CALL dlasr( 'R', 'V', 'F', n, 2, work( m ),
436 $ work( n-1+m ), z( 1, l-1 ), ldz )
437 ELSE
438 CALL dlae2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2 )
439 END IF
440 d( l-1 ) = rt1
441 d( l ) = rt2
442 e( l-1 ) = zero
443 l = l - 2
444 IF( l.GE.lend )
445 $ GO TO 90
446 GO TO 140
447 END IF
448*
449 IF( jtot.EQ.nmaxit )
450 $ GO TO 140
451 jtot = jtot + 1
452*
453* Form shift.
454*
455 g = ( d( l-1 )-p ) / ( two*e( l-1 ) )
456 r = dlapy2( g, one )
457 g = d( m ) - p + ( e( l-1 ) / ( g+sign( r, g ) ) )
458*
459 s = one
460 c = one
461 p = zero
462*
463* Inner loop
464*
465 lm1 = l - 1
466 DO 120 i = m, lm1
467 f = s*e( i )
468 b = c*e( i )
469 CALL dlartg( g, f, c, s, r )
470 IF( i.NE.m )
471 $ e( i-1 ) = r
472 g = d( i ) - p
473 r = ( d( i+1 )-g )*s + two*c*b
474 p = s*r
475 d( i ) = g + p
476 g = c*r - b
477*
478* If eigenvectors are desired, then save rotations.
479*
480 IF( icompz.GT.0 ) THEN
481 work( i ) = c
482 work( n-1+i ) = s
483 END IF
484*
485 120 CONTINUE
486*
487* If eigenvectors are desired, then apply saved rotations.
488*
489 IF( icompz.GT.0 ) THEN
490 mm = l - m + 1
491 CALL dlasr( 'R', 'V', 'F', n, mm, work( m ),
492 $ work( n-1+m ),
493 $ z( 1, m ), ldz )
494 END IF
495*
496 d( l ) = d( l ) - p
497 e( lm1 ) = g
498 GO TO 90
499*
500* Eigenvalue found.
501*
502 130 CONTINUE
503 d( l ) = p
504*
505 l = l - 1
506 IF( l.GE.lend )
507 $ GO TO 90
508 GO TO 140
509*
510 END IF
511*
512* Undo scaling if necessary
513*
514 140 CONTINUE
515 IF( iscale.EQ.1 ) THEN
516 CALL dlascl( 'G', 0, 0, ssfmax, anorm, lendsv-lsv+1, 1,
517 $ d( lsv ), n, info )
518 CALL dlascl( 'G', 0, 0, ssfmax, anorm, lendsv-lsv, 1,
519 $ e( lsv ),
520 $ n, info )
521 ELSE IF( iscale.EQ.2 ) THEN
522 CALL dlascl( 'G', 0, 0, ssfmin, anorm, lendsv-lsv+1, 1,
523 $ d( lsv ), n, info )
524 CALL dlascl( 'G', 0, 0, ssfmin, anorm, lendsv-lsv, 1,
525 $ e( lsv ),
526 $ n, info )
527 END IF
528*
529* Check for no convergence to an eigenvalue after a total
530* of N*MAXIT iterations.
531*
532 IF( jtot.LT.nmaxit )
533 $ GO TO 10
534 DO 150 i = 1, n - 1
535 IF( e( i ).NE.zero )
536 $ info = info + 1
537 150 CONTINUE
538 GO TO 190
539*
540* Order eigenvalues and eigenvectors.
541*
542 160 CONTINUE
543 IF( icompz.EQ.0 ) THEN
544*
545* Use Quick Sort
546*
547 CALL dlasrt( 'I', n, d, info )
548*
549 ELSE
550*
551* Use Selection Sort to minimize swaps of eigenvectors
552*
553 DO 180 ii = 2, n
554 i = ii - 1
555 k = i
556 p = d( i )
557 DO 170 j = ii, n
558 IF( d( j ).LT.p ) THEN
559 k = j
560 p = d( j )
561 END IF
562 170 CONTINUE
563 IF( k.NE.i ) THEN
564 d( k ) = d( i )
565 d( i ) = p
566 CALL dswap( n, z( 1, i ), 1, z( 1, k ), 1 )
567 END IF
568 180 CONTINUE
569 END IF
570*
571 190 CONTINUE
572 RETURN
573*
574* End of DSTEQR
575*
576 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dlae2(a, b, c, rt1, rt2)
DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
Definition dlae2.f:100
subroutine dlaev2(a, b, c, rt1, rt2, cs1, sn1)
DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
Definition dlaev2.f:118
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
Definition dlartg.f90:111
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition dlascl.f:142
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:108
subroutine dlasr(side, pivot, direct, m, n, c, s, a, lda)
DLASR applies a sequence of plane rotations to a general rectangular matrix.
Definition dlasr.f:197
subroutine dlasrt(id, n, d, info)
DLASRT sorts numbers in increasing or decreasing order.
Definition dlasrt.f:86
subroutine dsteqr(compz, n, d, e, z, ldz, work, info)
DSTEQR
Definition dsteqr.f:129
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
Definition dswap.f:82