3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SSTERF + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssterf.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssterf.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssterf.f">
21 * SUBROUTINE SSTERF( N, D, E, INFO )
23 * .. Scalar Arguments ..
26 * .. Array Arguments ..
36 *> SSTERF 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 REAL 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 REAL 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 SSTERF( 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 ..
101 * =====================================================================
104 REAL ZERO, ONE, TWO, THREE
105 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0, TWO = 2.0E0,
108 PARAMETER ( MAXIT = 30 )
110 * .. Local Scalars ..
111 INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,
113 REAL ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,
114 $ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,
115 $ SIGMA, SSFMAX, SSFMIN
117 * .. External Functions ..
118 REAL SLAMCH, SLANST, SLAPY2
119 EXTERNAL SLAMCH, SLANST, SLAPY2
121 * .. External Subroutines ..
122 EXTERNAL SLAE2, SLASCL, SLASRT, 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( 'SSTERF', -INFO )
143 * Determine the unit roundoff for this environment.
147 SAFMIN = SLAMCH( 'S' )
148 SAFMAX = ONE / SAFMIN
149 SSFMAX = SQRT( SAFMAX ) / THREE
150 SSFMIN = SQRT( SAFMIN ) / EPS2
152 * Compute the eigenvalues of the tridiagonal matrix.
158 * Determine where the matrix splits and choose QL or QR iteration
159 * for each block, according to whether top or bottom diagonal
160 * element is smaller.
170 IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*
171 $ SQRT( ABS( D( M+1 ) ) ) )*EPS ) THEN
187 * Scale submatrix in rows and columns L to LEND
189 ANORM = SLANST( 'M', LEND-L+1, D( L ), E( L ) )
193 IF( ANORM.GT.SSFMAX ) THEN
195 CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N,
197 CALL SLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N,
199 ELSE IF( ANORM.LT.SSFMIN ) THEN
201 CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N,
203 CALL SLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
207 DO 40 I = L, LEND - 1
211 * Choose between QL and QR iteration
213 IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN
222 * Look for small subdiagonal element.
226 DO 60 M = L, LEND - 1
227 IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) )
240 * If remaining matrix is 2 by 2, use SLAE2 to compute its
245 CALL SLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )
262 SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )
263 R = SLAPY2( SIGMA, ONE )
264 SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
268 GAMMA = D( M ) - SIGMA
273 DO 80 I = M - 1, L, -1
283 GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
284 D( I+1 ) = OLDGAM + ( ALPHA-GAMMA )
286 P = ( GAMMA*GAMMA ) / C
293 D( L ) = SIGMA + GAMMA
310 * Look for small superdiagonal element.
313 DO 110 M = L, LEND + 1, -1
314 IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) )
326 * If remaining matrix is 2 by 2, use SLAE2 to compute its
330 RTE = SQRT( E( L-1 ) )
331 CALL SLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )
347 RTE = SQRT( E( L-1 ) )
348 SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )
349 R = SLAPY2( SIGMA, ONE )
350 SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
354 GAMMA = D( M ) - SIGMA
369 GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
370 D( I ) = OLDGAM + ( ALPHA-GAMMA )
372 P = ( GAMMA*GAMMA ) / C
379 D( L ) = SIGMA + GAMMA
394 * Undo scaling if necessary
398 $ CALL SLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
399 $ D( LSV ), N, INFO )
401 $ CALL SLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
402 $ D( LSV ), N, INFO )
404 * Check for no convergence to an eigenvalue after a total
405 * of N*MAXIT iterations.
415 * Sort eigenvalues in increasing order.
418 CALL SLASRT( 'I', N, D, INFO )