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 slabad(SMALL, LARGE)
SLABAD
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 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 xerbla(SRNAME, INFO)
XERBLA
subroutine cgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
CGEQRF
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 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 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 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 clacpy(UPLO, M, N, A, LDA, B, LDB)
CLACPY copies all or part of one two-dimensional array to another.
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 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