3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DSTERF + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsterf.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsterf.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsterf.f">
21 * SUBROUTINE DSTERF( N, D, E, INFO )
23 * .. Scalar Arguments ..
26 * .. Array Arguments ..
27 * DOUBLE PRECISION D( * ), E( * )
36 *> DSTERF computes all eigenvalues of a symmetric tridiagonal matrix
37 *> using the Pal-Walker-Kahan variant of the QL or QR algorithm.
46 *> The order of the matrix. N >= 0.
51 *> D is DOUBLE PRECISION array, dimension (N)
52 *> On entry, the n diagonal elements of the tridiagonal matrix.
53 *> On exit, if INFO = 0, the eigenvalues in ascending order.
58 *> E is DOUBLE PRECISION array, dimension (N-1)
59 *> On entry, the (n-1) subdiagonal elements of the tridiagonal
61 *> On exit, E has been destroyed.
67 *> = 0: successful exit
68 *> < 0: if INFO = -i, the i-th argument had an illegal value
69 *> > 0: the algorithm failed to find all of the eigenvalues in
70 *> a total of 30*N iterations; if INFO = i, then i
71 *> elements of E have not converged to zero.
77 *> \author Univ. of Tennessee
78 *> \author Univ. of California Berkeley
79 *> \author Univ. of Colorado Denver
82 *> \date November 2011
84 *> \ingroup auxOTHERcomputational
86 * =====================================================================
87 SUBROUTINE DSTERF( N, D, E, INFO )
89 * -- LAPACK computational routine (version 3.4.0) --
90 * -- LAPACK is a software package provided by Univ. of Tennessee, --
91 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
94 * .. Scalar Arguments ..
97 * .. Array Arguments ..
98 DOUBLE PRECISION D( * ), E( * )
101 * =====================================================================
104 DOUBLE PRECISION ZERO, ONE, TWO, THREE
105 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
108 PARAMETER ( MAXIT = 30 )
110 * .. Local Scalars ..
111 INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,
113 DOUBLE PRECISION ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,
114 $ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,
115 $ SIGMA, SSFMAX, SSFMIN, RMAX
117 * .. External Functions ..
118 DOUBLE PRECISION DLAMCH, DLANST, DLAPY2
119 EXTERNAL DLAMCH, DLANST, DLAPY2
121 * .. External Subroutines ..
122 EXTERNAL DLAE2, DLASCL, DLASRT, XERBLA
124 * .. Intrinsic Functions ..
125 INTRINSIC ABS, SIGN, SQRT
127 * .. Executable Statements ..
129 * Test the input parameters.
133 * Quick return if possible
137 CALL XERBLA( 'DSTERF', -INFO )
143 * Determine the unit roundoff for this environment.
147 SAFMIN = DLAMCH( 'S' )
148 SAFMAX = ONE / SAFMIN
149 SSFMAX = SQRT( SAFMAX ) / THREE
150 SSFMIN = SQRT( SAFMIN ) / EPS2
153 * Compute the eigenvalues of the tridiagonal matrix.
159 * Determine where the matrix splits and choose QL or QR iteration
160 * for each block, according to whether top or bottom diagonal
161 * element is smaller.
171 IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+
172 $ 1 ) ) ) )*EPS ) THEN
188 * Scale submatrix in rows and columns L to LEND
190 ANORM = DLANST( 'M', LEND-L+1, D( L ), E( L ) )
194 IF( (ANORM.GT.SSFMAX) ) THEN
196 CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
198 CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
200 ELSE IF( ANORM.LT.SSFMIN ) THEN
202 CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
204 CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
208 DO 40 I = L, LEND - 1
212 * Choose between QL and QR iteration
214 IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
223 * Look for small subdiagonal element.
227 DO 60 M = L, LEND - 1
228 IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) )
241 * If remaining matrix is 2 by 2, use DLAE2 to compute its
246 CALL DLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )
263 SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )
264 R = DLAPY2( SIGMA, ONE )
265 SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
269 GAMMA = D( M ) - SIGMA
274 DO 80 I = M - 1, L, -1
284 GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
285 D( I+1 ) = OLDGAM + ( ALPHA-GAMMA )
287 P = ( GAMMA*GAMMA ) / C
294 D( L ) = SIGMA + GAMMA
311 * Look for small superdiagonal element.
314 DO 110 M = L, LEND + 1, -1
315 IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) )
327 * If remaining matrix is 2 by 2, use DLAE2 to compute its
331 RTE = SQRT( E( L-1 ) )
332 CALL DLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )
348 RTE = SQRT( E( L-1 ) )
349 SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )
350 R = DLAPY2( SIGMA, ONE )
351 SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
355 GAMMA = D( M ) - SIGMA
370 GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
371 D( I ) = OLDGAM + ( ALPHA-GAMMA )
373 P = ( GAMMA*GAMMA ) / C
380 D( L ) = SIGMA + GAMMA
395 * Undo scaling if necessary
399 $ CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
400 $ D( LSV ), N, INFO )
402 $ CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
403 $ D( LSV ), N, INFO )
405 * Check for no convergence to an eigenvalue after a total
406 * of N*MAXIT iterations.
416 * Sort eigenvalues in increasing order.
419 CALL DLASRT( 'I', N, D, INFO )