223 SUBROUTINE cgelsd( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
224 $ WORK, LWORK, RWORK, IWORK, INFO )
231 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
236 REAL RWORK( * ), S( * )
237 COMPLEX A( lda, * ), B( ldb, * ), WORK( * )
244 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
246 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
250 INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
251 $ ldwork, liwork, lrwork, maxmn, maxwrk, minmn,
252 $ minwrk, mm, mnthr, nlvl, nrwork, nwork, smlsiz
253 REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
264 EXTERNAL clange, slamch, ilaenv
267 INTRINSIC int, log, max, min, real
276 lquery = ( lwork.EQ.-1 )
279 ELSE IF( n.LT.0 )
THEN 281 ELSE IF( nrhs.LT.0 )
THEN 283 ELSE IF( lda.LT.max( 1, m ) )
THEN 285 ELSE IF( ldb.LT.max( 1, maxmn ) )
THEN 301 IF( minmn.GT.0 )
THEN 302 smlsiz = ilaenv( 9,
'CGELSD',
' ', 0, 0, 0, 0 )
303 mnthr = ilaenv( 6,
'CGELSD',
' ', m, n, nrhs, -1 )
304 nlvl = max( int( log(
REAL( MINMN ) /
REAL( SMLSIZ + 1 ) ) /
305 $ log( two ) ) + 1, 0 )
306 liwork = 3*minmn*nlvl + 11*minmn
308 IF( m.GE.n .AND. m.GE.mnthr )
THEN 314 maxwrk = max( maxwrk, n*ilaenv( 1,
'CGEQRF',
' ', m, n,
316 maxwrk = max( maxwrk, nrhs*ilaenv( 1,
'CUNMQR',
'LC', m,
323 lrwork = 10*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs +
324 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
325 maxwrk = max( maxwrk, 2*n + ( mm + n )*ilaenv( 1,
326 $
'CGEBRD',
' ', mm, n, -1, -1 ) )
327 maxwrk = max( maxwrk, 2*n + nrhs*ilaenv( 1,
'CUNMBR',
328 $
'QLC', mm, nrhs, n, -1 ) )
329 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
330 $
'CUNMBR',
'PLN', n, nrhs, n, -1 ) )
331 maxwrk = max( maxwrk, 2*n + n*nrhs )
332 minwrk = max( 2*n + mm, 2*n + n*nrhs )
335 lrwork = 10*m + 2*m*smlsiz + 8*m*nlvl + 3*smlsiz*nrhs +
336 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
337 IF( n.GE.mnthr )
THEN 342 maxwrk = m + m*ilaenv( 1,
'CGELQF',
' ', m, n, -1,
344 maxwrk = max( maxwrk, m*m + 4*m + 2*m*ilaenv( 1,
345 $
'CGEBRD',
' ', m, m, -1, -1 ) )
346 maxwrk = max( maxwrk, m*m + 4*m + nrhs*ilaenv( 1,
347 $
'CUNMBR',
'QLC', m, nrhs, m, -1 ) )
348 maxwrk = max( maxwrk, m*m + 4*m + ( m - 1 )*ilaenv( 1,
349 $
'CUNMLQ',
'LC', n, nrhs, m, -1 ) )
351 maxwrk = max( maxwrk, m*m + m + m*nrhs )
353 maxwrk = max( maxwrk, m*m + 2*m )
355 maxwrk = max( maxwrk, m*m + 4*m + m*nrhs )
358 maxwrk = max( maxwrk,
359 $ 4*m+m*m+max( m, 2*m-4, nrhs, n-3*m ) )
364 maxwrk = 2*m + ( n + m )*ilaenv( 1,
'CGEBRD',
' ', m,
366 maxwrk = max( maxwrk, 2*m + nrhs*ilaenv( 1,
'CUNMBR',
367 $
'QLC', m, nrhs, m, -1 ) )
368 maxwrk = max( maxwrk, 2*m + m*ilaenv( 1,
'CUNMBR',
369 $
'PLN', n, nrhs, m, -1 ) )
370 maxwrk = max( maxwrk, 2*m + m*nrhs )
372 minwrk = max( 2*m + n, 2*m + m*nrhs )
375 minwrk = min( minwrk, maxwrk )
380 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 386 CALL xerbla(
'CGELSD', -info )
388 ELSE IF( lquery )
THEN 394 IF( m.EQ.0 .OR. n.EQ.0 )
THEN 402 sfmin = slamch(
'S' )
404 bignum = one / smlnum
405 CALL slabad( smlnum, bignum )
409 anrm = clange(
'M', m, n, a, lda, rwork )
411 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 415 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
417 ELSE IF( anrm.GT.bignum )
THEN 421 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
423 ELSE IF( anrm.EQ.zero )
THEN 427 CALL claset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
428 CALL slaset(
'F', minmn, 1, zero, zero, s, 1 )
435 bnrm = clange(
'M', m, nrhs, b, ldb, rwork )
437 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN 441 CALL clascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
443 ELSE IF( bnrm.GT.bignum )
THEN 447 CALL clascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
454 $
CALL claset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
463 IF( m.GE.mnthr )
THEN 475 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
476 $ lwork-nwork+1, info )
482 CALL cunmqr(
'L',
'C', m, nrhs, n, a, lda, work( itau ), b,
483 $ ldb, work( nwork ), lwork-nwork+1, info )
488 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
503 CALL cgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
504 $ work( itaup ), work( nwork ), lwork-nwork+1,
510 CALL cunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, work( itauq ),
511 $ b, ldb, work( nwork ), lwork-nwork+1, info )
515 CALL clalsd(
'U', smlsiz, n, nrhs, s, rwork( ie ), b, ldb,
516 $ rcond, rank, work( nwork ), rwork( nrwork ),
524 CALL cunmbr(
'P',
'L',
'N', n, nrhs, n, a, lda, work( itaup ),
525 $ b, ldb, work( nwork ), lwork-nwork+1, info )
527 ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
528 $ max( m, 2*m-4, nrhs, n-3*m ) )
THEN 534 IF( lwork.GE.max( 4*m+m*lda+max( m, 2*m-4, nrhs, n-3*m ),
535 $ m*lda+m+m*nrhs ) )ldwork = lda
542 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
543 $ lwork-nwork+1, info )
548 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwork )
549 CALL claset(
'U', m-1, m-1, czero, czero, work( il+ldwork ),
551 itauq = il + ldwork*m
561 CALL cgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
562 $ work( itauq ), work( itaup ), work( nwork ),
563 $ lwork-nwork+1, info )
568 CALL cunmbr(
'Q',
'L',
'C', m, nrhs, m, work( il ), ldwork,
569 $ work( itauq ), b, ldb, work( nwork ),
570 $ lwork-nwork+1, info )
574 CALL clalsd(
'U', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
575 $ rcond, rank, work( nwork ), rwork( nrwork ),
583 CALL cunmbr(
'P',
'L',
'N', m, nrhs, m, work( il ), ldwork,
584 $ work( itaup ), b, ldb, work( nwork ),
585 $ lwork-nwork+1, info )
589 CALL claset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
595 CALL cunmlq(
'L',
'C', n, nrhs, m, a, lda, work( itau ), b,
596 $ ldb, work( nwork ), lwork-nwork+1, info )
612 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
613 $ work( itaup ), work( nwork ), lwork-nwork+1,
619 CALL cunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda, work( itauq ),
620 $ b, ldb, work( nwork ), lwork-nwork+1, info )
624 CALL clalsd(
'L', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
625 $ rcond, rank, work( nwork ), rwork( nrwork ),
633 CALL cunmbr(
'P',
'L',
'N', n, nrhs, m, a, lda, work( itaup ),
634 $ b, ldb, work( nwork ), lwork-nwork+1, info )
640 IF( iascl.EQ.1 )
THEN 641 CALL clascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
642 CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
644 ELSE IF( iascl.EQ.2 )
THEN 645 CALL clascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
646 CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
649 IF( ibscl.EQ.1 )
THEN 650 CALL clascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
651 ELSE IF( ibscl.EQ.2 )
THEN 652 CALL clascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
subroutine clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
subroutine cgelsd(M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, RWORK, IWORK, INFO)
CGELSD computes the minimum-norm solution to a linear least squares problem for GE matrices ...
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine cunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMBR
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...
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 slabad(SMALL, LARGE)
SLABAD
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine cgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGELQF
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 clalsd(UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND, RANK, WORK, RWORK, IWORK, INFO)
CLALSD uses the singular value decomposition of A to solve the least squares problem.
subroutine cunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMQR
subroutine cgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
CGEBRD
subroutine cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
subroutine cunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
CUNMLQ