215 SUBROUTINE cgelsd( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
216 $ WORK, LWORK, RWORK, IWORK, INFO )
223 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
228 REAL RWORK( * ), S( * )
229 COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
236 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
238 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
242 INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
243 $ ldwork, liwork, lrwork, maxmn, maxwrk, minmn,
244 $ minwrk, mm, mnthr, nlvl, nrwork, nwork, smlsiz
245 REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
255 REAL CLANGE, SLAMCH, SROUNDUP_LWORK
256 EXTERNAL clange, slamch, ilaenv,
260 INTRINSIC int, log, max, min, real
269 lquery = ( lwork.EQ.-1 )
272 ELSE IF( n.LT.0 )
THEN
274 ELSE IF( nrhs.LT.0 )
THEN
276 ELSE IF( lda.LT.max( 1, m ) )
THEN
278 ELSE IF( ldb.LT.max( 1, maxmn ) )
THEN
294 IF( minmn.GT.0 )
THEN
295 smlsiz = ilaenv( 9,
'CGELSD',
' ', 0, 0, 0, 0 )
296 mnthr = ilaenv( 6,
'CGELSD',
' ', m, n, nrhs, -1 )
297 nlvl = max( int( log( real( minmn ) / real( smlsiz + 1 ) ) /
298 $ log( two ) ) + 1, 0 )
299 liwork = 3*minmn*nlvl + 11*minmn
301 IF( m.GE.n .AND. m.GE.mnthr )
THEN
307 maxwrk = max( maxwrk, n*ilaenv( 1,
'CGEQRF',
' ', m,
310 maxwrk = max( maxwrk, nrhs*ilaenv( 1,
'CUNMQR',
'LC',
318 lrwork = 10*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs +
319 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
320 maxwrk = max( maxwrk, 2*n + ( mm + n )*ilaenv( 1,
321 $
'CGEBRD',
' ', mm, n, -1, -1 ) )
322 maxwrk = max( maxwrk, 2*n + nrhs*ilaenv( 1,
'CUNMBR',
323 $
'QLC', mm, nrhs, n, -1 ) )
324 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
325 $
'CUNMBR',
'PLN', n, nrhs, n, -1 ) )
326 maxwrk = max( maxwrk, 2*n + n*nrhs )
327 minwrk = max( 2*n + mm, 2*n + n*nrhs )
330 lrwork = 10*m + 2*m*smlsiz + 8*m*nlvl + 3*smlsiz*nrhs +
331 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
332 IF( n.GE.mnthr )
THEN
337 maxwrk = m + m*ilaenv( 1,
'CGELQF',
' ', m, n, -1,
339 maxwrk = max( maxwrk, m*m + 4*m + 2*m*ilaenv( 1,
340 $
'CGEBRD',
' ', m, m, -1, -1 ) )
341 maxwrk = max( maxwrk, m*m + 4*m + nrhs*ilaenv( 1,
342 $
'CUNMBR',
'QLC', m, nrhs, m, -1 ) )
343 maxwrk = max( maxwrk,
344 $ m*m + 4*m + ( m - 1 )*ilaenv( 1,
345 $
'CUNMLQ',
'LC', n, nrhs, m, -1 ) )
347 maxwrk = max( maxwrk, m*m + m + m*nrhs )
349 maxwrk = max( maxwrk, m*m + 2*m )
351 maxwrk = max( maxwrk, m*m + 4*m + m*nrhs )
354 maxwrk = max( maxwrk,
355 $ 4*m+m*m+max( m, 2*m-4, nrhs, n-3*m ) )
360 maxwrk = 2*m + ( n + m )*ilaenv( 1,
'CGEBRD',
' ',
363 maxwrk = max( maxwrk, 2*m + nrhs*ilaenv( 1,
365 $
'QLC', m, nrhs, m, -1 ) )
366 maxwrk = max( maxwrk, 2*m + m*ilaenv( 1,
'CUNMBR',
367 $
'PLN', n, nrhs, m, -1 ) )
368 maxwrk = max( maxwrk, 2*m + m*nrhs )
370 minwrk = max( 2*m + n, 2*m + m*nrhs )
373 minwrk = min( minwrk, maxwrk )
374 work( 1 ) = sroundup_lwork(maxwrk)
376 rwork( 1 ) = real( lrwork )
378 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
384 CALL xerbla(
'CGELSD', -info )
386 ELSE IF( lquery )
THEN
392 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
400 sfmin = slamch(
'S' )
402 bignum = one / smlnum
406 anrm = clange(
'M', m, n, a, lda, rwork )
408 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
412 CALL clascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
414 ELSE IF( anrm.GT.bignum )
THEN
418 CALL clascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
420 ELSE IF( anrm.EQ.zero )
THEN
424 CALL claset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
425 CALL slaset(
'F', minmn, 1, zero, zero, s, 1 )
432 bnrm = clange(
'M', m, nrhs, b, ldb, rwork )
434 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
438 CALL clascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb,
441 ELSE IF( bnrm.GT.bignum )
THEN
445 CALL clascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb,
453 $
CALL claset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ),
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 ),
484 $ ldb, work( nwork ), lwork-nwork+1, info )
489 CALL claset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
504 CALL cgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
505 $ work( itaup ), work( nwork ), lwork-nwork+1,
511 CALL cunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda,
513 $ b, ldb, work( nwork ), lwork-nwork+1, info )
517 CALL clalsd(
'U', smlsiz, n, nrhs, s, rwork( ie ), b, ldb,
518 $ rcond, rank, work( nwork ), rwork( nrwork ),
526 CALL cunmbr(
'P',
'L',
'N', n, nrhs, n, a, lda,
528 $ b, ldb, work( nwork ), lwork-nwork+1, info )
530 ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
531 $ max( m, 2*m-4, nrhs, n-3*m ) )
THEN
537 IF( lwork.GE.max( 4*m+m*lda+max( m, 2*m-4, nrhs, n-3*m ),
538 $ m*lda+m+m*nrhs ) )ldwork = lda
545 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
546 $ lwork-nwork+1, info )
551 CALL clacpy(
'L', m, m, a, lda, work( il ), ldwork )
552 CALL claset(
'U', m-1, m-1, czero, czero, work( il+ldwork ),
554 itauq = il + ldwork*m
564 CALL cgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
565 $ work( itauq ), work( itaup ), work( nwork ),
566 $ lwork-nwork+1, info )
571 CALL cunmbr(
'Q',
'L',
'C', m, nrhs, m, work( il ), ldwork,
572 $ work( itauq ), b, ldb, work( nwork ),
573 $ lwork-nwork+1, info )
577 CALL clalsd(
'U', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
578 $ rcond, rank, work( nwork ), rwork( nrwork ),
586 CALL cunmbr(
'P',
'L',
'N', m, nrhs, m, work( il ), ldwork,
587 $ work( itaup ), b, ldb, work( nwork ),
588 $ lwork-nwork+1, info )
592 CALL claset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ),
599 CALL cunmlq(
'L',
'C', n, nrhs, m, a, lda, work( itau ), b,
600 $ ldb, work( nwork ), lwork-nwork+1, info )
616 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
617 $ work( itaup ), work( nwork ), lwork-nwork+1,
623 CALL cunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda,
625 $ b, ldb, work( nwork ), lwork-nwork+1, info )
629 CALL clalsd(
'L', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
630 $ rcond, rank, work( nwork ), rwork( nrwork ),
638 CALL cunmbr(
'P',
'L',
'N', n, nrhs, m, a, lda,
640 $ b, ldb, work( nwork ), lwork-nwork+1, info )
646 IF( iascl.EQ.1 )
THEN
647 CALL clascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb,
649 CALL slascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
651 ELSE IF( iascl.EQ.2 )
THEN
652 CALL clascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb,
654 CALL slascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
657 IF( ibscl.EQ.1 )
THEN
658 CALL clascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb,
660 ELSE IF( ibscl.EQ.2 )
THEN
661 CALL clascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb,
666 work( 1 ) = sroundup_lwork(maxwrk)
668 rwork( 1 ) = real( lrwork )