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