OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
ssterf.f
Go to the documentation of this file.
1*> \brief \b SSTERF
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download SSTERF + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssterf.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssterf.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssterf.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE SSTERF( N, D, E, INFO )
22*
23* .. Scalar Arguments ..
24* INTEGER INFO, N
25* ..
26* .. Array Arguments ..
27* REAL D( * ), E( * )
28* ..
29*
30*
31*> \par Purpose:
32* =============
33*>
34*> \verbatim
35*>
36*> SSTERF computes all eigenvalues of a symmetric tridiagonal matrix
37*> using the Pal-Walker-Kahan variant of the QL or QR algorithm.
38*> \endverbatim
39*
40* Arguments:
41* ==========
42*
43*> \param[in] N
44*> \verbatim
45*> N is INTEGER
46*> The order of the matrix. N >= 0.
47*> \endverbatim
48*>
49*> \param[in,out] D
50*> \verbatim
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.
54*> \endverbatim
55*>
56*> \param[in,out] E
57*> \verbatim
58*> E is REAL array, dimension (N-1)
59*> On entry, the (n-1) subdiagonal elements of the tridiagonal
60*> matrix.
61*> On exit, E has been destroyed.
62*> \endverbatim
63*>
64*> \param[out] INFO
65*> \verbatim
66*> INFO is INTEGER
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.
72*> \endverbatim
73*
74* Authors:
75* ========
76*
77*> \author Univ. of Tennessee
78*> \author Univ. of California Berkeley
79*> \author Univ. of Colorado Denver
80*> \author NAG Ltd.
81*
82*> \ingroup auxOTHERcomputational
83*
84* =====================================================================
85 SUBROUTINE ssterf( N, D, E, INFO )
86*
87* -- LAPACK computational routine --
88* -- LAPACK is a software package provided by Univ. of Tennessee, --
89* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
90*
91* .. Scalar Arguments ..
92 INTEGER INFO, N
93* ..
94* .. Array Arguments ..
95 REAL D( * ), E( * )
96* ..
97*
98* =====================================================================
99*
100* .. Parameters ..
101 REAL ZERO, ONE, TWO, THREE
102 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0,
103 $ three = 3.0e0 )
104 INTEGER MAXIT
105 parameter( maxit = 30 )
106* ..
107* .. Local Scalars ..
108 INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M,
109 $ NMAXIT
110 REAL ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC,
111 $ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN,
112 $ SIGMA, SSFMAX, SSFMIN
113* ..
114* .. External Functions ..
115 REAL SLAMCH, SLANST, SLAPY2
116 EXTERNAL slamch, slanst, slapy2
117* ..
118* .. External Subroutines ..
119 EXTERNAL slae2, slascl, slasrt, xerbla
120* ..
121* .. Intrinsic Functions ..
122 INTRINSIC abs, sign, sqrt
123* ..
124* .. Executable Statements ..
125*
126* Test the input parameters.
127*
128 info = 0
129*
130* Quick return if possible
131*
132 IF( n.LT.0 ) THEN
133 info = -1
134 CALL xerbla( 'SSTERF', -info )
135 RETURN
136 END IF
137 IF( n.LE.1 )
138 $ RETURN
139*
140* Determine the unit roundoff for this environment.
141*
142 eps = slamch( 'E' )
143 eps2 = eps**2
144 safmin = slamch( 'S' )
145 safmax = one / safmin
146 ssfmax = sqrt( safmax ) / three
147 ssfmin = sqrt( safmin ) / eps2
148*
149* Compute the eigenvalues of the tridiagonal matrix.
150*
151 nmaxit = n*maxit
152 sigma = zero
153 jtot = 0
154*
155* Determine where the matrix splits and choose QL or QR iteration
156* for each block, according to whether top or bottom diagonal
157* element is smaller.
158*
159 l1 = 1
160*
161 10 CONTINUE
162 IF( l1.GT.n )
163 $ GO TO 170
164 IF( l1.GT.1 )
165 $ e( l1-1 ) = zero
166 DO 20 m = l1, n - 1
167 IF( abs( e( m ) ).LE.( sqrt( abs( d( m ) ) )*
168 $ sqrt( abs( d( m+1 ) ) ) )*eps ) THEN
169 e( m ) = zero
170 GO TO 30
171 END IF
172 20 CONTINUE
173 m = n
174*
175 30 CONTINUE
176 l = l1
177 lsv = l
178 lend = m
179 lendsv = lend
180 l1 = m + 1
181 IF( lend.EQ.l )
182 $ GO TO 10
183*
184* Scale submatrix in rows and columns L to LEND
185*
186 anorm = slanst( 'M', lend-l+1, d( l ), e( l ) )
187 iscale = 0
188 IF( anorm.EQ.zero )
189 $ GO TO 10
190 IF( anorm.GT.ssfmax ) THEN
191 iscale = 1
192 CALL slascl( 'G', 0, 0, anorm, ssfmax, lend-l+1, 1, d( l ), n,
193 $ info )
194 CALL slascl( 'G', 0, 0, anorm, ssfmax, lend-l, 1, e( l ), n,
195 $ info )
196 ELSE IF( anorm.LT.ssfmin ) THEN
197 iscale = 2
198 CALL slascl( 'G', 0, 0, anorm, ssfmin, lend-l+1, 1, d( l ), n,
199 $ info )
200 CALL slascl( 'g', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N,
201 $ INFO )
202 END IF
203*
204 DO 40 I = L, LEND - 1
205 E( I ) = E( I )**2
206 40 CONTINUE
207*
208* Choose between QL and QR iteration
209*
210.LT. IF( ABS( D( LEND ) )ABS( D( L ) ) ) THEN
211 LEND = LSV
212 L = LENDSV
213 END IF
214*
215.GE. IF( LENDL ) THEN
216*
217* QL Iteration
218*
219* Look for small subdiagonal element.
220*
221 50 CONTINUE
222.NE. IF( LLEND ) THEN
223 DO 60 M = L, LEND - 1
224.LE. IF( ABS( E( M ) )EPS2*ABS( D( M )*D( M+1 ) ) )
225 $ GO TO 70
226 60 CONTINUE
227 END IF
228 M = LEND
229*
230 70 CONTINUE
231.LT. IF( MLEND )
232 $ E( M ) = ZERO
233 P = D( L )
234.EQ. IF( ML )
235 $ GO TO 90
236*
237* If remaining matrix is 2 by 2, use SLAE2 to compute its
238* eigenvalues.
239*
240.EQ. IF( ML+1 ) THEN
241 RTE = SQRT( E( L ) )
242 CALL SLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 )
243 D( L ) = RT1
244 D( L+1 ) = RT2
245 E( L ) = ZERO
246 L = L + 2
247.LE. IF( LLEND )
248 $ GO TO 50
249 GO TO 150
250 END IF
251*
252.EQ. IF( JTOTNMAXIT )
253 $ GO TO 150
254 JTOT = JTOT + 1
255*
256* Form shift.
257*
258 RTE = SQRT( E( L ) )
259 SIGMA = ( D( L+1 )-P ) / ( TWO*RTE )
260 R = SLAPY2( SIGMA, ONE )
261 SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
262*
263 C = ONE
264 S = ZERO
265 GAMMA = D( M ) - SIGMA
266 P = GAMMA*GAMMA
267*
268* Inner loop
269*
270 DO 80 I = M - 1, L, -1
271 BB = E( I )
272 R = P + BB
273.NE. IF( IM-1 )
274 $ E( I+1 ) = S*R
275 OLDC = C
276 C = P / R
277 S = BB / R
278 OLDGAM = GAMMA
279 ALPHA = D( I )
280 GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
281 D( I+1 ) = OLDGAM + ( ALPHA-GAMMA )
282.NE. IF( CZERO ) THEN
283 P = ( GAMMA*GAMMA ) / C
284 ELSE
285 P = OLDC*BB
286 END IF
287 80 CONTINUE
288*
289 E( L ) = S*P
290 D( L ) = SIGMA + GAMMA
291 GO TO 50
292*
293* Eigenvalue found.
294*
295 90 CONTINUE
296 D( L ) = P
297*
298 L = L + 1
299.LE. IF( LLEND )
300 $ GO TO 50
301 GO TO 150
302*
303 ELSE
304*
305* QR Iteration
306*
307* Look for small superdiagonal element.
308*
309 100 CONTINUE
310 DO 110 M = L, LEND + 1, -1
311.LE. IF( ABS( E( M-1 ) )EPS2*ABS( D( M )*D( M-1 ) ) )
312 $ GO TO 120
313 110 CONTINUE
314 M = LEND
315*
316 120 CONTINUE
317.GT. IF( MLEND )
318 $ E( M-1 ) = ZERO
319 P = D( L )
320.EQ. IF( ML )
321 $ GO TO 140
322*
323* If remaining matrix is 2 by 2, use SLAE2 to compute its
324* eigenvalues.
325*
326.EQ. IF( ML-1 ) THEN
327 RTE = SQRT( E( L-1 ) )
328 CALL SLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 )
329 D( L ) = RT1
330 D( L-1 ) = RT2
331 E( L-1 ) = ZERO
332 L = L - 2
333.GE. IF( LLEND )
334 $ GO TO 100
335 GO TO 150
336 END IF
337*
338.EQ. IF( JTOTNMAXIT )
339 $ GO TO 150
340 JTOT = JTOT + 1
341*
342* Form shift.
343*
344 RTE = SQRT( E( L-1 ) )
345 SIGMA = ( D( L-1 )-P ) / ( TWO*RTE )
346 R = SLAPY2( SIGMA, ONE )
347 SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) )
348*
349 C = ONE
350 S = ZERO
351 GAMMA = D( M ) - SIGMA
352 P = GAMMA*GAMMA
353*
354* Inner loop
355*
356 DO 130 I = M, L - 1
357 BB = E( I )
358 R = P + BB
359.NE. IF( IM )
360 $ E( I-1 ) = S*R
361 OLDC = C
362 C = P / R
363 S = BB / R
364 OLDGAM = GAMMA
365 ALPHA = D( I+1 )
366 GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM
367 D( I ) = OLDGAM + ( ALPHA-GAMMA )
368.NE. IF( CZERO ) THEN
369 P = ( GAMMA*GAMMA ) / C
370 ELSE
371 P = OLDC*BB
372 END IF
373 130 CONTINUE
374*
375 E( L-1 ) = S*P
376 D( L ) = SIGMA + GAMMA
377 GO TO 100
378*
379* Eigenvalue found.
380*
381 140 CONTINUE
382 D( L ) = P
383*
384 L = L - 1
385.GE. IF( LLEND )
386 $ GO TO 100
387 GO TO 150
388*
389 END IF
390*
391* Undo scaling if necessary
392*
393 150 CONTINUE
394.EQ. IF( ISCALE1 )
395 $ CALL SLASCL( 'g', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1,
396 $ D( LSV ), N, INFO )
397.EQ. IF( ISCALE2 )
398 $ CALL SLASCL( 'g', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1,
399 $ D( LSV ), N, INFO )
400*
401* Check for no convergence to an eigenvalue after a total
402* of N*MAXIT iterations.
403*
404.LT. IF( JTOTNMAXIT )
405 $ GO TO 10
406 DO 160 I = 1, N - 1
407.NE. IF( E( I )ZERO )
408 $ INFO = INFO + 1
409 160 CONTINUE
410 GO TO 180
411*
412* Sort eigenvalues in increasing order.
413*
414 170 CONTINUE
415 CALL SLASRT( 'i', N, D, INFO )
416*
417 180 CONTINUE
418 RETURN
419*
420* End of SSTERF
421*
422 END
subroutine slae2(a, b, c, rt1, rt2)
SLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
Definition slae2.f:102
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition slascl.f:143
real function slanst(norm, n, d, e)
SLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition slanst.f:100
subroutine slasrt(id, n, d, info)
SLASRT sorts numbers in increasing or decreasing order.
Definition slasrt.f:88
subroutine ssterf(n, d, e, info)
SSTERF
Definition ssterf.f:86
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
real function slamch(cmach)
SLAMCH
Definition slamch.f:68