207 SUBROUTINE dgelsd( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
208 $ WORK, LWORK, IWORK, INFO )
215 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
216 DOUBLE PRECISION RCOND
220 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
226 DOUBLE PRECISION ZERO, ONE, TWO
227 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
231 INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
232 $ ldwork, liwork, maxmn, maxwrk, minmn, minwrk,
233 $ mm, mnthr, nlvl, nwork
234 DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
242 DOUBLE PRECISION DLAMCH, DLANGE
243 EXTERNAL ilaenv, dlamch, dlange
246 INTRINSIC dble, int, log,
max,
min
255 mnthr = ilaenv( 6,
'DGELSD',
' ', m, n, nrhs, -1 )
256 lquery = ( lwork.EQ.-1 )
259 ELSE IF( n.LT.0 )
THEN
261 ELSE IF( nrhs.LT.0 )
THEN
263 ELSE IF( lda.LT.
max( 1, m ) )
THEN
265 ELSE IF( ldb.LT.
max( 1, maxmn ) )
THEN
269 smlsiz = ilaenv( 9,
'DGELSD',
' ', 0, 0, 0, 0 )
280 minmn =
max( 1, minmn )
281 nlvl =
max( int( log( dble( minmn ) / dble( smlsiz+1 ) ) /
282 $ log( two ) ) + 1, 0 )
286 liwork = 3*minmn*nlvl + 11*minmn
288 IF( m.GE.n .AND. m.GE.mnthr )
THEN
293 maxwrk =
max( maxwrk, n+n*ilaenv( 1,
'DGEQRF',
' ', m, n,
295 maxwrk =
max( maxwrk, n+nrhs*
296 $ ilaenv( 1,
'DORMQR',
'LT', m, nrhs, n, -1 ) )
302 maxwrk =
max( maxwrk, 3*n+( mm+n )*
303 $ ilaenv( 1,
'DGEBRD',
' ', mm, n, -1, -1 ) )
304 maxwrk =
max( maxwrk, 3*n+nrhs*
305 $ ilaenv( 1,
'DORMBR',
'QLT', mm, nrhs, n, -1 ) )
306 maxwrk =
max( maxwrk, 3*n+( n-1 )*
307 $ ilaenv( 1,
'DORMBR',
'PLN', n, nrhs, n, -1 ) )
308 wlalsd = 9*n+2*n*smlsiz+8*n*nlvl+n*nrhs+(smlsiz+1)**2
309 maxwrk =
max( maxwrk, 3*n+wlalsd )
310 minwrk =
max( 3*n+mm, 3*n+nrhs, 3*n+wlalsd )
313 wlalsd = 9*m+2*m*smlsiz+8*m*nlvl+m*nrhs+(smlsiz+1)**2
314 IF( n.GE.mnthr )
THEN
319 maxwrk = m + m*ilaenv( 1,
'DGELQF',
' ', m, n, -1, -1 )
320 maxwrk =
max( maxwrk, m*m+4*m+2*m*
321 $ ilaenv( 1,
'DGEBRD',
' ', m, m, -1, -1 ) )
322 maxwrk =
max( maxwrk, m*m+4*m+nrhs*
323 $ ilaenv( 1,
'DORMBR',
'QLT', m, nrhs, m, -1 ) )
324 maxwrk =
max( maxwrk, m*m+4*m+( m-1 )*
325 $ ilaenv( 1,
'DORMBR',
'PLN', m, nrhs, m, -1 ) )
327 maxwrk =
max( maxwrk, m*m+m+m*nrhs )
329 maxwrk =
max( maxwrk, m*m+2*m )
331 maxwrk =
max( maxwrk, m+nrhs*
332 $ ilaenv( 1,
'DORMLQ',
'LT', n, nrhs, m, -1 ) )
333 maxwrk =
max( maxwrk, m*m+4*m+wlalsd )
336 maxwrk =
max( maxwrk,
337 $ 4*m+m*m+
max( m, 2*m-4, nrhs, n-3*m ) )
342 maxwrk = 3*m + ( n+m )*ilaenv( 1,
'DGEBRD',
' ', m, n,
344 maxwrk =
max( maxwrk, 3*m+nrhs*
345 $ ilaenv( 1,
'DORMBR',
'QLT', m, nrhs, n, -1 ) )
346 maxwrk =
max( maxwrk, 3*m+m*
347 $ ilaenv( 1,
'DORMBR',
'PLN', n, nrhs, m, -1 ) )
348 maxwrk =
max( maxwrk, 3*m+wlalsd )
350 minwrk =
max( 3*m+nrhs, 3*m+m, 3*m+wlalsd )
352 minwrk =
min( minwrk, maxwrk )
356 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN
362 CALL xerbla(
'DGELSD', -info )
364 ELSE IF( lquery )
THEN
370 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
378 sfmin = dlamch(
'S' )
380 bignum = one / smlnum
381 CALL dlabad( smlnum, bignum )
385 anrm = dlange(
'M', m, n, a, lda, work )
387 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
391 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
393 ELSE IF( anrm.GT.bignum )
THEN
397 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
399 ELSE IF( anrm.EQ.zero )
THEN
403 CALL dlaset(
'F',
max( m, n ), nrhs, zero, zero, b, ldb )
404 CALL dlaset(
'F', minmn, 1, zero, zero, s, 1 )
411 bnrm = dlange(
'M', m, nrhs, b, ldb, work )
413 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
417 CALL dlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
419 ELSE IF( bnrm.GT.bignum )
THEN
423 CALL dlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
430 $
CALL dlaset(
'F', n-m, nrhs, zero, zero, b( m+1, 1 ), ldb )
439 IF( m.GE.mnthr )
THEN
450 CALL dgeqrf( m, n, a, lda, work( itau ), work( nwork ),
451 $ lwork-nwork+1, info )
456 CALL dormqr(
'L',
'T', m, nrhs, n, a, lda, work( itau ), b,
457 $ ldb, work( nwork ), lwork-nwork+1, info )
462 CALL dlaset(
'L', n-1, n-1, zero, zero, a( 2, 1 ), lda )
474 CALL dgebrd( mm, n, a, lda, s, work( ie ), work( itauq ),
475 $ work( itaup ), work( nwork ), lwork-nwork+1,
481 CALL dormbr(
'Q',
'L',
'T', mm, nrhs, n, a, lda, work( itauq ),
482 $ b, ldb, work( nwork ), lwork-nwork+1, info )
486 CALL dlalsd(
'U', smlsiz, n, nrhs, s, work( ie ), b, ldb,
487 $ rcond, rank, work( nwork ), iwork, info )
494 CALL dormbr(
'P',
'L',
'N', n, nrhs, n, a, lda, work( itaup ),
495 $ b, ldb, work( nwork ), lwork-nwork+1, info )
497 ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
498 $
max( m, 2*m-4, nrhs, n-3*m, wlalsd ) )
THEN
504 IF( lwork.GE.
max( 4*m+m*lda+
max( m, 2*m-4, nrhs, n-3*m ),
505 $ m*lda+m+m*nrhs, 4*m+m*lda+wlalsd ) )ldwork = lda
512 CALL dgelqf( m, n, a, lda, work( itau ), work( nwork ),
513 $ lwork-nwork+1, info )
518 CALL dlacpy(
'L', m, m, a, lda, work( il ), ldwork )
519 CALL dlaset(
'U', m-1, m-1, zero, zero, work( il+ldwork ),
529 CALL dgebrd( m, m, work( il ), ldwork, s, work( ie ),
530 $ work( itauq ), work( itaup ), work( nwork ),
531 $ lwork-nwork+1, info )
536 CALL dormbr(
'Q',
'L',
'T', m, nrhs, m, work( il ), ldwork,
537 $ work( itauq ), b, ldb, work( nwork ),
538 $ lwork-nwork+1, info )
542 CALL dlalsd(
'U', smlsiz, m, nrhs, s, work( ie ), b, ldb,
543 $ rcond, rank, work( nwork ), iwork, info )
550 CALL dormbr(
'P',
'L',
'N', m, nrhs, m, work( il ), ldwork,
551 $ work( itaup ), b, ldb, work( nwork ),
552 $ lwork-nwork+1, info )
556 CALL dlaset(
'F', n-m, nrhs, zero, zero, b( m+1, 1 ), ldb )
562 CALL dormlq(
'L',
'T', n, nrhs, m, a, lda, work( itau ), b,
563 $ ldb, work( nwork ), lwork-nwork+1, info )
577 CALL dgebrd( m, n, a, lda, s, work( ie ), work( itauq ),
578 $ work( itaup ), work( nwork ), lwork-nwork+1,
584 CALL dormbr(
'Q',
'L',
'T', m, nrhs, n, a, lda, work( itauq ),
585 $ b, ldb, work( nwork ), lwork-nwork+1, info )
589 CALL dlalsd(
'L', smlsiz, m, nrhs, s, work( ie ), b, ldb,
590 $ rcond, rank, work( nwork ), iwork, info )
597 CALL dormbr(
'P',
'L',
'N', n, nrhs, m, a, lda, work( itaup ),
598 $ b, ldb, work( nwork ), lwork-nwork+1, info )
604 IF( iascl.EQ.1 )
THEN
605 CALL dlascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
606 CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
608 ELSE IF( iascl.EQ.2 )
THEN
609 CALL dlascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
610 CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
613 IF( ibscl.EQ.1 )
THEN
614 CALL dlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
615 ELSE IF( ibscl.EQ.2 )
THEN
616 CALL dlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )