KTH framework for Nek5000 toolboxes; testing version  0.0.1
dsterf.f
Go to the documentation of this file.
1  SUBROUTINE dsterf( N, D, E, INFO )
2 *
3 * -- LAPACK routine (version 3.0) --
4 * Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
5 * Courant Institute, Argonne National Lab, and Rice University
6 * June 30, 1999
7 *
8 * .. Scalar Arguments ..
9  INTEGER INFO, N
10 * ..
11 * .. Array Arguments ..
12  DOUBLE PRECISION D( * ), E( * )
13 * ..
14 *
15 * Purpose
16 * =======
17 *
18 * DSTERF computes all eigenvalues of a symmetric tridiagonal matrix
19 * using the Pal-Walker-Kahan variant of the QL or QR algorithm.
20 *
21 * Arguments
22 * =========
23 *
24 * N (input) INTEGER
25 * The order of the matrix. N >= 0.
26 *
27 * D (input/output) DOUBLE PRECISION array, dimension (N)
28 * On entry, the n diagonal elements of the tridiagonal matrix.
29 * On exit, if INFO = 0, the eigenvalues in ascending order.
30 *
31 * E (input/output) DOUBLE PRECISION array, dimension (N-1)
32 * On entry, the (n-1) subdiagonal elements of the tridiagonal
33 * matrix.
34 * On exit, E has been destroyed.
35 *
36 * INFO (output) INTEGER
37 * = 0: successful exit
38 * < 0: if INFO = -i, the i-th argument had an illegal value
39 * > 0: the algorithm failed to find all of the eigenvalues in
40 * a total of 30*N iterations; if INFO = i, then i
41 * elements of E have not converged to zero.
42 *
43 * =====================================================================
44 *
45 * .. Parameters ..
46  DOUBLE PRECISION ZERO, ONE, TWO, THREE
47  parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0,
48  $ three = 3.0d0 )
49  INTEGER MAXIT
50  parameter( maxit = 30 )
51 * ..
52 * .. Local Scalars ..
53  INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,
54  $ NMAXIT
55  DOUBLE PRECISION ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,
56  $ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,
57  $ SIGMA, SSFMAX, SSFMIN
58 * ..
59 * .. External Functions ..
60  DOUBLE PRECISION DLAMCH, DLANST, DLAPY2
61  EXTERNAL dlamch, dlanst, dlapy2
62 * ..
63 * .. External Subroutines ..
64  EXTERNAL dlae2, dlascl, dlasrt, xerbla
65 * ..
66 * .. Intrinsic Functions ..
67  INTRINSIC abs, sign, sqrt
68 * ..
69 * .. Executable Statements ..
70 *
71 * Test the input parameters.
72 *
73  info = 0
74 *
75 * Quick return if possible
76 *
77  IF( n.LT.0 ) THEN
78  info = -1
79  CALL xerbla( 'DSTERF', -info )
80  RETURN
81  END IF
82  IF( n.LE.1 )
83  $ RETURN
84 *
85 * Determine the unit roundoff for this environment.
86 *
87  eps = dlamch( 'E' )
88  eps2 = eps**2
89  safmin = dlamch( 'S' )
90  safmax = one / safmin
91  ssfmax = sqrt( safmax ) / three
92  ssfmin = sqrt( safmin ) / eps2
93 *
94 * Compute the eigenvalues of the tridiagonal matrix.
95 *
96  nmaxit = n*maxit
97  sigma = zero
98  jtot = 0
99 *
100 * Determine where the matrix splits and choose QL or QR iteration
101 * for each block, according to whether top or bottom diagonal
102 * element is smaller.
103 *
104  l1 = 1
105 *
106  10 CONTINUE
107  IF( l1.GT.n )
108  $ GO TO 170
109  IF( l1.GT.1 )
110  $ e( l1-1 ) = zero
111  DO 20 m = l1, n - 1
112  IF( abs( e( m ) ).LE.( sqrt( abs( d( m ) ) )*sqrt( abs( d( m+
113  $ 1 ) ) ) )*eps ) THEN
114  e( m ) = zero
115  GO TO 30
116  END IF
117  20 CONTINUE
118  m = n
119 *
120  30 CONTINUE
121  l = l1
122  lsv = l
123  lend = m
124  lendsv = lend
125  l1 = m + 1
126  IF( lend.EQ.l )
127  $ GO TO 10
128 *
129 * Scale submatrix in rows and columns L to LEND
130 *
131  anorm = dlanst( 'I', lend-l+1, d( l ), e( l ) )
132  iscale = 0
133  IF( anorm.GT.ssfmax ) THEN
134  iscale = 1
135  CALL dlascl( 'G', 0, 0, anorm, ssfmax, lend-l+1, 1, d( l ), n,
136  $ info )
137  CALL dlascl( 'G', 0, 0, anorm, ssfmax, lend-l, 1, e( l ), n,
138  $ info )
139  ELSE IF( anorm.LT.ssfmin ) THEN
140  iscale = 2
141  CALL dlascl( 'G', 0, 0, anorm, ssfmin, lend-l+1, 1, d( l ), n,
142  $ info )
143  CALL dlascl( 'G', 0, 0, anorm, ssfmin, lend-l, 1, e( l ), n,
144  $ info )
145  END IF
146 *
147  DO 40 i = l, lend - 1
148  e( i ) = e( i )**2
149  40 CONTINUE
150 *
151 * Choose between QL and QR iteration
152 *
153  IF( abs( d( lend ) ).LT.abs( d( l ) ) ) THEN
154  lend = lsv
155  l = lendsv
156  END IF
157 *
158  IF( lend.GE.l ) THEN
159 *
160 * QL Iteration
161 *
162 * Look for small subdiagonal element.
163 *
164  50 CONTINUE
165  IF( l.NE.lend ) THEN
166  DO 60 m = l, lend - 1
167  IF( abs( e( m ) ).LE.eps2*abs( d( m )*d( m+1 ) ) )
168  $ GO TO 70
169  60 CONTINUE
170  END IF
171  m = lend
172 *
173  70 CONTINUE
174  IF( m.LT.lend )
175  $ e( m ) = zero
176  p = d( l )
177  IF( m.EQ.l )
178  $ GO TO 90
179 *
180 * If remaining matrix is 2 by 2, use DLAE2 to compute its
181 * eigenvalues.
182 *
183  IF( m.EQ.l+1 ) THEN
184  rte = sqrt( e( l ) )
185  CALL dlae2( d( l ), rte, d( l+1 ), rt1, rt2 )
186  d( l ) = rt1
187  d( l+1 ) = rt2
188  e( l ) = zero
189  l = l + 2
190  IF( l.LE.lend )
191  $ GO TO 50
192  GO TO 150
193  END IF
194 *
195  IF( jtot.EQ.nmaxit )
196  $ GO TO 150
197  jtot = jtot + 1
198 *
199 * Form shift.
200 *
201  rte = sqrt( e( l ) )
202  sigma = ( d( l+1 )-p ) / ( two*rte )
203  r = dlapy2( sigma, one )
204  sigma = p - ( rte / ( sigma+sign( r, sigma ) ) )
205 *
206  c = one
207  s = zero
208  gamma = d( m ) - sigma
209  p = gamma*gamma
210 *
211 * Inner loop
212 *
213  DO 80 i = m - 1, l, -1
214  bb = e( i )
215  r = p + bb
216  IF( i.NE.m-1 )
217  $ e( i+1 ) = s*r
218  oldc = c
219  c = p / r
220  s = bb / r
221  oldgam = gamma
222  alpha = d( i )
223  gamma = c*( alpha-sigma ) - s*oldgam
224  d( i+1 ) = oldgam + ( alpha-gamma )
225  IF( c.NE.zero ) THEN
226  p = ( gamma*gamma ) / c
227  ELSE
228  p = oldc*bb
229  END IF
230  80 CONTINUE
231 *
232  e( l ) = s*p
233  d( l ) = sigma + gamma
234  GO TO 50
235 *
236 * Eigenvalue found.
237 *
238  90 CONTINUE
239  d( l ) = p
240 *
241  l = l + 1
242  IF( l.LE.lend )
243  $ GO TO 50
244  GO TO 150
245 *
246  ELSE
247 *
248 * QR Iteration
249 *
250 * Look for small superdiagonal element.
251 *
252  100 CONTINUE
253  DO 110 m = l, lend + 1, -1
254  IF( abs( e( m-1 ) ).LE.eps2*abs( d( m )*d( m-1 ) ) )
255  $ GO TO 120
256  110 CONTINUE
257  m = lend
258 *
259  120 CONTINUE
260  IF( m.GT.lend )
261  $ e( m-1 ) = zero
262  p = d( l )
263  IF( m.EQ.l )
264  $ GO TO 140
265 *
266 * If remaining matrix is 2 by 2, use DLAE2 to compute its
267 * eigenvalues.
268 *
269  IF( m.EQ.l-1 ) THEN
270  rte = sqrt( e( l-1 ) )
271  CALL dlae2( d( l ), rte, d( l-1 ), rt1, rt2 )
272  d( l ) = rt1
273  d( l-1 ) = rt2
274  e( l-1 ) = zero
275  l = l - 2
276  IF( l.GE.lend )
277  $ GO TO 100
278  GO TO 150
279  END IF
280 *
281  IF( jtot.EQ.nmaxit )
282  $ GO TO 150
283  jtot = jtot + 1
284 *
285 * Form shift.
286 *
287  rte = sqrt( e( l-1 ) )
288  sigma = ( d( l-1 )-p ) / ( two*rte )
289  r = dlapy2( sigma, one )
290  sigma = p - ( rte / ( sigma+sign( r, sigma ) ) )
291 *
292  c = one
293  s = zero
294  gamma = d( m ) - sigma
295  p = gamma*gamma
296 *
297 * Inner loop
298 *
299  DO 130 i = m, l - 1
300  bb = e( i )
301  r = p + bb
302  IF( i.NE.m )
303  $ e( i-1 ) = s*r
304  oldc = c
305  c = p / r
306  s = bb / r
307  oldgam = gamma
308  alpha = d( i+1 )
309  gamma = c*( alpha-sigma ) - s*oldgam
310  d( i ) = oldgam + ( alpha-gamma )
311  IF( c.NE.zero ) THEN
312  p = ( gamma*gamma ) / c
313  ELSE
314  p = oldc*bb
315  END IF
316  130 CONTINUE
317 *
318  e( l-1 ) = s*p
319  d( l ) = sigma + gamma
320  GO TO 100
321 *
322 * Eigenvalue found.
323 *
324  140 CONTINUE
325  d( l ) = p
326 *
327  l = l - 1
328  IF( l.GE.lend )
329  $ GO TO 100
330  GO TO 150
331 *
332  END IF
333 *
334 * Undo scaling if necessary
335 *
336  150 CONTINUE
337  IF( iscale.EQ.1 )
338  $ CALL dlascl( 'G', 0, 0, ssfmax, anorm, lendsv-lsv+1, 1,
339  $ d( lsv ), n, info )
340  IF( iscale.EQ.2 )
341  $ CALL dlascl( 'G', 0, 0, ssfmin, anorm, lendsv-lsv+1, 1,
342  $ d( lsv ), n, info )
343 *
344 * Check for no convergence to an eigenvalue after a total
345 * of N*MAXIT iterations.
346 *
347  IF( jtot.LT.nmaxit )
348  $ GO TO 10
349  DO 160 i = 1, n - 1
350  IF( e( i ).NE.zero )
351  $ info = info + 1
352  160 CONTINUE
353  GO TO 180
354 *
355 * Sort eigenvalues in increasing order.
356 *
357  170 CONTINUE
358  CALL dlasrt( 'I', n, d, info )
359 *
360  180 CONTINUE
361  RETURN
362 *
363 * End of DSTERF
364 *
365  END
subroutine dlae2(A, B, C, RT1, RT2)
Definition: dlae2.f:2
subroutine dlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
Definition: dlascl.f:2
subroutine dlasrt(ID, N, D, INFO)
Definition: dlasrt.f:2
subroutine dsterf(N, D, E, INFO)
Definition: dsterf.f:2
subroutine xerbla(SRNAME, INFO)
Definition: xerbla.f:2