268
  269
  270
  271
  272
  273
  274      CHARACTER          JOBU, JOBVT, RANGE
  275      INTEGER            IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
  276      REAL               VL, VU
  277
  278
  279      INTEGER            IWORK( * )
  280      REAL               S( * ), RWORK( * )
  281      COMPLEX            A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
  282     $                   WORK( * )
  283
  284
  285
  286
  287
  288      COMPLEX            CZERO, CONE
  289      parameter( czero = ( 0.0e0, 0.0e0 ),
  290     $                   cone = ( 1.0e0, 0.0e0 ) )
  291      REAL               ZERO, ONE
  292      parameter( zero = 0.0e0, one = 1.0e0 )
  293
  294
  295      CHARACTER          JOBZ, RNGTGK
  296      LOGICAL            ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
  297      INTEGER            I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
  298     $                   ITAU, ITAUP, ITAUQ, ITEMP, ITEMPR, ITGKZ,
  299     $                   IUTGK, J, K, MAXWRK, MINMN, MINWRK, MNTHR
  300      REAL               ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
  301
  302
  303      REAL               DUM( 1 )
  304
  305
  310
  311
  312      LOGICAL            LSAME
  313      INTEGER            ILAENV
  314      REAL               SLAMCH, CLANGE, SROUNDUP_LWORK
  317
  318
  319      INTRINSIC          max, min, sqrt
  320
  321
  322
  323
  324
  325      ns = 0
  326      info = 0
  328      lquery = ( lwork.EQ.-1 )
  329      minmn = min( m, n )
  330 
  331      wantu = 
lsame( jobu, 
'V' )
 
  332      wantvt = 
lsame( jobvt, 
'V' )
 
  333      IF( wantu .OR. wantvt ) THEN
  334         jobz = 'V'
  335      ELSE
  336         jobz = 'N'
  337      END IF
  338      alls = 
lsame( range, 
'A' )
 
  339      vals = 
lsame( range, 
'V' )
 
  340      inds = 
lsame( range, 
'I' )
 
  341
  342      info = 0
  343      IF( .NOT.
lsame( jobu, 
'V' ) .AND.
 
  344     $    .NOT.
lsame( jobu, 
'N' ) ) 
THEN 
  345         info = -1
  346      ELSE IF( .NOT.
lsame( jobvt, 
'V' ) .AND.
 
  347     $         .NOT.
lsame( jobvt, 
'N' ) ) 
THEN 
  348         info = -2
  349      ELSE IF( .NOT.( alls .OR. vals .OR. inds ) ) THEN
  350         info = -3
  351      ELSE IF( m.LT.0 ) THEN
  352         info = -4
  353      ELSE IF( n.LT.0 ) THEN
  354         info = -5
  355      ELSE IF( m.GT.lda ) THEN
  356         info = -7
  357      ELSE IF( minmn.GT.0 ) THEN
  358         IF( vals ) THEN
  359            IF( vl.LT.zero ) THEN
  360               info = -8
  361            ELSE IF( vu.LE.vl ) THEN
  362               info = -9
  363            END IF
  364         ELSE IF( inds ) THEN
  365            IF( il.LT.1 .OR. il.GT.max( 1, minmn ) ) THEN
  366               info = -10
  367            ELSE IF( iu.LT.min( minmn, il ) .OR. iu.GT.minmn ) THEN
  368               info = -11
  369            END IF
  370         END IF
  371         IF( info.EQ.0 ) THEN
  372            IF( wantu .AND. ldu.LT.m ) THEN
  373               info = -15
  374            ELSE IF( wantvt ) THEN
  375               IF( inds ) THEN
  376                   IF( ldvt.LT.iu-il+1 ) THEN
  377                       info = -17
  378                   END IF
  379               ELSE IF( ldvt.LT.minmn ) THEN
  380                   info = -17
  381               END IF
  382            END IF
  383         END IF
  384      END IF
  385
  386
  387
  388
  389
  390
  391
  392
  393      IF( info.EQ.0 ) THEN
  394         minwrk = 1
  395         maxwrk = 1
  396         IF( minmn.GT.0 ) THEN
  397            IF( m.GE.n ) THEN
  398               mnthr = 
