00001 SUBROUTINE CBDSQR( UPLO, N, NCVT, NRU, NCC, D, E, VT, LDVT, U,
00002 $ LDU, C, LDC, RWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER UPLO
00011 INTEGER INFO, LDC, LDU, LDVT, N, NCC, NCVT, NRU
00012
00013
00014 REAL D( * ), E( * ), RWORK( * )
00015 COMPLEX C( LDC, * ), U( LDU, * ), VT( LDVT, * )
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 REAL ZERO
00148 PARAMETER ( ZERO = 0.0E0 )
00149 REAL ONE
00150 PARAMETER ( ONE = 1.0E0 )
00151 REAL NEGONE
00152 PARAMETER ( NEGONE = -1.0E0 )
00153 REAL HNDRTH
00154 PARAMETER ( HNDRTH = 0.01E0 )
00155 REAL TEN
00156 PARAMETER ( TEN = 10.0E0 )
00157 REAL HNDRD
00158 PARAMETER ( HNDRD = 100.0E0 )
00159 REAL MEIGTH
00160 PARAMETER ( MEIGTH = -0.125E0 )
00161 INTEGER MAXITR
00162 PARAMETER ( MAXITR = 6 )
00163
00164
00165 LOGICAL LOWER, ROTATE
00166 INTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1,
00167 $ NM12, NM13, OLDLL, OLDM
00168 REAL ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
00169 $ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
00170 $ SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
00171 $ SN, THRESH, TOL, TOLMUL, UNFL
00172
00173
00174 LOGICAL LSAME
00175 REAL SLAMCH
00176 EXTERNAL LSAME, SLAMCH
00177
00178
00179 EXTERNAL CLASR, CSROT, CSSCAL, CSWAP, SLARTG, SLAS2,
00180 $ SLASQ1, SLASV2, XERBLA
00181
00182
00183 INTRINSIC ABS, MAX, MIN, REAL, SIGN, SQRT
00184
00185
00186
00187
00188
00189 INFO = 0
00190 LOWER = LSAME( UPLO, 'L' )
00191 IF( .NOT.LSAME( UPLO, 'U' ) .AND. .NOT.LOWER ) THEN
00192 INFO = -1
00193 ELSE IF( N.LT.0 ) THEN
00194 INFO = -2
00195 ELSE IF( NCVT.LT.0 ) THEN
00196 INFO = -3
00197 ELSE IF( NRU.LT.0 ) THEN
00198 INFO = -4
00199 ELSE IF( NCC.LT.0 ) THEN
00200 INFO = -5
00201 ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
00202 $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
00203 INFO = -9
00204 ELSE IF( LDU.LT.MAX( 1, NRU ) ) THEN
00205 INFO = -11
00206 ELSE IF( ( NCC.EQ.0 .AND. LDC.LT.1 ) .OR.
00207 $ ( NCC.GT.0 .AND. LDC.LT.MAX( 1, N ) ) ) THEN
00208 INFO = -13
00209 END IF
00210 IF( INFO.NE.0 ) THEN
00211 CALL XERBLA( 'CBDSQR', -INFO )
00212 RETURN
00213 END IF
00214 IF( N.EQ.0 )
00215 $ RETURN
00216 IF( N.EQ.1 )
00217 $ GO TO 160
00218
00219
00220
00221 ROTATE = ( NCVT.GT.0 ) .OR. ( NRU.GT.0 ) .OR. ( NCC.GT.0 )
00222
00223
00224
00225 IF( .NOT.ROTATE ) THEN
00226 CALL SLASQ1( N, D, E, RWORK, INFO )
00227 RETURN
00228 END IF
00229
00230 NM1 = N - 1
00231 NM12 = NM1 + NM1
00232 NM13 = NM12 + NM1
00233 IDIR = 0
00234
00235
00236
00237 EPS = SLAMCH( 'Epsilon' )
00238 UNFL = SLAMCH( 'Safe minimum' )
00239
00240
00241
00242
00243 IF( LOWER ) THEN
00244 DO 10 I = 1, N - 1
00245 CALL SLARTG( D( I ), E( I ), CS, SN, R )
00246 D( I ) = R
00247 E( I ) = SN*D( I+1 )
00248 D( I+1 ) = CS*D( I+1 )
00249 RWORK( I ) = CS
00250 RWORK( NM1+I ) = SN
00251 10 CONTINUE
00252
00253
00254
00255 IF( NRU.GT.0 )
00256 $ CALL CLASR( 'R', 'V', 'F', NRU, N, RWORK( 1 ), RWORK( N ),
00257 $ U, LDU )
00258 IF( NCC.GT.0 )
00259 $ CALL CLASR( 'L', 'V', 'F', N, NCC, RWORK( 1 ), RWORK( N ),
00260 $ C, LDC )
00261 END IF
00262
00263
00264
00265
00266
00267 TOLMUL = MAX( TEN, MIN( HNDRD, EPS**MEIGTH ) )
00268 TOL = TOLMUL*EPS
00269
00270
00271
00272 SMAX = ZERO
00273 DO 20 I = 1, N
00274 SMAX = MAX( SMAX, ABS( D( I ) ) )
00275 20 CONTINUE
00276 DO 30 I = 1, N - 1
00277 SMAX = MAX( SMAX, ABS( E( I ) ) )
00278 30 CONTINUE
00279 SMINL = ZERO
00280 IF( TOL.GE.ZERO ) THEN
00281
00282
00283
00284 SMINOA = ABS( D( 1 ) )
00285 IF( SMINOA.EQ.ZERO )
00286 $ GO TO 50
00287 MU = SMINOA
00288 DO 40 I = 2, N
00289 MU = ABS( D( I ) )*( MU / ( MU+ABS( E( I-1 ) ) ) )
00290 SMINOA = MIN( SMINOA, MU )
00291 IF( SMINOA.EQ.ZERO )
00292 $ GO TO 50
00293 40 CONTINUE
00294 50 CONTINUE
00295 SMINOA = SMINOA / SQRT( REAL( N ) )
00296 THRESH = MAX( TOL*SMINOA, MAXITR*N*N*UNFL )
00297 ELSE
00298
00299
00300
00301 THRESH = MAX( ABS( TOL )*SMAX, MAXITR*N*N*UNFL )
00302 END IF
00303
00304
00305
00306
00307
00308 MAXIT = MAXITR*N*N
00309 ITER = 0
00310 OLDLL = -1
00311 OLDM = -1
00312
00313
00314
00315 M = N
00316
00317
00318
00319 60 CONTINUE
00320
00321
00322
00323 IF( M.LE.1 )
00324 $ GO TO 160
00325 IF( ITER.GT.MAXIT )
00326 $ GO TO 200
00327
00328
00329
00330 IF( TOL.LT.ZERO .AND. ABS( D( M ) ).LE.THRESH )
00331 $ D( M ) = ZERO
00332 SMAX = ABS( D( M ) )
00333 SMIN = SMAX
00334 DO 70 LLL = 1, M - 1
00335 LL = M - LLL
00336 ABSS = ABS( D( LL ) )
00337 ABSE = ABS( E( LL ) )
00338 IF( TOL.LT.ZERO .AND. ABSS.LE.THRESH )
00339 $ D( LL ) = ZERO
00340 IF( ABSE.LE.THRESH )
00341 $ GO TO 80
00342 SMIN = MIN( SMIN, ABSS )
00343 SMAX = MAX( SMAX, ABSS, ABSE )
00344 70 CONTINUE
00345 LL = 0
00346 GO TO 90
00347 80 CONTINUE
00348 E( LL ) = ZERO
00349
00350
00351
00352 IF( LL.EQ.M-1 ) THEN
00353
00354
00355
00356 M = M - 1
00357 GO TO 60
00358 END IF
00359 90 CONTINUE
00360 LL = LL + 1
00361
00362
00363
00364 IF( LL.EQ.M-1 ) THEN
00365
00366
00367
00368 CALL SLASV2( D( M-1 ), E( M-1 ), D( M ), SIGMN, SIGMX, SINR,
00369 $ COSR, SINL, COSL )
00370 D( M-1 ) = SIGMX
00371 E( M-1 ) = ZERO
00372 D( M ) = SIGMN
00373
00374
00375
00376 IF( NCVT.GT.0 )
00377 $ CALL CSROT( NCVT, VT( M-1, 1 ), LDVT, VT( M, 1 ), LDVT,
00378 $ COSR, SINR )
00379 IF( NRU.GT.0 )
00380 $ CALL CSROT( NRU, U( 1, M-1 ), 1, U( 1, M ), 1, COSL, SINL )
00381 IF( NCC.GT.0 )
00382 $ CALL CSROT( NCC, C( M-1, 1 ), LDC, C( M, 1 ), LDC, COSL,
00383 $ SINL )
00384 M = M - 2
00385 GO TO 60
00386 END IF
00387
00388
00389
00390
00391 IF( LL.GT.OLDM .OR. M.LT.OLDLL ) THEN
00392 IF( ABS( D( LL ) ).GE.ABS( D( M ) ) ) THEN
00393
00394
00395
00396 IDIR = 1
00397 ELSE
00398
00399
00400
00401 IDIR = 2
00402 END IF
00403 END IF
00404
00405
00406
00407 IF( IDIR.EQ.1 ) THEN
00408
00409
00410
00411
00412 IF( ABS( E( M-1 ) ).LE.ABS( TOL )*ABS( D( M ) ) .OR.
00413 $ ( TOL.LT.ZERO .AND. ABS( E( M-1 ) ).LE.THRESH ) ) THEN
00414 E( M-1 ) = ZERO
00415 GO TO 60
00416 END IF
00417
00418 IF( TOL.GE.ZERO ) THEN
00419
00420
00421
00422
00423 MU = ABS( D( LL ) )
00424 SMINL = MU
00425 DO 100 LLL = LL, M - 1
00426 IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
00427 E( LLL ) = ZERO
00428 GO TO 60
00429 END IF
00430 MU = ABS( D( LLL+1 ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
00431 SMINL = MIN( SMINL, MU )
00432 100 CONTINUE
00433 END IF
00434
00435 ELSE
00436
00437
00438
00439
00440 IF( ABS( E( LL ) ).LE.ABS( TOL )*ABS( D( LL ) ) .OR.
00441 $ ( TOL.LT.ZERO .AND. ABS( E( LL ) ).LE.THRESH ) ) THEN
00442 E( LL ) = ZERO
00443 GO TO 60
00444 END IF
00445
00446 IF( TOL.GE.ZERO ) THEN
00447
00448
00449
00450
00451 MU = ABS( D( M ) )
00452 SMINL = MU
00453 DO 110 LLL = M - 1, LL, -1
00454 IF( ABS( E( LLL ) ).LE.TOL*MU ) THEN
00455 E( LLL ) = ZERO
00456 GO TO 60
00457 END IF
00458 MU = ABS( D( LLL ) )*( MU / ( MU+ABS( E( LLL ) ) ) )
00459 SMINL = MIN( SMINL, MU )
00460 110 CONTINUE
00461 END IF
00462 END IF
00463 OLDLL = LL
00464 OLDM = M
00465
00466
00467
00468
00469 IF( TOL.GE.ZERO .AND. N*TOL*( SMINL / SMAX ).LE.
00470 $ MAX( EPS, HNDRTH*TOL ) ) THEN
00471
00472
00473
00474 SHIFT = ZERO
00475 ELSE
00476
00477
00478
00479 IF( IDIR.EQ.1 ) THEN
00480 SLL = ABS( D( LL ) )
00481 CALL SLAS2( D( M-1 ), E( M-1 ), D( M ), SHIFT, R )
00482 ELSE
00483 SLL = ABS( D( M ) )
00484 CALL SLAS2( D( LL ), E( LL ), D( LL+1 ), SHIFT, R )
00485 END IF
00486
00487
00488
00489 IF( SLL.GT.ZERO ) THEN
00490 IF( ( SHIFT / SLL )**2.LT.EPS )
00491 $ SHIFT = ZERO
00492 END IF
00493 END IF
00494
00495
00496
00497 ITER = ITER + M - LL
00498
00499
00500
00501 IF( SHIFT.EQ.ZERO ) THEN
00502 IF( IDIR.EQ.1 ) THEN
00503
00504
00505
00506
00507 CS = ONE
00508 OLDCS = ONE
00509 DO 120 I = LL, M - 1
00510 CALL SLARTG( D( I )*CS, E( I ), CS, SN, R )
00511 IF( I.GT.LL )
00512 $ E( I-1 ) = OLDSN*R
00513 CALL SLARTG( OLDCS*R, D( I+1 )*SN, OLDCS, OLDSN, D( I ) )
00514 RWORK( I-LL+1 ) = CS
00515 RWORK( I-LL+1+NM1 ) = SN
00516 RWORK( I-LL+1+NM12 ) = OLDCS
00517 RWORK( I-LL+1+NM13 ) = OLDSN
00518 120 CONTINUE
00519 H = D( M )*CS
00520 D( M ) = H*OLDCS
00521 E( M-1 ) = H*OLDSN
00522
00523
00524
00525 IF( NCVT.GT.0 )
00526 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
00527 $ RWORK( N ), VT( LL, 1 ), LDVT )
00528 IF( NRU.GT.0 )
00529 $ CALL CLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
00530 $ RWORK( NM13+1 ), U( 1, LL ), LDU )
00531 IF( NCC.GT.0 )
00532 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
00533 $ RWORK( NM13+1 ), C( LL, 1 ), LDC )
00534
00535
00536
00537 IF( ABS( E( M-1 ) ).LE.THRESH )
00538 $ E( M-1 ) = ZERO
00539
00540 ELSE
00541
00542
00543
00544
00545 CS = ONE
00546 OLDCS = ONE
00547 DO 130 I = M, LL + 1, -1
00548 CALL SLARTG( D( I )*CS, E( I-1 ), CS, SN, R )
00549 IF( I.LT.M )
00550 $ E( I ) = OLDSN*R
00551 CALL SLARTG( OLDCS*R, D( I-1 )*SN, OLDCS, OLDSN, D( I ) )
00552 RWORK( I-LL ) = CS
00553 RWORK( I-LL+NM1 ) = -SN
00554 RWORK( I-LL+NM12 ) = OLDCS
00555 RWORK( I-LL+NM13 ) = -OLDSN
00556 130 CONTINUE
00557 H = D( LL )*CS
00558 D( LL ) = H*OLDCS
00559 E( LL ) = H*OLDSN
00560
00561
00562
00563 IF( NCVT.GT.0 )
00564 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
00565 $ RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
00566 IF( NRU.GT.0 )
00567 $ CALL CLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
00568 $ RWORK( N ), U( 1, LL ), LDU )
00569 IF( NCC.GT.0 )
00570 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
00571 $ RWORK( N ), C( LL, 1 ), LDC )
00572
00573
00574
00575 IF( ABS( E( LL ) ).LE.THRESH )
00576 $ E( LL ) = ZERO
00577 END IF
00578 ELSE
00579
00580
00581
00582 IF( IDIR.EQ.1 ) THEN
00583
00584
00585
00586
00587 F = ( ABS( D( LL ) )-SHIFT )*
00588 $ ( SIGN( ONE, D( LL ) )+SHIFT / D( LL ) )
00589 G = E( LL )
00590 DO 140 I = LL, M - 1
00591 CALL SLARTG( F, G, COSR, SINR, R )
00592 IF( I.GT.LL )
00593 $ E( I-1 ) = R
00594 F = COSR*D( I ) + SINR*E( I )
00595 E( I ) = COSR*E( I ) - SINR*D( I )
00596 G = SINR*D( I+1 )
00597 D( I+1 ) = COSR*D( I+1 )
00598 CALL SLARTG( F, G, COSL, SINL, R )
00599 D( I ) = R
00600 F = COSL*E( I ) + SINL*D( I+1 )
00601 D( I+1 ) = COSL*D( I+1 ) - SINL*E( I )
00602 IF( I.LT.M-1 ) THEN
00603 G = SINL*E( I+1 )
00604 E( I+1 ) = COSL*E( I+1 )
00605 END IF
00606 RWORK( I-LL+1 ) = COSR
00607 RWORK( I-LL+1+NM1 ) = SINR
00608 RWORK( I-LL+1+NM12 ) = COSL
00609 RWORK( I-LL+1+NM13 ) = SINL
00610 140 CONTINUE
00611 E( M-1 ) = F
00612
00613
00614
00615 IF( NCVT.GT.0 )
00616 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCVT, RWORK( 1 ),
00617 $ RWORK( N ), VT( LL, 1 ), LDVT )
00618 IF( NRU.GT.0 )
00619 $ CALL CLASR( 'R', 'V', 'F', NRU, M-LL+1, RWORK( NM12+1 ),
00620 $ RWORK( NM13+1 ), U( 1, LL ), LDU )
00621 IF( NCC.GT.0 )
00622 $ CALL CLASR( 'L', 'V', 'F', M-LL+1, NCC, RWORK( NM12+1 ),
00623 $ RWORK( NM13+1 ), C( LL, 1 ), LDC )
00624
00625
00626
00627 IF( ABS( E( M-1 ) ).LE.THRESH )
00628 $ E( M-1 ) = ZERO
00629
00630 ELSE
00631
00632
00633
00634
00635 F = ( ABS( D( M ) )-SHIFT )*( SIGN( ONE, D( M ) )+SHIFT /
00636 $ D( M ) )
00637 G = E( M-1 )
00638 DO 150 I = M, LL + 1, -1
00639 CALL SLARTG( F, G, COSR, SINR, R )
00640 IF( I.LT.M )
00641 $ E( I ) = R
00642 F = COSR*D( I ) + SINR*E( I-1 )
00643 E( I-1 ) = COSR*E( I-1 ) - SINR*D( I )
00644 G = SINR*D( I-1 )
00645 D( I-1 ) = COSR*D( I-1 )
00646 CALL SLARTG( F, G, COSL, SINL, R )
00647 D( I ) = R
00648 F = COSL*E( I-1 ) + SINL*D( I-1 )
00649 D( I-1 ) = COSL*D( I-1 ) - SINL*E( I-1 )
00650 IF( I.GT.LL+1 ) THEN
00651 G = SINL*E( I-2 )
00652 E( I-2 ) = COSL*E( I-2 )
00653 END IF
00654 RWORK( I-LL ) = COSR
00655 RWORK( I-LL+NM1 ) = -SINR
00656 RWORK( I-LL+NM12 ) = COSL
00657 RWORK( I-LL+NM13 ) = -SINL
00658 150 CONTINUE
00659 E( LL ) = F
00660
00661
00662
00663 IF( ABS( E( LL ) ).LE.THRESH )
00664 $ E( LL ) = ZERO
00665
00666
00667
00668 IF( NCVT.GT.0 )
00669 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCVT, RWORK( NM12+1 ),
00670 $ RWORK( NM13+1 ), VT( LL, 1 ), LDVT )
00671 IF( NRU.GT.0 )
00672 $ CALL CLASR( 'R', 'V', 'B', NRU, M-LL+1, RWORK( 1 ),
00673 $ RWORK( N ), U( 1, LL ), LDU )
00674 IF( NCC.GT.0 )
00675 $ CALL CLASR( 'L', 'V', 'B', M-LL+1, NCC, RWORK( 1 ),
00676 $ RWORK( N ), C( LL, 1 ), LDC )
00677 END IF
00678 END IF
00679
00680
00681
00682 GO TO 60
00683
00684
00685
00686 160 CONTINUE
00687 DO 170 I = 1, N
00688 IF( D( I ).LT.ZERO ) THEN
00689 D( I ) = -D( I )
00690
00691
00692
00693 IF( NCVT.GT.0 )
00694 $ CALL CSSCAL( NCVT, NEGONE, VT( I, 1 ), LDVT )
00695 END IF
00696 170 CONTINUE
00697
00698
00699
00700
00701 DO 190 I = 1, N - 1
00702
00703
00704
00705 ISUB = 1
00706 SMIN = D( 1 )
00707 DO 180 J = 2, N + 1 - I
00708 IF( D( J ).LE.SMIN ) THEN
00709 ISUB = J
00710 SMIN = D( J )
00711 END IF
00712 180 CONTINUE
00713 IF( ISUB.NE.N+1-I ) THEN
00714
00715
00716
00717 D( ISUB ) = D( N+1-I )
00718 D( N+1-I ) = SMIN
00719 IF( NCVT.GT.0 )
00720 $ CALL CSWAP( NCVT, VT( ISUB, 1 ), LDVT, VT( N+1-I, 1 ),
00721 $ LDVT )
00722 IF( NRU.GT.0 )
00723 $ CALL CSWAP( NRU, U( 1, ISUB ), 1, U( 1, N+1-I ), 1 )
00724 IF( NCC.GT.0 )
00725 $ CALL CSWAP( NCC, C( ISUB, 1 ), LDC, C( N+1-I, 1 ), LDC )
00726 END IF
00727 190 CONTINUE
00728 GO TO 220
00729
00730
00731
00732 200 CONTINUE
00733 INFO = 0
00734 DO 210 I = 1, N - 1
00735 IF( E( I ).NE.ZERO )
00736 $ INFO = INFO + 1
00737 210 CONTINUE
00738 220 CONTINUE
00739 RETURN
00740
00741
00742
00743 END