00001 SUBROUTINE SGEJSV( JOBA, JOBU, JOBV, JOBR, JOBT, JOBP,
00002 & M, N, A, LDA, SVA, U, LDU, V, LDV,
00003 & WORK, LWORK, IWORK, INFO )
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 IMPLICIT NONE
00022 INTEGER INFO, LDA, LDU, LDV, LWORK, M, N
00023
00024
00025
00026 REAL A( LDA, * ), SVA( N ), U( LDU, * ), V( LDV, * ),
00027 & WORK( LWORK )
00028 INTEGER IWORK( * )
00029 CHARACTER*1 JOBA, JOBP, JOBR, JOBT, JOBU, JOBV
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
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 REAL ZERO, ONE
00372 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
00373
00374
00375 REAL AAPP, AAQQ, AATMAX, AATMIN, BIG, BIG1, COND_OK,
00376 & CONDR1, CONDR2, ENTRA, ENTRAT, EPSLN, MAXPRJ, SCALEM,
00377 & SCONDA, SFMIN, SMALL, TEMP1, USCAL1, USCAL2, XSC
00378 INTEGER IERR, N1, NR, NUMRANK, p, q, WARNING
00379 LOGICAL ALMORT, DEFR, ERREST, GOSCAL, JRACC, KILL, LSVEC,
00380 & L2ABER, L2KILL, L2PERT, L2RANK, L2TRAN,
00381 & NOSCAL, ROWPIV, RSVEC, TRANSP
00382
00383
00384 INTRINSIC ABS, ALOG, AMAX1, AMIN1, FLOAT,
00385 & MAX0, MIN0, NINT, SIGN, SQRT
00386
00387
00388 REAL SLAMCH, SNRM2
00389 INTEGER ISAMAX
00390 LOGICAL LSAME
00391 EXTERNAL ISAMAX, LSAME, SLAMCH, SNRM2
00392
00393
00394 EXTERNAL SCOPY, SGELQF, SGEQP3, SGEQRF, SLACPY, SLASCL,
00395 & SLASET, SLASSQ, SLASWP, SORGQR, SORMLQ,
00396 & SORMQR, SPOCON, SSCAL, SSWAP, STRSM, XERBLA
00397
00398 EXTERNAL SGESVJ
00399
00400
00401
00402
00403 LSVEC = LSAME( JOBU, 'U' ) .OR. LSAME( JOBU, 'F' )
00404 JRACC = LSAME( JOBV, 'J' )
00405 RSVEC = LSAME( JOBV, 'V' ) .OR. JRACC
00406 ROWPIV = LSAME( JOBA, 'F' ) .OR. LSAME( JOBA, 'G' )
00407 L2RANK = LSAME( JOBA, 'R' )
00408 L2ABER = LSAME( JOBA, 'A' )
00409 ERREST = LSAME( JOBA, 'E' ) .OR. LSAME( JOBA, 'G' )
00410 L2TRAN = LSAME( JOBT, 'T' )
00411 L2KILL = LSAME( JOBR, 'R' )
00412 DEFR = LSAME( JOBR, 'N' )
00413 L2PERT = LSAME( JOBP, 'P' )
00414
00415 IF ( .NOT.(ROWPIV .OR. L2RANK .OR. L2ABER .OR.
00416 & ERREST .OR. LSAME( JOBA, 'C' ) )) THEN
00417 INFO = - 1
00418 ELSE IF ( .NOT.( LSVEC .OR. LSAME( JOBU, 'N' ) .OR.
00419 & LSAME( JOBU, 'W' )) ) THEN
00420 INFO = - 2
00421 ELSE IF ( .NOT.( RSVEC .OR. LSAME( JOBV, 'N' ) .OR.
00422 & LSAME( JOBV, 'W' )) .OR. ( JRACC .AND. (.NOT.LSVEC) ) ) THEN
00423 INFO = - 3
00424 ELSE IF ( .NOT. ( L2KILL .OR. DEFR ) ) THEN
00425 INFO = - 4
00426 ELSE IF ( .NOT. ( L2TRAN .OR. LSAME( JOBT, 'N' ) ) ) THEN
00427 INFO = - 5
00428 ELSE IF ( .NOT. ( L2PERT .OR. LSAME( JOBP, 'N' ) ) ) THEN
00429 INFO = - 6
00430 ELSE IF ( M .LT. 0 ) THEN
00431 INFO = - 7
00432 ELSE IF ( ( N .LT. 0 ) .OR. ( N .GT. M ) ) THEN
00433 INFO = - 8
00434 ELSE IF ( LDA .LT. M ) THEN
00435 INFO = - 10
00436 ELSE IF ( LSVEC .AND. ( LDU .LT. M ) ) THEN
00437 INFO = - 13
00438 ELSE IF ( RSVEC .AND. ( LDV .LT. N ) ) THEN
00439 INFO = - 14
00440 ELSE IF ( (.NOT.(LSVEC .OR. RSVEC .OR. ERREST).AND.
00441 & (LWORK .LT. MAX0(7,4*N+1,2*M+N))) .OR.
00442 & (.NOT.(LSVEC .OR. LSVEC) .AND. ERREST .AND.
00443 & (LWORK .LT. MAX0(7,4*N+N*N,2*M+N))) .OR.
00444 & (LSVEC .AND. (.NOT.RSVEC) .AND. (LWORK .LT. MAX0(7,2*N+M))) .OR.
00445 & (RSVEC .AND. (.NOT.LSVEC) .AND. (LWORK .LT. MAX0(7,2*N+M))) .OR.
00446 & (LSVEC .AND. RSVEC .AND. .NOT.JRACC .AND. (LWORK.LT.6*N+2*N*N))
00447 & .OR. (LSVEC.AND.RSVEC.AND.JRACC.AND.LWORK.LT.MAX0(7,M+3*N+N*N)))
00448 & THEN
00449 INFO = - 17
00450 ELSE
00451
00452 INFO = 0
00453 END IF
00454
00455 IF ( INFO .NE. 0 ) THEN
00456
00457 CALL XERBLA( 'SGEJSV', - INFO )
00458 END IF
00459
00460
00461
00462 IF ( ( M .EQ. 0 ) .OR. ( N .EQ. 0 ) ) RETURN
00463
00464
00465
00466 IF ( LSVEC ) THEN
00467 N1 = N
00468 IF ( LSAME( JOBU, 'F' ) ) N1 = M
00469 END IF
00470
00471
00472
00473
00474
00475 EPSLN = SLAMCH('Epsilon')
00476 SFMIN = SLAMCH('SafeMinimum')
00477 SMALL = SFMIN / EPSLN
00478 BIG = SLAMCH('O')
00479
00480
00481
00482
00483
00484
00485
00486 SCALEM = ONE / SQRT(FLOAT(M)*FLOAT(N))
00487 NOSCAL = .TRUE.
00488 GOSCAL = .TRUE.
00489 DO 1874 p = 1, N
00490 AAPP = ZERO
00491 AAQQ = ZERO
00492 CALL SLASSQ( M, A(1,p), 1, AAPP, AAQQ )
00493 IF ( AAPP .GT. BIG ) THEN
00494 INFO = - 9
00495 CALL XERBLA( 'SGEJSV', -INFO )
00496 RETURN
00497 END IF
00498 AAQQ = SQRT(AAQQ)
00499 IF ( ( AAPP .LT. (BIG / AAQQ) ) .AND. NOSCAL ) THEN
00500 SVA(p) = AAPP * AAQQ
00501 ELSE
00502 NOSCAL = .FALSE.
00503 SVA(p) = AAPP * ( AAQQ * SCALEM )
00504 IF ( GOSCAL ) THEN
00505 GOSCAL = .FALSE.
00506 CALL SSCAL( p-1, SCALEM, SVA, 1 )
00507 END IF
00508 END IF
00509 1874 CONTINUE
00510
00511 IF ( NOSCAL ) SCALEM = ONE
00512
00513 AAPP = ZERO
00514 AAQQ = BIG
00515 DO 4781 p = 1, N
00516 AAPP = AMAX1( AAPP, SVA(p) )
00517 IF ( SVA(p) .NE. ZERO ) AAQQ = AMIN1( AAQQ, SVA(p) )
00518 4781 CONTINUE
00519
00520
00521
00522 IF ( AAPP .EQ. ZERO ) THEN
00523 IF ( LSVEC ) CALL SLASET( 'G', M, N1, ZERO, ONE, U, LDU )
00524 IF ( RSVEC ) CALL SLASET( 'G', N, N, ZERO, ONE, V, LDV )
00525 WORK(1) = ONE
00526 WORK(2) = ONE
00527 IF ( ERREST ) WORK(3) = ONE
00528 IF ( LSVEC .AND. RSVEC ) THEN
00529 WORK(4) = ONE
00530 WORK(5) = ONE
00531 END IF
00532 IF ( L2TRAN ) THEN
00533 WORK(6) = ZERO
00534 WORK(7) = ZERO
00535 END IF
00536 IWORK(1) = 0
00537 IWORK(2) = 0
00538 RETURN
00539 END IF
00540
00541
00542
00543
00544
00545 WARNING = 0
00546 IF ( AAQQ .LE. SFMIN ) THEN
00547 L2RANK = .TRUE.
00548 L2KILL = .TRUE.
00549 WARNING = 1
00550 END IF
00551
00552
00553
00554 IF ( N .EQ. 1 ) THEN
00555
00556 IF ( LSVEC ) THEN
00557 CALL SLASCL( 'G',0,0,SVA(1),SCALEM, M,1,A(1,1),LDA,IERR )
00558 CALL SLACPY( 'A', M, 1, A, LDA, U, LDU )
00559
00560 IF ( N1 .NE. N ) THEN
00561 CALL SGEQRF( M, N, U,LDU, WORK, WORK(N+1),LWORK-N,IERR )
00562 CALL SORGQR( M,N1,1, U,LDU,WORK,WORK(N+1),LWORK-N,IERR )
00563 CALL SCOPY( M, A(1,1), 1, U(1,1), 1 )
00564 END IF
00565 END IF
00566 IF ( RSVEC ) THEN
00567 V(1,1) = ONE
00568 END IF
00569 IF ( SVA(1) .LT. (BIG*SCALEM) ) THEN
00570 SVA(1) = SVA(1) / SCALEM
00571 SCALEM = ONE
00572 END IF
00573 WORK(1) = ONE / SCALEM
00574 WORK(2) = ONE
00575 IF ( SVA(1) .NE. ZERO ) THEN
00576 IWORK(1) = 1
00577 IF ( ( SVA(1) / SCALEM) .GE. SFMIN ) THEN
00578 IWORK(2) = 1
00579 ELSE
00580 IWORK(2) = 0
00581 END IF
00582 ELSE
00583 IWORK(1) = 0
00584 IWORK(2) = 0
00585 END IF
00586 IF ( ERREST ) WORK(3) = ONE
00587 IF ( LSVEC .AND. RSVEC ) THEN
00588 WORK(4) = ONE
00589 WORK(5) = ONE
00590 END IF
00591 IF ( L2TRAN ) THEN
00592 WORK(6) = ZERO
00593 WORK(7) = ZERO
00594 END IF
00595 RETURN
00596
00597 END IF
00598
00599 TRANSP = .FALSE.
00600 L2TRAN = L2TRAN .AND. ( M .EQ. N )
00601
00602 AATMAX = -ONE
00603 AATMIN = BIG
00604 IF ( ROWPIV .OR. L2TRAN ) THEN
00605
00606
00607
00608
00609
00610
00611 IF ( L2TRAN ) THEN
00612 DO 1950 p = 1, M
00613 XSC = ZERO
00614 TEMP1 = ZERO
00615 CALL SLASSQ( N, A(p,1), LDA, XSC, TEMP1 )
00616
00617
00618 WORK(M+N+p) = XSC * SCALEM
00619 WORK(N+p) = XSC * (SCALEM*SQRT(TEMP1))
00620 AATMAX = AMAX1( AATMAX, WORK(N+p) )
00621 IF (WORK(N+p) .NE. ZERO) AATMIN = AMIN1(AATMIN,WORK(N+p))
00622 1950 CONTINUE
00623 ELSE
00624 DO 1904 p = 1, M
00625 WORK(M+N+p) = SCALEM*ABS( A(p,ISAMAX(N,A(p,1),LDA)) )
00626 AATMAX = AMAX1( AATMAX, WORK(M+N+p) )
00627 AATMIN = AMIN1( AATMIN, WORK(M+N+p) )
00628 1904 CONTINUE
00629 END IF
00630
00631 END IF
00632
00633
00634
00635
00636
00637
00638
00639
00640 ENTRA = ZERO
00641 ENTRAT = ZERO
00642 IF ( L2TRAN ) THEN
00643
00644 XSC = ZERO
00645 TEMP1 = ZERO
00646 CALL SLASSQ( N, SVA, 1, XSC, TEMP1 )
00647 TEMP1 = ONE / TEMP1
00648
00649 ENTRA = ZERO
00650 DO 1113 p = 1, N
00651 BIG1 = ( ( SVA(p) / XSC )**2 ) * TEMP1
00652 IF ( BIG1 .NE. ZERO ) ENTRA = ENTRA + BIG1 * ALOG(BIG1)
00653 1113 CONTINUE
00654 ENTRA = - ENTRA / ALOG(FLOAT(N))
00655
00656
00657
00658
00659
00660
00661
00662 ENTRAT = ZERO
00663 DO 1114 p = N+1, N+M
00664 BIG1 = ( ( WORK(p) / XSC )**2 ) * TEMP1
00665 IF ( BIG1 .NE. ZERO ) ENTRAT = ENTRAT + BIG1 * ALOG(BIG1)
00666 1114 CONTINUE
00667 ENTRAT = - ENTRAT / ALOG(FLOAT(M))
00668
00669
00670
00671
00672 TRANSP = ( ENTRAT .LT. ENTRA )
00673
00674
00675
00676 IF ( TRANSP ) THEN
00677
00678
00679 DO 1115 p = 1, N - 1
00680 DO 1116 q = p + 1, N
00681 TEMP1 = A(q,p)
00682 A(q,p) = A(p,q)
00683 A(p,q) = TEMP1
00684 1116 CONTINUE
00685 1115 CONTINUE
00686 DO 1117 p = 1, N
00687 WORK(M+N+p) = SVA(p)
00688 SVA(p) = WORK(N+p)
00689 1117 CONTINUE
00690 TEMP1 = AAPP
00691 AAPP = AATMAX
00692 AATMAX = TEMP1
00693 TEMP1 = AAQQ
00694 AAQQ = AATMIN
00695 AATMIN = TEMP1
00696 KILL = LSVEC
00697 LSVEC = RSVEC
00698 RSVEC = KILL
00699
00700 ROWPIV = .TRUE.
00701 END IF
00702
00703 END IF
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 BIG1 = SQRT( BIG )
00717 TEMP1 = SQRT( BIG / FLOAT(N) )
00718
00719 CALL SLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )
00720 IF ( AAQQ .GT. (AAPP * SFMIN) ) THEN
00721 AAQQ = ( AAQQ / AAPP ) * TEMP1
00722 ELSE
00723 AAQQ = ( AAQQ * TEMP1 ) / AAPP
00724 END IF
00725 TEMP1 = TEMP1 * SCALEM
00726 CALL SLASCL( 'G', 0, 0, AAPP, TEMP1, M, N, A, LDA, IERR )
00727
00728
00729
00730
00731 USCAL1 = TEMP1
00732 USCAL2 = AAPP
00733
00734 IF ( L2KILL ) THEN
00735
00736
00737
00738 XSC = SQRT( SFMIN )
00739 ELSE
00740 XSC = SMALL
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 IF ( ( AAQQ.LT.SQRT(SFMIN) ) .AND. LSVEC .AND. RSVEC ) THEN
00751 JRACC = .TRUE.
00752 END IF
00753
00754 END IF
00755 IF ( AAQQ .LT. XSC ) THEN
00756 DO 700 p = 1, N
00757 IF ( SVA(p) .LT. XSC ) THEN
00758 CALL SLASET( 'A', M, 1, ZERO, ZERO, A(1,p), LDA )
00759 SVA(p) = ZERO
00760 END IF
00761 700 CONTINUE
00762 END IF
00763
00764
00765
00766 IF ( ROWPIV ) THEN
00767
00768
00769
00770
00771
00772 DO 1952 p = 1, M - 1
00773 q = ISAMAX( M-p+1, WORK(M+N+p), 1 ) + p - 1
00774 IWORK(2*N+p) = q
00775 IF ( p .NE. q ) THEN
00776 TEMP1 = WORK(M+N+p)
00777 WORK(M+N+p) = WORK(M+N+q)
00778 WORK(M+N+q) = TEMP1
00779 END IF
00780 1952 CONTINUE
00781 CALL SLASWP( N, A, LDA, 1, M-1, IWORK(2*N+1), 1 )
00782 END IF
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 DO 1963 p = 1, N
00800
00801 IWORK(p) = 0
00802 1963 CONTINUE
00803 CALL SGEQP3( M,N,A,LDA, IWORK,WORK, WORK(N+1),LWORK-N, IERR )
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 NR = 1
00814 IF ( L2ABER ) THEN
00815
00816
00817
00818
00819 TEMP1 = SQRT(FLOAT(N))*EPSLN
00820 DO 3001 p = 2, N
00821 IF ( ABS(A(p,p)) .GE. (TEMP1*ABS(A(1,1))) ) THEN
00822 NR = NR + 1
00823 ELSE
00824 GO TO 3002
00825 END IF
00826 3001 CONTINUE
00827 3002 CONTINUE
00828 ELSE IF ( L2RANK ) THEN
00829
00830
00831
00832 TEMP1 = SQRT(SFMIN)
00833 DO 3401 p = 2, N
00834 IF ( ( ABS(A(p,p)) .LT. (EPSLN*ABS(A(p-1,p-1))) ) .OR.
00835 & ( ABS(A(p,p)) .LT. SMALL ) .OR.
00836 & ( L2KILL .AND. (ABS(A(p,p)) .LT. TEMP1) ) ) GO TO 3402
00837 NR = NR + 1
00838 3401 CONTINUE
00839 3402 CONTINUE
00840
00841 ELSE
00842
00843
00844
00845
00846
00847
00848
00849 TEMP1 = SQRT(SFMIN)
00850 DO 3301 p = 2, N
00851 IF ( ( ABS(A(p,p)) .LT. SMALL ) .OR.
00852 & ( L2KILL .AND. (ABS(A(p,p)) .LT. TEMP1) ) ) GO TO 3302
00853 NR = NR + 1
00854 3301 CONTINUE
00855 3302 CONTINUE
00856
00857 END IF
00858
00859 ALMORT = .FALSE.
00860 IF ( NR .EQ. N ) THEN
00861 MAXPRJ = ONE
00862 DO 3051 p = 2, N
00863 TEMP1 = ABS(A(p,p)) / SVA(IWORK(p))
00864 MAXPRJ = AMIN1( MAXPRJ, TEMP1 )
00865 3051 CONTINUE
00866 IF ( MAXPRJ**2 .GE. ONE - FLOAT(N)*EPSLN ) ALMORT = .TRUE.
00867 END IF
00868
00869
00870 SCONDA = - ONE
00871 CONDR1 = - ONE
00872 CONDR2 = - ONE
00873
00874 IF ( ERREST ) THEN
00875 IF ( N .EQ. NR ) THEN
00876 IF ( RSVEC ) THEN
00877
00878 CALL SLACPY( 'U', N, N, A, LDA, V, LDV )
00879 DO 3053 p = 1, N
00880 TEMP1 = SVA(IWORK(p))
00881 CALL SSCAL( p, ONE/TEMP1, V(1,p), 1 )
00882 3053 CONTINUE
00883 CALL SPOCON( 'U', N, V, LDV, ONE, TEMP1,
00884 & WORK(N+1), IWORK(2*N+M+1), IERR )
00885 ELSE IF ( LSVEC ) THEN
00886
00887 CALL SLACPY( 'U', N, N, A, LDA, U, LDU )
00888 DO 3054 p = 1, N
00889 TEMP1 = SVA(IWORK(p))
00890 CALL SSCAL( p, ONE/TEMP1, U(1,p), 1 )
00891 3054 CONTINUE
00892 CALL SPOCON( 'U', N, U, LDU, ONE, TEMP1,
00893 & WORK(N+1), IWORK(2*N+M+1), IERR )
00894 ELSE
00895 CALL SLACPY( 'U', N, N, A, LDA, WORK(N+1), N )
00896 DO 3052 p = 1, N
00897 TEMP1 = SVA(IWORK(p))
00898 CALL SSCAL( p, ONE/TEMP1, WORK(N+(p-1)*N+1), 1 )
00899 3052 CONTINUE
00900
00901 CALL SPOCON( 'U', N, WORK(N+1), N, ONE, TEMP1,
00902 & WORK(N+N*N+1), IWORK(2*N+M+1), IERR )
00903 END IF
00904 SCONDA = ONE / SQRT(TEMP1)
00905
00906
00907 ELSE
00908 SCONDA = - ONE
00909 END IF
00910 END IF
00911
00912 L2PERT = L2PERT .AND. ( ABS( A(1,1)/A(NR,NR) ) .GT. SQRT(BIG1) )
00913
00914
00915
00916
00917 IF ( .NOT. ( RSVEC .OR. LSVEC ) ) THEN
00918
00919
00920
00921
00922 DO 1946 p = 1, MIN0( N-1, NR )
00923 CALL SCOPY( N-p, A(p,p+1), LDA, A(p+1,p), 1 )
00924 1946 CONTINUE
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 IF ( .NOT. ALMORT ) THEN
00939
00940 IF ( L2PERT ) THEN
00941
00942 XSC = EPSLN / FLOAT(N)
00943 DO 4947 q = 1, NR
00944 TEMP1 = XSC*ABS(A(q,q))
00945 DO 4949 p = 1, N
00946 IF ( ( (p.GT.q) .AND. (ABS(A(p,q)).LE.TEMP1) )
00947 & .OR. ( p .LT. q ) )
00948 & A(p,q) = SIGN( TEMP1, A(p,q) )
00949 4949 CONTINUE
00950 4947 CONTINUE
00951 ELSE
00952 CALL SLASET( 'U', NR-1,NR-1, ZERO,ZERO, A(1,2),LDA )
00953 END IF
00954
00955
00956
00957 CALL SGEQRF( N,NR, A,LDA, WORK, WORK(N+1),LWORK-N, IERR )
00958
00959
00960 DO 1948 p = 1, NR - 1
00961 CALL SCOPY( NR-p, A(p,p+1), LDA, A(p+1,p), 1 )
00962 1948 CONTINUE
00963
00964 END IF
00965
00966
00967
00968
00969
00970 IF ( L2PERT ) THEN
00971
00972 XSC = EPSLN / FLOAT(N)
00973 DO 1947 q = 1, NR
00974 TEMP1 = XSC*ABS(A(q,q))
00975 DO 1949 p = 1, NR
00976 IF ( ( (p.GT.q) .AND. (ABS(A(p,q)).LE.TEMP1) )
00977 & .OR. ( p .LT. q ) )
00978 & A(p,q) = SIGN( TEMP1, A(p,q) )
00979 1949 CONTINUE
00980 1947 CONTINUE
00981 ELSE
00982 CALL SLASET( 'U', NR-1, NR-1, ZERO, ZERO, A(1,2), LDA )
00983 END IF
00984
00985
00986
00987
00988
00989 CALL SGESVJ( 'L', 'NoU', 'NoV', NR, NR, A, LDA, SVA,
00990 & N, V, LDV, WORK, LWORK, INFO )
00991
00992 SCALEM = WORK(1)
00993 NUMRANK = NINT(WORK(2))
00994
00995
00996 ELSE IF ( RSVEC .AND. ( .NOT. LSVEC ) ) THEN
00997
00998
00999
01000 IF ( ALMORT ) THEN
01001
01002
01003 DO 1998 p = 1, NR
01004 CALL SCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )
01005 1998 CONTINUE
01006 CALL SLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01007
01008 CALL SGESVJ( 'L','U','N', N, NR, V,LDV, SVA, NR, A,LDA,
01009 & WORK, LWORK, INFO )
01010 SCALEM = WORK(1)
01011 NUMRANK = NINT(WORK(2))
01012
01013 ELSE
01014
01015
01016
01017
01018 CALL SLASET( 'Lower', NR-1, NR-1, ZERO, ZERO, A(2,1), LDA )
01019 CALL SGELQF( NR, N, A, LDA, WORK, WORK(N+1), LWORK-N, IERR)
01020 CALL SLACPY( 'Lower', NR, NR, A, LDA, V, LDV )
01021 CALL SLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01022 CALL SGEQRF( NR, NR, V, LDV, WORK(N+1), WORK(2*N+1),
01023 & LWORK-2*N, IERR )
01024 DO 8998 p = 1, NR
01025 CALL SCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 )
01026 8998 CONTINUE
01027 CALL SLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01028
01029 CALL SGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U,
01030 & LDU, WORK(N+1), LWORK, INFO )
01031 SCALEM = WORK(N+1)
01032 NUMRANK = NINT(WORK(N+2))
01033 IF ( NR .LT. N ) THEN
01034 CALL SLASET( 'A',N-NR, NR, ZERO,ZERO, V(NR+1,1), LDV )
01035 CALL SLASET( 'A',NR, N-NR, ZERO,ZERO, V(1,NR+1), LDV )
01036 CALL SLASET( 'A',N-NR,N-NR,ZERO,ONE, V(NR+1,NR+1), LDV )
01037 END IF
01038
01039 CALL SORMLQ( 'Left', 'Transpose', N, N, NR, A, LDA, WORK,
01040 & V, LDV, WORK(N+1), LWORK-N, IERR )
01041
01042 END IF
01043
01044 DO 8991 p = 1, N
01045 CALL SCOPY( N, V(p,1), LDV, A(IWORK(p),1), LDA )
01046 8991 CONTINUE
01047 CALL SLACPY( 'All', N, N, A, LDA, V, LDV )
01048
01049 IF ( TRANSP ) THEN
01050 CALL SLACPY( 'All', N, N, V, LDV, U, LDU )
01051 END IF
01052
01053 ELSE IF ( LSVEC .AND. ( .NOT. RSVEC ) ) THEN
01054
01055
01056
01057
01058
01059 DO 1965 p = 1, NR
01060 CALL SCOPY( N-p+1, A(p,p), LDA, U(p,p), 1 )
01061 1965 CONTINUE
01062 CALL SLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )
01063
01064 CALL SGEQRF( N, NR, U, LDU, WORK(N+1), WORK(2*N+1),
01065 & LWORK-2*N, IERR )
01066
01067 DO 1967 p = 1, NR - 1
01068 CALL SCOPY( NR-p, U(p,p+1), LDU, U(p+1,p), 1 )
01069 1967 CONTINUE
01070 CALL SLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )
01071
01072 CALL SGESVJ( 'Lower', 'U', 'N', NR,NR, U, LDU, SVA, NR, A,
01073 & LDA, WORK(N+1), LWORK-N, INFO )
01074 SCALEM = WORK(N+1)
01075 NUMRANK = NINT(WORK(N+2))
01076
01077 IF ( NR .LT. M ) THEN
01078 CALL SLASET( 'A', M-NR, NR,ZERO, ZERO, U(NR+1,1), LDU )
01079 IF ( NR .LT. N1 ) THEN
01080 CALL SLASET( 'A',NR, N1-NR, ZERO, ZERO, U(1,NR+1), LDU )
01081 CALL SLASET( 'A',M-NR,N1-NR,ZERO,ONE,U(NR+1,NR+1), LDU )
01082 END IF
01083 END IF
01084
01085 CALL SORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,
01086 & LDU, WORK(N+1), LWORK-N, IERR )
01087
01088 IF ( ROWPIV )
01089 & CALL SLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01090
01091 DO 1974 p = 1, N1
01092 XSC = ONE / SNRM2( M, U(1,p), 1 )
01093 CALL SSCAL( M, XSC, U(1,p), 1 )
01094 1974 CONTINUE
01095
01096 IF ( TRANSP ) THEN
01097 CALL SLACPY( 'All', N, N, U, LDU, V, LDV )
01098 END IF
01099
01100 ELSE
01101
01102
01103
01104 IF ( .NOT. JRACC ) THEN
01105
01106 IF ( .NOT. ALMORT ) THEN
01107
01108
01109
01110
01111
01112
01113
01114
01115 DO 1968 p = 1, NR
01116 CALL SCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )
01117 1968 CONTINUE
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 IF ( L2PERT ) THEN
01132 XSC = SQRT(SMALL)
01133 DO 2969 q = 1, NR
01134 TEMP1 = XSC*ABS( V(q,q) )
01135 DO 2968 p = 1, N
01136 IF ( ( p .GT. q ) .AND. ( ABS(V(p,q)) .LE. TEMP1 )
01137 & .OR. ( p .LT. q ) )
01138 & V(p,q) = SIGN( TEMP1, V(p,q) )
01139 IF ( p. LT. q ) V(p,q) = - V(p,q)
01140 2968 CONTINUE
01141 2969 CONTINUE
01142 ELSE
01143 CALL SLASET( 'U', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01144 END IF
01145
01146
01147
01148
01149
01150 CALL SLACPY( 'L', NR, NR, V, LDV, WORK(2*N+1), NR )
01151 DO 3950 p = 1, NR
01152 TEMP1 = SNRM2(NR-p+1,WORK(2*N+(p-1)*NR+p),1)
01153 CALL SSCAL(NR-p+1,ONE/TEMP1,WORK(2*N+(p-1)*NR+p),1)
01154 3950 CONTINUE
01155 CALL SPOCON('Lower',NR,WORK(2*N+1),NR,ONE,TEMP1,
01156 & WORK(2*N+NR*NR+1),IWORK(M+2*N+1),IERR)
01157 CONDR1 = ONE / SQRT(TEMP1)
01158
01159
01160
01161
01162
01163 COND_OK = SQRT(FLOAT(NR))
01164
01165
01166 IF ( CONDR1 .LT. COND_OK ) THEN
01167
01168
01169
01170
01171 CALL SGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),
01172 & LWORK-2*N, IERR )
01173
01174 IF ( L2PERT ) THEN
01175 XSC = SQRT(SMALL)/EPSLN
01176 DO 3959 p = 2, NR
01177 DO 3958 q = 1, p - 1
01178 TEMP1 = XSC * AMIN1(ABS(V(p,p)),ABS(V(q,q)))
01179 IF ( ABS(V(q,p)) .LE. TEMP1 )
01180 & V(q,p) = SIGN( TEMP1, V(q,p) )
01181 3958 CONTINUE
01182 3959 CONTINUE
01183 END IF
01184
01185 IF ( NR .NE. N )
01186
01187 & CALL SLACPY( 'A', N, NR, V, LDV, WORK(2*N+1), N )
01188
01189
01190 DO 1969 p = 1, NR - 1
01191 CALL SCOPY( NR-p, V(p,p+1), LDV, V(p+1,p), 1 )
01192 1969 CONTINUE
01193
01194 CONDR2 = CONDR1
01195
01196 ELSE
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 DO 3003 p = 1, NR
01207 IWORK(N+p) = 0
01208 3003 CONTINUE
01209 CALL SGEQP3( N, NR, V, LDV, IWORK(N+1), WORK(N+1),
01210 & WORK(2*N+1), LWORK-2*N, IERR )
01211
01212
01213 IF ( L2PERT ) THEN
01214 XSC = SQRT(SMALL)
01215 DO 3969 p = 2, NR
01216 DO 3968 q = 1, p - 1
01217 TEMP1 = XSC * AMIN1(ABS(V(p,p)),ABS(V(q,q)))
01218 IF ( ABS(V(q,p)) .LE. TEMP1 )
01219 & V(q,p) = SIGN( TEMP1, V(q,p) )
01220 3968 CONTINUE
01221 3969 CONTINUE
01222 END IF
01223
01224 CALL SLACPY( 'A', N, NR, V, LDV, WORK(2*N+1), N )
01225
01226 IF ( L2PERT ) THEN
01227 XSC = SQRT(SMALL)
01228 DO 8970 p = 2, NR
01229 DO 8971 q = 1, p - 1
01230 TEMP1 = XSC * AMIN1(ABS(V(p,p)),ABS(V(q,q)))
01231 V(p,q) = - SIGN( TEMP1, V(q,p) )
01232 8971 CONTINUE
01233 8970 CONTINUE
01234 ELSE
01235 CALL SLASET( 'L',NR-1,NR-1,ZERO,ZERO,V(2,1),LDV )
01236 END IF
01237
01238 CALL SGELQF( NR, NR, V, LDV, WORK(2*N+N*NR+1),
01239 & WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, IERR )
01240
01241 CALL SLACPY( 'L',NR,NR,V,LDV,WORK(2*N+N*NR+NR+1),NR )
01242 DO 4950 p = 1, NR
01243 TEMP1 = SNRM2( p, WORK(2*N+N*NR+NR+p), NR )
01244 CALL SSCAL( p, ONE/TEMP1, WORK(2*N+N*NR+NR+p), NR )
01245 4950 CONTINUE
01246 CALL SPOCON( 'L',NR,WORK(2*N+N*NR+NR+1),NR,ONE,TEMP1,
01247 & WORK(2*N+N*NR+NR+NR*NR+1),IWORK(M+2*N+1),IERR )
01248 CONDR2 = ONE / SQRT(TEMP1)
01249
01250 IF ( CONDR2 .GE. COND_OK ) THEN
01251
01252
01253
01254
01255 CALL SLACPY( 'U', NR, NR, V, LDV, WORK(2*N+1), N )
01256
01257
01258 END IF
01259
01260 END IF
01261
01262 IF ( L2PERT ) THEN
01263 XSC = SQRT(SMALL)
01264 DO 4968 q = 2, NR
01265 TEMP1 = XSC * V(q,q)
01266 DO 4969 p = 1, q - 1
01267
01268 V(p,q) = - SIGN( TEMP1, V(p,q) )
01269 4969 CONTINUE
01270 4968 CONTINUE
01271 ELSE
01272 CALL SLASET( 'U', NR-1,NR-1, ZERO,ZERO, V(1,2), LDV )
01273 END IF
01274
01275
01276
01277
01278
01279
01280
01281 IF ( CONDR1 .LT. COND_OK ) THEN
01282
01283 CALL SGESVJ( 'L','U','N',NR,NR,V,LDV,SVA,NR,U,
01284 & LDU,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,INFO )
01285 SCALEM = WORK(2*N+N*NR+NR+1)
01286 NUMRANK = NINT(WORK(2*N+N*NR+NR+2))
01287 DO 3970 p = 1, NR
01288 CALL SCOPY( NR, V(1,p), 1, U(1,p), 1 )
01289 CALL SSCAL( NR, SVA(p), V(1,p), 1 )
01290 3970 CONTINUE
01291
01292
01293
01294 IF ( NR. EQ. N ) THEN
01295
01296
01297
01298
01299 CALL STRSM( 'L','U','N','N', NR,NR,ONE, A,LDA, V,LDV )
01300 ELSE
01301
01302
01303
01304
01305 CALL STRSM('L','U','T','N',NR,NR,ONE,WORK(2*N+1),
01306 & N,V,LDV)
01307 IF ( NR .LT. N ) THEN
01308 CALL SLASET('A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV)
01309 CALL SLASET('A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV)
01310 CALL SLASET('A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV)
01311 END IF
01312 CALL SORMQR('L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01313 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR)
01314 END IF
01315
01316 ELSE IF ( CONDR2 .LT. COND_OK ) THEN
01317
01318
01319
01320
01321
01322
01323
01324 CALL SGESVJ( 'L', 'U', 'N', NR, NR, V, LDV, SVA, NR, U,
01325 & LDU, WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, INFO )
01326 SCALEM = WORK(2*N+N*NR+NR+1)
01327 NUMRANK = NINT(WORK(2*N+N*NR+NR+2))
01328 DO 3870 p = 1, NR
01329 CALL SCOPY( NR, V(1,p), 1, U(1,p), 1 )
01330 CALL SSCAL( NR, SVA(p), U(1,p), 1 )
01331 3870 CONTINUE
01332 CALL STRSM('L','U','N','N',NR,NR,ONE,WORK(2*N+1),N,U,LDU)
01333
01334 DO 873 q = 1, NR
01335 DO 872 p = 1, NR
01336 WORK(2*N+N*NR+NR+IWORK(N+p)) = U(p,q)
01337 872 CONTINUE
01338 DO 874 p = 1, NR
01339 U(p,q) = WORK(2*N+N*NR+NR+p)
01340 874 CONTINUE
01341 873 CONTINUE
01342 IF ( NR .LT. N ) THEN
01343 CALL SLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
01344 CALL SLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
01345 CALL SLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
01346 END IF
01347 CALL SORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01348 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )
01349 ELSE
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361 CALL SGESVJ( 'L', 'U', 'V', NR, NR, V, LDV, SVA, NR, U,
01362 & LDU, WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, INFO )
01363 SCALEM = WORK(2*N+N*NR+NR+1)
01364 NUMRANK = NINT(WORK(2*N+N*NR+NR+2))
01365 IF ( NR .LT. N ) THEN
01366 CALL SLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
01367 CALL SLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
01368 CALL SLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
01369 END IF
01370 CALL SORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01371 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )
01372
01373 CALL SORMLQ( 'L', 'T', NR, NR, NR, WORK(2*N+1), N,
01374 & WORK(2*N+N*NR+1), U, LDU, WORK(2*N+N*NR+NR+1),
01375 & LWORK-2*N-N*NR-NR, IERR )
01376 DO 773 q = 1, NR
01377 DO 772 p = 1, NR
01378 WORK(2*N+N*NR+NR+IWORK(N+p)) = U(p,q)
01379 772 CONTINUE
01380 DO 774 p = 1, NR
01381 U(p,q) = WORK(2*N+N*NR+NR+p)
01382 774 CONTINUE
01383 773 CONTINUE
01384
01385 END IF
01386
01387
01388
01389
01390
01391 TEMP1 = SQRT(FLOAT(N)) * EPSLN
01392 DO 1972 q = 1, N
01393 DO 972 p = 1, N
01394 WORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)
01395 972 CONTINUE
01396 DO 973 p = 1, N
01397 V(p,q) = WORK(2*N+N*NR+NR+p)
01398 973 CONTINUE
01399 XSC = ONE / SNRM2( N, V(1,q), 1 )
01400 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01401 & CALL SSCAL( N, XSC, V(1,q), 1 )
01402 1972 CONTINUE
01403
01404
01405 IF ( NR .LT. M ) THEN
01406 CALL SLASET( 'A', M-NR, NR, ZERO, ZERO, U(NR+1,1), LDU )
01407 IF ( NR .LT. N1 ) THEN
01408 CALL SLASET('A',NR,N1-NR,ZERO,ZERO,U(1,NR+1),LDU)
01409 CALL SLASET('A',M-NR,N1-NR,ZERO,ONE,U(NR+1,NR+1),LDU)
01410 END IF
01411 END IF
01412
01413
01414
01415
01416 CALL SORMQR( 'Left', 'No_Tr', M, N1, N, A, LDA, WORK, U,
01417 & LDU, WORK(N+1), LWORK-N, IERR )
01418
01419
01420 TEMP1 = SQRT(FLOAT(M)) * EPSLN
01421 DO 1973 p = 1, NR
01422 XSC = ONE / SNRM2( M, U(1,p), 1 )
01423 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01424 & CALL SSCAL( M, XSC, U(1,p), 1 )
01425 1973 CONTINUE
01426
01427
01428
01429
01430 IF ( ROWPIV )
01431 & CALL SLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01432
01433 ELSE
01434
01435
01436
01437
01438 CALL SLACPY( 'Upper', N, N, A, LDA, WORK(N+1), N )
01439 IF ( L2PERT ) THEN
01440 XSC = SQRT(SMALL)
01441 DO 5970 p = 2, N
01442 TEMP1 = XSC * WORK( N + (p-1)*N + p )
01443 DO 5971 q = 1, p - 1
01444 WORK(N+(q-1)*N+p)=-SIGN(TEMP1,WORK(N+(p-1)*N+q))
01445 5971 CONTINUE
01446 5970 CONTINUE
01447 ELSE
01448 CALL SLASET( 'Lower',N-1,N-1,ZERO,ZERO,WORK(N+2),N )
01449 END IF
01450
01451 CALL SGESVJ( 'Upper', 'U', 'N', N, N, WORK(N+1), N, SVA,
01452 & N, U, LDU, WORK(N+N*N+1), LWORK-N-N*N, INFO )
01453
01454 SCALEM = WORK(N+N*N+1)
01455 NUMRANK = NINT(WORK(N+N*N+2))
01456 DO 6970 p = 1, N
01457 CALL SCOPY( N, WORK(N+(p-1)*N+1), 1, U(1,p), 1 )
01458 CALL SSCAL( N, SVA(p), WORK(N+(p-1)*N+1), 1 )
01459 6970 CONTINUE
01460
01461 CALL STRSM( 'Left', 'Upper', 'NoTrans', 'No UD', N, N,
01462 & ONE, A, LDA, WORK(N+1), N )
01463 DO 6972 p = 1, N
01464 CALL SCOPY( N, WORK(N+p), N, V(IWORK(p),1), LDV )
01465 6972 CONTINUE
01466 TEMP1 = SQRT(FLOAT(N))*EPSLN
01467 DO 6971 p = 1, N
01468 XSC = ONE / SNRM2( N, V(1,p), 1 )
01469 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01470 & CALL SSCAL( N, XSC, V(1,p), 1 )
01471 6971 CONTINUE
01472
01473
01474
01475 IF ( N .LT. M ) THEN
01476 CALL SLASET( 'A', M-N, N, ZERO, ZERO, U(NR+1,1), LDU )
01477 IF ( N .LT. N1 ) THEN
01478 CALL SLASET( 'A',N, N1-N, ZERO, ZERO, U(1,N+1),LDU )
01479 CALL SLASET( 'A',M-N,N1-N, ZERO, ONE,U(NR+1,N+1),LDU )
01480 END IF
01481 END IF
01482 CALL SORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,
01483 & LDU, WORK(N+1), LWORK-N, IERR )
01484 TEMP1 = SQRT(FLOAT(M))*EPSLN
01485 DO 6973 p = 1, N1
01486 XSC = ONE / SNRM2( M, U(1,p), 1 )
01487 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01488 & CALL SSCAL( M, XSC, U(1,p), 1 )
01489 6973 CONTINUE
01490
01491 IF ( ROWPIV )
01492 & CALL SLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01493
01494 END IF
01495
01496
01497
01498 ELSE
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 DO 7968 p = 1, NR
01511 CALL SCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )
01512 7968 CONTINUE
01513
01514 IF ( L2PERT ) THEN
01515 XSC = SQRT(SMALL/EPSLN)
01516 DO 5969 q = 1, NR
01517 TEMP1 = XSC*ABS( V(q,q) )
01518 DO 5968 p = 1, N
01519 IF ( ( p .GT. q ) .AND. ( ABS(V(p,q)) .LE. TEMP1 )
01520 & .OR. ( p .LT. q ) )
01521 & V(p,q) = SIGN( TEMP1, V(p,q) )
01522 IF ( p. LT. q ) V(p,q) = - V(p,q)
01523 5968 CONTINUE
01524 5969 CONTINUE
01525 ELSE
01526 CALL SLASET( 'U', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01527 END IF
01528
01529 CALL SGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),
01530 & LWORK-2*N, IERR )
01531 CALL SLACPY( 'L', N, NR, V, LDV, WORK(2*N+1), N )
01532
01533 DO 7969 p = 1, NR
01534 CALL SCOPY( NR-p+1, V(p,p), LDV, U(p,p), 1 )
01535 7969 CONTINUE
01536
01537 IF ( L2PERT ) THEN
01538 XSC = SQRT(SMALL/EPSLN)
01539 DO 9970 q = 2, NR
01540 DO 9971 p = 1, q - 1
01541 TEMP1 = XSC * AMIN1(ABS(U(p,p)),ABS(U(q,q)))
01542 U(p,q) = - SIGN( TEMP1, U(q,p) )
01543 9971 CONTINUE
01544 9970 CONTINUE
01545 ELSE
01546 CALL SLASET('U', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )
01547 END IF
01548
01549 CALL SGESVJ( 'L', 'U', 'V', NR, NR, U, LDU, SVA,
01550 & N, V, LDV, WORK(2*N+N*NR+1), LWORK-2*N-N*NR, INFO )
01551 SCALEM = WORK(2*N+N*NR+1)
01552 NUMRANK = NINT(WORK(2*N+N*NR+2))
01553
01554 IF ( NR .LT. N ) THEN
01555 CALL SLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
01556 CALL SLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
01557 CALL SLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
01558 END IF
01559
01560 CALL SORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01561 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )
01562
01563
01564
01565
01566
01567 TEMP1 = SQRT(FLOAT(N)) * EPSLN
01568 DO 7972 q = 1, N
01569 DO 8972 p = 1, N
01570 WORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)
01571 8972 CONTINUE
01572 DO 8973 p = 1, N
01573 V(p,q) = WORK(2*N+N*NR+NR+p)
01574 8973 CONTINUE
01575 XSC = ONE / SNRM2( N, V(1,q), 1 )
01576 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01577 & CALL SSCAL( N, XSC, V(1,q), 1 )
01578 7972 CONTINUE
01579
01580
01581
01582
01583 IF ( N .LT. M ) THEN
01584 CALL SLASET( 'A', M-N, N, ZERO, ZERO, U(NR+1,1), LDU )
01585 IF ( N .LT. N1 ) THEN
01586 CALL SLASET( 'A',N, N1-N, ZERO, ZERO, U(1,N+1),LDU )
01587 CALL SLASET( 'A',M-N,N1-N, ZERO, ONE,U(NR+1,N+1),LDU )
01588 END IF
01589 END IF
01590
01591 CALL SORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,
01592 & LDU, WORK(N+1), LWORK-N, IERR )
01593
01594 IF ( ROWPIV )
01595 & CALL SLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01596
01597
01598 END IF
01599 IF ( TRANSP ) THEN
01600
01601 DO 6974 p = 1, N
01602 CALL SSWAP( N, U(1,p), 1, V(1,p), 1 )
01603 6974 CONTINUE
01604 END IF
01605
01606 END IF
01607
01608
01609
01610
01611 IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THEN
01612 CALL SLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )
01613 USCAL1 = ONE
01614 USCAL2 = ONE
01615 END IF
01616
01617 IF ( NR .LT. N ) THEN
01618 DO 3004 p = NR+1, N
01619 SVA(p) = ZERO
01620 3004 CONTINUE
01621 END IF
01622
01623 WORK(1) = USCAL2 * SCALEM
01624 WORK(2) = USCAL1
01625 IF ( ERREST ) WORK(3) = SCONDA
01626 IF ( LSVEC .AND. RSVEC ) THEN
01627 WORK(4) = CONDR1
01628 WORK(5) = CONDR2
01629 END IF
01630 IF ( L2TRAN ) THEN
01631 WORK(6) = ENTRA
01632 WORK(7) = ENTRAT
01633 END IF
01634
01635 IWORK(1) = NR
01636 IWORK(2) = NUMRANK
01637 IWORK(3) = WARNING
01638
01639 RETURN
01640
01641
01642
01643 END
01644