ilaenv( 6, 
'CGESVD', jobu // jobvt, m, n, 0,
 
  399     $                         0 )
  400               IF( m.GE.mnthr ) THEN
  401
  402
  403
  404                  minwrk = n*(n+5)
  405                  maxwrk = n + n*
ilaenv(1,
'CGEQRF',
' ',m,n,-1,-1)
 
  406                  maxwrk = max(maxwrk,
  407     $                     n*n+2*n+2*n*
ilaenv(1,
'CGEBRD',
' ',n,n,-1,
 
  408     $                                         -1))
  409                  IF (wantu .OR. wantvt) THEN
  410                     maxwrk = max(maxwrk,
  411     $                       n*n+2*n+n*
ilaenv(1,
'CUNMQR',
'LN',n,n,n,
 
  412     $                                         -1))
  413                  END IF
  414               ELSE
  415
  416
  417
  418                  minwrk = 3*n + m
  419                  maxwrk = 2*n + (m+n)*
ilaenv(1,
'CGEBRD',
' ',m,n,-1,
 
  420     $                             -1)
  421                  IF (wantu .OR. wantvt) THEN
  422                     maxwrk = max(maxwrk,
  423     $                        2*n+n*
ilaenv(1,
'CUNMQR',
'LN',n,n,n,-1))
 
  424                  END IF
  425               END IF
  426            ELSE
  427               mnthr = 
ilaenv( 6, 
'CGESVD', jobu // jobvt, m, n, 0,
 
  428     $                         0 )
  429               IF( n.GE.mnthr ) THEN
  430
  431
  432
  433                  minwrk = m*(m+5)
  434                  maxwrk = m + m*
ilaenv(1,
'CGELQF',
' ',m,n,-1,-1)
 
  435                  maxwrk = max(maxwrk,
  436     $                     m*m+2*m+2*m*
ilaenv(1,
'CGEBRD',
' ',m,m,-1,
 
  437     $                                         -1))
  438                  IF (wantu .OR. wantvt) THEN
  439                     maxwrk = max(maxwrk,
  440     $                       m*m+2*m+m*
ilaenv(1,
'CUNMQR',
'LN',m,m,m,
 
  441     $                                         -1))
  442                  END IF
  443               ELSE
  444
  445
  446
  447
  448                  minwrk = 3*m + n
  449                  maxwrk = 2*m + (m+n)*
ilaenv(1,
'CGEBRD',
' ',m,n,-1,
 
  450     $                             -1)
  451                  IF (wantu .OR. wantvt) THEN
  452                     maxwrk = max(maxwrk,
  453     $                        2*m+m*
ilaenv(1,
'CUNMQR',
'LN',m,m,m,-1))
 
  454                  END IF
  455               END IF
  456            END IF
  457         END IF
  458         maxwrk = max( maxwrk, minwrk )
  460
  461         IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
  462            info = -19
  463         END IF
  464      END IF
  465
  466      IF( info.NE.0 ) THEN
  467         CALL xerbla( 
'CGESVDX', -info )
 
  468         RETURN
  469      ELSE IF( lquery ) THEN
  470         RETURN
  471      END IF
  472
  473
  474
  475      IF( minmn.EQ.0 ) THEN
  476         RETURN
  477      END IF
  478
  479
  480
  481      IF( alls ) THEN
  482         rngtgk = 'I'
  483         iltgk = 1
  484         iutgk = min( m, n )
  485      ELSE IF( inds ) THEN
  486         rngtgk = 'I'
  487         iltgk = il
  488         iutgk = iu
  489      ELSE
  490         rngtgk = 'V'
  491         iltgk = 0
  492         iutgk = 0
  493      END IF
  494
  495
  496
  498      smlnum = sqrt( 
slamch( 
'S' ) ) / eps
 
  499      bignum = one / smlnum
  500
  501
  502
  503      anrm = 
