00001 SUBROUTINE SGSVJ1( 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 REAL EPS, SFMIN, TOL
00022 INTEGER INFO, LDA, LDV, LWORK, M, MV, N, N1, NSWEEP
00023 CHARACTER*1 JOBV
00024
00025
00026 REAL 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 REAL ZERO, HALF, ONE, TWO
00164 PARAMETER ( ZERO = 0.0E0, HALF = 0.5E0, ONE = 1.0E0,
00165 + TWO = 2.0E0 )
00166
00167
00168 REAL 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 REAL FASTR( 5 )
00179
00180
00181 INTRINSIC ABS, AMAX1, FLOAT, MIN0, SIGN, SQRT
00182
00183
00184 REAL SDOT, SNRM2
00185 INTEGER ISAMAX
00186 LOGICAL LSAME
00187 EXTERNAL ISAMAX, LSAME, SDOT, SNRM2
00188
00189
00190 EXTERNAL SAXPY, SCOPY, SLASCL, SLASSQ, SROTM, SSWAP
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( ( RSVEC.OR.APPLV ) .AND. ( MV.LT.0 ) ) THEN
00209 INFO = -9
00210 ELSE IF( ( RSVEC.AND.( LDV.LT.N ) ).OR.
00211 & ( APPLV.AND.( LDV.LT.MV ) ) ) THEN
00212 INFO = -11
00213 ELSE IF( TOL.LE.EPS ) THEN
00214 INFO = -14
00215 ELSE IF( NSWEEP.LT.0 ) THEN
00216 INFO = -15
00217 ELSE IF( LWORK.LT.M ) THEN
00218 INFO = -17
00219 ELSE
00220 INFO = 0
00221 END IF
00222
00223
00224 IF( INFO.NE.0 ) THEN
00225 CALL XERBLA( 'SGSVJ1', -INFO )
00226 RETURN
00227 END IF
00228
00229 IF( RSVEC ) THEN
00230 MVL = N
00231 ELSE IF( APPLV ) THEN
00232 MVL = MV
00233 END IF
00234 RSVEC = RSVEC .OR. APPLV
00235
00236 ROOTEPS = SQRT( EPS )
00237 ROOTSFMIN = SQRT( SFMIN )
00238 SMALL = SFMIN / EPS
00239 BIG = ONE / SFMIN
00240 ROOTBIG = ONE / ROOTSFMIN
00241 LARGE = BIG / SQRT( FLOAT( M*N ) )
00242 BIGTHETA = ONE / ROOTEPS
00243 ROOTTOL = SQRT( TOL )
00244
00245
00246
00247
00248
00249 EMPTSW = N1*( N-N1 )
00250 NOTROT = 0
00251 FASTR( 1 ) = ZERO
00252
00253
00254
00255 KBL = MIN0( 8, N )
00256 NBLR = N1 / KBL
00257 IF( ( NBLR*KBL ).NE.N1 )NBLR = NBLR + 1
00258
00259
00260
00261 NBLC = ( N-N1 ) / KBL
00262 IF( ( NBLC*KBL ).NE.( N-N1 ) )NBLC = NBLC + 1
00263 BLSKIP = ( KBL**2 ) + 1
00264
00265
00266 ROWSKIP = MIN0( 5, KBL )
00267
00268 SWBAND = 0
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 DO 1993 i = 1, NSWEEP
00283
00284
00285 MXAAPQ = ZERO
00286 MXSINJ = ZERO
00287 ISWROT = 0
00288
00289 NOTROT = 0
00290 PSKIPPED = 0
00291
00292 DO 2000 ibr = 1, NBLR
00293
00294 igl = ( ibr-1 )*KBL + 1
00295
00296
00297
00298
00299
00300 igl = ( ibr-1 )*KBL + 1
00301
00302 DO 2010 jbc = 1, NBLC
00303
00304 jgl = N1 + ( jbc-1 )*KBL + 1
00305
00306
00307
00308 IJBLSK = 0
00309 DO 2100 p = igl, MIN0( igl+KBL-1, N1 )
00310
00311 AAPP = SVA( p )
00312
00313 IF( AAPP.GT.ZERO ) THEN
00314
00315 PSKIPPED = 0
00316
00317 DO 2200 q = jgl, MIN0( jgl+KBL-1, N )
00318
00319 AAQQ = SVA( q )
00320
00321 IF( AAQQ.GT.ZERO ) THEN
00322 AAPP0 = AAPP
00323
00324
00325
00326
00327
00328 IF( AAQQ.GE.ONE ) THEN
00329 IF( AAPP.GE.AAQQ ) THEN
00330 ROTOK = ( SMALL*AAPP ).LE.AAQQ
00331 ELSE
00332 ROTOK = ( SMALL*AAQQ ).LE.AAPP
00333 END IF
00334 IF( AAPP.LT.( BIG / AAQQ ) ) THEN
00335 AAPQ = ( SDOT( M, A( 1, p ), 1, A( 1,
00336 + q ), 1 )*D( p )*D( q ) / AAQQ )
00337 + / AAPP
00338 ELSE
00339 CALL SCOPY( M, A( 1, p ), 1, WORK, 1 )
00340 CALL SLASCL( 'G', 0, 0, AAPP, D( p ),
00341 + M, 1, WORK, LDA, IERR )
00342 AAPQ = SDOT( M, WORK, 1, A( 1, q ),
00343 + 1 )*D( q ) / AAQQ
00344 END IF
00345 ELSE
00346 IF( AAPP.GE.AAQQ ) THEN
00347 ROTOK = AAPP.LE.( AAQQ / SMALL )
00348 ELSE
00349 ROTOK = AAQQ.LE.( AAPP / SMALL )
00350 END IF
00351 IF( AAPP.GT.( SMALL / AAQQ ) ) THEN
00352 AAPQ = ( SDOT( M, A( 1, p ), 1, A( 1,
00353 + q ), 1 )*D( p )*D( q ) / AAQQ )
00354 + / AAPP
00355 ELSE
00356 CALL SCOPY( M, A( 1, q ), 1, WORK, 1 )
00357 CALL SLASCL( 'G', 0, 0, AAQQ, D( q ),
00358 + M, 1, WORK, LDA, IERR )
00359 AAPQ = SDOT( M, WORK, 1, A( 1, p ),
00360 + 1 )*D( p ) / AAPP
00361 END IF
00362 END IF
00363
00364 MXAAPQ = AMAX1( MXAAPQ, ABS( AAPQ ) )
00365
00366
00367
00368 IF( ABS( AAPQ ).GT.TOL ) THEN
00369 NOTROT = 0
00370
00371 PSKIPPED = 0
00372 ISWROT = ISWROT + 1
00373
00374 IF( ROTOK ) THEN
00375
00376 AQOAP = AAQQ / AAPP
00377 APOAQ = AAPP / AAQQ
00378 THETA = -HALF*ABS( AQOAP-APOAQ ) / AAPQ
00379 IF( AAQQ.GT.AAPP0 )THETA = -THETA
00380
00381 IF( ABS( 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 SROTM( M, A( 1, p ), 1,
00386 + A( 1, q ), 1, FASTR )
00387 IF( RSVEC )CALL SROTM( MVL,
00388 + V( 1, p ), 1,
00389 + V( 1, q ), 1,
00390 + FASTR )
00391 SVA( q ) = AAQQ*SQRT( AMAX1( ZERO,
00392 + ONE+T*APOAQ*AAPQ ) )
00393 AAPP = AAPP*SQRT( AMAX1( ZERO,
00394 + ONE-T*AQOAP*AAPQ ) )
00395 MXSINJ = AMAX1( MXSINJ, ABS( T ) )
00396 ELSE
00397
00398
00399
00400 THSIGN = -SIGN( ONE, AAPQ )
00401 IF( AAQQ.GT.AAPP0 )THSIGN = -THSIGN
00402 T = ONE / ( THETA+THSIGN*
00403 + SQRT( ONE+THETA*THETA ) )
00404 CS = SQRT( ONE / ( ONE+T*T ) )
00405 SN = T*CS
00406 MXSINJ = AMAX1( MXSINJ, ABS( SN ) )
00407 SVA( q ) = AAQQ*SQRT( AMAX1( ZERO,
00408 + ONE+T*APOAQ*AAPQ ) )
00409 AAPP = AAPP*SQRT( AMAX1( ZERO,
00410 + ONE-T*AQOAP*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 SROTM( M, A( 1, p ), 1,
00422 + A( 1, q ), 1,
00423 + FASTR )
00424 IF( RSVEC )CALL SROTM( MVL,
00425 + V( 1, p ), 1, V( 1, q ),
00426 + 1, FASTR )
00427 ELSE
00428 CALL SAXPY( M, -T*AQOAP,
00429 + A( 1, q ), 1,
00430 + A( 1, p ), 1 )
00431 CALL SAXPY( M, CS*SN*APOAQ,
00432 + A( 1, p ), 1,
00433 + A( 1, q ), 1 )
00434 IF( RSVEC ) THEN
00435 CALL SAXPY( MVL, -T*AQOAP,
00436 + V( 1, q ), 1,
00437 + V( 1, p ), 1 )
00438 CALL SAXPY( 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 SAXPY( M, T*APOAQ,
00449 + A( 1, p ), 1,
00450 + A( 1, q ), 1 )
00451 CALL SAXPY( M, -CS*SN*AQOAP,
00452 + A( 1, q ), 1,
00453 + A( 1, p ), 1 )
00454 IF( RSVEC ) THEN
00455 CALL SAXPY( MVL, T*APOAQ,
00456 + V( 1, p ), 1,
00457 + V( 1, q ), 1 )
00458 CALL SAXPY( 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 SAXPY( M, -T*AQOAP,
00468 + A( 1, q ), 1,
00469 + A( 1, p ), 1 )
00470 CALL SAXPY( 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 SAXPY( MVL,
00477 + -T*AQOAP,
00478 + V( 1, q ), 1,
00479 + V( 1, p ), 1 )
00480 CALL SAXPY( MVL,
00481 + CS*SN*APOAQ,
00482 + V( 1, p ), 1,
00483 + V( 1, q ), 1 )
00484 END IF
00485 ELSE
00486 CALL SAXPY( M, T*APOAQ,
00487 + A( 1, p ), 1,
00488 + A( 1, q ), 1 )
00489 CALL SAXPY( 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 SAXPY( MVL,
00497 + T*APOAQ, V( 1, p ),
00498 + 1, V( 1, q ), 1 )
00499 CALL SAXPY( 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 SCOPY( M, A( 1, p ), 1, WORK,
00512 + 1 )
00513 CALL SLASCL( 'G', 0, 0, AAPP, ONE,
00514 + M, 1, WORK, LDA, IERR )
00515 CALL SLASCL( 'G', 0, 0, AAQQ, ONE,
00516 + M, 1, A( 1, q ), LDA,
00517 + IERR )
00518 TEMP1 = -AAPQ*D( p ) / D( q )
00519 CALL SAXPY( M, TEMP1, WORK, 1,
00520 + A( 1, q ), 1 )
00521 CALL SLASCL( 'G', 0, 0, ONE, AAQQ,
00522 + M, 1, A( 1, q ), LDA,
00523 + IERR )
00524 SVA( q ) = AAQQ*SQRT( AMAX1( ZERO,
00525 + ONE-AAPQ*AAPQ ) )
00526 MXSINJ = AMAX1( MXSINJ, SFMIN )
00527 ELSE
00528 CALL SCOPY( M, A( 1, q ), 1, WORK,
00529 + 1 )
00530 CALL SLASCL( 'G', 0, 0, AAQQ, ONE,
00531 + M, 1, WORK, LDA, IERR )
00532 CALL SLASCL( 'G', 0, 0, AAPP, ONE,
00533 + M, 1, A( 1, p ), LDA,
00534 + IERR )
00535 TEMP1 = -AAPQ*D( q ) / D( p )
00536 CALL SAXPY( M, TEMP1, WORK, 1,
00537 + A( 1, p ), 1 )
00538 CALL SLASCL( 'G', 0, 0, ONE, AAPP,
00539 + M, 1, A( 1, p ), LDA,
00540 + IERR )
00541 SVA( p ) = AAPP*SQRT( AMAX1( ZERO,
00542 + ONE-AAPQ*AAPQ ) )
00543 MXSINJ = AMAX1( 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 ) = SNRM2( M, A( 1, q ), 1 )*
00555 + D( q )
00556 ELSE
00557 T = ZERO
00558 AAQQ = ONE
00559 CALL SLASSQ( M, A( 1, q ), 1, T,
00560 + AAQQ )
00561 SVA( q ) = T*SQRT( 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 = SNRM2( M, A( 1, p ), 1 )*
00568 + D( p )
00569 ELSE
00570 T = ZERO
00571 AAPP = ONE
00572 CALL SLASSQ( M, A( 1, p ), 1, T,
00573 + AAPP )
00574 AAPP = T*SQRT( 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 ) = ABS( 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 ) = SNRM2( M, A( 1, N ), 1 )*D( N )
00636 ELSE
00637 T = ZERO
00638 AAPP = ONE
00639 CALL SLASSQ( M, A( 1, N ), 1, T, AAPP )
00640 SVA( N ) = T*SQRT( 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.FLOAT( N )*TOL ) .AND.
00649 + ( FLOAT( 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 = ISAMAX( 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 SSWAP( M, A( 1, p ), 1, A( 1, q ), 1 )
00682 IF( RSVEC )CALL SSWAP( MVL, V( 1, p ), 1, V( 1, q ), 1 )
00683 END IF
00684 5991 CONTINUE
00685
00686 RETURN
00687
00688
00689
00690 END