168      SUBROUTINE sgelss( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
 
  169     $                   WORK, LWORK, INFO )
 
  176      INTEGER            INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
 
  180      REAL               A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
 
  187      parameter( zero = 0.0e+0, one = 1.0e+0 )
 
  191      INTEGER            BDSPAC, BL, CHUNK, I, IASCL, IBSCL, IE, IL,
 
  192     $                   itau, itaup, itauq, iwork, ldwork, maxmn,
 
  193     $                   maxwrk, minmn, minwrk, mm, mnthr
 
  194      INTEGER            LWORK_SGEQRF, LWORK_SORMQR, LWORK_SGEBRD,
 
  195     $                   lwork_sormbr, lwork_sorgbr, lwork_sormlq
 
  196      REAL               ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
 
  209      REAL               SLAMCH, SLANGE, SROUNDUP_LWORK
 
  210      EXTERNAL           ilaenv, slamch, slange,
 
  223      lquery = ( lwork.EQ.-1 )
 
  226      ELSE IF( n.LT.0 ) 
THEN 
  228      ELSE IF( nrhs.LT.0 ) 
THEN 
  230      ELSE IF( lda.LT.max( 1, m ) ) 
THEN 
  232      ELSE IF( ldb.LT.max( 1, maxmn ) ) 
THEN 
  246         IF( minmn.GT.0 ) 
THEN 
  248            mnthr = ilaenv( 6, 
'SGELSS', 
' ', m, n, nrhs, -1 )
 
  249            IF( m.GE.n .AND. m.GE.mnthr ) 