clange( 
'M', m, n, a, lda, dum )
 
  504      iscl = 0
  505      IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
  506         iscl = 1
  507         CALL clascl( 
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
 
  508      ELSE IF( anrm.GT.bignum ) THEN
  509         iscl = 1
  510         CALL clascl( 
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
 
  511      END IF
  512
  513      IF( m.GE.n ) THEN
  514
  515
  516
  517
  518
  519         IF( m.GE.mnthr ) THEN
  520
  521
  522
  523
  524
  525
  526
  527
  528
  529            itau = 1
  530            itemp = itau + n
  531            CALL cgeqrf( m, n, a, lda, work( itau ), work( itemp ),
 
  532     $                   lwork-itemp+1, info )
  533
  534
  535
  536
  537            iqrf = itemp
  538            itauq = itemp + n*n
  539            itaup = itauq + n
  540            itemp = itaup + n
  541            id = 1
  542            ie = id + n
  543            itgkz = ie + n
  544            CALL clacpy( 
'U', n, n, a, lda, work( iqrf ), n )
 
  545            CALL claset( 
'L', n-1, n-1, czero, czero,
 
  546     $                   work( iqrf+1 ), n )
  547            CALL cgebrd( n, n, work( iqrf ), n, rwork( id ),
 
  548     $                   rwork( ie ), work( itauq ), work( itaup ),
  549     $                   work( itemp ), lwork-itemp+1, info )
  550            itempr = itgkz + n*(n*2+1)
  551
  552
  553
  554
  555            CALL sbdsvdx( 
'U', jobz, rngtgk, n, rwork( id ),
 
  556     $                    rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
  557     $                    rwork( itgkz ), n*2, rwork( itempr ),
  558     $                    iwork, info)
  559
  560
  561
  562            IF( wantu ) THEN
  563               k = itgkz
  564               DO i = 1, ns
  565                  DO j = 1, n
  566                     u( j, i ) = cmplx( rwork( k ), zero )
  567                     k = k + 1
  568                  END DO
  569                  k = k + n
  570               END DO
  571               CALL claset( 
'A', m-n, ns, czero, czero, u( n+1,1 ),
 
  572     $                      ldu)
  573
  574
  575
  576
  577               CALL cunmbr( 
'Q', 
'L', 
'N', n, ns, n, work( iqrf ), n,
 
  578     $                      work( itauq ), u, ldu, work( itemp ),
  579     $                      lwork-itemp+1, info )
  580
  581
  582
  583
  584               CALL cunmqr( 
'L', 
'N', m, ns, n, a, lda,
 
  585     $                      work( itau ), u, ldu, work( itemp ),
  586     $                      lwork-itemp+1, info )
  587            END IF
  588
  589
  590
  591            IF( wantvt) THEN
  592               k = itgkz + n
  593               DO i = 1, ns
  594                  DO j = 1, n
  595                     vt( i, j ) = cmplx( rwork( k ), zero )
  596                     k = k + 1
  597                  END DO
  598                  k = k + n
  599               END DO
  600
  601
  602
  603
  604               CALL cunmbr( 
'P', 
'R', 
'C', ns, n, n, work( iqrf ), n,
 
  605     $                      work( itaup ), vt, ldvt, work( itemp ),
  606     $                      lwork-itemp+1, info )
  607            END IF
  608         ELSE
  609
  610
  611
  612
  613
  614
  615
  616
  617
  618            itauq = 1
  619            itaup = itauq + n
  620            itemp = itaup + n
  621            id = 1
  622            ie = id + n
  623            itgkz = ie + n
  624            CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
 
  625     $                   work( itauq ), work( itaup ), work( itemp ),
  626     $                   lwork-itemp+1, info )
  627            itempr = itgkz + n*(n*2+1)
  628
  629
  630
  631
  632            CALL sbdsvdx( 
'U', jobz, rngtgk, n, rwork( id ),
 
  633     $                    rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
  634     $                    rwork( itgkz ), n*2, rwork( itempr ),
  635     $                    iwork, info)
  636
  637
  638
  639            IF( wantu ) THEN
  640               k = itgkz
  641               DO i = 1, ns
  642                  DO j = 1, n
  643                     u( j, i ) = cmplx( rwork( k ), zero )
  644                     k = k + 1
  645                  END DO
  646                  k = k + n
  647               END DO
  648               CALL claset( 
'A', m-n, ns, czero, czero, u( n+1,1 ),
 
  649     $                      ldu)
  650
  651
  652
  653
  654               CALL cunmbr( 
'Q', 
'L', 
'N', m, ns, n, a, lda,
 
  655     $                      work( itauq ), u, ldu, work( itemp ),
  656     $                      lwork-itemp+1, ierr )
  657            END IF
  658
  659
  660
  661            IF( wantvt) THEN
  662               k = itgkz + n
  663               DO i = 1, ns
  664                  DO j = 1, n
  665                     vt( i, j ) = cmplx( rwork( k ), zero )
  666                     k = k + 1
  667                  END DO
  668                  k = k + n
  669               END DO
  670
  671
  672
  673
  674               CALL cunmbr( 
'P', 
'R', 
'C', ns, n, n, a, lda,
 
  675     $                      work( itaup ), vt, ldvt, work( itemp ),
  676     $                      lwork-itemp+1, ierr )
  677            END IF
  678         END IF
  679      ELSE
  680
  681
  682
  683
  684         IF( n.GE.mnthr ) THEN
  685
  686
  687
  688
  689
  690
  691
  692
  693
  694            itau = 1
  695            itemp = itau + m
  696            CALL cgelqf( m, n, a, lda, work( itau ), work( itemp ),
 
  697     $                   lwork-itemp+1, info )
  698 
  699
  700
  701
  702            ilqf = itemp
  703            itauq = ilqf + m*m
  704            itaup = itauq + m
  705            itemp = itaup + m
  706            id = 1
  707            ie = id + m
  708            itgkz = ie + m
  709            CALL clacpy( 
'L', m, m, a, lda, work( ilqf ), m )
 
  710            CALL claset( 
'U', m-1, m-1, czero, czero,
 
  711     $                   work( ilqf+m ), m )
  712            CALL cgebrd( m, m, work( ilqf ), m, rwork( id ),
 
  713     $                   rwork( ie ), work( itauq ), work( itaup ),
  714     $                   work( itemp ), lwork-itemp+1, info )
  715            itempr = itgkz + m*(m*2+1)
  716
  717
  718
  719
  720            CALL sbdsvdx( 
'U', jobz, rngtgk, m, rwork( id ),
 
  721     $                    rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
  722     $                    rwork( itgkz ), m*2, rwork( itempr ),
  723     $                    iwork, info)
  724
  725
  726
  727            IF( wantu ) THEN
  728               k = itgkz
  729               DO i = 1, ns
  730                  DO j = 1, m
  731                     u( j, i ) = cmplx( rwork( k ), zero )
  732                     k = k + 1
  733                  END DO
  734                  k = k + m
  735               END DO
  736
  737
  738
  739
  740               CALL cunmbr( 
'Q', 
'L', 
'N', m, ns, m, work( ilqf ), m,
 
  741     $                      work( itauq ), u, ldu, work( itemp ),
  742     $                      lwork-itemp+1, info )
  743            END IF
  744
  745
  746
  747            IF( wantvt) THEN
  748               k = itgkz + m
  749               DO i = 1, ns
  750                  DO j = 1, m
  751                     vt( i, j ) = cmplx( rwork( k ), zero )
  752                     k = k + 1
  753                  END DO
  754                  k = k + m
  755               END DO
  756               CALL claset( 
'A', ns, n-m, czero, czero,
 
  757     $                      vt( 1,m+1 ), ldvt )
  758
  759
  760
  761
  762               CALL cunmbr( 
'P', 
'R', 
'C', ns, m, m, work( ilqf ), m,
 
  763     $                      work( itaup ), vt, ldvt, work( itemp ),
  764     $                      lwork-itemp+1, info )
  765
  766
  767
  768
  769               CALL cunmlq( 
'R', 
'N', ns, n, m, a, lda,
 
  770     $                      work( itau ), vt, ldvt, work( itemp ),
  771     $                      lwork-itemp+1, info )
  772            END IF
  773         ELSE
  774
  775
  776
  777
  778
  779
  780
  781
  782
  783            itauq = 1
  784            itaup = itauq + m
  785            itemp = itaup + m
  786            id = 1
  787            ie = id + m
  788            itgkz = ie + m
  789            CALL cgebrd( m, n, a, lda, rwork( id ), rwork( ie ),
 
  790     $                   work( itauq ), work( itaup ), work( itemp ),
  791     $                   lwork-itemp+1, info )
  792            itempr = itgkz + m*(m*2+1)
  793
  794
  795
  796
  797            CALL sbdsvdx( 
'L', jobz, rngtgk, m, rwork( id ),
 
  798     $                    rwork( ie ), vl, vu, iltgk, iutgk, ns, s,
  799     $                    rwork( itgkz ), m*2, rwork( itempr ),
  800     $                    iwork, info)
  801
  802
  803
  804            IF( wantu ) THEN
  805               k = itgkz
  806               DO i = 1, ns
  807                  DO j = 1, m
  808                     u( j, i ) = cmplx( rwork( k ), zero )
  809                     k = k + 1
  810                  END DO
  811                  k = k + m
  812               END DO
  813
  814
  815
  816
  817               CALL cunmbr( 
'Q', 
'L', 
'N', m, ns, n, a, lda,
 
  818     $                      work( itauq ), u, ldu, work( itemp ),
  819     $                      lwork-itemp+1, info )
  820            END IF
  821
  822
  823
  824            IF( wantvt) THEN
  825               k = itgkz + m
  826               DO i = 1, ns
  827                  DO j = 1, m
  828                     vt( i, j ) = cmplx( rwork( k ), zero )
  829                     k = k + 1
  830                  END DO
  831                  k = k + m
  832               END DO
  833               CALL claset( 
'A', ns, n-m, czero, czero,
 
  834     $                      vt( 1,m+1 ), ldvt )
  835
  836
  837
  838
  839               CALL cunmbr( 
'P', 
'R', 
'C', ns, n, m, a, lda,
 
  840     $                      work( itaup ), vt, ldvt, work( itemp ),
  841     $                      lwork-itemp+1, info )
  842            END IF
  843         END IF
  844      END IF
  845
  846
  847
  848      IF( iscl.EQ.1 ) THEN
  849         IF( anrm.GT.bignum )
  850     $      
CALL slascl( 
'G', 0, 0, bignum, anrm, minmn, 1,
 
  851     $                   s, minmn, info )
  852         IF( anrm.LT.smlnum )
  853     $      
CALL slascl( 
'G', 0, 0, smlnum, anrm, minmn, 1,
 
  854     $                   s, minmn, info )
  855      END IF
  856
  857
  858
  860
  861      RETURN
  862
  863
  864
subroutine xerbla(srname, info)
subroutine sbdsvdx(uplo, jobz, range, n, d, e, vl, vu, il, iu, ns, s, z, ldz, work, iwork, info)
SBDSVDX
subroutine cgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
CGEBRD
subroutine cgelqf(m, n, a, lda, tau, work, lwork, info)
CGELQF
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
logical function lsame(ca, cb)
LSAME
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine cunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMBR
subroutine cunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMLQ
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR