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