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 = ZERO
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 = ZERO
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 = ZERO
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
00701 ROWPIV = .TRUE.
00702 END IF
00703
00704 END IF
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 BIG1 = DSQRT( BIG )
00718 TEMP1 = DSQRT( BIG / DBLE(N) )
00719
00720 CALL DLASCL( 'G', 0, 0, AAPP, TEMP1, N, 1, SVA, N, IERR )
00721 IF ( AAQQ .GT. (AAPP * SFMIN) ) THEN
00722 AAQQ = ( AAQQ / AAPP ) * TEMP1
00723 ELSE
00724 AAQQ = ( AAQQ * TEMP1 ) / AAPP
00725 END IF
00726 TEMP1 = TEMP1 * SCALEM
00727 CALL DLASCL( 'G', 0, 0, AAPP, TEMP1, M, N, A, LDA, IERR )
00728
00729
00730
00731
00732 USCAL1 = TEMP1
00733 USCAL2 = AAPP
00734
00735 IF ( L2KILL ) THEN
00736
00737
00738
00739 XSC = DSQRT( SFMIN )
00740 ELSE
00741 XSC = SMALL
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 IF ( ( AAQQ.LT.DSQRT(SFMIN) ) .AND. LSVEC .AND. RSVEC ) THEN
00752 JRACC = .TRUE.
00753 END IF
00754
00755 END IF
00756 IF ( AAQQ .LT. XSC ) THEN
00757 DO 700 p = 1, N
00758 IF ( SVA(p) .LT. XSC ) THEN
00759 CALL DLASET( 'A', M, 1, ZERO, ZERO, A(1,p), LDA )
00760 SVA(p) = ZERO
00761 END IF
00762 700 CONTINUE
00763 END IF
00764
00765
00766
00767 IF ( ROWPIV ) THEN
00768
00769
00770
00771
00772
00773 DO 1952 p = 1, M - 1
00774 q = IDAMAX( M-p+1, WORK(M+N+p), 1 ) + p - 1
00775 IWORK(2*N+p) = q
00776 IF ( p .NE. q ) THEN
00777 TEMP1 = WORK(M+N+p)
00778 WORK(M+N+p) = WORK(M+N+q)
00779 WORK(M+N+q) = TEMP1
00780 END IF
00781 1952 CONTINUE
00782 CALL DLASWP( N, A, LDA, 1, M-1, IWORK(2*N+1), 1 )
00783 END IF
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800 DO 1963 p = 1, N
00801
00802 IWORK(p) = 0
00803 1963 CONTINUE
00804 CALL DGEQP3( M,N,A,LDA, IWORK,WORK, WORK(N+1),LWORK-N, IERR )
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 NR = 1
00815 IF ( L2ABER ) THEN
00816
00817
00818
00819
00820 TEMP1 = DSQRT(DBLE(N))*EPSLN
00821 DO 3001 p = 2, N
00822 IF ( DABS(A(p,p)) .GE. (TEMP1*DABS(A(1,1))) ) THEN
00823 NR = NR + 1
00824 ELSE
00825 GO TO 3002
00826 END IF
00827 3001 CONTINUE
00828 3002 CONTINUE
00829 ELSE IF ( L2RANK ) THEN
00830
00831
00832
00833 TEMP1 = DSQRT(SFMIN)
00834 DO 3401 p = 2, N
00835 IF ( ( DABS(A(p,p)) .LT. (EPSLN*DABS(A(p-1,p-1))) ) .OR.
00836 & ( DABS(A(p,p)) .LT. SMALL ) .OR.
00837 & ( L2KILL .AND. (DABS(A(p,p)) .LT. TEMP1) ) ) GO TO 3402
00838 NR = NR + 1
00839 3401 CONTINUE
00840 3402 CONTINUE
00841
00842 ELSE
00843
00844
00845
00846
00847
00848
00849
00850 TEMP1 = DSQRT(SFMIN)
00851 DO 3301 p = 2, N
00852 IF ( ( DABS(A(p,p)) .LT. SMALL ) .OR.
00853 & ( L2KILL .AND. (DABS(A(p,p)) .LT. TEMP1) ) ) GO TO 3302
00854 NR = NR + 1
00855 3301 CONTINUE
00856 3302 CONTINUE
00857
00858 END IF
00859
00860 ALMORT = .FALSE.
00861 IF ( NR .EQ. N ) THEN
00862 MAXPRJ = ONE
00863 DO 3051 p = 2, N
00864 TEMP1 = DABS(A(p,p)) / SVA(IWORK(p))
00865 MAXPRJ = DMIN1( MAXPRJ, TEMP1 )
00866 3051 CONTINUE
00867 IF ( MAXPRJ**2 .GE. ONE - DBLE(N)*EPSLN ) ALMORT = .TRUE.
00868 END IF
00869
00870
00871 SCONDA = - ONE
00872 CONDR1 = - ONE
00873 CONDR2 = - ONE
00874
00875 IF ( ERREST ) THEN
00876 IF ( N .EQ. NR ) THEN
00877 IF ( RSVEC ) THEN
00878
00879 CALL DLACPY( 'U', N, N, A, LDA, V, LDV )
00880 DO 3053 p = 1, N
00881 TEMP1 = SVA(IWORK(p))
00882 CALL DSCAL( p, ONE/TEMP1, V(1,p), 1 )
00883 3053 CONTINUE
00884 CALL DPOCON( 'U', N, V, LDV, ONE, TEMP1,
00885 & WORK(N+1), IWORK(2*N+M+1), IERR )
00886 ELSE IF ( LSVEC ) THEN
00887
00888 CALL DLACPY( 'U', N, N, A, LDA, U, LDU )
00889 DO 3054 p = 1, N
00890 TEMP1 = SVA(IWORK(p))
00891 CALL DSCAL( p, ONE/TEMP1, U(1,p), 1 )
00892 3054 CONTINUE
00893 CALL DPOCON( 'U', N, U, LDU, ONE, TEMP1,
00894 & WORK(N+1), IWORK(2*N+M+1), IERR )
00895 ELSE
00896 CALL DLACPY( 'U', N, N, A, LDA, WORK(N+1), N )
00897 DO 3052 p = 1, N
00898 TEMP1 = SVA(IWORK(p))
00899 CALL DSCAL( p, ONE/TEMP1, WORK(N+(p-1)*N+1), 1 )
00900 3052 CONTINUE
00901
00902 CALL DPOCON( 'U', N, WORK(N+1), N, ONE, TEMP1,
00903 & WORK(N+N*N+1), IWORK(2*N+M+1), IERR )
00904 END IF
00905 SCONDA = ONE / DSQRT(TEMP1)
00906
00907
00908 ELSE
00909 SCONDA = - ONE
00910 END IF
00911 END IF
00912
00913 L2PERT = L2PERT .AND. ( DABS( A(1,1)/A(NR,NR) ) .GT. DSQRT(BIG1) )
00914
00915
00916
00917
00918
00919 IF ( .NOT. ( RSVEC .OR. LSVEC ) ) THEN
00920
00921
00922
00923
00924 DO 1946 p = 1, MIN0( N-1, NR )
00925 CALL DCOPY( N-p, A(p,p+1), LDA, A(p+1,p), 1 )
00926 1946 CONTINUE
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940 IF ( .NOT. ALMORT ) THEN
00941
00942 IF ( L2PERT ) THEN
00943
00944 XSC = EPSLN / DBLE(N)
00945 DO 4947 q = 1, NR
00946 TEMP1 = XSC*DABS(A(q,q))
00947 DO 4949 p = 1, N
00948 IF ( ( (p.GT.q) .AND. (DABS(A(p,q)).LE.TEMP1) )
00949 & .OR. ( p .LT. q ) )
00950 & A(p,q) = DSIGN( TEMP1, A(p,q) )
00951 4949 CONTINUE
00952 4947 CONTINUE
00953 ELSE
00954 CALL DLASET( 'U', NR-1,NR-1, ZERO,ZERO, A(1,2),LDA )
00955 END IF
00956
00957
00958
00959 CALL DGEQRF( N,NR, A,LDA, WORK, WORK(N+1),LWORK-N, IERR )
00960
00961
00962 DO 1948 p = 1, NR - 1
00963 CALL DCOPY( NR-p, A(p,p+1), LDA, A(p+1,p), 1 )
00964 1948 CONTINUE
00965
00966 END IF
00967
00968
00969
00970
00971
00972 IF ( L2PERT ) THEN
00973
00974 XSC = EPSLN / DBLE(N)
00975 DO 1947 q = 1, NR
00976 TEMP1 = XSC*DABS(A(q,q))
00977 DO 1949 p = 1, NR
00978 IF ( ( (p.GT.q) .AND. (DABS(A(p,q)).LE.TEMP1) )
00979 & .OR. ( p .LT. q ) )
00980 & A(p,q) = DSIGN( TEMP1, A(p,q) )
00981 1949 CONTINUE
00982 1947 CONTINUE
00983 ELSE
00984 CALL DLASET( 'U', NR-1, NR-1, ZERO, ZERO, A(1,2), LDA )
00985 END IF
00986
00987
00988
00989
00990
00991 CALL DGESVJ( 'L', 'NoU', 'NoV', NR, NR, A, LDA, SVA,
00992 & N, V, LDV, WORK, LWORK, INFO )
00993
00994 SCALEM = WORK(1)
00995 NUMRANK = IDNINT(WORK(2))
00996
00997
00998 ELSE IF ( RSVEC .AND. ( .NOT. LSVEC ) ) THEN
00999
01000
01001
01002 IF ( ALMORT ) THEN
01003
01004
01005 DO 1998 p = 1, NR
01006 CALL DCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )
01007 1998 CONTINUE
01008 CALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01009
01010 CALL DGESVJ( 'L','U','N', N, NR, V,LDV, SVA, NR, A,LDA,
01011 & WORK, LWORK, INFO )
01012 SCALEM = WORK(1)
01013 NUMRANK = IDNINT(WORK(2))
01014
01015 ELSE
01016
01017
01018
01019
01020 CALL DLASET( 'Lower', NR-1, NR-1, ZERO, ZERO, A(2,1), LDA )
01021 CALL DGELQF( NR, N, A, LDA, WORK, WORK(N+1), LWORK-N, IERR)
01022 CALL DLACPY( 'Lower', NR, NR, A, LDA, V, LDV )
01023 CALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01024 CALL DGEQRF( NR, NR, V, LDV, WORK(N+1), WORK(2*N+1),
01025 & LWORK-2*N, IERR )
01026 DO 8998 p = 1, NR
01027 CALL DCOPY( NR-p+1, V(p,p), LDV, V(p,p), 1 )
01028 8998 CONTINUE
01029 CALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01030
01031 CALL DGESVJ( 'Lower', 'U','N', NR, NR, V,LDV, SVA, NR, U,
01032 & LDU, WORK(N+1), LWORK, INFO )
01033 SCALEM = WORK(N+1)
01034 NUMRANK = IDNINT(WORK(N+2))
01035 IF ( NR .LT. N ) THEN
01036 CALL DLASET( 'A',N-NR, NR, ZERO,ZERO, V(NR+1,1), LDV )
01037 CALL DLASET( 'A',NR, N-NR, ZERO,ZERO, V(1,NR+1), LDV )
01038 CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE, V(NR+1,NR+1), LDV )
01039 END IF
01040
01041 CALL DORMLQ( 'Left', 'Transpose', N, N, NR, A, LDA, WORK,
01042 & V, LDV, WORK(N+1), LWORK-N, IERR )
01043
01044 END IF
01045
01046 DO 8991 p = 1, N
01047 CALL DCOPY( N, V(p,1), LDV, A(IWORK(p),1), LDA )
01048 8991 CONTINUE
01049 CALL DLACPY( 'All', N, N, A, LDA, V, LDV )
01050
01051 IF ( TRANSP ) THEN
01052 CALL DLACPY( 'All', N, N, V, LDV, U, LDU )
01053 END IF
01054
01055 ELSE IF ( LSVEC .AND. ( .NOT. RSVEC ) ) THEN
01056
01057
01058
01059
01060
01061 DO 1965 p = 1, NR
01062 CALL DCOPY( N-p+1, A(p,p), LDA, U(p,p), 1 )
01063 1965 CONTINUE
01064 CALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )
01065
01066 CALL DGEQRF( N, NR, U, LDU, WORK(N+1), WORK(2*N+1),
01067 & LWORK-2*N, IERR )
01068
01069 DO 1967 p = 1, NR - 1
01070 CALL DCOPY( NR-p, U(p,p+1), LDU, U(p+1,p), 1 )
01071 1967 CONTINUE
01072 CALL DLASET( 'Upper', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )
01073
01074 CALL DGESVJ( 'Lower', 'U', 'N', NR,NR, U, LDU, SVA, NR, A,
01075 & LDA, WORK(N+1), LWORK-N, INFO )
01076 SCALEM = WORK(N+1)
01077 NUMRANK = IDNINT(WORK(N+2))
01078
01079 IF ( NR .LT. M ) THEN
01080 CALL DLASET( 'A', M-NR, NR,ZERO, ZERO, U(NR+1,1), LDU )
01081 IF ( NR .LT. N1 ) THEN
01082 CALL DLASET( 'A',NR, N1-NR, ZERO, ZERO, U(1,NR+1), LDU )
01083 CALL DLASET( 'A',M-NR,N1-NR,ZERO,ONE,U(NR+1,NR+1), LDU )
01084 END IF
01085 END IF
01086
01087 CALL DORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,
01088 & LDU, WORK(N+1), LWORK-N, IERR )
01089
01090 IF ( ROWPIV )
01091 & CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01092
01093 DO 1974 p = 1, N1
01094 XSC = ONE / DNRM2( M, U(1,p), 1 )
01095 CALL DSCAL( M, XSC, U(1,p), 1 )
01096 1974 CONTINUE
01097
01098 IF ( TRANSP ) THEN
01099 CALL DLACPY( 'All', N, N, U, LDU, V, LDV )
01100 END IF
01101
01102 ELSE
01103
01104
01105
01106 IF ( .NOT. JRACC ) THEN
01107
01108 IF ( .NOT. ALMORT ) THEN
01109
01110
01111
01112
01113
01114
01115
01116
01117 DO 1968 p = 1, NR
01118 CALL DCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )
01119 1968 CONTINUE
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 IF ( L2PERT ) THEN
01134 XSC = DSQRT(SMALL)
01135 DO 2969 q = 1, NR
01136 TEMP1 = XSC*DABS( V(q,q) )
01137 DO 2968 p = 1, N
01138 IF ( ( p .GT. q ) .AND. ( DABS(V(p,q)) .LE. TEMP1 )
01139 & .OR. ( p .LT. q ) )
01140 & V(p,q) = DSIGN( TEMP1, V(p,q) )
01141 IF ( p. LT. q ) V(p,q) = - V(p,q)
01142 2968 CONTINUE
01143 2969 CONTINUE
01144 ELSE
01145 CALL DLASET( 'U', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01146 END IF
01147
01148
01149
01150
01151
01152 CALL DLACPY( 'L', NR, NR, V, LDV, WORK(2*N+1), NR )
01153 DO 3950 p = 1, NR
01154 TEMP1 = DNRM2(NR-p+1,WORK(2*N+(p-1)*NR+p),1)
01155 CALL DSCAL(NR-p+1,ONE/TEMP1,WORK(2*N+(p-1)*NR+p),1)
01156 3950 CONTINUE
01157 CALL DPOCON('Lower',NR,WORK(2*N+1),NR,ONE,TEMP1,
01158 & WORK(2*N+NR*NR+1),IWORK(M+2*N+1),IERR)
01159 CONDR1 = ONE / DSQRT(TEMP1)
01160
01161
01162
01163
01164
01165 COND_OK = DSQRT(DBLE(NR))
01166
01167
01168 IF ( CONDR1 .LT. COND_OK ) THEN
01169
01170
01171
01172
01173 CALL DGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),
01174 & LWORK-2*N, IERR )
01175
01176 IF ( L2PERT ) THEN
01177 XSC = DSQRT(SMALL)/EPSLN
01178 DO 3959 p = 2, NR
01179 DO 3958 q = 1, p - 1
01180 TEMP1 = XSC * DMIN1(DABS(V(p,p)),DABS(V(q,q)))
01181 IF ( DABS(V(q,p)) .LE. TEMP1 )
01182 & V(q,p) = DSIGN( TEMP1, V(q,p) )
01183 3958 CONTINUE
01184 3959 CONTINUE
01185 END IF
01186
01187 IF ( NR .NE. N )
01188
01189 & CALL DLACPY( 'A', N, NR, V, LDV, WORK(2*N+1), N )
01190
01191
01192 DO 1969 p = 1, NR - 1
01193 CALL DCOPY( NR-p, V(p,p+1), LDV, V(p+1,p), 1 )
01194 1969 CONTINUE
01195
01196 CONDR2 = CONDR1
01197
01198 ELSE
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 DO 3003 p = 1, NR
01209 IWORK(N+p) = 0
01210 3003 CONTINUE
01211 CALL DGEQP3( N, NR, V, LDV, IWORK(N+1), WORK(N+1),
01212 & WORK(2*N+1), LWORK-2*N, IERR )
01213
01214
01215 IF ( L2PERT ) THEN
01216 XSC = DSQRT(SMALL)
01217 DO 3969 p = 2, NR
01218 DO 3968 q = 1, p - 1
01219 TEMP1 = XSC * DMIN1(DABS(V(p,p)),DABS(V(q,q)))
01220 IF ( DABS(V(q,p)) .LE. TEMP1 )
01221 & V(q,p) = DSIGN( TEMP1, V(q,p) )
01222 3968 CONTINUE
01223 3969 CONTINUE
01224 END IF
01225
01226 CALL DLACPY( 'A', N, NR, V, LDV, WORK(2*N+1), N )
01227
01228 IF ( L2PERT ) THEN
01229 XSC = DSQRT(SMALL)
01230 DO 8970 p = 2, NR
01231 DO 8971 q = 1, p - 1
01232 TEMP1 = XSC * DMIN1(DABS(V(p,p)),DABS(V(q,q)))
01233 V(p,q) = - DSIGN( TEMP1, V(q,p) )
01234 8971 CONTINUE
01235 8970 CONTINUE
01236 ELSE
01237 CALL DLASET( 'L',NR-1,NR-1,ZERO,ZERO,V(2,1),LDV )
01238 END IF
01239
01240 CALL DGELQF( NR, NR, V, LDV, WORK(2*N+N*NR+1),
01241 & WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, IERR )
01242
01243 CALL DLACPY( 'L',NR,NR,V,LDV,WORK(2*N+N*NR+NR+1),NR )
01244 DO 4950 p = 1, NR
01245 TEMP1 = DNRM2( p, WORK(2*N+N*NR+NR+p), NR )
01246 CALL DSCAL( p, ONE/TEMP1, WORK(2*N+N*NR+NR+p), NR )
01247 4950 CONTINUE
01248 CALL DPOCON( 'L',NR,WORK(2*N+N*NR+NR+1),NR,ONE,TEMP1,
01249 & WORK(2*N+N*NR+NR+NR*NR+1),IWORK(M+2*N+1),IERR )
01250 CONDR2 = ONE / DSQRT(TEMP1)
01251
01252 IF ( CONDR2 .GE. COND_OK ) THEN
01253
01254
01255
01256
01257 CALL DLACPY( 'U', NR, NR, V, LDV, WORK(2*N+1), N )
01258
01259
01260 END IF
01261
01262 END IF
01263
01264 IF ( L2PERT ) THEN
01265 XSC = DSQRT(SMALL)
01266 DO 4968 q = 2, NR
01267 TEMP1 = XSC * V(q,q)
01268 DO 4969 p = 1, q - 1
01269
01270 V(p,q) = - DSIGN( TEMP1, V(p,q) )
01271 4969 CONTINUE
01272 4968 CONTINUE
01273 ELSE
01274 CALL DLASET( 'U', NR-1,NR-1, ZERO,ZERO, V(1,2), LDV )
01275 END IF
01276
01277
01278
01279
01280
01281
01282
01283 IF ( CONDR1 .LT. COND_OK ) THEN
01284
01285 CALL DGESVJ( 'L','U','N',NR,NR,V,LDV,SVA,NR,U,
01286 & LDU,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,INFO )
01287 SCALEM = WORK(2*N+N*NR+NR+1)
01288 NUMRANK = IDNINT(WORK(2*N+N*NR+NR+2))
01289 DO 3970 p = 1, NR
01290 CALL DCOPY( NR, V(1,p), 1, U(1,p), 1 )
01291 CALL DSCAL( NR, SVA(p), V(1,p), 1 )
01292 3970 CONTINUE
01293
01294
01295
01296 IF ( NR. EQ. N ) THEN
01297
01298
01299
01300
01301 CALL DTRSM( 'L','U','N','N', NR,NR,ONE, A,LDA, V,LDV )
01302 ELSE
01303
01304
01305
01306
01307 CALL DTRSM('L','U','T','N',NR,NR,ONE,WORK(2*N+1),
01308 & N,V,LDV)
01309 IF ( NR .LT. N ) THEN
01310 CALL DLASET('A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV)
01311 CALL DLASET('A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV)
01312 CALL DLASET('A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV)
01313 END IF
01314 CALL DORMQR('L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01315 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR)
01316 END IF
01317
01318 ELSE IF ( CONDR2 .LT. COND_OK ) THEN
01319
01320
01321
01322
01323
01324
01325
01326 CALL DGESVJ( 'L', 'U', 'N', NR, NR, V, LDV, SVA, NR, U,
01327 & LDU, WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, INFO )
01328 SCALEM = WORK(2*N+N*NR+NR+1)
01329 NUMRANK = IDNINT(WORK(2*N+N*NR+NR+2))
01330 DO 3870 p = 1, NR
01331 CALL DCOPY( NR, V(1,p), 1, U(1,p), 1 )
01332 CALL DSCAL( NR, SVA(p), U(1,p), 1 )
01333 3870 CONTINUE
01334 CALL DTRSM('L','U','N','N',NR,NR,ONE,WORK(2*N+1),N,U,LDU)
01335
01336 DO 873 q = 1, NR
01337 DO 872 p = 1, NR
01338 WORK(2*N+N*NR+NR+IWORK(N+p)) = U(p,q)
01339 872 CONTINUE
01340 DO 874 p = 1, NR
01341 U(p,q) = WORK(2*N+N*NR+NR+p)
01342 874 CONTINUE
01343 873 CONTINUE
01344 IF ( NR .LT. N ) THEN
01345 CALL DLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
01346 CALL DLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
01347 CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
01348 END IF
01349 CALL DORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01350 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )
01351 ELSE
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 CALL DGESVJ( 'L', 'U', 'V', NR, NR, V, LDV, SVA, NR, U,
01364 & LDU, WORK(2*N+N*NR+NR+1), LWORK-2*N-N*NR-NR, INFO )
01365 SCALEM = WORK(2*N+N*NR+NR+1)
01366 NUMRANK = IDNINT(WORK(2*N+N*NR+NR+2))
01367 IF ( NR .LT. N ) THEN
01368 CALL DLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
01369 CALL DLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
01370 CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
01371 END IF
01372 CALL DORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01373 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )
01374
01375 CALL DORMLQ( 'L', 'T', NR, NR, NR, WORK(2*N+1), N,
01376 & WORK(2*N+N*NR+1), U, LDU, WORK(2*N+N*NR+NR+1),
01377 & LWORK-2*N-N*NR-NR, IERR )
01378 DO 773 q = 1, NR
01379 DO 772 p = 1, NR
01380 WORK(2*N+N*NR+NR+IWORK(N+p)) = U(p,q)
01381 772 CONTINUE
01382 DO 774 p = 1, NR
01383 U(p,q) = WORK(2*N+N*NR+NR+p)
01384 774 CONTINUE
01385 773 CONTINUE
01386
01387 END IF
01388
01389
01390
01391
01392
01393 TEMP1 = DSQRT(DBLE(N)) * EPSLN
01394 DO 1972 q = 1, N
01395 DO 972 p = 1, N
01396 WORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)
01397 972 CONTINUE
01398 DO 973 p = 1, N
01399 V(p,q) = WORK(2*N+N*NR+NR+p)
01400 973 CONTINUE
01401 XSC = ONE / DNRM2( N, V(1,q), 1 )
01402 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01403 & CALL DSCAL( N, XSC, V(1,q), 1 )
01404 1972 CONTINUE
01405
01406
01407 IF ( NR .LT. M ) THEN
01408 CALL DLASET( 'A', M-NR, NR, ZERO, ZERO, U(NR+1,1), LDU )
01409 IF ( NR .LT. N1 ) THEN
01410 CALL DLASET('A',NR,N1-NR,ZERO,ZERO,U(1,NR+1),LDU)
01411 CALL DLASET('A',M-NR,N1-NR,ZERO,ONE,U(NR+1,NR+1),LDU)
01412 END IF
01413 END IF
01414
01415
01416
01417
01418 CALL DORMQR( 'Left', 'No_Tr', M, N1, N, A, LDA, WORK, U,
01419 & LDU, WORK(N+1), LWORK-N, IERR )
01420
01421
01422 TEMP1 = DSQRT(DBLE(M)) * EPSLN
01423 DO 1973 p = 1, NR
01424 XSC = ONE / DNRM2( M, U(1,p), 1 )
01425 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01426 & CALL DSCAL( M, XSC, U(1,p), 1 )
01427 1973 CONTINUE
01428
01429
01430
01431
01432 IF ( ROWPIV )
01433 & CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01434
01435 ELSE
01436
01437
01438
01439
01440 CALL DLACPY( 'Upper', N, N, A, LDA, WORK(N+1), N )
01441 IF ( L2PERT ) THEN
01442 XSC = DSQRT(SMALL)
01443 DO 5970 p = 2, N
01444 TEMP1 = XSC * WORK( N + (p-1)*N + p )
01445 DO 5971 q = 1, p - 1
01446 WORK(N+(q-1)*N+p)=-DSIGN(TEMP1,WORK(N+(p-1)*N+q))
01447 5971 CONTINUE
01448 5970 CONTINUE
01449 ELSE
01450 CALL DLASET( 'Lower',N-1,N-1,ZERO,ZERO,WORK(N+2),N )
01451 END IF
01452
01453 CALL DGESVJ( 'Upper', 'U', 'N', N, N, WORK(N+1), N, SVA,
01454 & N, U, LDU, WORK(N+N*N+1), LWORK-N-N*N, INFO )
01455
01456 SCALEM = WORK(N+N*N+1)
01457 NUMRANK = IDNINT(WORK(N+N*N+2))
01458 DO 6970 p = 1, N
01459 CALL DCOPY( N, WORK(N+(p-1)*N+1), 1, U(1,p), 1 )
01460 CALL DSCAL( N, SVA(p), WORK(N+(p-1)*N+1), 1 )
01461 6970 CONTINUE
01462
01463 CALL DTRSM( 'Left', 'Upper', 'NoTrans', 'No UD', N, N,
01464 & ONE, A, LDA, WORK(N+1), N )
01465 DO 6972 p = 1, N
01466 CALL DCOPY( N, WORK(N+p), N, V(IWORK(p),1), LDV )
01467 6972 CONTINUE
01468 TEMP1 = DSQRT(DBLE(N))*EPSLN
01469 DO 6971 p = 1, N
01470 XSC = ONE / DNRM2( N, V(1,p), 1 )
01471 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01472 & CALL DSCAL( N, XSC, V(1,p), 1 )
01473 6971 CONTINUE
01474
01475
01476
01477 IF ( N .LT. M ) THEN
01478 CALL DLASET( 'A', M-N, N, ZERO, ZERO, U(NR+1,1), LDU )
01479 IF ( N .LT. N1 ) THEN
01480 CALL DLASET( 'A',N, N1-N, ZERO, ZERO, U(1,N+1),LDU )
01481 CALL DLASET( 'A',M-N,N1-N, ZERO, ONE,U(NR+1,N+1),LDU )
01482 END IF
01483 END IF
01484 CALL DORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,
01485 & LDU, WORK(N+1), LWORK-N, IERR )
01486 TEMP1 = DSQRT(DBLE(M))*EPSLN
01487 DO 6973 p = 1, N1
01488 XSC = ONE / DNRM2( M, U(1,p), 1 )
01489 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01490 & CALL DSCAL( M, XSC, U(1,p), 1 )
01491 6973 CONTINUE
01492
01493 IF ( ROWPIV )
01494 & CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01495
01496 END IF
01497
01498
01499
01500 ELSE
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512 DO 7968 p = 1, NR
01513 CALL DCOPY( N-p+1, A(p,p), LDA, V(p,p), 1 )
01514 7968 CONTINUE
01515
01516 IF ( L2PERT ) THEN
01517 XSC = DSQRT(SMALL/EPSLN)
01518 DO 5969 q = 1, NR
01519 TEMP1 = XSC*DABS( V(q,q) )
01520 DO 5968 p = 1, N
01521 IF ( ( p .GT. q ) .AND. ( DABS(V(p,q)) .LE. TEMP1 )
01522 & .OR. ( p .LT. q ) )
01523 & V(p,q) = DSIGN( TEMP1, V(p,q) )
01524 IF ( p. LT. q ) V(p,q) = - V(p,q)
01525 5968 CONTINUE
01526 5969 CONTINUE
01527 ELSE
01528 CALL DLASET( 'U', NR-1, NR-1, ZERO, ZERO, V(1,2), LDV )
01529 END IF
01530
01531 CALL DGEQRF( N, NR, V, LDV, WORK(N+1), WORK(2*N+1),
01532 & LWORK-2*N, IERR )
01533 CALL DLACPY( 'L', N, NR, V, LDV, WORK(2*N+1), N )
01534
01535 DO 7969 p = 1, NR
01536 CALL DCOPY( NR-p+1, V(p,p), LDV, U(p,p), 1 )
01537 7969 CONTINUE
01538
01539 IF ( L2PERT ) THEN
01540 XSC = DSQRT(SMALL/EPSLN)
01541 DO 9970 q = 2, NR
01542 DO 9971 p = 1, q - 1
01543 TEMP1 = XSC * DMIN1(DABS(U(p,p)),DABS(U(q,q)))
01544 U(p,q) = - DSIGN( TEMP1, U(q,p) )
01545 9971 CONTINUE
01546 9970 CONTINUE
01547 ELSE
01548 CALL DLASET('U', NR-1, NR-1, ZERO, ZERO, U(1,2), LDU )
01549 END IF
01550
01551 CALL DGESVJ( 'G', 'U', 'V', NR, NR, U, LDU, SVA,
01552 & N, V, LDV, WORK(2*N+N*NR+1), LWORK-2*N-N*NR, INFO )
01553 SCALEM = WORK(2*N+N*NR+1)
01554 NUMRANK = IDNINT(WORK(2*N+N*NR+2))
01555
01556 IF ( NR .LT. N ) THEN
01557 CALL DLASET( 'A',N-NR,NR,ZERO,ZERO,V(NR+1,1),LDV )
01558 CALL DLASET( 'A',NR,N-NR,ZERO,ZERO,V(1,NR+1),LDV )
01559 CALL DLASET( 'A',N-NR,N-NR,ZERO,ONE,V(NR+1,NR+1),LDV )
01560 END IF
01561
01562 CALL DORMQR( 'L','N',N,N,NR,WORK(2*N+1),N,WORK(N+1),
01563 & V,LDV,WORK(2*N+N*NR+NR+1),LWORK-2*N-N*NR-NR,IERR )
01564
01565
01566
01567
01568
01569 TEMP1 = DSQRT(DBLE(N)) * EPSLN
01570 DO 7972 q = 1, N
01571 DO 8972 p = 1, N
01572 WORK(2*N+N*NR+NR+IWORK(p)) = V(p,q)
01573 8972 CONTINUE
01574 DO 8973 p = 1, N
01575 V(p,q) = WORK(2*N+N*NR+NR+p)
01576 8973 CONTINUE
01577 XSC = ONE / DNRM2( N, V(1,q), 1 )
01578 IF ( (XSC .LT. (ONE-TEMP1)) .OR. (XSC .GT. (ONE+TEMP1)) )
01579 & CALL DSCAL( N, XSC, V(1,q), 1 )
01580 7972 CONTINUE
01581
01582
01583
01584
01585 IF ( N .LT. M ) THEN
01586 CALL DLASET( 'A', M-N, N, ZERO, ZERO, U(NR+1,1), LDU )
01587 IF ( N .LT. N1 ) THEN
01588 CALL DLASET( 'A',N, N1-N, ZERO, ZERO, U(1,N+1),LDU )
01589 CALL DLASET( 'A',M-N,N1-N, ZERO, ONE,U(NR+1,N+1),LDU )
01590 END IF
01591 END IF
01592
01593 CALL DORMQR( 'Left', 'No Tr', M, N1, N, A, LDA, WORK, U,
01594 & LDU, WORK(N+1), LWORK-N, IERR )
01595
01596 IF ( ROWPIV )
01597 & CALL DLASWP( N1, U, LDU, 1, M-1, IWORK(2*N+1), -1 )
01598
01599
01600 END IF
01601 IF ( TRANSP ) THEN
01602
01603 DO 6974 p = 1, N
01604 CALL DSWAP( N, U(1,p), 1, V(1,p), 1 )
01605 6974 CONTINUE
01606 END IF
01607
01608 END IF
01609
01610
01611
01612
01613 IF ( USCAL2 .LE. (BIG/SVA(1))*USCAL1 ) THEN
01614 CALL DLASCL( 'G', 0, 0, USCAL1, USCAL2, NR, 1, SVA, N, IERR )
01615 USCAL1 = ONE
01616 USCAL2 = ONE
01617 END IF
01618
01619 IF ( NR .LT. N ) THEN
01620 DO 3004 p = NR+1, N
01621 SVA(p) = ZERO
01622 3004 CONTINUE
01623 END IF
01624
01625 WORK(1) = USCAL2 * SCALEM
01626 WORK(2) = USCAL1
01627 IF ( ERREST ) WORK(3) = SCONDA
01628 IF ( LSVEC .AND. RSVEC ) THEN
01629 WORK(4) = CONDR1
01630 WORK(5) = CONDR2
01631 END IF
01632 IF ( L2TRAN ) THEN
01633 WORK(6) = ENTRA
01634 WORK(7) = ENTRAT
01635 END IF
01636
01637 IWORK(1) = NR
01638 IWORK(2) = NUMRANK
01639 IWORK(3) = WARNING
01640
01641 RETURN
01642
01643
01644
01645 END
01646