2
3
4
5
6
7
8
9 CHARACTER COMPZ
10 INTEGER INFO, LDZ, N,
11
12
13 DOUBLE PRECISION D( * ), E( * ), WORK( * ), Z( LDZ, * )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 DOUBLE PRECISION ZERO, ONE, TWO, THREE
84 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0,
85 $ three = 3.0d0 )
86 INTEGER MAXIT
87 parameter( maxit = 30 )
88
89
90 INTEGER I, ICOMPZ, II, ISCALE, J, JTOT, K, , L1, LEND,
91 $ LENDM1, LENDP1, LENDSV, LM1, LSV, M, MM, MM1,
92 $ NM1, NMAXIT
93 DOUBLE PRECISION , B, C, EPS, EPS2, F, G, P, R, RT1, RT2,
94 $ S, SAFMAX, SAFMIN, SSFMAX, SSFMIN, TST
95
96
97 LOGICAL LSAME
98 DOUBLE PRECISION DLAMCH, DLANST, DLAPY2
100
101
104
105
106 INTRINSIC abs,
max, sign, sqrt
107
108
109
110
111
112 info = 0
113
114 IF(
lsame( compz,
'N' ) )
THEN
115 icompz = 0
116 ELSE IF(
lsame( compz,
'I' ) )
THEN
117 icompz = 1
118 ELSE
119 icompz = -1
120 END IF
121 IF( icompz.LT.0 ) THEN
122 info = -1
123 ELSE IF( n.LT.0 ) THEN
124 info = -2
125 ELSE IF( icompz.GT.0 .AND. ldz.LT.
max( 1, nr ) )
THEN
126 info = -6
127 END IF
128 IF( info.NE.0 ) THEN
129 CALL xerbla(
'DSTEQR2', -info )
130 RETURN
131 END IF
132
133
134
135 IF( n.EQ.0 )
136 $ RETURN
137
138 IF( n.EQ.1 ) THEN
139 IF( icompz.EQ.1 )
140 $ z( 1, 1 ) = one
141 RETURN
142 END IF
143
144
145
147 eps2 = eps**2
149 safmax = one / safmin
150 ssfmax = sqrt( safmax ) / three
151 ssfmin = sqrt( safmin ) / eps2
152
153
154
155
156 nmaxit = n*maxit
157 jtot = 0
158
159
160
161
162
163 l1 = 1
164 nm1 = n - 1
165
166 10 CONTINUE
167 IF( l1.GT.n )
168 $ GO TO 160
169 IF( l1.GT.1 )
170 $ e( l1-1 ) = zero
171 IF( l1.LE.nm1 ) THEN
172 DO 20 m = l1, nm1
173 tst = abs( e( m ) )
174 IF( tst.EQ.zero )
175 $ GO TO 30
176 IF( tst.LE.( sqrt( abs( d( m ) ) )*sqrt( abs( d( m+
177 $ 1 ) ) ) )*eps ) THEN
178 e( m ) = zero
179 GO TO 30
180 END IF
181 20 CONTINUE
182 END IF
183 m = n
184
185 30 CONTINUE
186 l = l1
187 lsv = l
188 lend = m
189 lendsv = lend
190 l1 = m + 1
191 IF( lend.EQ.l )
192 $ GO TO 10
193
194
195
196 anorm =
dlanst(
'I', lend-l+1, d( l ), e( l ) )
197 iscale = 0
198 IF( anorm.EQ.zero )
199 $ GO TO 10
200 IF( anorm.GT.ssfmax ) THEN
201 iscale = 1
202 CALL dlascl(
'G', 0, 0, anorm, ssfmax, lend-l+1, 1, d( l ), n,
203 $ info )
204 CALL dlascl(
'G', 0, 0, anorm, ssfmax, lend-l, 1, e( l ), n,
205 $ info )
206 ELSE IF( anorm.LT.ssfmin ) THEN
207 iscale = 2
208 CALL dlascl(
'G', 0, 0, anorm, ssfmin, lend-l+1, 1, d( l ), n,
209 $ info )
210 CALL dlascl(
'G', 0, 0, anorm, ssfmin, lend-l, 1, e( l ), n,
211 $ info )
212 END IF
213
214
215
216 IF( abs( d( lend ) ).LT.abs( d( l ) ) ) THEN
217 lend = lsv
218 l = lendsv
219 END IF
220
221 IF( lend.GT.l ) THEN
222
223
224
225
226
227 40 CONTINUE
228 IF( l.NE.lend ) THEN
229 lendm1 = lend - 1
230 DO 50 m = l, lendm1
231 tst = abs( e( m ) )**2
232 IF( tst.LE.( eps2*abs( d( m ) ) )*abs( d( m+1 ) )+
233 $ safmin )GO TO 60
234 50 CONTINUE
235 END IF
236
237 m = lend
238
239 60 CONTINUE
240 IF( m.LT.lend )
241 $ e( m ) = zero
242 p = d( l )
243 IF( m.EQ.l )
244 $ GO TO 80
245
246
247
248
249 IF( m.EQ.l+1 ) THEN
250 IF( icompz.GT.0 ) THEN
251 CALL dlaev2( d( l ), e( l ), d( l+1 ), rt1, rt2, c, s )
252 work( l ) = c
253 work( n-1+l ) = s
254 CALL dlasr(
'R',
'V',
'B', nr, 2, work( l ),
255 $ work( n-1+l ), z( 1, l ), ldz )
256 ELSE
257 CALL dlae2( d( l ), e( l ), d( l+1 ), rt1, rt2 )
258 END IF
259 d( l ) = rt1
260 d( l+1 ) = rt2
261 e( l ) = zero
262 l = l + 2
263 IF( l.LE.lend )
264 $ GO TO 40
265 GO TO 140
266 END IF
267
268 IF( jtot.EQ.nmaxit )
269 $ GO TO 140
270 jtot = jtot + 1
271
272
273
274 g = ( d( l+1 )-p ) / ( two*e( l ) )
276 g = d( m ) - p + ( e( l ) / ( g+sign( r, g ) ) )
277
278 s = one
279 c = one
280 p = zero
281
282
283
284 mm1 = m - 1
285 DO 70 i = mm1, l, -1
286 f = s*e( i )
287 b = c*e( i )
288 CALL dlartg( g, f, c, s, r )
289 IF( i.NE.m-1 )
290 $ e( i+1 ) = r
291 g = d( i+1 ) - p
292 r = ( d( i )-g )*s + two*c*b
293 p = s*r
294 d( i+1 ) = g + p
295 g = c*r - b
296
297
298
299 IF( icompz.GT.0 ) THEN
300 work( i ) = c
301 work( n-1+i ) = -s
302 END IF
303
304 70 CONTINUE
305
306
307
308 IF( icompz.GT.0 ) THEN
309 mm = m - l + 1
310 CALL dlasr(
'R',
'V',
'B', nr, mm, work( l ), work( n-1+l ),
311 $ z( 1, l ), ldz )
312 END IF
313
314 d( l ) = d( l ) - p
315 e( l ) = g
316 GO TO 40
317
318
319
320 80 CONTINUE
321 d( l ) = p
322
323 l = l + 1
324 IF( l.LE.lend )
325 $ GO TO 40
326 GO TO 140
327
328 ELSE
329
330
331
332
333
334 90 CONTINUE
335 IF( l.NE.lend ) THEN
336 lendp1 = lend
337 DO 100 m = l, lendp1, -1
338 tst = abs( e( m-1 ) )**2
339 IF( tst.LE.( eps2*abs( d( m ) ) )*abs( d( m-1 ) )+
340 $ safmin )GO TO 110
341 100 CONTINUE
342 END IF
343
344 m = lend
345
346 110 CONTINUE
347 IF( m.GT.lend )
348 $ e( m-1 ) = zero
349 p = d( l )
350 IF( m.EQ.l )
351 $ GO TO 130
352
353
354
355
356 IF( m.EQ.l-1 ) THEN
357 IF( icompz.GT.0 ) THEN
358 CALL dlaev2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2, c, s )
359 work( m ) = c
360 work( n-1+m ) = s
361 CALL dlasr(
'R',
'V',
'F', nr, 2, work( m ),
362 $ work( n-1+m ), z( 1, l-1 ), ldz )
363 ELSE
364 CALL dlae2( d( l-1 ), e( l-1 ), d( l ), rt1, rt2 )
365 END IF
366 d( l-1 ) = rt1
367 d( l ) = rt2
368 e( l-1 ) = zero
369 l = l - 2
370 IF( l.GE.lend )
371 $ GO TO 90
372 GO TO 140
373 END IF
374
375 IF( jtot.EQ.nmaxit )
376 $ GO TO 140
377 jtot = jtot + 1
378
379
380
381 g = ( d( l-1 )-p ) / ( two*e( l-1 ) )
383 g = d( m ) - p + ( e( l-1 ) / ( g+sign( r, g ) ) )
384
385 s = one
386 c = one
387 p = zero
388
389
390
391 lm1 = l - 1
392 DO 120 i = m, lm1
393 f = s*e( i )
394 b = c*e( i )
395 CALL dlartg( g, f, c, s, r )
396 IF( i.NE.m )
397 $ e( i-1 ) = r
398 g = d( i ) - p
399 r = ( d( i+1 )-g )*s + two*c*b
400 p = s*r
401 d( i ) = g + p
402 g = c*r - b
403
404
405
406 IF( icompz.GT.0 ) THEN
407 work( i ) = c
408 work( n-1+i ) = s
409 END IF
410
411 120 CONTINUE
412
413
414
415 IF( icompz.GT.0 ) THEN
416 mm = l - m + 1
417 CALL dlasr(
'R',
'V',
'F', nr, mm, work( m ), work( n-1+m ),
418 $ z( 1, m ), ldz )
419 END IF
420
421 d( l ) = d( l ) - p
422 e( lm1 ) = g
423 GO TO 90
424
425
426
427 130 CONTINUE
428 d( l ) = p
429
430 l = l - 1
431 IF( l.GE.lend )
432 $ GO TO 90
433 GO TO 140
434
435 END IF
436
437
438
439 140 CONTINUE
440 IF( iscale.EQ.1 ) THEN
441 CALL dlascl(
'G', 0, 0, ssfmax, anorm, lendsv-lsv+1, 1,
442 $ d( lsv ), n, info )
443 CALL dlascl(
'G', 0, 0, ssfmax, anorm, lendsv-lsv, 1, e( lsv ),
444 $ n, info )
445 ELSE IF( iscale.EQ.2 ) THEN
446 CALL dlascl(
'G', 0, 0, ssfmin, anorm, lendsv-lsv+1, 1,
447 $ d( lsv ), n, info )
448 CALL dlascl(
'G', 0, 0, ssfmin, anorm, lendsv-lsv, 1, e( lsv ),
449 $ n, info )
450 END IF
451
452
453
454
455 IF( jtot.LT.nmaxit )
456 $ GO TO 10
457 DO 150 i = 1, n - 1
458 IF( e( i ).NE.zero )
459 $ info = info + 1
460 150 CONTINUE
461 GO TO 190
462
463
464
465 160 CONTINUE
466 IF( icompz.EQ.0 ) THEN
467
468
469
470 CALL dlasrt(
'I', n, d, info )
471
472 ELSE
473
474
475
476 DO 180 ii = 2, n
477 i = ii - 1
478 k = i
479 p = d( i )
480 DO 170 j = ii, n
481 IF( d( j ).LT.p ) THEN
482 k = j
483 p = d( j )
484 END IF
485 170 CONTINUE
486 IF( k.NE.i ) THEN
487 d( k ) = d( i )
488 d( i ) = p
489 CALL dswap( nr, z( 1, i ), 1, z( 1, k ), 1 )
490 END IF
491 180 CONTINUE
492 END IF
493
494 190 CONTINUE
495 RETURN
496
497
498
subroutine dlae2(a, b, c, rt1, rt2)
DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix.
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
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 dlaev2(a, b, c, rt1, rt2, cs1, sn1)
DLAEV2 computes the eigenvalues and eigenvectors of a 2-by-2 symmetric/Hermitian matrix.
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 dlasr(side, pivot, direct, m, n, c, s, a, lda)
DLASR 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.
subroutine xerbla(srname, info)
XERBLA
logical function lsame(ca, cb)
LSAME
subroutine dswap(n, dx, incx, dy, incy)
DSWAP
double precision function dlamch(cmach)
DLAMCH