176 SUBROUTINE zgelss( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
177 $ WORK, LWORK, RWORK, INFO )
184 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
185 DOUBLE PRECISION RCOND
188 DOUBLE PRECISION RWORK( * ), S( * )
189 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * )
195 DOUBLE PRECISION ZERO, ONE
196 parameter( zero = 0.0d+0, one = 1.0d+0 )
197 COMPLEX*16 CZERO, CONE
198 parameter( czero = ( 0.0d+0, 0.0d+0 ),
199 $ cone = ( 1.0d+0, 0.0d+0 ) )
203 INTEGER BL, CHUNK, I, IASCL, IBSCL, IE, IL, IRWORK,
204 $ itau, itaup, itauq, iwork, ldwork, maxmn,
205 $ maxwrk, minmn, minwrk, mm, mnthr
206 INTEGER LWORK_ZGEQRF, LWORK_ZUNMQR, LWORK_ZGEBRD,
207 $ lwork_zunmbr, lwork_zungbr, lwork_zunmlq,
209 DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
221 DOUBLE PRECISION DLAMCH, ZLANGE
222 EXTERNAL ilaenv, dlamch, zlange
234 lquery = ( lwork.EQ.-1 )
237 ELSE IF( n.LT.0 )
THEN
239 ELSE IF( nrhs.LT.0 )
THEN
241 ELSE IF( lda.LT.max( 1, m ) )
THEN
243 ELSE IF( ldb.LT.max( 1, maxmn ) )
THEN
258 IF( minmn.GT.0 )
THEN
260 mnthr = ilaenv( 6,
'ZGELSS',
' ', m, n, nrhs, -1 )
261 IF( m.GE.n .AND. m.GE.mnthr )
THEN
267 CALL zgeqrf( m, n, a, lda, dum(1), dum(1), -1, info )
268 lwork_zgeqrf = int( dum(1) )
270 CALL zunmqr(
'L',
'C', m, nrhs, n, a, lda, dum(1), b,
271 $ ldb, dum(1), -1, info )
272 lwork_zunmqr = int( dum(1) )
274 maxwrk = max( maxwrk, n + n*ilaenv( 1,
'ZGEQRF',
' ', m,
276 maxwrk = max( maxwrk, n + nrhs*ilaenv( 1,
'ZUNMQR',
'LC',
284 CALL zgebrd( mm, n, a, lda, s, s, dum(1), dum(1), dum(1),
286 lwork_zgebrd = int( dum(1) )
288 CALL zunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, dum(1),
289 $ b, ldb, dum(1), -1, info )
290 lwork_zunmbr = int( dum(1) )
292 CALL zungbr(
'P', n, n, n, a, lda, dum(1),
294 lwork_zungbr = int( dum(1) )
296 maxwrk = max( maxwrk, 2*n + lwork_zgebrd )
297 maxwrk = max( maxwrk, 2*n + lwork_zunmbr )
298 maxwrk = max( maxwrk, 2*n + lwork_zungbr )
299 maxwrk = max( maxwrk, n*nrhs )
300 minwrk = 2*n + max( nrhs, m )
303 minwrk = 2*m + max( nrhs, n )
304 IF( n.GE.mnthr )
THEN
310 CALL zgelqf( m, n, a, lda, dum(1), dum(1),
312 lwork_zgelqf = int( dum(1) )
314 CALL zgebrd( m, m, a, lda, s, s, dum(1), dum(1),
316 lwork_zgebrd = int( dum(1) )
318 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda,
319 $ dum(1), b, ldb, dum(1), -1, info )
320 lwork_zunmbr = int( dum(1) )
322 CALL zungbr(
'P', m, m, m, a, lda, dum(1),
324 lwork_zungbr = int( dum(1) )
326 CALL zunmlq(
'L',
'C', n, nrhs, m, a, lda, dum(1),
327 $ b, ldb, dum(1), -1, info )
328 lwork_zunmlq = int( dum(1) )
330 maxwrk = m + lwork_zgelqf
331 maxwrk = max( maxwrk, 3*m + m*m + lwork_zgebrd )
332 maxwrk = max( maxwrk, 3*m + m*m + lwork_zunmbr )
333 maxwrk = max( maxwrk, 3*m + m*m + lwork_zungbr )
335 maxwrk = max( maxwrk, m*m + m + m*nrhs )
337 maxwrk = max( maxwrk, m*m + 2*m )
339 maxwrk = max( maxwrk, m + lwork_zunmlq )
345 CALL zgebrd( m, n, a, lda, s, s, dum(1), dum(1),
347 lwork_zgebrd = int( dum(1) )
349 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, m, a, lda,
350 $ dum(1), b, ldb, dum(1), -1, info )
351 lwork_zunmbr = int( dum(1) )
353 CALL zungbr(
'P', m, n, m, a, lda, dum(1),
355 lwork_zungbr = int( dum(1) )
356 maxwrk = 2*m + lwork_zgebrd
357 maxwrk = max( maxwrk, 2*m + lwork_zunmbr )
358 maxwrk = max( maxwrk, 2*m + lwork_zungbr )
359 maxwrk = max( maxwrk, n*nrhs )
362 maxwrk = max( minwrk, maxwrk )
366 IF( lwork.LT.minwrk .AND. .NOT.lquery )
371 CALL xerbla(
'ZGELSS', -info )
373 ELSE IF( lquery )
THEN
379 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
387 sfmin = dlamch(
'S' )
389 bignum = one / smlnum
393 anrm = zlange(
'M', m, n, a, lda, rwork )
395 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
399 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
401 ELSE IF( anrm.GT.bignum )
THEN
405 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
407 ELSE IF( anrm.EQ.zero )
THEN
411 CALL zlaset(
'F', max( m, n ), nrhs, czero, czero, b, ldb )
412 CALL dlaset(
'F', minmn, 1, zero, zero, s, minmn )
419 bnrm = zlange(
'M', m, nrhs, b, ldb, rwork )
421 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
425 CALL zlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
427 ELSE IF( bnrm.GT.bignum )
THEN
431 CALL zlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
442 IF( m.GE.mnthr )
THEN
454 CALL zgeqrf( m, n, a, lda, work( itau ), work( iwork ),
455 $ lwork-iwork+1, info )
461 CALL zunmqr(
'L',
'C', m, nrhs, n, a, lda, work( itau ), b,
462 $ ldb, work( iwork ), lwork-iwork+1, info )
467 $
CALL zlaset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
480 CALL zgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
481 $ work( itaup ), work( iwork ), lwork-iwork+1,
488 CALL zunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, work( itauq ),
489 $ b, ldb, work( iwork ), lwork-iwork+1, info )
495 CALL zungbr(
'P', n, n, n, a, lda, work( itaup ),
496 $ work( iwork ), lwork-iwork+1, info )
505 CALL zbdsqr(
'U', n, n, 0, nrhs, s, rwork( ie ), a, lda, dum,
506 $ 1, b, ldb, rwork( irwork ), info )
512 thr = max( rcond*s( 1 ), sfmin )
514 $ thr = max( eps*s( 1 ), sfmin )
517 IF( s( i ).GT.thr )
THEN
518 CALL zdrscl( nrhs, s( i ), b( i, 1 ), ldb )
521 CALL zlaset(
'F', 1, nrhs, czero, czero, b( i, 1 ), ldb )
529 IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 )
THEN
530 CALL zgemm(
'C',
'N', n, nrhs, n, cone, a, lda, b, ldb,
532 CALL zlacpy(
'G', n, nrhs, work, ldb, b, ldb )
533 ELSE IF( nrhs.GT.1 )
THEN
535 DO 20 i = 1, nrhs, chunk
536 bl = min( nrhs-i+1, chunk )
537 CALL zgemm(
'C',
'N', n, bl, n, cone, a, lda, b( 1, i ),
538 $ ldb, czero, work, n )
539 CALL zlacpy(
'G', n, bl, work, n, b( 1, i ), ldb )
541 ELSE IF( nrhs.EQ.1 )
THEN
542 CALL zgemv(
'C', n, n, cone, a, lda, b, 1, czero, work, 1 )
543 CALL zcopy( n, work, 1, b, 1 )
546 ELSE IF( n.GE.mnthr .AND. lwork.GE.3*m+m*m+max( m, nrhs, n-2*m ) )
555 IF( lwork.GE.3*m+m*lda+max( m, nrhs, n-2*m ) )
564 CALL zgelqf( m, n, a, lda, work( itau ), work( iwork ),
565 $ lwork-iwork+1, info )
570 CALL zlacpy(
'L', m, m, a, lda, work( il ), ldwork )
571 CALL zlaset(
'U', m-1, m-1, czero, czero, work( il+ldwork ),
574 itauq = il + ldwork*m
582 CALL zgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
583 $ work( itauq ), work( itaup ), work( iwork ),
584 $ lwork-iwork+1, info )
590 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, m, work( il ), ldwork,
591 $ work( itauq ), b, ldb, work( iwork ),
592 $ lwork-iwork+1, info )
598 CALL zungbr(
'P', m, m, m, work( il ), ldwork, work( itaup ),
599 $ work( iwork ), lwork-iwork+1, info )
608 CALL zbdsqr(
'U', m, m, 0, nrhs, s, rwork( ie ), work( il ),
609 $ ldwork, a, lda, b, ldb, rwork( irwork ), info )
615 thr = max( rcond*s( 1 ), sfmin )
617 $ thr = max( eps*s( 1 ), sfmin )
620 IF( s( i ).GT.thr )
THEN
621 CALL zdrscl( nrhs, s( i ), b( i, 1 ), ldb )
624 CALL zlaset(
'F', 1, nrhs, czero, czero, b( i, 1 ), ldb )
627 iwork = il + m*ldwork
633 IF( lwork.GE.ldb*nrhs+iwork-1 .AND. nrhs.GT.1 )
THEN
634 CALL zgemm(
'C',
'N', m, nrhs, m, cone, work( il ), ldwork,
635 $ b, ldb, czero, work( iwork ), ldb )
636 CALL zlacpy(
'G', m, nrhs, work( iwork ), ldb, b, ldb )
637 ELSE IF( nrhs.GT.1 )
THEN
638 chunk = ( lwork-iwork+1 ) / m
639 DO 40 i = 1, nrhs, chunk
640 bl = min( nrhs-i+1, chunk )
641 CALL zgemm(
'C',
'N', m, bl, m, cone, work( il ), ldwork,
642 $ b( 1, i ), ldb, czero, work( iwork ), m )
643 CALL zlacpy(
'G', m, bl, work( iwork ), m, b( 1, i ),
646 ELSE IF( nrhs.EQ.1 )
THEN
647 CALL zgemv(
'C', m, m, cone, work( il ), ldwork, b( 1, 1 ),
648 $ 1, czero, work( iwork ), 1 )
649 CALL zcopy( m, work( iwork ), 1, b( 1, 1 ), 1 )
654 CALL zlaset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
661 CALL zunmlq(
'L',
'C', n, nrhs, m, a, lda, work( itau ), b,
662 $ ldb, work( iwork ), lwork-iwork+1, info )
677 CALL zgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
678 $ work( itaup ), work( iwork ), lwork-iwork+1,
685 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda, work( itauq ),
686 $ b, ldb, work( iwork ), lwork-iwork+1, info )
692 CALL zungbr(
'P', m, n, m, a, lda, work( itaup ),
693 $ work( iwork ), lwork-iwork+1, info )
702 CALL zbdsqr(
'L', m, n, 0, nrhs, s, rwork( ie ), a, lda, dum,
703 $ 1, b, ldb, rwork( irwork ), info )
709 thr = max( rcond*s( 1 ), sfmin )
711 $ thr = max( eps*s( 1 ), sfmin )
714 IF( s( i ).GT.thr )
THEN
715 CALL zdrscl( nrhs, s( i ), b( i, 1 ), ldb )
718 CALL zlaset(
'F', 1, nrhs, czero, czero, b( i, 1 ), ldb )
726 IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 )
THEN
727 CALL zgemm(
'C',
'N', n, nrhs, m, cone, a, lda, b, ldb,
729 CALL zlacpy(
'G', n, nrhs, work, ldb, b, ldb )
730 ELSE IF( nrhs.GT.1 )
THEN
732 DO 60 i = 1, nrhs, chunk
733 bl = min( nrhs-i+1, chunk )
734 CALL zgemm(
'C',
'N', n, bl, m, cone, a, lda, b( 1, i ),
735 $ ldb, czero, work, n )
736 CALL zlacpy(
'F', n, bl, work, n, b( 1, i ), ldb )
738 ELSE IF( nrhs.EQ.1 )
THEN
739 CALL zgemv(
'C', m, n, cone, a, lda, b, 1, czero, work, 1 )
740 CALL zcopy( n, work, 1, b, 1 )
746 IF( iascl.EQ.1 )
THEN
747 CALL zlascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
748 CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
750 ELSE IF( iascl.EQ.2 )
THEN
751 CALL zlascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
752 CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
755 IF( ibscl.EQ.1 )
THEN
756 CALL zlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
757 ELSE IF( ibscl.EQ.2 )
THEN
758 CALL zlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
subroutine xerbla(srname, info)
subroutine zbdsqr(uplo, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, rwork, info)
ZBDSQR
subroutine zcopy(n, zx, incx, zy, incy)
ZCOPY
subroutine zgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
ZGEBRD
subroutine zgelqf(m, n, a, lda, tau, work, lwork, info)
ZGELQF
subroutine zgelss(m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, rwork, info)
ZGELSS solves overdetermined or underdetermined systems for GE matrices
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
subroutine zgeqrf(m, n, a, lda, tau, work, lwork, info)
ZGEQRF
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
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 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 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 zdrscl(n, sa, sx, incx)
ZDRSCL multiplies a vector by the reciprocal of a real scalar.
subroutine zungbr(vect, m, n, k, a, lda, tau, work, lwork, info)
ZUNGBR
subroutine zunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMBR
subroutine zunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMLQ
subroutine zunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMQR