00001 SUBROUTINE DBBCSD( JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS, M, P, Q,
00002 $ THETA, PHI, U1, LDU1, U2, LDU2, V1T, LDV1T,
00003 $ V2T, LDV2T, B11D, B11E, B12D, B12E, B21D, B21E,
00004 $ B22D, B22E, WORK, LWORK, INFO )
00005 IMPLICIT NONE
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 CHARACTER JOBU1, JOBU2, JOBV1T, JOBV2T, TRANS
00017 INTEGER INFO, LDU1, LDU2, LDV1T, LDV2T, LWORK, M, P, Q
00018
00019
00020 DOUBLE PRECISION B11D( * ), B11E( * ), B12D( * ), B12E( * ),
00021 $ B21D( * ), B21E( * ), B22D( * ), B22E( * ),
00022 $ PHI( * ), THETA( * ), WORK( * )
00023 DOUBLE PRECISION U1( LDU1, * ), U2( LDU2, * ), V1T( LDV1T, * ),
00024 $ V2T( LDV2T, * )
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
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 INTEGER MAXITR
00195 PARAMETER ( MAXITR = 6 )
00196 DOUBLE PRECISION HUNDRED, MEIGHTH, ONE, PIOVER2, TEN, ZERO
00197 PARAMETER ( HUNDRED = 100.0D0, MEIGHTH = -0.125D0,
00198 $ ONE = 1.0D0, PIOVER2 = 1.57079632679489662D0,
00199 $ TEN = 10.0D0, ZERO = 0.0D0 )
00200 DOUBLE PRECISION NEGONECOMPLEX
00201 PARAMETER ( NEGONECOMPLEX = -1.0D0 )
00202
00203
00204 LOGICAL COLMAJOR, LQUERY, RESTART11, RESTART12,
00205 $ RESTART21, RESTART22, WANTU1, WANTU2, WANTV1T,
00206 $ WANTV2T
00207 INTEGER I, IMIN, IMAX, ITER, IU1CS, IU1SN, IU2CS,
00208 $ IU2SN, IV1TCS, IV1TSN, IV2TCS, IV2TSN, J,
00209 $ LWORKMIN, LWORKOPT, MAXIT, MINI
00210 DOUBLE PRECISION B11BULGE, B12BULGE, B21BULGE, B22BULGE, DUMMY,
00211 $ EPS, MU, NU, R, SIGMA11, SIGMA21,
00212 $ TEMP, THETAMAX, THETAMIN, THRESH, TOL, TOLMUL,
00213 $ UNFL, X1, X2, Y1, Y2
00214
00215
00216 EXTERNAL DLASR, DSCAL, DSWAP, DLARTGP, DLARTGS, DLAS2,
00217 $ XERBLA
00218
00219
00220 DOUBLE PRECISION DLAMCH
00221 LOGICAL LSAME
00222 EXTERNAL LSAME, DLAMCH
00223
00224
00225 INTRINSIC ABS, ATAN2, COS, MAX, MIN, SIN, SQRT
00226
00227
00228
00229
00230
00231 INFO = 0
00232 LQUERY = LWORK .EQ. -1
00233 WANTU1 = LSAME( JOBU1, 'Y' )
00234 WANTU2 = LSAME( JOBU2, 'Y' )
00235 WANTV1T = LSAME( JOBV1T, 'Y' )
00236 WANTV2T = LSAME( JOBV2T, 'Y' )
00237 COLMAJOR = .NOT. LSAME( TRANS, 'T' )
00238
00239 IF( M .LT. 0 ) THEN
00240 INFO = -6
00241 ELSE IF( P .LT. 0 .OR. P .GT. M ) THEN
00242 INFO = -7
00243 ELSE IF( Q .LT. 0 .OR. Q .GT. M ) THEN
00244 INFO = -8
00245 ELSE IF( Q .GT. P .OR. Q .GT. M-P .OR. Q .GT. M-Q ) THEN
00246 INFO = -8
00247 ELSE IF( WANTU1 .AND. LDU1 .LT. P ) THEN
00248 INFO = -12
00249 ELSE IF( WANTU2 .AND. LDU2 .LT. M-P ) THEN
00250 INFO = -14
00251 ELSE IF( WANTV1T .AND. LDV1T .LT. Q ) THEN
00252 INFO = -16
00253 ELSE IF( WANTV2T .AND. LDV2T .LT. M-Q ) THEN
00254 INFO = -18
00255 END IF
00256
00257
00258
00259 IF( INFO .EQ. 0 .AND. Q .EQ. 0 ) THEN
00260 LWORKMIN = 1
00261 WORK(1) = LWORKMIN
00262 RETURN
00263 END IF
00264
00265
00266
00267 IF( INFO .EQ. 0 ) THEN
00268 IU1CS = 1
00269 IU1SN = IU1CS + Q
00270 IU2CS = IU1SN + Q
00271 IU2SN = IU2CS + Q
00272 IV1TCS = IU2SN + Q
00273 IV1TSN = IV1TCS + Q
00274 IV2TCS = IV1TSN + Q
00275 IV2TSN = IV2TCS + Q
00276 LWORKOPT = IV2TSN + Q - 1
00277 LWORKMIN = LWORKOPT
00278 WORK(1) = LWORKOPT
00279 IF( LWORK .LT. LWORKMIN .AND. .NOT. LQUERY ) THEN
00280 INFO = -28
00281 END IF
00282 END IF
00283
00284 IF( INFO .NE. 0 ) THEN
00285 CALL XERBLA( 'DBBCSD', -INFO )
00286 RETURN
00287 ELSE IF( LQUERY ) THEN
00288 RETURN
00289 END IF
00290
00291
00292
00293 EPS = DLAMCH( 'Epsilon' )
00294 UNFL = DLAMCH( 'Safe minimum' )
00295 TOLMUL = MAX( TEN, MIN( HUNDRED, EPS**MEIGHTH ) )
00296 TOL = TOLMUL*EPS
00297 THRESH = MAX( TOL, MAXITR*Q*Q*UNFL )
00298
00299
00300
00301 DO I = 1, Q
00302 IF( THETA(I) .LT. THRESH ) THEN
00303 THETA(I) = ZERO
00304 ELSE IF( THETA(I) .GT. PIOVER2-THRESH ) THEN
00305 THETA(I) = PIOVER2
00306 END IF
00307 END DO
00308 DO I = 1, Q-1
00309 IF( PHI(I) .LT. THRESH ) THEN
00310 PHI(I) = ZERO
00311 ELSE IF( PHI(I) .GT. PIOVER2-THRESH ) THEN
00312 PHI(I) = PIOVER2
00313 END IF
00314 END DO
00315
00316
00317
00318 IMAX = Q
00319 DO WHILE( ( IMAX .GT. 1 ) .AND. ( PHI(IMAX-1) .EQ. ZERO ) )
00320 IMAX = IMAX - 1
00321 END DO
00322 IMIN = IMAX - 1
00323 IF ( IMIN .GT. 1 ) THEN
00324 DO WHILE( PHI(IMIN-1) .NE. ZERO )
00325 IMIN = IMIN - 1
00326 IF ( IMIN .LE. 1 ) EXIT
00327 END DO
00328 END IF
00329
00330
00331
00332 MAXIT = MAXITR*Q*Q
00333 ITER = 0
00334
00335
00336
00337 DO WHILE( IMAX .GT. 1 )
00338
00339
00340
00341 B11D(IMIN) = COS( THETA(IMIN) )
00342 B21D(IMIN) = -SIN( THETA(IMIN) )
00343 DO I = IMIN, IMAX - 1
00344 B11E(I) = -SIN( THETA(I) ) * SIN( PHI(I) )
00345 B11D(I+1) = COS( THETA(I+1) ) * COS( PHI(I) )
00346 B12D(I) = SIN( THETA(I) ) * COS( PHI(I) )
00347 B12E(I) = COS( THETA(I+1) ) * SIN( PHI(I) )
00348 B21E(I) = -COS( THETA(I) ) * SIN( PHI(I) )
00349 B21D(I+1) = -SIN( THETA(I+1) ) * COS( PHI(I) )
00350 B22D(I) = COS( THETA(I) ) * COS( PHI(I) )
00351 B22E(I) = -SIN( THETA(I+1) ) * SIN( PHI(I) )
00352 END DO
00353 B12D(IMAX) = SIN( THETA(IMAX) )
00354 B22D(IMAX) = COS( THETA(IMAX) )
00355
00356
00357
00358 IF( ITER .GT. MAXIT ) THEN
00359 INFO = 0
00360 DO I = 1, Q
00361 IF( PHI(I) .NE. ZERO )
00362 $ INFO = INFO + 1
00363 END DO
00364 RETURN
00365 END IF
00366
00367 ITER = ITER + IMAX - IMIN
00368
00369
00370
00371 THETAMAX = THETA(IMIN)
00372 THETAMIN = THETA(IMIN)
00373 DO I = IMIN+1, IMAX
00374 IF( THETA(I) > THETAMAX )
00375 $ THETAMAX = THETA(I)
00376 IF( THETA(I) < THETAMIN )
00377 $ THETAMIN = THETA(I)
00378 END DO
00379
00380 IF( THETAMAX .GT. PIOVER2 - THRESH ) THEN
00381
00382
00383
00384
00385 MU = ZERO
00386 NU = ONE
00387
00388 ELSE IF( THETAMIN .LT. THRESH ) THEN
00389
00390
00391
00392
00393 MU = ONE
00394 NU = ZERO
00395
00396 ELSE
00397
00398
00399
00400 CALL DLAS2( B11D(IMAX-1), B11E(IMAX-1), B11D(IMAX), SIGMA11,
00401 $ DUMMY )
00402 CALL DLAS2( B21D(IMAX-1), B21E(IMAX-1), B21D(IMAX), SIGMA21,
00403 $ DUMMY )
00404
00405 IF( SIGMA11 .LE. SIGMA21 ) THEN
00406 MU = SIGMA11
00407 NU = SQRT( ONE - MU**2 )
00408 IF( MU .LT. THRESH ) THEN
00409 MU = ZERO
00410 NU = ONE
00411 END IF
00412 ELSE
00413 NU = SIGMA21
00414 MU = SQRT( 1.0 - NU**2 )
00415 IF( NU .LT. THRESH ) THEN
00416 MU = ONE
00417 NU = ZERO
00418 END IF
00419 END IF
00420 END IF
00421
00422
00423
00424 IF( MU .LE. NU ) THEN
00425 CALL DLARTGS( B11D(IMIN), B11E(IMIN), MU,
00426 $ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1) )
00427 ELSE
00428 CALL DLARTGS( B21D(IMIN), B21E(IMIN), NU,
00429 $ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1) )
00430 END IF
00431
00432 TEMP = WORK(IV1TCS+IMIN-1)*B11D(IMIN) +
00433 $ WORK(IV1TSN+IMIN-1)*B11E(IMIN)
00434 B11E(IMIN) = WORK(IV1TCS+IMIN-1)*B11E(IMIN) -
00435 $ WORK(IV1TSN+IMIN-1)*B11D(IMIN)
00436 B11D(IMIN) = TEMP
00437 B11BULGE = WORK(IV1TSN+IMIN-1)*B11D(IMIN+1)
00438 B11D(IMIN+1) = WORK(IV1TCS+IMIN-1)*B11D(IMIN+1)
00439 TEMP = WORK(IV1TCS+IMIN-1)*B21D(IMIN) +
00440 $ WORK(IV1TSN+IMIN-1)*B21E(IMIN)
00441 B21E(IMIN) = WORK(IV1TCS+IMIN-1)*B21E(IMIN) -
00442 $ WORK(IV1TSN+IMIN-1)*B21D(IMIN)
00443 B21D(IMIN) = TEMP
00444 B21BULGE = WORK(IV1TSN+IMIN-1)*B21D(IMIN+1)
00445 B21D(IMIN+1) = WORK(IV1TCS+IMIN-1)*B21D(IMIN+1)
00446
00447
00448
00449 THETA( IMIN ) = ATAN2( SQRT( B21D(IMIN)**2+B21BULGE**2 ),
00450 $ SQRT( B11D(IMIN)**2+B11BULGE**2 ) )
00451
00452
00453
00454 IF( B11D(IMIN)**2+B11BULGE**2 .GT. THRESH**2 ) THEN
00455 CALL DLARTGP( B11BULGE, B11D(IMIN), WORK(IU1SN+IMIN-1),
00456 $ WORK(IU1CS+IMIN-1), R )
00457 ELSE IF( MU .LE. NU ) THEN
00458 CALL DLARTGS( B11E( IMIN ), B11D( IMIN + 1 ), MU,
00459 $ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1) )
00460 ELSE
00461 CALL DLARTGS( B12D( IMIN ), B12E( IMIN ), NU,
00462 $ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1) )
00463 END IF
00464 IF( B21D(IMIN)**2+B21BULGE**2 .GT. THRESH**2 ) THEN
00465 CALL DLARTGP( B21BULGE, B21D(IMIN), WORK(IU2SN+IMIN-1),
00466 $ WORK(IU2CS+IMIN-1), R )
00467 ELSE IF( NU .LT. MU ) THEN
00468 CALL DLARTGS( B21E( IMIN ), B21D( IMIN + 1 ), NU,
00469 $ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1) )
00470 ELSE
00471 CALL DLARTGS( B22D(IMIN), B22E(IMIN), MU,
00472 $ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1) )
00473 END IF
00474 WORK(IU2CS+IMIN-1) = -WORK(IU2CS+IMIN-1)
00475 WORK(IU2SN+IMIN-1) = -WORK(IU2SN+IMIN-1)
00476
00477 TEMP = WORK(IU1CS+IMIN-1)*B11E(IMIN) +
00478 $ WORK(IU1SN+IMIN-1)*B11D(IMIN+1)
00479 B11D(IMIN+1) = WORK(IU1CS+IMIN-1)*B11D(IMIN+1) -
00480 $ WORK(IU1SN+IMIN-1)*B11E(IMIN)
00481 B11E(IMIN) = TEMP
00482 IF( IMAX .GT. IMIN+1 ) THEN
00483 B11BULGE = WORK(IU1SN+IMIN-1)*B11E(IMIN+1)
00484 B11E(IMIN+1) = WORK(IU1CS+IMIN-1)*B11E(IMIN+1)
00485 END IF
00486 TEMP = WORK(IU1CS+IMIN-1)*B12D(IMIN) +
00487 $ WORK(IU1SN+IMIN-1)*B12E(IMIN)
00488 B12E(IMIN) = WORK(IU1CS+IMIN-1)*B12E(IMIN) -
00489 $ WORK(IU1SN+IMIN-1)*B12D(IMIN)
00490 B12D(IMIN) = TEMP
00491 B12BULGE = WORK(IU1SN+IMIN-1)*B12D(IMIN+1)
00492 B12D(IMIN+1) = WORK(IU1CS+IMIN-1)*B12D(IMIN+1)
00493 TEMP = WORK(IU2CS+IMIN-1)*B21E(IMIN) +
00494 $ WORK(IU2SN+IMIN-1)*B21D(IMIN+1)
00495 B21D(IMIN+1) = WORK(IU2CS+IMIN-1)*B21D(IMIN+1) -
00496 $ WORK(IU2SN+IMIN-1)*B21E(IMIN)
00497 B21E(IMIN) = TEMP
00498 IF( IMAX .GT. IMIN+1 ) THEN
00499 B21BULGE = WORK(IU2SN+IMIN-1)*B21E(IMIN+1)
00500 B21E(IMIN+1) = WORK(IU2CS+IMIN-1)*B21E(IMIN+1)
00501 END IF
00502 TEMP = WORK(IU2CS+IMIN-1)*B22D(IMIN) +
00503 $ WORK(IU2SN+IMIN-1)*B22E(IMIN)
00504 B22E(IMIN) = WORK(IU2CS+IMIN-1)*B22E(IMIN) -
00505 $ WORK(IU2SN+IMIN-1)*B22D(IMIN)
00506 B22D(IMIN) = TEMP
00507 B22BULGE = WORK(IU2SN+IMIN-1)*B22D(IMIN+1)
00508 B22D(IMIN+1) = WORK(IU2CS+IMIN-1)*B22D(IMIN+1)
00509
00510
00511
00512
00513
00514 DO I = IMIN+1, IMAX-1
00515
00516
00517
00518 X1 = SIN(THETA(I-1))*B11E(I-1) + COS(THETA(I-1))*B21E(I-1)
00519 X2 = SIN(THETA(I-1))*B11BULGE + COS(THETA(I-1))*B21BULGE
00520 Y1 = SIN(THETA(I-1))*B12D(I-1) + COS(THETA(I-1))*B22D(I-1)
00521 Y2 = SIN(THETA(I-1))*B12BULGE + COS(THETA(I-1))*B22BULGE
00522
00523 PHI(I-1) = ATAN2( SQRT(X1**2+X2**2), SQRT(Y1**2+Y2**2) )
00524
00525
00526
00527
00528 RESTART11 = B11E(I-1)**2 + B11BULGE**2 .LE. THRESH**2
00529 RESTART21 = B21E(I-1)**2 + B21BULGE**2 .LE. THRESH**2
00530 RESTART12 = B12D(I-1)**2 + B12BULGE**2 .LE. THRESH**2
00531 RESTART22 = B22D(I-1)**2 + B22BULGE**2 .LE. THRESH**2
00532
00533
00534
00535
00536
00537 IF( .NOT. RESTART11 .AND. .NOT. RESTART21 ) THEN
00538 CALL DLARTGP( X2, X1, WORK(IV1TSN+I-1), WORK(IV1TCS+I-1),
00539 $ R )
00540 ELSE IF( .NOT. RESTART11 .AND. RESTART21 ) THEN
00541 CALL DLARTGP( B11BULGE, B11E(I-1), WORK(IV1TSN+I-1),
00542 $ WORK(IV1TCS+I-1), R )
00543 ELSE IF( RESTART11 .AND. .NOT. RESTART21 ) THEN
00544 CALL DLARTGP( B21BULGE, B21E(I-1), WORK(IV1TSN+I-1),
00545 $ WORK(IV1TCS+I-1), R )
00546 ELSE IF( MU .LE. NU ) THEN
00547 CALL DLARTGS( B11D(I), B11E(I), MU, WORK(IV1TCS+I-1),
00548 $ WORK(IV1TSN+I-1) )
00549 ELSE
00550 CALL DLARTGS( B21D(I), B21E(I), NU, WORK(IV1TCS+I-1),
00551 $ WORK(IV1TSN+I-1) )
00552 END IF
00553 WORK(IV1TCS+I-1) = -WORK(IV1TCS+I-1)
00554 WORK(IV1TSN+I-1) = -WORK(IV1TSN+I-1)
00555 IF( .NOT. RESTART12 .AND. .NOT. RESTART22 ) THEN
00556 CALL DLARTGP( Y2, Y1, WORK(IV2TSN+I-1-1),
00557 $ WORK(IV2TCS+I-1-1), R )
00558 ELSE IF( .NOT. RESTART12 .AND. RESTART22 ) THEN
00559 CALL DLARTGP( B12BULGE, B12D(I-1), WORK(IV2TSN+I-1-1),
00560 $ WORK(IV2TCS+I-1-1), R )
00561 ELSE IF( RESTART12 .AND. .NOT. RESTART22 ) THEN
00562 CALL DLARTGP( B22BULGE, B22D(I-1), WORK(IV2TSN+I-1-1),
00563 $ WORK(IV2TCS+I-1-1), R )
00564 ELSE IF( NU .LT. MU ) THEN
00565 CALL DLARTGS( B12E(I-1), B12D(I), NU, WORK(IV2TCS+I-1-1),
00566 $ WORK(IV2TSN+I-1-1) )
00567 ELSE
00568 CALL DLARTGS( B22E(I-1), B22D(I), MU, WORK(IV2TCS+I-1-1),
00569 $ WORK(IV2TSN+I-1-1) )
00570 END IF
00571
00572 TEMP = WORK(IV1TCS+I-1)*B11D(I) + WORK(IV1TSN+I-1)*B11E(I)
00573 B11E(I) = WORK(IV1TCS+I-1)*B11E(I) -
00574 $ WORK(IV1TSN+I-1)*B11D(I)
00575 B11D(I) = TEMP
00576 B11BULGE = WORK(IV1TSN+I-1)*B11D(I+1)
00577 B11D(I+1) = WORK(IV1TCS+I-1)*B11D(I+1)
00578 TEMP = WORK(IV1TCS+I-1)*B21D(I) + WORK(IV1TSN+I-1)*B21E(I)
00579 B21E(I) = WORK(IV1TCS+I-1)*B21E(I) -
00580 $ WORK(IV1TSN+I-1)*B21D(I)
00581 B21D(I) = TEMP
00582 B21BULGE = WORK(IV1TSN+I-1)*B21D(I+1)
00583 B21D(I+1) = WORK(IV1TCS+I-1)*B21D(I+1)
00584 TEMP = WORK(IV2TCS+I-1-1)*B12E(I-1) +
00585 $ WORK(IV2TSN+I-1-1)*B12D(I)
00586 B12D(I) = WORK(IV2TCS+I-1-1)*B12D(I) -
00587 $ WORK(IV2TSN+I-1-1)*B12E(I-1)
00588 B12E(I-1) = TEMP
00589 B12BULGE = WORK(IV2TSN+I-1-1)*B12E(I)
00590 B12E(I) = WORK(IV2TCS+I-1-1)*B12E(I)
00591 TEMP = WORK(IV2TCS+I-1-1)*B22E(I-1) +
00592 $ WORK(IV2TSN+I-1-1)*B22D(I)
00593 B22D(I) = WORK(IV2TCS+I-1-1)*B22D(I) -
00594 $ WORK(IV2TSN+I-1-1)*B22E(I-1)
00595 B22E(I-1) = TEMP
00596 B22BULGE = WORK(IV2TSN+I-1-1)*B22E(I)
00597 B22E(I) = WORK(IV2TCS+I-1-1)*B22E(I)
00598
00599
00600
00601 X1 = COS(PHI(I-1))*B11D(I) + SIN(PHI(I-1))*B12E(I-1)
00602 X2 = COS(PHI(I-1))*B11BULGE + SIN(PHI(I-1))*B12BULGE
00603 Y1 = COS(PHI(I-1))*B21D(I) + SIN(PHI(I-1))*B22E(I-1)
00604 Y2 = COS(PHI(I-1))*B21BULGE + SIN(PHI(I-1))*B22BULGE
00605
00606 THETA(I) = ATAN2( SQRT(Y1**2+Y2**2), SQRT(X1**2+X2**2) )
00607
00608
00609
00610
00611 RESTART11 = B11D(I)**2 + B11BULGE**2 .LE. THRESH**2
00612 RESTART12 = B12E(I-1)**2 + B12BULGE**2 .LE. THRESH**2
00613 RESTART21 = B21D(I)**2 + B21BULGE**2 .LE. THRESH**2
00614 RESTART22 = B22E(I-1)**2 + B22BULGE**2 .LE. THRESH**2
00615
00616
00617
00618
00619
00620 IF( .NOT. RESTART11 .AND. .NOT. RESTART12 ) THEN
00621 CALL DLARTGP( X2, X1, WORK(IU1SN+I-1), WORK(IU1CS+I-1),
00622 $ R )
00623 ELSE IF( .NOT. RESTART11 .AND. RESTART12 ) THEN
00624 CALL DLARTGP( B11BULGE, B11D(I), WORK(IU1SN+I-1),
00625 $ WORK(IU1CS+I-1), R )
00626 ELSE IF( RESTART11 .AND. .NOT. RESTART12 ) THEN
00627 CALL DLARTGP( B12BULGE, B12E(I-1), WORK(IU1SN+I-1),
00628 $ WORK(IU1CS+I-1), R )
00629 ELSE IF( MU .LE. NU ) THEN
00630 CALL DLARTGS( B11E(I), B11D(I+1), MU, WORK(IU1CS+I-1),
00631 $ WORK(IU1SN+I-1) )
00632 ELSE
00633 CALL DLARTGS( B12D(I), B12E(I), NU, WORK(IU1CS+I-1),
00634 $ WORK(IU1SN+I-1) )
00635 END IF
00636 IF( .NOT. RESTART21 .AND. .NOT. RESTART22 ) THEN
00637 CALL DLARTGP( Y2, Y1, WORK(IU2SN+I-1), WORK(IU2CS+I-1),
00638 $ R )
00639 ELSE IF( .NOT. RESTART21 .AND. RESTART22 ) THEN
00640 CALL DLARTGP( B21BULGE, B21D(I), WORK(IU2SN+I-1),
00641 $ WORK(IU2CS+I-1), R )
00642 ELSE IF( RESTART21 .AND. .NOT. RESTART22 ) THEN
00643 CALL DLARTGP( B22BULGE, B22E(I-1), WORK(IU2SN+I-1),
00644 $ WORK(IU2CS+I-1), R )
00645 ELSE IF( NU .LT. MU ) THEN
00646 CALL DLARTGS( B21E(I), B21E(I+1), NU, WORK(IU2CS+I-1),
00647 $ WORK(IU2SN+I-1) )
00648 ELSE
00649 CALL DLARTGS( B22D(I), B22E(I), MU, WORK(IU2CS+I-1),
00650 $ WORK(IU2SN+I-1) )
00651 END IF
00652 WORK(IU2CS+I-1) = -WORK(IU2CS+I-1)
00653 WORK(IU2SN+I-1) = -WORK(IU2SN+I-1)
00654
00655 TEMP = WORK(IU1CS+I-1)*B11E(I) + WORK(IU1SN+I-1)*B11D(I+1)
00656 B11D(I+1) = WORK(IU1CS+I-1)*B11D(I+1) -
00657 $ WORK(IU1SN+I-1)*B11E(I)
00658 B11E(I) = TEMP
00659 IF( I .LT. IMAX - 1 ) THEN
00660 B11BULGE = WORK(IU1SN+I-1)*B11E(I+1)
00661 B11E(I+1) = WORK(IU1CS+I-1)*B11E(I+1)
00662 END IF
00663 TEMP = WORK(IU2CS+I-1)*B21E(I) + WORK(IU2SN+I-1)*B21D(I+1)
00664 B21D(I+1) = WORK(IU2CS+I-1)*B21D(I+1) -
00665 $ WORK(IU2SN+I-1)*B21E(I)
00666 B21E(I) = TEMP
00667 IF( I .LT. IMAX - 1 ) THEN
00668 B21BULGE = WORK(IU2SN+I-1)*B21E(I+1)
00669 B21E(I+1) = WORK(IU2CS+I-1)*B21E(I+1)
00670 END IF
00671 TEMP = WORK(IU1CS+I-1)*B12D(I) + WORK(IU1SN+I-1)*B12E(I)
00672 B12E(I) = WORK(IU1CS+I-1)*B12E(I) - WORK(IU1SN+I-1)*B12D(I)
00673 B12D(I) = TEMP
00674 B12BULGE = WORK(IU1SN+I-1)*B12D(I+1)
00675 B12D(I+1) = WORK(IU1CS+I-1)*B12D(I+1)
00676 TEMP = WORK(IU2CS+I-1)*B22D(I) + WORK(IU2SN+I-1)*B22E(I)
00677 B22E(I) = WORK(IU2CS+I-1)*B22E(I) - WORK(IU2SN+I-1)*B22D(I)
00678 B22D(I) = TEMP
00679 B22BULGE = WORK(IU2SN+I-1)*B22D(I+1)
00680 B22D(I+1) = WORK(IU2CS+I-1)*B22D(I+1)
00681
00682 END DO
00683
00684
00685
00686 X1 = SIN(THETA(IMAX-1))*B11E(IMAX-1) +
00687 $ COS(THETA(IMAX-1))*B21E(IMAX-1)
00688 Y1 = SIN(THETA(IMAX-1))*B12D(IMAX-1) +
00689 $ COS(THETA(IMAX-1))*B22D(IMAX-1)
00690 Y2 = SIN(THETA(IMAX-1))*B12BULGE + COS(THETA(IMAX-1))*B22BULGE
00691
00692 PHI(IMAX-1) = ATAN2( ABS(X1), SQRT(Y1**2+Y2**2) )
00693
00694
00695
00696 RESTART12 = B12D(IMAX-1)**2 + B12BULGE**2 .LE. THRESH**2
00697 RESTART22 = B22D(IMAX-1)**2 + B22BULGE**2 .LE. THRESH**2
00698
00699 IF( .NOT. RESTART12 .AND. .NOT. RESTART22 ) THEN
00700 CALL DLARTGP( Y2, Y1, WORK(IV2TSN+IMAX-1-1),
00701 $ WORK(IV2TCS+IMAX-1-1), R )
00702 ELSE IF( .NOT. RESTART12 .AND. RESTART22 ) THEN
00703 CALL DLARTGP( B12BULGE, B12D(IMAX-1), WORK(IV2TSN+IMAX-1-1),
00704 $ WORK(IV2TCS+IMAX-1-1), R )
00705 ELSE IF( RESTART12 .AND. .NOT. RESTART22 ) THEN
00706 CALL DLARTGP( B22BULGE, B22D(IMAX-1), WORK(IV2TSN+IMAX-1-1),
00707 $ WORK(IV2TCS+IMAX-1-1), R )
00708 ELSE IF( NU .LT. MU ) THEN
00709 CALL DLARTGS( B12E(IMAX-1), B12D(IMAX), NU,
00710 $ WORK(IV2TCS+IMAX-1-1), WORK(IV2TSN+IMAX-1-1) )
00711 ELSE
00712 CALL DLARTGS( B22E(IMAX-1), B22D(IMAX), MU,
00713 $ WORK(IV2TCS+IMAX-1-1), WORK(IV2TSN+IMAX-1-1) )
00714 END IF
00715
00716 TEMP = WORK(IV2TCS+IMAX-1-1)*B12E(IMAX-1) +
00717 $ WORK(IV2TSN+IMAX-1-1)*B12D(IMAX)
00718 B12D(IMAX) = WORK(IV2TCS+IMAX-1-1)*B12D(IMAX) -
00719 $ WORK(IV2TSN+IMAX-1-1)*B12E(IMAX-1)
00720 B12E(IMAX-1) = TEMP
00721 TEMP = WORK(IV2TCS+IMAX-1-1)*B22E(IMAX-1) +
00722 $ WORK(IV2TSN+IMAX-1-1)*B22D(IMAX)
00723 B22D(IMAX) = WORK(IV2TCS+IMAX-1-1)*B22D(IMAX) -
00724 $ WORK(IV2TSN+IMAX-1-1)*B22E(IMAX-1)
00725 B22E(IMAX-1) = TEMP
00726
00727
00728
00729 IF( WANTU1 ) THEN
00730 IF( COLMAJOR ) THEN
00731 CALL DLASR( 'R', 'V', 'F', P, IMAX-IMIN+1,
00732 $ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1),
00733 $ U1(1,IMIN), LDU1 )
00734 ELSE
00735 CALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, P,
00736 $ WORK(IU1CS+IMIN-1), WORK(IU1SN+IMIN-1),
00737 $ U1(IMIN,1), LDU1 )
00738 END IF
00739 END IF
00740 IF( WANTU2 ) THEN
00741 IF( COLMAJOR ) THEN
00742 CALL DLASR( 'R', 'V', 'F', M-P, IMAX-IMIN+1,
00743 $ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1),
00744 $ U2(1,IMIN), LDU2 )
00745 ELSE
00746 CALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, M-P,
00747 $ WORK(IU2CS+IMIN-1), WORK(IU2SN+IMIN-1),
00748 $ U2(IMIN,1), LDU2 )
00749 END IF
00750 END IF
00751 IF( WANTV1T ) THEN
00752 IF( COLMAJOR ) THEN
00753 CALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, Q,
00754 $ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1),
00755 $ V1T(IMIN,1), LDV1T )
00756 ELSE
00757 CALL DLASR( 'R', 'V', 'F', Q, IMAX-IMIN+1,
00758 $ WORK(IV1TCS+IMIN-1), WORK(IV1TSN+IMIN-1),
00759 $ V1T(1,IMIN), LDV1T )
00760 END IF
00761 END IF
00762 IF( WANTV2T ) THEN
00763 IF( COLMAJOR ) THEN
00764 CALL DLASR( 'L', 'V', 'F', IMAX-IMIN+1, M-Q,
00765 $ WORK(IV2TCS+IMIN-1), WORK(IV2TSN+IMIN-1),
00766 $ V2T(IMIN,1), LDV2T )
00767 ELSE
00768 CALL DLASR( 'R', 'V', 'F', M-Q, IMAX-IMIN+1,
00769 $ WORK(IV2TCS+IMIN-1), WORK(IV2TSN+IMIN-1),
00770 $ V2T(1,IMIN), LDV2T )
00771 END IF
00772 END IF
00773
00774
00775
00776 IF( B11E(IMAX-1)+B21E(IMAX-1) .GT. 0 ) THEN
00777 B11D(IMAX) = -B11D(IMAX)
00778 B21D(IMAX) = -B21D(IMAX)
00779 IF( WANTV1T ) THEN
00780 IF( COLMAJOR ) THEN
00781 CALL DSCAL( Q, NEGONECOMPLEX, V1T(IMAX,1), LDV1T )
00782 ELSE
00783 CALL DSCAL( Q, NEGONECOMPLEX, V1T(1,IMAX), 1 )
00784 END IF
00785 END IF
00786 END IF
00787
00788
00789
00790 X1 = COS(PHI(IMAX-1))*B11D(IMAX) +
00791 $ SIN(PHI(IMAX-1))*B12E(IMAX-1)
00792 Y1 = COS(PHI(IMAX-1))*B21D(IMAX) +
00793 $ SIN(PHI(IMAX-1))*B22E(IMAX-1)
00794
00795 THETA(IMAX) = ATAN2( ABS(Y1), ABS(X1) )
00796
00797
00798
00799
00800 IF( B11D(IMAX)+B12E(IMAX-1) .LT. 0 ) THEN
00801 B12D(IMAX) = -B12D(IMAX)
00802 IF( WANTU1 ) THEN
00803 IF( COLMAJOR ) THEN
00804 CALL DSCAL( P, NEGONECOMPLEX, U1(1,IMAX), 1 )
00805 ELSE
00806 CALL DSCAL( P, NEGONECOMPLEX, U1(IMAX,1), LDU1 )
00807 END IF
00808 END IF
00809 END IF
00810 IF( B21D(IMAX)+B22E(IMAX-1) .GT. 0 ) THEN
00811 B22D(IMAX) = -B22D(IMAX)
00812 IF( WANTU2 ) THEN
00813 IF( COLMAJOR ) THEN
00814 CALL DSCAL( M-P, NEGONECOMPLEX, U2(1,IMAX), 1 )
00815 ELSE
00816 CALL DSCAL( M-P, NEGONECOMPLEX, U2(IMAX,1), LDU2 )
00817 END IF
00818 END IF
00819 END IF
00820
00821
00822
00823 IF( B12D(IMAX)+B22D(IMAX) .LT. 0 ) THEN
00824 IF( WANTV2T ) THEN
00825 IF( COLMAJOR ) THEN
00826 CALL DSCAL( M-Q, NEGONECOMPLEX, V2T(IMAX,1), LDV2T )
00827 ELSE
00828 CALL DSCAL( M-Q, NEGONECOMPLEX, V2T(1,IMAX), 1 )
00829 END IF
00830 END IF
00831 END IF
00832
00833
00834
00835 DO I = IMIN, IMAX
00836 IF( THETA(I) .LT. THRESH ) THEN
00837 THETA(I) = ZERO
00838 ELSE IF( THETA(I) .GT. PIOVER2-THRESH ) THEN
00839 THETA(I) = PIOVER2
00840 END IF
00841 END DO
00842 DO I = IMIN, IMAX-1
00843 IF( PHI(I) .LT. THRESH ) THEN
00844 PHI(I) = ZERO
00845 ELSE IF( PHI(I) .GT. PIOVER2-THRESH ) THEN
00846 PHI(I) = PIOVER2
00847 END IF
00848 END DO
00849
00850
00851
00852 IF (IMAX .GT. 1) THEN
00853 DO WHILE( PHI(IMAX-1) .EQ. ZERO )
00854 IMAX = IMAX - 1
00855 IF (IMAX .LE. 1) EXIT
00856 END DO
00857 END IF
00858 IF( IMIN .GT. IMAX - 1 )
00859 $ IMIN = IMAX - 1
00860 IF (IMIN .GT. 1) THEN
00861 DO WHILE (PHI(IMIN-1) .NE. ZERO)
00862 IMIN = IMIN - 1
00863 IF (IMIN .LE. 1) EXIT
00864 END DO
00865 END IF
00866
00867
00868
00869 END DO
00870
00871
00872
00873 DO I = 1, Q
00874
00875 MINI = I
00876 THETAMIN = THETA(I)
00877 DO J = I+1, Q
00878 IF( THETA(J) .LT. THETAMIN ) THEN
00879 MINI = J
00880 THETAMIN = THETA(J)
00881 END IF
00882 END DO
00883
00884 IF( MINI .NE. I ) THEN
00885 THETA(MINI) = THETA(I)
00886 THETA(I) = THETAMIN
00887 IF( COLMAJOR ) THEN
00888 IF( WANTU1 )
00889 $ CALL DSWAP( P, U1(1,I), 1, U1(1,MINI), 1 )
00890 IF( WANTU2 )
00891 $ CALL DSWAP( M-P, U2(1,I), 1, U2(1,MINI), 1 )
00892 IF( WANTV1T )
00893 $ CALL DSWAP( Q, V1T(I,1), LDV1T, V1T(MINI,1), LDV1T )
00894 IF( WANTV2T )
00895 $ CALL DSWAP( M-Q, V2T(I,1), LDV2T, V2T(MINI,1),
00896 $ LDV2T )
00897 ELSE
00898 IF( WANTU1 )
00899 $ CALL DSWAP( P, U1(I,1), LDU1, U1(MINI,1), LDU1 )
00900 IF( WANTU2 )
00901 $ CALL DSWAP( M-P, U2(I,1), LDU2, U2(MINI,1), LDU2 )
00902 IF( WANTV1T )
00903 $ CALL DSWAP( Q, V1T(1,I), 1, V1T(1,MINI), 1 )
00904 IF( WANTV2T )
00905 $ CALL DSWAP( M-Q, V2T(1,I), 1, V2T(1,MINI), 1 )
00906 END IF
00907 END IF
00908
00909 END DO
00910
00911 RETURN
00912
00913
00914
00915 END
00916