THEN 
  255               CALL sgeqrf( m, n, a, lda, dum(1), dum(1), -1, info )
 
  256               lwork_sgeqrf = int( dum(1) )
 
  258               CALL sormqr( 
'L', 
'T', m, nrhs, n, a, lda, dum(1), b,
 
  259     $                   ldb, dum(1), -1, info )
 
  260               lwork_sormqr = int( dum(1) )
 
  262               maxwrk = max( maxwrk, n + lwork_sgeqrf )
 
  263               maxwrk = max( maxwrk, n + lwork_sormqr )
 
  271               bdspac = max( 1, 5*n )
 
  273               CALL sgebrd( mm, n, a, lda, s, dum(1), dum(1),
 
  274     $                      dum(1), dum(1), -1, info )
 
  275               lwork_sgebrd = int( dum(1) )
 
  277               CALL sormbr( 
'Q', 
'L', 
'T', mm, nrhs, n, a, lda,
 
  279     $                b, ldb, dum(1), -1, info )
 
  280               lwork_sormbr = int( dum(1) )
 
  282               CALL sorgbr( 
'P', n, n, n, a, lda, dum(1),
 
  284               lwork_sorgbr = int( dum(1) )
 
  286               maxwrk = max( maxwrk, 3*n + lwork_sgebrd )
 
  287               maxwrk = max( maxwrk, 3*n + lwork_sormbr )
 
  288               maxwrk = max( maxwrk, 3*n + lwork_sorgbr )
 
  289               maxwrk = max( maxwrk, bdspac )
 
  290               maxwrk = max( maxwrk, n*nrhs )
 
  291               minwrk = max( 3*n + mm, 3*n + nrhs, bdspac )
 
  292               maxwrk = max( minwrk, maxwrk )
 
  298               bdspac = max( 1, 5*m )
 
  299               minwrk = max( 3*m+nrhs, 3*m+n, bdspac )
 
  300               IF( n.GE.mnthr ) 
THEN 
  306                  CALL sgebrd( m, m, a, lda, s, dum(1), dum(1),
 
  307     $                      dum(1), dum(1), -1, info )
 
  308                  lwork_sgebrd = int( dum(1) )
 
  310                  CALL sormbr( 
'Q', 
'L', 
'T', m, nrhs, n, a, lda,
 
  311     $                dum(1), b, ldb, dum(1), -1, info )
 
  312                  lwork_sormbr = int( dum(1) )
 
  314                  CALL sorgbr( 
'P', m, m, m, a, lda, dum(1),
 
  316                  lwork_sorgbr = int( dum(1) )
 
  318                  CALL sormlq( 
'L', 
'T', n, nrhs, m, a, lda, dum(1),
 
  319     $                 b, ldb, dum(1), -1, info )
 
  320                  lwork_sormlq = int( dum(1) )
 
  322                  maxwrk = m + m*ilaenv( 1, 
'SGELQF', 
' ', m, n, -1,
 
  324                  maxwrk = max( maxwrk, m*m + 4*m + lwork_sgebrd )
 
  325                  maxwrk = max( maxwrk, m*m + 4*m + lwork_sormbr )
 
  326                  maxwrk = max( maxwrk, m*m + 4*m + lwork_sorgbr )
 
  327                  maxwrk = max( maxwrk, m*m + m + bdspac )
 
  329                     maxwrk = max( maxwrk, m*m + m + m*nrhs )
 
  331                     maxwrk = max( maxwrk, m*m + 2*m )
 
  333                  maxwrk = max( maxwrk, m + lwork_sormlq )
 
  339                  CALL sgebrd( m, n, a, lda, s, dum(1), dum(1),
 
  340     $                      dum(1), dum(1), -1, info )
 
  341                  lwork_sgebrd = int( dum(1) )
 
  343                  CALL sormbr( 
'Q', 
'L', 
'T', m, nrhs, m, a, lda,
 
  344     $                dum(1), b, ldb, dum(1), -1, info )
 
  345                  lwork_sormbr = int( dum(1) )
 
  347                  CALL sorgbr( 
'P', m, n, m, a, lda, dum(1),
 
  349                  lwork_sorgbr = int( dum(1) )
 
  350                  maxwrk = 3*m + lwork_sgebrd
 
  351                  maxwrk = max( maxwrk, 3*m + lwork_sormbr )
 
  352                  maxwrk = max( maxwrk, 3*m + lwork_sorgbr )
 
  353                  maxwrk = max( maxwrk, bdspac )
 
  354                  maxwrk = max( maxwrk, n*nrhs )
 
  357            maxwrk = max( minwrk, maxwrk )
 
  359         work( 1 ) = sroundup_lwork(maxwrk)
 
  361         IF( lwork.LT.minwrk .AND. .NOT.lquery )
 
  366         CALL xerbla( 
'SGELSS', -info )
 
  368      ELSE IF( lquery ) 
THEN 
  374      IF( m.EQ.0 .OR. n.EQ.0 ) 
THEN 
  382      sfmin = slamch( 
'S' )
 
  384      bignum = one / smlnum
 
  388      anrm = slange( 
'M', m, n, a, lda, work )
 
  390      IF( anrm.GT.zero .AND. anrm.LT.smlnum ) 
THEN 
  394         CALL slascl( 
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
 
  396      ELSE IF( anrm.GT.bignum ) 
THEN 
  400         CALL slascl( 
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
 
  402      ELSE IF( anrm.EQ.zero ) 
THEN 
  406         CALL slaset( 
'F', max( m, n ), nrhs, zero, zero, b, ldb )
 
  407         CALL slaset( 
'F', minmn, 1, zero, zero, s, minmn )
 
  414      bnrm = slange( 
'M', m, nrhs, b, ldb, work )
 
  416      IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) 
THEN 
  420         CALL slascl( 
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb,
 
  423      ELSE IF( bnrm.GT.bignum ) 
THEN 
  427         CALL slascl( 
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb,
 
  439         IF( m.GE.mnthr ) 
THEN 
  450            CALL sgeqrf( m, n, a, lda, work( itau ), work( iwork ),
 
  451     $                   lwork-iwork+1, info )
 
  456            CALL sormqr( 
'L', 
'T', m, nrhs, n, a, lda, work( itau ),
 
  458     $                   ldb, work( iwork ), lwork-iwork+1, info )
 
  463     $         
CALL slaset( 
'L', n-1, n-1, zero, zero, a( 2, 1 ),
 
  475         CALL sgebrd( mm, n, a, lda, s, work( ie ), work( itauq ),
 
  476     $                work( itaup ), work( iwork ), lwork-iwork+1,
 
  482         CALL sormbr( 
'Q', 
'L', 
'T', mm, nrhs, n, a, lda,
 
  484     $                b, ldb, work( iwork ), lwork-iwork+1, info )
 
  489         CALL sorgbr( 
'P', n, n, n, a, lda, work( itaup ),
 
  490     $                work( iwork ), lwork-iwork+1, info )
 
  498         CALL sbdsqr( 
'U', n, n, 0, nrhs, s, work( ie ), a, lda, dum,
 
  499     $                1, b, ldb, work( iwork ), info )
 
  505         thr = max( rcond*s( 1 ), sfmin )
 
  507     $      thr = max( eps*s( 1 ), sfmin )
 
  510            IF( s( i ).GT.thr ) 
THEN 
  511               CALL srscl( nrhs, s( i ), b( i, 1 ), ldb )
 
  514               CALL slaset( 
'F', 1, nrhs, zero, zero, b( i, 1 ),
 
  522         IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 ) 
THEN 
  523            CALL sgemm( 
'T', 
'N', n, nrhs, n, one, a, lda, b, ldb,
 
  526            CALL slacpy( 
'G', n, nrhs, work, ldb, b, ldb )
 
  527         ELSE IF( nrhs.GT.1 ) 
THEN 
  529            DO 20 i = 1, nrhs, chunk
 
  530               bl = min( nrhs-i+1, chunk )
 
  531               CALL sgemm( 
'T', 
'N', n, bl, n, one, a, lda, b( 1,
 
  533     $                     ldb, zero, work, n )
 
  534               CALL slacpy( 
'G', n, bl, work, n, b( 1, i ), ldb )
 
  536         ELSE IF( nrhs.EQ.1 ) 
THEN 
  537            CALL sgemv( 
'T', n, n, one, a, lda, b, 1, zero, work, 1 )
 
  538            CALL scopy( n, work, 1, b, 1 )
 
  541      ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
 
  542     $         max( m, 2*m-4, nrhs, n-3*m ) ) 
THEN 
  548         IF( lwork.GE.max( 4*m+m*lda+max( m, 2*m-4, nrhs, n-3*m ),
 
  549     $       m*lda+m+m*nrhs ) )ldwork = lda
 
  556         CALL sgelqf( m, n, a, lda, work( itau ), work( iwork ),
 
  557     $                lwork-iwork+1, info )
 
  562         CALL slacpy( 
'L', m, m, a, lda, work( il ), ldwork )
 
  563         CALL slaset( 
'U', m-1, m-1, zero, zero, work( il+ldwork ),
 
  573         CALL sgebrd( m, m, work( il ), ldwork, s, work( ie ),
 
  574     $                work( itauq ), work( itaup ), work( iwork ),
 
  575     $                lwork-iwork+1, info )
 
  580         CALL sormbr( 
'Q', 
'L', 
'T', m, nrhs, m, work( il ), ldwork,
 
  581     $                work( itauq ), b, ldb, work( iwork ),
 
  582     $                lwork-iwork+1, info )
 
  587         CALL sorgbr( 
'P', m, m, m, work( il ), ldwork,
 
  589     $                work( iwork ), lwork-iwork+1, info )
 
  597         CALL sbdsqr( 
'U', m, m, 0, nrhs, s, work( ie ), work( il ),
 
  598     $                ldwork, a, lda, b, ldb, work( iwork ), info )
 
  604         thr = max( rcond*s( 1 ), sfmin )
 
  606     $      thr = max( eps*s( 1 ), sfmin )
 
  609            IF( s( i ).GT.thr ) 
THEN 
  610               CALL srscl( nrhs, s( i ), b( i, 1 ), ldb )
 
  613               CALL slaset( 
'F', 1, nrhs, zero, zero, b( i, 1 ),
 
  622         IF( lwork.GE.ldb*nrhs+iwork-1 .AND. nrhs.GT.1 ) 
THEN 
  623            CALL sgemm( 
'T', 
'N', m, nrhs, m, one, work( il ),
 
  625     $                  b, ldb, zero, work( iwork ), ldb )
 
  626            CALL slacpy( 
'G', m, nrhs, work( iwork ), ldb, b, ldb )
 
  627         ELSE IF( nrhs.GT.1 ) 
THEN 
  628            chunk = ( lwork-iwork+1 ) / m
 
  629            DO 40 i = 1, nrhs, chunk
 
  630               bl = min( nrhs-i+1, chunk )
 
  631               CALL sgemm( 
'T', 
'N', m, bl, m, one, work( il ),
 
  633     $                     b( 1, i ), ldb, zero, work( iwork ), m )
 
  634               CALL slacpy( 
'G', m, bl, work( iwork ), m, b( 1, i ),
 
  637         ELSE IF( nrhs.EQ.1 ) 
THEN 
  638            CALL sgemv( 
'T', m, m, one, work( il ), ldwork, b( 1,
 
  639     $                  1 ), 1, zero, work( iwork ), 1 )
 
  640            CALL scopy( m, work( iwork ), 1, b( 1, 1 ), 1 )
 
  645         CALL slaset( 
'F', n-m, nrhs, zero, zero, b( m+1, 1 ), ldb )
 
  651         CALL sormlq( 
'L', 
'T', n, nrhs, m, a, lda, work( itau ), b,
 
  652     $                ldb, work( iwork ), lwork-iwork+1, info )
 
  666         CALL sgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
 
  667     $                work( itaup ), work( iwork ), lwork-iwork+1,
 
  673         CALL sormbr( 
'Q', 
'L', 
'T', m, nrhs, n, a, lda,
 
  675     $                b, ldb, work( iwork ), lwork-iwork+1, info )
 
  680         CALL sorgbr( 
'P', m, n, m, a, lda, work( itaup ),
 
  681     $                work( iwork ), lwork-iwork+1, info )
 
  689         CALL sbdsqr( 
'L', m, n, 0, nrhs, s, work( ie ), a, lda, dum,
 
  690     $                1, b, ldb, work( iwork ), info )
 
  696         thr = max( rcond*s( 1 ), sfmin )
 
  698     $      thr = max( eps*s( 1 ), sfmin )
 
  701            IF( s( i ).GT.thr ) 
THEN 
  702               CALL srscl( nrhs, s( i ), b( i, 1 ), ldb )
 
  705               CALL slaset( 
'F', 1, nrhs, zero, zero, b( i, 1 ),
 
  713         IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 ) 
THEN 
  714            CALL sgemm( 
'T', 
'N', n, nrhs, m, one, a, lda, b, ldb,
 
  717            CALL slacpy( 
'F', n, nrhs, work, ldb, b, ldb )
 
  718         ELSE IF( nrhs.GT.1 ) 
THEN 
  720            DO 60 i = 1, nrhs, chunk
 
  721               bl = min( nrhs-i+1, chunk )
 
  722               CALL sgemm( 
'T', 
'N', n, bl, m, one, a, lda, b( 1,
 
  724     $                     ldb, zero, work, n )
 
  725               CALL slacpy( 
'F', n, bl, work, n, b( 1, i ), ldb )
 
  727         ELSE IF( nrhs.EQ.1 ) 
THEN 
  728            CALL sgemv( 
'T', m, n, one, a, lda, b, 1, zero, work, 1 )
 
  729            CALL scopy( n, work, 1, b, 1 )
 
  735      IF( iascl.EQ.1 ) 
THEN 
  736         CALL slascl( 
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb,
 
  738         CALL slascl( 
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
 
  740      ELSE IF( iascl.EQ.2 ) 
THEN 
  741         CALL slascl( 
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb,
 
  743         CALL slascl( 
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
 
  746      IF( ibscl.EQ.1 ) 
THEN 
  747         CALL slascl( 
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb,
 
  749      ELSE IF( ibscl.EQ.2 ) 
THEN 
  750         CALL slascl( 
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb,
 
  755      work( 1 ) = sroundup_lwork(maxwrk)