129
130
131
132
133
134
135 CHARACTER COMPZ
136 INTEGER INFO, LDZ, N
137
138
139 REAL D( * ), E( * ), WORK( * ), Z( LDZ, * )
140
141
142
143
144
145 REAL ZERO, ONE, TWO, THREE
146 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0,
147 $ three = 3.0e0 )
148 INTEGER MAXIT
149 parameter( maxit = 30 )
150
151
152 INTEGER I, ICOMPZ, II, ISCALE, J, JTOT, K, L, L1, LEND,
153 $ LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
154 $ NM1, NMAXIT
155 REAL ANORM, B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
156 $ S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
157
158
159 LOGICAL LSAME
160 REAL SLAMCH, SLANST, SLAPY2
162
163
167
168
169 INTRINSIC abs, max, sign, sqrt
170
171
172
173
174
175 info = 0
176
177 IF(
lsame( compz,
'N' ) )
THEN
178 icompz = 0
179 ELSE IF(
lsame( compz,
'V' ) )
THEN
180 icompz = 1
181 ELSE IF(
lsame( compz,
'I' ) )
THEN
182 icompz = 2
183 ELSE
184 icompz = -1
185 END IF
186 IF( icompz.LT.0 ) THEN
187 info = -1
188 ELSE IF( n.LT.0 ) THEN
189 info = -2
190 ELSE IF( ( ldz.LT.1 ) .OR. ( icompz.GT.0 .AND. ldz.LT.max( 1,
191 $ n ) ) ) THEN
192 info = -6
193 END IF
194 IF( info.NE.0 ) THEN
195 CALL xerbla(
'SSTEQR', -info )
196 RETURN
197 END IF
198
199
200
201 IF( n.EQ.0 )
202 $ RETURN
203
204 IF( n.EQ.1 ) THEN
205 IF( icompz.EQ.2 )
206 $ z( 1, 1 ) = one
207 RETURN
208 END IF
209
210
211
213 eps2 = eps**2
215 safmax = one / safmin
216 ssfmax = sqrt( safmax ) / three
217 ssfmin = sqrt( safmin ) / eps2
218
219
220
221
222 IF( icompz.EQ.2 )
223 $
CALL slaset(
'Full', n, n, zero, one, z, ldz )
224
225 nmaxit = n*maxit
226 jtot = 0
227
228
229
230
231
232 l1 = 1
233 nm1 = n - 1
234
235 10 CONTINUE
236 IF( l1.GT.n )
237 $ GO TO 160
238 IF( l1.GT.1 )
239 $ e( l1-1 ) = zero
240 IF( l1.LE.nm1 ) THEN
241 DO 20 m = l1, nm1
242 tst = abs( e( m ) )
243 IF( tst.EQ.zero )
244 $ GO TO 30
245 IF( tst.LE.( sqrt( abs( d( m ) ) )*sqrt( abs( d( m+
246 $ 1 ) ) ) )*eps ) THEN
247 e( m ) = zero
248 GO TO 30
249 END IF
250 20 CONTINUE
251 END IF
252 m = n
253
254 30 CONTINUE
255 l = l1
256 lsv = l
257 lend = m
258 lendsv = lend
259 l1 = m + 1
260 IF( lend.EQ.l )
261 $ GO TO 10
262
263
264
265 anorm =
slanst(
'M', lend-l+1, d( l ), e( l ) )
266 iscale = 0
267 IF( anorm.EQ.zero )
268 $ GO TO 10
269 IF( anorm.GT.ssfmax ) THEN
270 iscale = 1
271 CALL slascl(
'G', 0, 0, anorm, ssfmax, lend-l+1, 1, d( l ),
272 $ n,
273 $ info )
274 CALL slascl(
'G', 0, 0, anorm, ssfmax, lend-l, 1, e( l ), n,
275 $ info )
276 ELSE IF( anorm.LT.ssfmin ) THEN
277 iscale = 2
278 CALL slascl(
'G', 0, 0, anorm, ssfmin, lend-l+1, 1, d( l ),
279 $ n,
280 $ info )
281 CALL slascl(
'G', 0, 0, anorm, ssfmin, lend-l, 1, e( l ), n,
282 $ info )
283 END IF
284
285
286
287 IF( abs( d( lend ) ).LT.abs( d( l ) ) ) THEN
288 lend = lsv
289 l = lendsv
290 END IF
291
292 IF( lend.GT.l ) THEN
293
294
295
296
297
298 40 CONTINUE
299 IF( l.NE.lend ) THEN
300 lendm1 = lend - 1
301 DO 50 m = l, lendm1
302 tst = abs( e( m ) )**2
303 IF( tst.LE.( eps2*abs( d( m ) ) )*abs( d( m+1 ) )+
304 $ safmin )GO TO 60
305 50 CONTINUE
306 END IF
307
308 m = lend
309
310 60 CONTINUE
311 IF( m.LT.lend )
312 $ e( m ) = zero
313 p = d( l )
314 IF( m.EQ.l )
315 $ GO TO 80
316
317
318
319
320 IF( m.EQ.l+1 ) THEN
321 IF( icompz.GT.0 ) THEN
322 CALL slaev2( d( l ), e( l ), d( l+1 ), rt1, rt2, c,
323 $ s )
324 work( l ) = c
325 work( n-1+l ) = s
326 CALL slasr(
'R',
'V',
'B', n, 2, work( l ),
327 $ work( n-1+l ), z( 1, l ), ldz )
328 ELSE
329 CALL slae2( d( l ), e( l ), d( l+1 ), rt1, rt2 )
330 END IF
331 d( l ) = rt1
332 d( l+1 ) = rt2
333 e( l ) = zero
334 l = l + 2
335 IF( l.LE.lend )
336 $ GO TO 40
337 GO TO 140
338 END IF
339
340 IF( jtot.EQ.nmaxit )
341 $ GO TO 140
342 jtot = jtot + 1
343
344
345
346 g = ( d( l+1 )-p ) / ( two*e( l ) )
348 g = d( m ) - p + ( e( l ) / ( g+sign( r, g ) ) )
349
350 s = one
351 c = one
352 p = zero
353
354
355
356 mm1 = m - 1
357 DO 70 i = mm1, l, -1
358 f = s*e( i )
359 b = c*e( i )
360 CALL slartg( g, f, c, s, r )
361 IF( i.NE.m-1 )
362 $ e( i+1 ) = r
363 g = d( i+1 ) - p
364 r = ( d( i )-g )*s + two*c*b
365 p = s*r
366 d( i+1 ) = g + p
367 g = c*r - b
368
369
370
371 IF( icompz.GT.0 ) THEN
372 work( i ) = c
373 work( n-1+i ) = -s
374 END IF
375
376 70 CONTINUE
377
378
379
380 IF( icompz.GT.0 ) THEN
381 mm = m - l + 1
382 CALL slasr(
'R',
'V',
'B', n, mm, work( l ),
383 $ work( n-1+l ),
384 $ z( 1, l ), ldz )
385 END IF
386
387 d( l ) = d( l ) - p
388 e( l ) = g
389 GO TO 40
390
391
392
393 80 CONTINUE
394 d( l ) = p
395
396 l = l + 1
397 IF( l.LE.lend )
398 $ GO TO 40
399 GO TO 140
400
401 ELSE
402
403
404
405
406
407 90 CONTINUE
408 IF( l.NE.lend ) THEN
409 lendp1 = lend + 1
410 DO 100 m = l, lendp1, -1
411 tst = abs( e( m-1 ) )**2
412 IF( tst.LE.( eps2*abs( d( m ) ) )*abs( d( m-1 ) )+
413 $ safmin )GO TO 110
414 100 CONTINUE
415 END IF
416
417 m = lend
418
419 110 CONTINUE
420 IF( m.GT.lend )
421 $ e( m-1 ) = zero
422 p = d( l )
423 IF( m.EQ.l )
424 $ GO TO 130
425
426
427
428
429 IF( m.EQ.l-1 ) THEN
430 IF( icompz.GT.0 ) THEN
431 CALL slaev2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2, c,
432 $ s )
433 work( m ) = c
434 work( n-1+m ) = s
435 CALL slasr(
'R',
'V',
'F', n, 2, work( m ),
436 $ work( n-1+m ), z( 1, l-1 ), ldz )
437 ELSE
438 CALL slae2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2 )
439 END IF
440 d( l-1 ) = rt1
441 d( l ) = rt2
442 e( l-1 ) = zero
443 l = l - 2
444 IF( l.GE.lend )
445 $ GO TO 90
446 GO TO 140
447 END IF
448
449 IF( jtot.EQ.nmaxit )
450 $ GO TO 140
451 jtot = jtot + 1
452
453
454
455 g = ( d( l-1 )-p ) / ( two*e( l-1 ) )
457 g = d( m ) - p + ( e( l-1 ) / ( g+sign( r, g ) ) )
458
459 s = one
460 c = one
461 p = zero
462
463
464
465 lm1 = l - 1
466 DO 120 i = m, lm1
467 f = s*e( i )
468 b = c*e( i )
469 CALL slartg( g, f, c, s, r )
470 IF( i.NE.m )
471 $ e( i-1 ) = r
472 g = d( i ) - p
473 r = ( d( i+1 )-g )*s + two*c*b
474 p = s*r
475 d( i ) = g + p
476 g = c*r - b
477
478
479
480 IF( icompz.GT.0 ) THEN
481 work( i ) = c
482 work( n-1+i ) = s
483 END IF
484
485 120 CONTINUE
486
487
488
489 IF( icompz.GT.0 ) THEN
490 mm = l - m + 1
491 CALL slasr(
'R',
'V',
'F', n, mm, work( m ),
492 $ work( n-1+m ),
493 $ z( 1, m ), ldz )
494 END IF
495
496 d( l ) = d( l ) - p
497 e( lm1 ) = g
498 GO TO 90
499
500
501
502 130 CONTINUE
503 d( l ) = p
504
505 l = l - 1
506 IF( l.GE.lend )
507 $ GO TO 90
508 GO TO 140
509
510 END IF
511
512
513
514 140 CONTINUE
515 IF( iscale.EQ.1 ) THEN
516 CALL slascl(
'G', 0, 0, ssfmax, anorm, lendsv-lsv+1, 1,
517 $ d( lsv ), n, info )
518 CALL slascl(
'G', 0, 0, ssfmax, anorm, lendsv-lsv, 1,
519 $ e( lsv ),
520 $ n, info )
521 ELSE IF( iscale.EQ.2 ) THEN
522 CALL slascl(
'G', 0, 0, ssfmin, anorm, lendsv-lsv+1, 1,
523 $ d( lsv ), n, info )
524 CALL slascl(
'G', 0, 0, ssfmin, anorm, lendsv-lsv, 1,
525 $ e( lsv ),
526 $ n, info )
527 END IF
528
529
530
531
532 IF( jtot.LT.nmaxit )
533 $ GO TO 10
534 DO 150 i = 1, n - 1
535 IF( e( i ).NE.zero )
536 $ info = info + 1
537 150 CONTINUE
538 GO TO 190
539
540
541
542 160 CONTINUE
543 IF( icompz.EQ.0 ) THEN
544
545
546
547 CALL slasrt(
'I', n, d, info )
548
549 ELSE
550
551
552
553 DO 180 ii = 2, n
554 i = ii - 1
555 k = i
556 p = d( i )
557 DO 170 j = ii, n
558 IF( d( j ).LT.p ) THEN
559 k = j
560 p = d( j )
561 END IF
562 170 CONTINUE
563 IF( k.NE.i ) THEN
564 d( k ) = d( i )
565 d( i ) = p
566 CALL sswap( n, z( 1, i ), 1, z( 1, k ), 1 )
567 END IF
568 180 CONTINUE
569 END IF
570
571 190 CONTINUE
572 RETURN
573
574
575
subroutine xerbla(srname, info)
subroutine slae2(a, b, c, rt1, rt2)
SLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine slaev2(a, b, c, rt1, rt2, cs1, sn1)
SLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian 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 slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
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 slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slasr(side, pivot, direct, m, n, c, s, a, lda)
SLASR applies a sequence of plane rotations to a general rectangular matrix.
subroutine slasrt(id, n, d, info)
SLASRT sorts numbers in increasing or decreasing order.
logical function lsame(ca, cb)
LSAME
subroutine sswap(n, sx, incx, sy, incy)
SSWAP