00001 SUBROUTINE DGSVJ1( JOBV, M, N, N1, A, LDA, D, SVA, MV, V, LDV,
00002 + EPS, SFMIN, TOL, NSWEEP, WORK, LWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 IMPLICIT NONE
00019
00020
00021 DOUBLE PRECISION EPS, SFMIN, TOL
00022 INTEGER INFO, LDA, LDV, LWORK, M, MV, N, N1, NSWEEP
00023 CHARACTER*1 JOBV
00024
00025
00026 DOUBLE PRECISION A( LDA, * ), D( N ), SVA( N ), V( LDV, * ),
00027 + WORK( LWORK )
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 DOUBLE PRECISION ZERO, HALF, ONE, TWO
00164 PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0,
00165 + TWO = 2.0D0 )
00166
00167
00168 DOUBLE PRECISION AAPP, AAPP0, AAPQ, AAQQ, APOAQ, AQOAP, BIG,
00169 + BIGTHETA, CS, LARGE, MXAAPQ, MXSINJ, ROOTBIG,
00170 + ROOTEPS, ROOTSFMIN, ROOTTOL, SMALL, SN, T,
00171 + TEMP1, THETA, THSIGN
00172 INTEGER BLSKIP, EMPTSW, i, ibr, igl, IERR, IJBLSK,
00173 + ISWROT, jbc, jgl, KBL, MVL, NOTROT, nblc, nblr,
00174 + p, PSKIPPED, q, ROWSKIP, SWBAND
00175 LOGICAL APPLV, ROTOK, RSVEC
00176
00177
00178 DOUBLE PRECISION FASTR( 5 )
00179
00180
00181 INTRINSIC DABS, DMAX1, DBLE, MIN0, DSIGN, DSQRT
00182
00183
00184 DOUBLE PRECISION DDOT, DNRM2
00185 INTEGER IDAMAX
00186 LOGICAL LSAME
00187 EXTERNAL IDAMAX, LSAME, DDOT, DNRM2
00188
00189
00190 EXTERNAL DAXPY, DCOPY, DLASCL, DLASSQ, DROTM, DSWAP
00191
00192
00193
00194
00195
00196 APPLV = LSAME( JOBV, 'A' )
00197 RSVEC = LSAME( JOBV, 'V' )
00198 IF( .NOT.( RSVEC .OR. APPLV .OR. LSAME( JOBV, 'N' ) ) ) THEN
00199 INFO = -1
00200 ELSE IF( M.LT.0 ) THEN
00201 INFO = -2
00202 ELSE IF( ( N.LT.0 ) .OR. ( N.GT.M ) ) THEN
00203 INFO = -3
00204 ELSE IF( N1.LT.0 ) THEN
00205 INFO = -4
00206 ELSE IF( LDA.LT.M ) THEN
00207 INFO = -6
00208 ELSE IF( MV.LT.0 ) THEN
00209 INFO = -9
00210 ELSE IF( LDV.LT.M ) THEN
00211 INFO = -11
00212 ELSE IF( TOL.LE.EPS ) THEN
00213 INFO = -14
00214 ELSE IF( NSWEEP.LT.0 ) THEN
00215 INFO = -15
00216 ELSE IF( LWORK.LT.M ) THEN
00217 INFO = -17
00218 ELSE
00219 INFO = 0
00220 END IF
00221
00222
00223 IF( INFO.NE.0 ) THEN
00224 CALL XERBLA( 'DGSVJ1', -INFO )
00225 RETURN
00226 END IF
00227
00228 IF( RSVEC ) THEN
00229 MVL = N
00230 ELSE IF( APPLV ) THEN
00231 MVL = MV
00232 END IF
00233 RSVEC = RSVEC .OR. APPLV
00234
00235 ROOTEPS = DSQRT( EPS )
00236 ROOTSFMIN = DSQRT( SFMIN )
00237 SMALL = SFMIN / EPS
00238 BIG = ONE / SFMIN
00239 ROOTBIG = ONE / ROOTSFMIN
00240 LARGE = BIG / DSQRT( DBLE( M*N ) )
00241 BIGTHETA = ONE / ROOTEPS
00242 ROOTTOL = DSQRT( TOL )
00243
00244
00245
00246
00247
00248 EMPTSW = N1*( N-N1 )
00249 NOTROT = 0
00250 FASTR( 1 ) = ZERO
00251
00252
00253
00254 KBL = MIN0( 8, N )
00255 NBLR = N1 / KBL
00256 IF( ( NBLR*KBL ).NE.N1 )NBLR = NBLR + 1
00257
00258
00259
00260 NBLC = ( N-N1 ) / KBL
00261 IF( ( NBLC*KBL ).NE.( N-N1 ) )NBLC = NBLC + 1
00262 BLSKIP = ( KBL**2 ) + 1
00263
00264
00265 ROWSKIP = MIN0( 5, KBL )
00266
00267 SWBAND = 0
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 DO 1993 i = 1, NSWEEP
00282
00283
00284 MXAAPQ = ZERO
00285 MXSINJ = ZERO
00286 ISWROT = 0
00287
00288 NOTROT = 0
00289 PSKIPPED = 0
00290
00291 DO 2000 ibr = 1, NBLR
00292
00293 igl = ( ibr-1 )*KBL + 1
00294
00295
00296
00297
00298
00299 igl = ( ibr-1 )*KBL + 1
00300
00301 DO 2010 jbc = 1, NBLC
00302
00303 jgl = N1 + ( jbc-1 )*KBL + 1
00304
00305
00306
00307 IJBLSK = 0
00308 DO 2100 p = igl, MIN0( igl+KBL-1, N1 )
00309
00310 AAPP = SVA( p )
00311
00312 IF( AAPP.GT.ZERO ) THEN
00313
00314 PSKIPPED = 0
00315
00316 DO 2200 q = jgl, MIN0( jgl+KBL-1, N )
00317
00318 AAQQ = SVA( q )
00319
00320 IF( AAQQ.GT.ZERO ) THEN
00321 AAPP0 = AAPP
00322
00323
00324
00325
00326
00327 IF( AAQQ.GE.ONE ) THEN
00328 IF( AAPP.GE.AAQQ ) THEN
00329 ROTOK = ( SMALL*AAPP ).LE.AAQQ
00330 ELSE
00331 ROTOK = ( SMALL*AAQQ ).LE.AAPP
00332 END IF
00333 IF( AAPP.LT.( BIG / AAQQ ) ) THEN
00334 AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,
00335 + q ), 1 )*D( p )*D( q ) / AAQQ )
00336 + / AAPP
00337 ELSE
00338 CALL DCOPY( M, A( 1, p ), 1, WORK, 1 )
00339 CALL DLASCL( 'G', 0, 0, AAPP, D( p ),
00340 + M, 1, WORK, LDA, IERR )
00341 AAPQ = DDOT( M, WORK, 1, A( 1, q ),
00342 + 1 )*D( q ) / AAQQ
00343 END IF
00344 ELSE
00345 IF( AAPP.GE.AAQQ ) THEN
00346 ROTOK = AAPP.LE.( AAQQ / SMALL )
00347 ELSE
00348 ROTOK = AAQQ.LE.( AAPP / SMALL )
00349 END IF
00350 IF( AAPP.GT.( SMALL / AAQQ ) ) THEN
00351 AAPQ = ( DDOT( M, A( 1, p ), 1, A( 1,
00352 + q ), 1 )*D( p )*D( q ) / AAQQ )
00353 + / AAPP
00354 ELSE
00355 CALL DCOPY( M, A( 1, q ), 1, WORK, 1 )
00356 CALL DLASCL( 'G', 0, 0, AAQQ, D( q ),
00357 + M, 1, WORK, LDA, IERR )
00358 AAPQ = DDOT( M, WORK, 1, A( 1, p ),
00359 + 1 )*D( p ) / AAPP
00360 END IF
00361 END IF
00362
00363 MXAAPQ = DMAX1( MXAAPQ, DABS( AAPQ ) )
00364
00365
00366
00367 IF( DABS( AAPQ ).GT.TOL ) THEN
00368 NOTROT = 0
00369
00370 PSKIPPED = 0
00371 ISWROT = ISWROT + 1
00372
00373 IF( ROTOK ) THEN
00374
00375 AQOAP = AAQQ / AAPP
00376 APOAQ = AAPP / AAQQ
00377 THETA = -HALF*DABS( AQOAP-APOAQ ) /
00378 + AAPQ
00379 IF( AAQQ.GT.AAPP0 )THETA = -THETA
00380
00381 IF( DABS( THETA ).GT.BIGTHETA ) THEN
00382 T = HALF / THETA
00383 FASTR( 3 ) = T*D( p ) / D( q )
00384 FASTR( 4 ) = -T*D( q ) / D( p )
00385 CALL DROTM( M, A( 1, p ), 1,
00386 + A( 1, q ), 1, FASTR )
00387 IF( RSVEC )CALL DROTM( MVL,
00388 + V( 1, p ), 1,
00389 + V( 1, q ), 1,
00390 + FASTR )
00391 SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO,
00392 + ONE+T*APOAQ*AAPQ ) )
00393 AAPP = AAPP*DSQRT( DMAX1( ZERO,
00394 + ONE-T*AQOAP*AAPQ ) )
00395 MXSINJ = DMAX1( MXSINJ, DABS( T ) )
00396 ELSE
00397
00398
00399
00400 THSIGN = -DSIGN( ONE, AAPQ )
00401 IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGN
00402 T = ONE / ( THETA+THSIGN*
00403 + DSQRT( ONE+THETA*THETA ) )
00404 CS = DSQRT( ONE / ( ONE+T*T ) )
00405 SN = T*CS
00406 MXSINJ = DMAX1( MXSINJ, DABS( SN ) )
00407 SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO,
00408 + ONE+T*APOAQ*AAPQ ) )
00409 AAPP = AAPP*DSQRT( ONE-T*AQOAP*
00410 + AAPQ )
00411
00412 APOAQ = D( p ) / D( q )
00413 AQOAP = D( q ) / D( p )
00414 IF( D( p ).GE.ONE ) THEN
00415
00416 IF( D( q ).GE.ONE ) THEN
00417 FASTR( 3 ) = T*APOAQ
00418 FASTR( 4 ) = -T*AQOAP
00419 D( p ) = D( p )*CS
00420 D( q ) = D( q )*CS
00421 CALL DROTM( M, A( 1, p ), 1,
00422 + A( 1, q ), 1,
00423 + FASTR )
00424 IF( RSVEC )CALL DROTM( MVL,
00425 + V( 1, p ), 1, V( 1, q ),
00426 + 1, FASTR )
00427 ELSE
00428 CALL DAXPY( M, -T*AQOAP,
00429 + A( 1, q ), 1,
00430 + A( 1, p ), 1 )
00431 CALL DAXPY( M, CS*SN*APOAQ,
00432 + A( 1, p ), 1,
00433 + A( 1, q ), 1 )
00434 IF( RSVEC ) THEN
00435 CALL DAXPY( MVL, -T*AQOAP,
00436 + V( 1, q ), 1,
00437 + V( 1, p ), 1 )
00438 CALL DAXPY( MVL,
00439 + CS*SN*APOAQ,
00440 + V( 1, p ), 1,
00441 + V( 1, q ), 1 )
00442 END IF
00443 D( p ) = D( p )*CS
00444 D( q ) = D( q ) / CS
00445 END IF
00446 ELSE
00447 IF( D( q ).GE.ONE ) THEN
00448 CALL DAXPY( M, T*APOAQ,
00449 + A( 1, p ), 1,
00450 + A( 1, q ), 1 )
00451 CALL DAXPY( M, -CS*SN*AQOAP,
00452 + A( 1, q ), 1,
00453 + A( 1, p ), 1 )
00454 IF( RSVEC ) THEN
00455 CALL DAXPY( MVL, T*APOAQ,
00456 + V( 1, p ), 1,
00457 + V( 1, q ), 1 )
00458 CALL DAXPY( MVL,
00459 + -CS*SN*AQOAP,
00460 + V( 1, q ), 1,
00461 + V( 1, p ), 1 )
00462 END IF
00463 D( p ) = D( p ) / CS
00464 D( q ) = D( q )*CS
00465 ELSE
00466 IF( D( p ).GE.D( q ) ) THEN
00467 CALL DAXPY( M, -T*AQOAP,
00468 + A( 1, q ), 1,
00469 + A( 1, p ), 1 )
00470 CALL DAXPY( M, CS*SN*APOAQ,
00471 + A( 1, p ), 1,
00472 + A( 1, q ), 1 )
00473 D( p ) = D( p )*CS
00474 D( q ) = D( q ) / CS
00475 IF( RSVEC ) THEN
00476 CALL DAXPY( MVL,
00477 + -T*AQOAP,
00478 + V( 1, q ), 1,
00479 + V( 1, p ), 1 )
00480 CALL DAXPY( MVL,
00481 + CS*SN*APOAQ,
00482 + V( 1, p ), 1,
00483 + V( 1, q ), 1 )
00484 END IF
00485 ELSE
00486 CALL DAXPY( M, T*APOAQ,
00487 + A( 1, p ), 1,
00488 + A( 1, q ), 1 )
00489 CALL DAXPY( M,
00490 + -CS*SN*AQOAP,
00491 + A( 1, q ), 1,
00492 + A( 1, p ), 1 )
00493 D( p ) = D( p ) / CS
00494 D( q ) = D( q )*CS
00495 IF( RSVEC ) THEN
00496 CALL DAXPY( MVL,
00497 + T*APOAQ, V( 1, p ),
00498 + 1, V( 1, q ), 1 )
00499 CALL DAXPY( MVL,
00500 + -CS*SN*AQOAP,
00501 + V( 1, q ), 1,
00502 + V( 1, p ), 1 )
00503 END IF
00504 END IF
00505 END IF
00506 END IF
00507 END IF
00508
00509 ELSE
00510 IF( AAPP.GT.AAQQ ) THEN
00511 CALL DCOPY( M, A( 1, p ), 1, WORK,
00512 + 1 )
00513 CALL DLASCL( 'G', 0, 0, AAPP, ONE,
00514 + M, 1, WORK, LDA, IERR )
00515 CALL DLASCL( 'G', 0, 0, AAQQ, ONE,
00516 + M, 1, A( 1, q ), LDA,
00517 + IERR )
00518 TEMP1 = -AAPQ*D( p ) / D( q )
00519 CALL DAXPY( M, TEMP1, WORK, 1,
00520 + A( 1, q ), 1 )
00521 CALL DLASCL( 'G', 0, 0, ONE, AAQQ,
00522 + M, 1, A( 1, q ), LDA,
00523 + IERR )
00524 SVA( q ) = AAQQ*DSQRT( DMAX1( ZERO,
00525 + ONE-AAPQ*AAPQ ) )
00526 MXSINJ = DMAX1( MXSINJ, SFMIN )
00527 ELSE
00528 CALL DCOPY( M, A( 1, q ), 1, WORK,
00529 + 1 )
00530 CALL DLASCL( 'G', 0, 0, AAQQ, ONE,
00531 + M, 1, WORK, LDA, IERR )
00532 CALL DLASCL( 'G', 0, 0, AAPP, ONE,
00533 + M, 1, A( 1, p ), LDA,
00534 + IERR )
00535 TEMP1 = -AAPQ*D( q ) / D( p )
00536 CALL DAXPY( M, TEMP1, WORK, 1,
00537 + A( 1, p ), 1 )
00538 CALL DLASCL( 'G', 0, 0, ONE, AAPP,
00539 + M, 1, A( 1, p ), LDA,
00540 + IERR )
00541 SVA( p ) = AAPP*DSQRT( DMAX1( ZERO,
00542 + ONE-AAPQ*AAPQ ) )
00543 MXSINJ = DMAX1( MXSINJ, SFMIN )
00544 END IF
00545 END IF
00546
00547
00548
00549
00550 IF( ( SVA( q ) / AAQQ )**2.LE.ROOTEPS )
00551 + THEN
00552 IF( ( AAQQ.LT.ROOTBIG ) .AND.
00553 + ( AAQQ.GT.ROOTSFMIN ) ) THEN
00554 SVA( q ) = DNRM2( M, A( 1, q ), 1 )*
00555 + D( q )
00556 ELSE
00557 T = ZERO
00558 AAQQ = ZERO
00559 CALL DLASSQ( M, A( 1, q ), 1, T,
00560 + AAQQ )
00561 SVA( q ) = T*DSQRT( AAQQ )*D( q )
00562 END IF
00563 END IF
00564 IF( ( AAPP / AAPP0 )**2.LE.ROOTEPS ) THEN
00565 IF( ( AAPP.LT.ROOTBIG ) .AND.
00566 + ( AAPP.GT.ROOTSFMIN ) ) THEN
00567 AAPP = DNRM2( M, A( 1, p ), 1 )*
00568 + D( p )
00569 ELSE
00570 T = ZERO
00571 AAPP = ZERO
00572 CALL DLASSQ( M, A( 1, p ), 1, T,
00573 + AAPP )
00574 AAPP = T*DSQRT( AAPP )*D( p )
00575 END IF
00576 SVA( p ) = AAPP
00577 END IF
00578
00579 ELSE
00580 NOTROT = NOTROT + 1
00581
00582 PSKIPPED = PSKIPPED + 1
00583 IJBLSK = IJBLSK + 1
00584 END IF
00585 ELSE
00586 NOTROT = NOTROT + 1
00587 PSKIPPED = PSKIPPED + 1
00588 IJBLSK = IJBLSK + 1
00589 END IF
00590
00591
00592 IF( ( i.LE.SWBAND ) .AND. ( IJBLSK.GE.BLSKIP ) )
00593 + THEN
00594 SVA( p ) = AAPP
00595 NOTROT = 0
00596 GO TO 2011
00597 END IF
00598 IF( ( i.LE.SWBAND ) .AND.
00599 + ( PSKIPPED.GT.ROWSKIP ) ) THEN
00600 AAPP = -AAPP
00601 NOTROT = 0
00602 GO TO 2203
00603 END IF
00604
00605
00606 2200 CONTINUE
00607
00608 2203 CONTINUE
00609
00610 SVA( p ) = AAPP
00611
00612 ELSE
00613 IF( AAPP.EQ.ZERO )NOTROT = NOTROT +
00614 + MIN0( jgl+KBL-1, N ) - jgl + 1
00615 IF( AAPP.LT.ZERO )NOTROT = 0
00616
00617 END IF
00618
00619 2100 CONTINUE
00620
00621 2010 CONTINUE
00622
00623 2011 CONTINUE
00624
00625 DO 2012 p = igl, MIN0( igl+KBL-1, N )
00626 SVA( p ) = DABS( SVA( p ) )
00627 2012 CONTINUE
00628
00629 2000 CONTINUE
00630
00631
00632
00633 IF( ( SVA( N ).LT.ROOTBIG ) .AND. ( SVA( N ).GT.ROOTSFMIN ) )
00634 + THEN
00635 SVA( N ) = DNRM2( M, A( 1, N ), 1 )*D( N )
00636 ELSE
00637 T = ZERO
00638 AAPP = ZERO
00639 CALL DLASSQ( M, A( 1, N ), 1, T, AAPP )
00640 SVA( N ) = T*DSQRT( AAPP )*D( N )
00641 END IF
00642
00643
00644
00645 IF( ( i.LT.SWBAND ) .AND. ( ( MXAAPQ.LE.ROOTTOL ) .OR.
00646 + ( ISWROT.LE.N ) ) )SWBAND = i
00647
00648 IF( ( i.GT.SWBAND+1 ) .AND. ( MXAAPQ.LT.DBLE( N )*TOL ) .AND.
00649 + ( DBLE( N )*MXAAPQ*MXSINJ.LT.TOL ) ) THEN
00650 GO TO 1994
00651 END IF
00652
00653
00654 IF( NOTROT.GE.EMPTSW )GO TO 1994
00655
00656 1993 CONTINUE
00657
00658
00659
00660 INFO = NSWEEP - 1
00661 GO TO 1995
00662 1994 CONTINUE
00663
00664
00665
00666 INFO = 0
00667
00668 1995 CONTINUE
00669
00670
00671
00672 DO 5991 p = 1, N - 1
00673 q = IDAMAX( N-p+1, SVA( p ), 1 ) + p - 1
00674 IF( p.NE.q ) THEN
00675 TEMP1 = SVA( p )
00676 SVA( p ) = SVA( q )
00677 SVA( q ) = TEMP1
00678 TEMP1 = D( p )
00679 D( p ) = D( q )
00680 D( q ) = TEMP1
00681 CALL DSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )
00682 IF( RSVEC )CALL DSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )
00683 END IF
00684 5991 CONTINUE
00685
00686 RETURN
00687
00688
00689
00690 END