90
91
92
93
94
95
96 INTEGER KNT, NIN
97
98
99 INTEGER LMAX( 3 ), NINFO( 3 )
100 REAL RMAX( 3 )
101
102
103
104
105
106 REAL ZERO, ONE, TWO
107 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0 )
108 REAL EPSIN
109 parameter( epsin = 5.9605e-8 )
110 INTEGER LDT, LWORK
111 parameter( ldt = 20, lwork = 2*ldt*( 10+ldt ) )
112
113
114 INTEGER I, ICMP, IFND, INFO, ISCL, J, KMIN, M, N
115 REAL BIGNUM, EPS, SMLNUM, TNRM, TOL, TOLIN, V,
116 $ VIMIN, VMAX, VMUL, VRMIN
117
118
119 LOGICAL SELECT( LDT )
120 INTEGER IWORK( 2*LDT ), LCMP( 3 )
121 REAL DUM( 1 ), LE( LDT, LDT ), RE( LDT, LDT ),
122 $ S( LDT ), SEP( LDT ), SEPIN( LDT ),
123 $ SEPTMP( LDT ), SIN( LDT ), STMP( LDT ),
124 $ T( LDT, LDT ), TMP( LDT, LDT ), VAL( 3 ),
125 $ WI( LDT ), WIIN( LDT ), WITMP( LDT ),
126 $ WORK( LWORK ), WR( LDT ), WRIN( LDT ),
127 $ WRTMP( LDT )
128
129
130 REAL SLAMCH, SLANGE
132
133
136
137
138 INTRINSIC max, real, sqrt
139
140
141
143 smlnum =
slamch(
'S' ) / eps
144 bignum = one / smlnum
145
146
147
148 eps = max( eps, epsin )
149 rmax( 1 ) = zero
150 rmax( 2 ) = zero
151 rmax( 3 ) = zero
152 lmax( 1 ) = 0
153 lmax( 2 ) = 0
154 lmax( 3 ) = 0
155 knt = 0
156 ninfo( 1 ) = 0
157 ninfo( 2 ) = 0
158 ninfo( 3 ) = 0
159
160 val( 1 ) = sqrt( smlnum )
161 val( 2 ) = one
162 val( 3 ) = sqrt( bignum )
163
164
165
166
167
168 10 CONTINUE
169 READ( nin, fmt = * )n
170 IF( n.EQ.0 )
171 $ RETURN
172 DO 20 i = 1, n
173 READ( nin, fmt = * )( tmp( i, j ), j = 1, n )
174 20 CONTINUE
175 DO 30 i = 1, n
176 READ( nin, fmt = * )wrin( i ), wiin( i ), sin( i ), sepin( i )
177 30 CONTINUE
178 tnrm =
slange(
'M', n, n, tmp, ldt, work )
179
180
181
182 DO 240 iscl = 1, 3
183
184
185
186 knt = knt + 1
187 CALL slacpy(
'F', n, n, tmp, ldt, t, ldt )
188 vmul = val( iscl )
189 DO 40 i = 1, n
190 CALL sscal( n, vmul, t( 1, i ), 1 )
191 40 CONTINUE
192 IF( tnrm.EQ.zero )
193 $ vmul = one
194
195
196
197 CALL sgehrd( n, 1, n, t, ldt, work( 1 ), work( n+1 ), lwork-n,
198 $ info )
199 IF( info.NE.0 ) THEN
200 lmax( 1 ) = knt
201 ninfo( 1 ) = ninfo( 1 ) + 1
202 GO TO 240
203 END IF
204 DO 60 j = 1, n - 2
205 DO 50 i = j + 2, n
206 t( i, j ) = zero
207 50 CONTINUE
208 60 CONTINUE
209
210
211
212 CALL shseqr(
'S',
'N', n, 1, n, t, ldt, wr, wi, dum, 1, work,
213 $ lwork, info )
214 IF( info.NE.0 ) THEN
215 lmax( 2 ) = knt
216 ninfo( 2 ) = ninfo( 2 ) + 1
217 GO TO 240
218 END IF
219
220
221
222 CALL strevc(
'Both',
'All',
SELECT, n, t, ldt, le, ldt, re,
223 $ ldt, n, m, work, info )
224
225
226
227 CALL strsna(
'Both',
'All',
SELECT, n, t, ldt, le, ldt, re,
228 $ ldt, s, sep, n, m, work, n, iwork, info )
229 IF( info.NE.0 ) THEN
230 lmax( 3 ) = knt
231 ninfo( 3 ) = ninfo( 3 ) + 1
232 GO TO 240
233 END IF
234
235
236
237
238 CALL scopy( n, wr, 1, wrtmp, 1 )
239 CALL scopy( n, wi, 1, witmp, 1 )
240 CALL scopy( n, s, 1, stmp, 1 )
241 CALL scopy( n, sep, 1, septmp, 1 )
242 CALL sscal( n, one / vmul, septmp, 1 )
243 DO 80 i = 1, n - 1
244 kmin = i
245 vrmin = wrtmp( i )
246 vimin = witmp( i )
247 DO 70 j = i + 1, n
248 IF( wrtmp( j ).LT.vrmin ) THEN
249 kmin = j
250 vrmin = wrtmp( j )
251 vimin = witmp( j )
252 END IF
253 70 CONTINUE
254 wrtmp( kmin ) = wrtmp( i )
255 witmp( kmin ) = witmp( i )
256 wrtmp( i ) = vrmin
257 witmp( i ) = vimin
258 vrmin = stmp( kmin )
259 stmp( kmin ) = stmp( i )
260 stmp( i ) = vrmin
261 vrmin = septmp( kmin )
262 septmp( kmin ) = septmp( i )
263 septmp( i ) = vrmin
264 80 CONTINUE
265
266
267
268
269 v = max( two*real( n )*eps*tnrm, smlnum )
270 IF( tnrm.EQ.zero )
271 $ v = one
272 DO 90 i = 1, n
273 IF( v.GT.septmp( i ) ) THEN
274 tol = one
275 ELSE
276 tol = v / septmp( i )
277 END IF
278 IF( v.GT.sepin( i ) ) THEN
279 tolin = one
280 ELSE
281 tolin = v / sepin( i )
282 END IF
283 tol = max( tol, smlnum / eps )
284 tolin = max( tolin, smlnum / eps )
285 IF( eps*( sin( i )-tolin ).GT.stmp( i )+tol ) THEN
286 vmax = one / eps
287 ELSE IF( sin( i )-tolin.GT.stmp( i )+tol ) THEN
288 vmax = ( sin( i )-tolin ) / ( stmp( i )+tol )
289 ELSE IF( sin( i )+tolin.LT.eps*( stmp( i )-tol ) ) THEN
290 vmax = one / eps
291 ELSE IF( sin( i )+tolin.LT.stmp( i )-tol ) THEN
292 vmax = ( stmp( i )-tol ) / ( sin( i )+tolin )
293 ELSE
294 vmax = one
295 END IF
296 IF( vmax.GT.rmax( 2 ) ) THEN
297 rmax( 2 ) = vmax
298 IF( ninfo( 2 ).EQ.0 )
299 $ lmax( 2 ) = knt
300 END IF
301 90 CONTINUE
302
303
304
305
306 DO 100 i = 1, n
307 IF( v.GT.septmp( i )*stmp( i ) ) THEN
308 tol = septmp( i )
309 ELSE
310 tol = v / stmp( i )
311 END IF
312 IF( v.GT.sepin( i )*sin( i ) ) THEN
313 tolin = sepin( i )
314 ELSE
315 tolin = v / sin( i )
316 END IF
317 tol = max( tol, smlnum / eps )
318 tolin = max( tolin, smlnum / eps )
319 IF( eps*( sepin( i )-tolin ).GT.septmp( i )+tol ) THEN
320 vmax = one / eps
321 ELSE IF( sepin( i )-tolin.GT.septmp( i )+tol ) THEN
322 vmax = ( sepin( i )-tolin ) / ( septmp( i )+tol )
323 ELSE IF( sepin( i )+tolin.LT.eps*( septmp( i )-tol ) ) THEN
324 vmax = one / eps
325 ELSE IF( sepin( i )+tolin.LT.septmp( i )-tol ) THEN
326 vmax = ( septmp( i )-tol ) / ( sepin( i )+tolin )
327 ELSE
328 vmax = one
329 END IF
330 IF( vmax.GT.rmax( 2 ) ) THEN
331 rmax( 2 ) = vmax
332 IF( ninfo( 2 ).EQ.0 )
333 $ lmax( 2 ) = knt
334 END IF
335 100 CONTINUE
336
337
338
339
340 DO 110 i = 1, n
341 IF( sin( i ).LE.real( 2*n )*eps .AND. stmp( i ).LE.
342 $ real( 2*n )*eps ) THEN
343 vmax = one
344 ELSE IF( eps*sin( i ).GT.stmp( i ) ) THEN
345 vmax = one / eps
346 ELSE IF( sin( i ).GT.stmp( i ) ) THEN
347 vmax = sin( i ) / stmp( i )
348 ELSE IF( sin( i ).LT.eps*stmp( i ) ) THEN
349 vmax = one / eps
350 ELSE IF( sin( i ).LT.stmp( i ) ) THEN
351 vmax = stmp( i ) / sin( i )
352 ELSE
353 vmax = one
354 END IF
355 IF( vmax.GT.rmax( 3 ) ) THEN
356 rmax( 3 ) = vmax
357 IF( ninfo( 3 ).EQ.0 )
358 $ lmax( 3 ) = knt
359 END IF
360 110 CONTINUE
361
362
363
364
365 DO 120 i = 1, n
366 IF( sepin( i ).LE.v .AND. septmp( i ).LE.v ) THEN
367 vmax = one
368 ELSE IF( eps*sepin( i ).GT.septmp( i ) ) THEN
369 vmax = one / eps
370 ELSE IF( sepin( i ).GT.septmp( i ) ) THEN
371 vmax = sepin( i ) / septmp( i )
372 ELSE IF( sepin( i ).LT.eps*septmp( i ) ) THEN
373 vmax = one / eps
374 ELSE IF( sepin( i ).LT.septmp( i ) ) THEN
375 vmax = septmp( i ) / sepin( i )
376 ELSE
377 vmax = one
378 END IF
379 IF( vmax.GT.rmax( 3 ) ) THEN
380 rmax( 3 ) = vmax
381 IF( ninfo( 3 ).EQ.0 )
382 $ lmax( 3 ) = knt
383 END IF
384 120 CONTINUE
385
386
387
388 vmax = zero
389 dum( 1 ) = -one
390 CALL scopy( n, dum, 0, stmp, 1 )
391 CALL scopy( n, dum, 0, septmp, 1 )
392 CALL strsna(
'Eigcond',
'All',
SELECT, n, t, ldt, le, ldt, re,
393 $ ldt, stmp, septmp, n, m, work, n, iwork, info )
394 IF( info.NE.0 ) THEN
395 lmax( 3 ) = knt
396 ninfo( 3 ) = ninfo( 3 ) + 1
397 GO TO 240
398 END IF
399 DO 130 i = 1, n
400 IF( stmp( i ).NE.s( i ) )
401 $ vmax = one / eps
402 IF( septmp( i ).NE.dum( 1 ) )
403 $ vmax = one / eps
404 130 CONTINUE
405
406
407
408 CALL scopy( n, dum, 0, stmp, 1 )
409 CALL scopy( n, dum, 0, septmp, 1 )
410 CALL strsna(
'Veccond',
'All',
SELECT, n, t, ldt, le, ldt, re,
411 $ ldt, stmp, septmp, n, m, work, n, iwork, info )
412 IF( info.NE.0 ) THEN
413 lmax( 3 ) = knt
414 ninfo( 3 ) = ninfo( 3 ) + 1
415 GO TO 240
416 END IF
417 DO 140 i = 1, n
418 IF( stmp( i ).NE.dum( 1 ) )
419 $ vmax = one / eps
420 IF( septmp( i ).NE.sep( i ) )
421 $ vmax = one / eps
422 140 CONTINUE
423
424
425
426 DO 150 i = 1, n
427 SELECT( i ) = .true.
428 150 CONTINUE
429 CALL scopy( n, dum, 0, stmp, 1 )
430 CALL scopy( n, dum, 0, septmp, 1 )
431 CALL strsna(
'Bothcond',
'Some',
SELECT, n, t, ldt, le, ldt,
432 $ re, ldt, stmp, septmp, n, m, work, n, iwork,
433 $ info )
434 IF( info.NE.0 ) THEN
435 lmax( 3 ) = knt
436 ninfo( 3 ) = ninfo( 3 ) + 1
437 GO TO 240
438 END IF
439 DO 160 i = 1, n
440 IF( septmp( i ).NE.sep( i ) )
441 $ vmax = one / eps
442 IF( stmp( i ).NE.s( i ) )
443 $ vmax = one / eps
444 160 CONTINUE
445
446
447
448 CALL scopy( n, dum, 0, stmp, 1 )
449 CALL scopy( n, dum, 0, septmp, 1 )
450 CALL strsna(
'Eigcond',
'Some',
SELECT, n, t, ldt, le, ldt, re,
451 $ ldt, stmp, septmp, n, m, work, n, iwork, info )
452 IF( info.NE.0 ) THEN
453 lmax( 3 ) = knt
454 ninfo( 3 ) = ninfo( 3 ) + 1
455 GO TO 240
456 END IF
457 DO 170 i = 1, n
458 IF( stmp( i ).NE.s( i ) )
459 $ vmax = one / eps
460 IF( septmp( i ).NE.dum( 1 ) )
461 $ vmax = one / eps
462 170 CONTINUE
463
464
465
466 CALL scopy( n, dum, 0, stmp, 1 )
467 CALL scopy( n, dum, 0, septmp, 1 )
468 CALL strsna(
'Veccond',
'Some',
SELECT, n, t, ldt, le, ldt, re,
469 $ ldt, stmp, septmp, n, m, work, n, iwork, info )
470 IF( info.NE.0 ) THEN
471 lmax( 3 ) = knt
472 ninfo( 3 ) = ninfo( 3 ) + 1
473 GO TO 240
474 END IF
475 DO 180 i = 1, n
476 IF( stmp( i ).NE.dum( 1 ) )
477 $ vmax = one / eps
478 IF( septmp( i ).NE.sep( i ) )
479 $ vmax = one / eps
480 180 CONTINUE
481 IF( vmax.GT.rmax( 1 ) ) THEN
482 rmax( 1 ) = vmax
483 IF( ninfo( 1 ).EQ.0 )
484 $ lmax( 1 ) = knt
485 END IF
486
487
488
489 IF( wi( 1 ).EQ.zero ) THEN
490 lcmp( 1 ) = 1
491 ifnd = 0
492 DO 190 i = 2, n
493 IF( ifnd.EQ.1 .OR. wi( i ).EQ.zero ) THEN
494 SELECT( i ) = .false.
495 ELSE
496 ifnd = 1
497 lcmp( 2 ) = i
498 lcmp( 3 ) = i + 1
499 CALL scopy( n, re( 1, i ), 1, re( 1, 2 ), 1 )
500 CALL scopy( n, re( 1, i+1 ), 1, re( 1, 3 ), 1 )
501 CALL scopy( n, le( 1, i ), 1, le( 1, 2 ), 1 )
502 CALL scopy( n, le( 1, i+1 ), 1, le( 1, 3 ), 1 )
503 END IF
504 190 CONTINUE
505 IF( ifnd.EQ.0 ) THEN
506 icmp = 1
507 ELSE
508 icmp = 3
509 END IF
510 ELSE
511 lcmp( 1 ) = 1
512 lcmp( 2 ) = 2
513 ifnd = 0
514 DO 200 i = 3, n
515 IF( ifnd.EQ.1 .OR. wi( i ).NE.zero ) THEN
516 SELECT( i ) = .false.
517 ELSE
518 lcmp( 3 ) = i
519 ifnd = 1
520 CALL scopy( n, re( 1, i ), 1, re( 1, 3 ), 1 )
521 CALL scopy( n, le( 1, i ), 1, le( 1, 3 ), 1 )
522 END IF
523 200 CONTINUE
524 IF( ifnd.EQ.0 ) THEN
525 icmp = 2
526 ELSE
527 icmp = 3
528 END IF
529 END IF
530
531
532
533 CALL scopy( icmp, dum, 0, stmp, 1 )
534 CALL scopy( icmp, dum, 0, septmp, 1 )
535 CALL strsna(
'Bothcond',
'Some',
SELECT, n, t, ldt, le, ldt,
536 $ re, ldt, stmp, septmp, n, m, work, n, iwork,
537 $ info )
538 IF( info.NE.0 ) THEN
539 lmax( 3 ) = knt
540 ninfo( 3 ) = ninfo( 3 ) + 1
541 GO TO 240
542 END IF
543 DO 210 i = 1, icmp
544 j = lcmp( i )
545 IF( septmp( i ).NE.sep( j ) )
546 $ vmax = one / eps
547 IF( stmp( i ).NE.s( j ) )
548 $ vmax = one / eps
549 210 CONTINUE
550
551
552
553 CALL scopy( icmp, dum, 0, stmp, 1 )
554 CALL scopy( icmp, dum, 0, septmp, 1 )
555 CALL strsna(
'Eigcond',
'Some',
SELECT, n, t, ldt, le, ldt, re,
556 $ ldt, stmp, septmp, n, m, work, n, iwork, info )
557 IF( info.NE.0 ) THEN
558 lmax( 3 ) = knt
559 ninfo( 3 ) = ninfo( 3 ) + 1
560 GO TO 240
561 END IF
562 DO 220 i = 1, icmp
563 j = lcmp( i )
564 IF( stmp( i ).NE.s( j ) )
565 $ vmax = one / eps
566 IF( septmp( i ).NE.dum( 1 ) )
567 $ vmax = one / eps
568 220 CONTINUE
569
570
571
572 CALL scopy( icmp, dum, 0, stmp, 1 )
573 CALL scopy( icmp, dum, 0, septmp, 1 )
574 CALL strsna(
'Veccond',
'Some',
SELECT, n, t, ldt, le, ldt, re,
575 $ ldt, stmp, septmp, n, m, work, n, iwork, info )
576 IF( info.NE.0 ) THEN
577 lmax( 3 ) = knt
578 ninfo( 3 ) = ninfo( 3 ) + 1
579 GO TO 240
580 END IF
581 DO 230 i = 1, icmp
582 j = lcmp( i )
583 IF( stmp( i ).NE.dum( 1 ) )
584 $ vmax = one / eps
585 IF( septmp( i ).NE.sep( j ) )
586 $ vmax = one / eps
587 230 CONTINUE
588 IF( vmax.GT.rmax( 1 ) ) THEN
589 rmax( 1 ) = vmax
590 IF( ninfo( 1 ).EQ.0 )
591 $ lmax( 1 ) = knt
592 END IF
593 240 CONTINUE
594 GO TO 10
595
596
597
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
subroutine sgehrd(n, ilo, ihi, a, lda, tau, work, lwork, info)
SGEHRD
subroutine shseqr(job, compz, n, ilo, ihi, h, ldh, wr, wi, z, ldz, work, lwork, info)
SHSEQR
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
real function slange(norm, m, n, a, lda, work)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine sscal(n, sa, sx, incx)
SSCAL
subroutine strevc(side, howmny, select, n, t, ldt, vl, ldvl, vr, ldvr, mm, m, work, info)
STREVC
subroutine strsna(job, howmny, select, n, t, ldt, vl, ldvl, vr, ldvr, s, sep, mm, m, work, ldwork, iwork, info)
STRSNA