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 dlabad(SMALL, LARGE)
DLABAD
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 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 xerbla(SRNAME, INFO)
XERBLA
subroutine zgelqf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGELQF
subroutine zgebrd(M, N, A, LDA, D, E, TAUQ, TAUP, WORK, LWORK, INFO)
ZGEBRD
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 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 zunmlq(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMLQ
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 zunmqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMQR
subroutine zunmbr(VECT, SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
ZUNMBR
subroutine zgeqrf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
ZGEQRF VARIANT: left-looking Level 3 BLAS of the algorithm.