217 SUBROUTINE cgelsd( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
218 $ WORK, LWORK, RWORK, IWORK, INFO )
225 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
230 REAL RWORK( * ), S( * )
231 COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
238 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
240 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
244 INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
245 $ ldwork, liwork, lrwork, maxmn, maxwrk, minmn,
246 $ minwrk, mm, mnthr, nlvl, nrwork, nwork, smlsiz
247 REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
257 REAL CLANGE, SLAMCH, SROUNDUP_LWORK
258 EXTERNAL clange, slamch, ilaenv, sroundup_lwork
261 INTRINSIC int, log, max, min, real
270 lquery = ( lwork.EQ.-1 )
273 ELSE IF( n.LT.0 )
THEN
275 ELSE IF( nrhs.LT.0 )
THEN
277 ELSE IF( lda.LT.max( 1, m ) )
THEN
279 ELSE IF( ldb.LT.max( 1, maxmn ) )
THEN
295 IF( minmn.GT.0 )
THEN
296 smlsiz = ilaenv( 9,
'CGELSD',
' ', 0, 0, 0, 0 )
297 mnthr = ilaenv( 6,
'CGELSD',
' ', m, n, nrhs, -1 )
298 nlvl = max( int( log( real( minmn ) / real( smlsiz + 1 ) ) /
299 $ log( two ) ) + 1, 0 )
300 liwork = 3*minmn*nlvl + 11*minmn
302 IF( m.GE.n .AND. m.GE.mnthr )
THEN
308 maxwrk = max( maxwrk, n*ilaenv( 1,
'CGEQRF',
' ', m, n,
310 maxwrk = max( maxwrk, nrhs*ilaenv( 1,
'CUNMQR',
'LC', m,
317 lrwork = 10*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs +
318 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
319 maxwrk = max( maxwrk, 2*n + ( mm + n )*ilaenv( 1,
320 $
'CGEBRD',
' ', mm, n, -1, -1 ) )
321 maxwrk = max( maxwrk, 2*n + nrhs*ilaenv( 1,
'CUNMBR',
322 $
'QLC', mm, nrhs, n, -1 ) )
323 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
324 $
'CUNMBR',
'PLN', n, nrhs, n, -1 ) )
325 maxwrk = max( maxwrk, 2*n + n*nrhs )
326 minwrk = max( 2*n + mm, 2*n + n*nrhs )
329 lrwork = 10*m + 2*m*smlsiz + 8*m*nlvl + 3*smlsiz*nrhs +
330 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
331 IF( n.GE.mnthr )
THEN
336 maxwrk = m + m*ilaenv( 1,
'CGELQF',
' ', m, n, -1,
338 maxwrk = max( maxwrk, m*m + 4*m + 2*m*ilaenv( 1,
339 $
'CGEBRD',
' ', m, m, -1, -1 ) )
340 maxwrk = max( maxwrk, m*m + 4*m + nrhs*ilaenv( 1,
341 $
'CUNMBR',
'QLC', m, nrhs, m, -1 ) )
342 maxwrk = max( maxwrk, m*m + 4*m + ( m - 1 )*ilaenv( 1,
343 $
'CUNMLQ',
'LC', n, nrhs, m, -1 ) )
345 maxwrk = max( maxwrk, m*m + m + m*nrhs )
347 maxwrk = max( maxwrk, m*m + 2*m )
349 maxwrk = max( maxwrk, m*m + 4*m + m*nrhs )
352 maxwrk = max( maxwrk,
353 $ 4*m+m*m+max( m, 2*m-4, nrhs, n-3*m ) )
358 maxwrk = 2*m + ( n + m )*ilaenv( 1,
'CGEBRD',
' ', m,
360 maxwrk = max( maxwrk, 2*m + nrhs*ilaenv( 1,
'CUNMBR',
361 $
'QLC', m, nrhs, m, -1 ) )
362 maxwrk = max( maxwrk, 2*m + m*ilaenv( 1,
'CUNMBR',
363 $
'PLN', n, nrhs, m, -1 ) )
364 maxwrk = max( maxwrk, 2*m + m*nrhs )
366 minwrk = max( 2*m + n, 2*m + m*nrhs )
369 minwrk = min( minwrk, maxwrk )
370 work( 1 ) = sroundup_lwork(maxwrk)
374 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
380 CALL xerbla(
'CGELSD', -info )
382 ELSE IF( lquery )
THEN
388 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
396 sfmin = slamch(
'S' )
398 bignum = one / smlnum
402 anrm = clange(
'M', m, n, a, lda, rwork )
404 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
408 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
410 ELSE IF( anrm.GT.bignum )
THEN
414 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
416 ELSE IF( anrm.EQ.zero )
THEN
420 CALL claset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
421 CALL slaset(
'F', minmn, 1, zero, zero, s, 1 )
428 bnrm = clange(
'M', m, nrhs, b, ldb, rwork )
430 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
434 CALL clascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
436 ELSE IF( bnrm.GT.bignum )
THEN
440 CALL clascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
447 $
CALL claset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
456 IF( m.GE.mnthr )
THEN
468 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
469 $ lwork-nwork+1, info )
475 CALL cunmqr(
'L',
'C', m, nrhs, n, a, lda, work( itau ), b,
476 $ ldb, work( nwork ), lwork-nwork+1, info )
481 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
496 CALL cgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
497 $ work( itaup ), work( nwork ), lwork-nwork+1,
503 CALL cunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, work( itauq ),
504 $ b, ldb, work( nwork ), lwork-nwork+1, info )
508 CALL clalsd(
'U', smlsiz, n, nrhs, s, rwork( ie ), b, ldb,
509 $ rcond, rank, work( nwork ), rwork( nrwork ),
517 CALL cunmbr(
'P',
'L',
'N', n, nrhs, n, a, lda, work( itaup ),
518 $ b, ldb, work( nwork ), lwork-nwork+1, info )
520 ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
521 $ max( m, 2*m-4, nrhs, n-3*m ) )
THEN
527 IF( lwork.GE.max( 4*m+m*lda+max( m, 2*m-4, nrhs, n-3*m ),
528 $ m*lda+m+m*nrhs ) )ldwork = lda
535 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
536 $ lwork-nwork+1, info )
541 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwork )
542 CALL claset(
'U', m-1, m-1, czero, czero, work( il+ldwork ),
544 itauq = il + ldwork*m
554 CALL cgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
555 $ work( itauq ), work( itaup ), work( nwork ),
556 $ lwork-nwork+1, info )
561 CALL cunmbr(
'Q',
'L',
'C', m, nrhs, m, work( il ), ldwork,
562 $ work( itauq ), b, ldb, work( nwork ),
563 $ lwork-nwork+1, info )
567 CALL clalsd(
'U', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
568 $ rcond, rank, work( nwork ), rwork( nrwork ),
576 CALL cunmbr(
'P',
'L',
'N', m, nrhs, m, work( il ), ldwork,
577 $ work( itaup ), b, ldb, work( nwork ),
578 $ lwork-nwork+1, info )
582 CALL claset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
588 CALL cunmlq(
'L',
'C', n, nrhs, m, a, lda, work( itau ), b,
589 $ ldb, work( nwork ), lwork-nwork+1, info )
605 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
606 $ work( itaup ), work( nwork ), lwork-nwork+1,
612 CALL cunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda, work( itauq ),
613 $ b, ldb, work( nwork ), lwork-nwork+1, info )
617 CALL clalsd(
'L', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
618 $ rcond, rank, work( nwork ), rwork( nrwork ),
626 CALL cunmbr(
'P',
'L',
'N', n, nrhs, m, a, lda, work( itaup ),
627 $ b, ldb, work( nwork ), lwork-nwork+1, info )
633 IF( iascl.EQ.1 )
THEN
634 CALL clascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
635 CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
637 ELSE IF( iascl.EQ.2 )
THEN
638 CALL clascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
639 CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
642 IF( ibscl.EQ.1 )
THEN
643 CALL clascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
644 ELSE IF( ibscl.EQ.2 )
THEN
645 CALL clascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
649 work( 1 ) = sroundup_lwork(maxwrk)
subroutine xerbla(srname, info)
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 cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
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 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 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 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 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