86
87
88
89
90
91
92 INTEGER INFO, N
93
94
95 REAL D( * ), E( * )
96
97
98
99
100
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
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
115 REAL SLAMCH, SLANST, SLAPY2
117
118
120
121
122 INTRINSIC abs, sign, sqrt
123
124
125
126
127
128 info = 0
129
130
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
141
143 eps2 = eps**2
145 safmax = one / safmin
146 ssfmax = sqrt( safmax ) / three
147 ssfmin = sqrt( safmin ) / eps2
148
149
150
151 nmaxit = n*maxit
152 sigma = zero
153 jtot = 0
154
155
156
157
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
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
209
210 IF( abs( d( lend ) ).LT.abs( d( l ) ) ) THEN
211 lend = lsv
212 l = lendsv
213 END IF
214
215 IF( lend.GE.l ) THEN
216
217
218
219
220
221 50 CONTINUE
222 IF( l.NE.lend ) THEN
223 DO 60 m = l, lend - 1
224 IF( abs( e( m ) ).LE.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 IF( m.LT.lend )
232 $ e( m ) = zero
233 p = d( l )
234 IF( m.EQ.l )
235 $ GO TO 90
236
237
238
239
240 IF( m.EQ.l+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 IF( l.LE.lend )
248 $ GO TO 50
249 GO TO 150
250 END IF
251
252 IF( jtot.EQ.nmaxit )
253 $ GO TO 150
254 jtot = jtot + 1
255
256
257
258 rte = sqrt( e( l ) )
259 sigma = ( d( l+1 )-p ) / ( two*rte )
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
269
270 DO 80 i = m - 1, l, -1
271 bb = e( i )
272 r = p + bb
273 IF( i.NE.m-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 IF( c.NE.zero ) 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
294
295 90 CONTINUE
296 d( l ) = p
297
298 l = l + 1
299 IF( l.LE.lend )
300 $ GO TO 50
301 GO TO 150
302
303 ELSE
304
305
306
307
308
309 100 CONTINUE
310 DO 110 m = l, lend + 1, -1
311 IF( abs( e( m-1 ) ).LE.eps2*abs( d( m )*d( m-1 ) ) )
312 $ GO TO 120
313 110 CONTINUE
314 m = lend
315
316 120 CONTINUE
317 IF( m.GT.lend )
318 $ e( m-1 ) = zero
319 p = d( l )
320 IF( m.EQ.l )
321 $ GO TO 140
322
323
324
325
326 IF( m.EQ.l-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 IF( l.GE.lend )
334 $ GO TO 100
335 GO TO 150
336 END IF
337
338 IF( jtot.EQ.nmaxit )
339 $ GO TO 150
340 jtot = jtot + 1
341
342
343
344 rte = sqrt( e( l-1 ) )
345 sigma = ( d( l-1 )-p ) / ( two*rte )
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
355
356 DO 130 i = m, l - 1
357 bb = e( i )
358 r = p + bb
359 IF( i.NE.m )
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 IF( c.NE.zero ) 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
380
381 140 CONTINUE
382 d( l ) = p
383
384 l = l - 1
385 IF( l.GE.lend )
386 $ GO TO 100
387 GO TO 150
388
389 END IF
390
391
392
393 150 CONTINUE
394 IF( iscale.EQ.1 )
395 $
CALL slascl(
'G', 0, 0, ssfmax, anorm, lendsv-lsv+1, 1,
396 $ d( lsv ), n, info )
397 IF( iscale.EQ.2 )
398 $
CALL slascl(
'G', 0, 0, ssfmin, anorm, lendsv-lsv+1, 1,
399 $ d( lsv ), n, info )
400
401
402
403
404 IF( jtot.LT.nmaxit )
405 $ GO TO 10
406 DO 160 i = 1, n - 1
407 IF( e( i ).NE.zero )
408 $ info = info + 1
409 160 CONTINUE
410 GO TO 180
411
412
413
414 170 CONTINUE
415 CALL slasrt(
'I', n, d, info )
416
417 180 CONTINUE
418 RETURN
419
420
421
subroutine xerbla(srname, info)
subroutine slae2(a, b, c, rt1, rt2)
SLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
real function slamch(cmach)
SLAMCH
real function slanst(norm, n, d, e)
SLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
real function slapy2(x, y)
SLAPY2 returns sqrt(x2+y2).
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.
subroutine slasrt(id, n, d, info)
SLASRT sorts numbers in increasing or decreasing order.