223 SUBROUTINE zgelsd( 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
232 DOUBLE PRECISION RCOND
236 DOUBLE PRECISION RWORK( * ), S( * )
237 COMPLEX*16 A( lda, * ), B( ldb, * ), WORK( * )
243 DOUBLE PRECISION ZERO, ONE, TWO
244 parameter( zero = 0.0d+0, one = 1.0d+0, two = 2.0d+0 )
246 parameter( czero = ( 0.0d+0, 0.0d+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 DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
262 DOUBLE PRECISION DLAMCH, ZLANGE
263 EXTERNAL ilaenv, dlamch, zlange
266 INTRINSIC int, log, max, min, dble
275 lquery = ( lwork.EQ.-1 )
278 ELSE IF( n.LT.0 )
THEN 280 ELSE IF( nrhs.LT.0 )
THEN 282 ELSE IF( lda.LT.max( 1, m ) )
THEN 284 ELSE IF( ldb.LT.max( 1, maxmn ) )
THEN 300 IF( minmn.GT.0 )
THEN 301 smlsiz = ilaenv( 9,
'ZGELSD',
' ', 0, 0, 0, 0 )
302 mnthr = ilaenv( 6,
'ZGELSD',
' ', m, n, nrhs, -1 )
303 nlvl = max( int( log( dble( minmn ) / dble( smlsiz + 1 ) ) /
304 $ log( two ) ) + 1, 0 )
305 liwork = 3*minmn*nlvl + 11*minmn
307 IF( m.GE.n .AND. m.GE.mnthr )
THEN 313 maxwrk = max( maxwrk, n*ilaenv( 1,
'ZGEQRF',
' ', m, n,
315 maxwrk = max( maxwrk, nrhs*ilaenv( 1,
'ZUNMQR',
'LC', m,
322 lrwork = 10*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs +
323 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
324 maxwrk = max( maxwrk, 2*n + ( mm + n )*ilaenv( 1,
325 $
'ZGEBRD',
' ', mm, n, -1, -1 ) )
326 maxwrk = max( maxwrk, 2*n + nrhs*ilaenv( 1,
'ZUNMBR',
327 $
'QLC', mm, nrhs, n, -1 ) )
328 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
329 $
'ZUNMBR',
'PLN', n, nrhs, n, -1 ) )
330 maxwrk = max( maxwrk, 2*n + n*nrhs )
331 minwrk = max( 2*n + mm, 2*n + n*nrhs )
334 lrwork = 10*m + 2*m*smlsiz + 8*m*nlvl + 3*smlsiz*nrhs +
335 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
336 IF( n.GE.mnthr )
THEN 341 maxwrk = m + m*ilaenv( 1,
'ZGELQF',
' ', m, n, -1,
343 maxwrk = max( maxwrk, m*m + 4*m + 2*m*ilaenv( 1,
344 $
'ZGEBRD',
' ', m, m, -1, -1 ) )
345 maxwrk = max( maxwrk, m*m + 4*m + nrhs*ilaenv( 1,
346 $
'ZUNMBR',
'QLC', m, nrhs, m, -1 ) )
347 maxwrk = max( maxwrk, m*m + 4*m + ( m - 1 )*ilaenv( 1,
348 $
'ZUNMLQ',
'LC', n, nrhs, m, -1 ) )
350 maxwrk = max( maxwrk, m*m + m + m*nrhs )
352 maxwrk = max( maxwrk, m*m + 2*m )
354 maxwrk = max( maxwrk, m*m + 4*m + m*nrhs )
357 maxwrk = max( maxwrk,
358 $ 4*m+m*m+max( m, 2*m-4, nrhs, n-3*m ) )
363 maxwrk = 2*m + ( n + m )*ilaenv( 1,
'ZGEBRD',
' ', m,
365 maxwrk = max( maxwrk, 2*m + nrhs*ilaenv( 1,
'ZUNMBR',
366 $
'QLC', m, nrhs, m, -1 ) )
367 maxwrk = max( maxwrk, 2*m + m*ilaenv( 1,
'ZUNMBR',
368 $
'PLN', n, nrhs, m, -1 ) )
369 maxwrk = max( maxwrk, 2*m + m*nrhs )
371 minwrk = max( 2*m + n, 2*m + m*nrhs )
374 minwrk = min( minwrk, maxwrk )
379 IF( lwork.LT.minwrk .AND. .NOT.lquery )
THEN 385 CALL xerbla(
'ZGELSD', -info )
387 ELSE IF( lquery )
THEN 393 IF( m.EQ.0 .OR. n.EQ.0 )
THEN 401 sfmin = dlamch(
'S' )
403 bignum = one / smlnum
404 CALL dlabad( smlnum, bignum )
408 anrm = zlange(
'M', m, n, a, lda, rwork )
410 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 414 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
416 ELSE IF( anrm.GT.bignum )
THEN 420 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
422 ELSE IF( anrm.EQ.zero )
THEN 426 CALL zlaset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
427 CALL dlaset(
'F', minmn, 1, zero, zero, s, 1 )
434 bnrm = zlange(
'M', m, nrhs, b, ldb, rwork )
436 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN 440 CALL zlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
442 ELSE IF( bnrm.GT.bignum )
THEN 446 CALL zlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
453 $
CALL zlaset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
462 IF( m.GE.mnthr )
THEN 474 CALL zgeqrf( m, n, a, lda, work( itau ), work( nwork ),
475 $ lwork-nwork+1, info )
481 CALL zunmqr(
'L',
'C', m, nrhs, n, a, lda, work( itau ), b,
482 $ ldb, work( nwork ), lwork-nwork+1, info )
487 CALL zlaset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
502 CALL zgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
503 $ work( itaup ), work( nwork ), lwork-nwork+1,
509 CALL zunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, work( itauq ),
510 $ b, ldb, work( nwork ), lwork-nwork+1, info )
514 CALL zlalsd(
'U', smlsiz, n, nrhs, s, rwork( ie ), b, ldb,
515 $ rcond, rank, work( nwork ), rwork( nrwork ),
523 CALL zunmbr(
'P',
'L',
'N', n, nrhs, n, a, lda, work( itaup ),
524 $ b, ldb, work( nwork ), lwork-nwork+1, info )
526 ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
527 $ max( m, 2*m-4, nrhs, n-3*m ) )
THEN 533 IF( lwork.GE.max( 4*m+m*lda+max( m, 2*m-4, nrhs, n-3*m ),
534 $ m*lda+m+m*nrhs ) )ldwork = lda
541 CALL zgelqf( m, n, a, lda, work( itau ), work( nwork ),
542 $ lwork-nwork+1, info )
547 CALL zlacpy(
'L', m, m, a, lda, work( il ), ldwork )
548 CALL zlaset(
'U', m-1, m-1, czero, czero, work( il+ldwork ),
550 itauq = il + ldwork*m
560 CALL zgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
561 $ work( itauq ), work( itaup ), work( nwork ),
562 $ lwork-nwork+1, info )
567 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, m, work( il ), ldwork,
568 $ work( itauq ), b, ldb, work( nwork ),
569 $ lwork-nwork+1, info )
573 CALL zlalsd(
'U', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
574 $ rcond, rank, work( nwork ), rwork( nrwork ),
582 CALL zunmbr(
'P',
'L',
'N', m, nrhs, m, work( il ), ldwork,
583 $ work( itaup ), b, ldb, work( nwork ),
584 $ lwork-nwork+1, info )
588 CALL zlaset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
594 CALL zunmlq(
'L',
'C', n, nrhs, m, a, lda, work( itau ), b,
595 $ ldb, work( nwork ), lwork-nwork+1, info )
611 CALL zgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
612 $ work( itaup ), work( nwork ), lwork-nwork+1,
618 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda, work( itauq ),
619 $ b, ldb, work( nwork ), lwork-nwork+1, info )
623 CALL zlalsd(
'L', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
624 $ rcond, rank, work( nwork ), rwork( nrwork ),
632 CALL zunmbr(
'P',
'L',
'N', n, nrhs, m, a, lda, work( itaup ),
633 $ b, ldb, work( nwork ), lwork-nwork+1, info )
639 IF( iascl.EQ.1 )
THEN 640 CALL zlascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
641 CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
643 ELSE IF( iascl.EQ.2 )
THEN 644 CALL zlascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
645 CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
648 IF( ibscl.EQ.1 )
THEN 649 CALL zlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
650 ELSE IF( ibscl.EQ.2 )
THEN 651 CALL zlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMLQ
subroutine zgelsd(M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, RWORK, IWORK, INFO)
ZGELSD computes the minimum-norm solution to a linear least squares problem for GE matrices ...
subroutine zgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGEQRF
subroutine zgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGELQF
subroutine zlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine zunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMQR
subroutine dlascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine zunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMBR
subroutine dlaset(UPLO, M, N, ALPHA, BETA, A, LDA)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values...
subroutine zlalsd(UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND, RANK, WORK, RWORK, IWORK, INFO)
ZLALSD uses the singular value decomposition of A to solve the least squares problem.
subroutine zgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
ZGEBRD
subroutine dlabad(SMALL, LARGE)
DLABAD