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, , RANK
185 DOUBLE PRECISION RCOND
188 DOUBLE PRECISION RWORK( * ), S( * )
189 COMPLEX*16 ( 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
209 DOUBLE PRECISION ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
222 DOUBLE PRECISION DLAMCH, ZLANGE
223 EXTERNAL ilaenv, dlamch, zlange
235 lquery = ( lwork.EQ.-1 )
238 ELSE IF( n.LT.0 )
THEN
240 ELSE IF( nrhs.LT.0 )
THEN
242 ELSE IF( lda.LT.
max( 1, m ) )
THEN
244 ELSE IF( ldb.LT.
max( 1, maxmn ) )
THEN
259 IF( minmn.GT.0 )
THEN
261 mnthr = ilaenv( 6,
'ZGELSS',
' ', m, n, nrhs, -1 )
262 IF( m.GE.n .AND. m.GE.mnthr )
THEN
268 CALL zgeqrf( m, n, a, lda, dum(1), dum(1), -1, info )
269 lwork_zgeqrf = dble( dum(1) )
271 CALL zunmqr(
'L',
'C', m, nrhs, n, a, lda, dum(1), b,
272 $ ldb, dum(1), -1, info )
273 lwork_zunmqr = dble( dum(1) )
275 maxwrk =
max( maxwrk, n + n*ilaenv( 1,
'ZGEQRF',
' ', m,
277 maxwrk =
max( maxwrk, n + nrhs*ilaenv( 1,
'ZUNMQR',
'LC',
285 CALL zgebrd( mm, n, a, lda, s, s, dum(1), dum(1), dum(1),
287 lwork_zgebrd = dble( dum(1) )
289 CALL zunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, dum(1),
290 $ b, ldb, dum(1), -1, info )
291 lwork_zunmbr = dble( dum(1) )
293 CALL zungbr(
'P', n, n, n, a, lda, dum(1),
295 lwork_zungbr = dble( dum(1) )
297 maxwrk =
max( maxwrk, 2*n + lwork_zgebrd )
298 maxwrk =
max( maxwrk, 2*n + lwork_zunmbr )
299 maxwrk =
max( maxwrk, 2*n + lwork_zungbr )
300 maxwrk =
max( maxwrk, n*nrhs )
301 minwrk = 2*n +
max( nrhs, m )
304 minwrk = 2*m +
max( nrhs, n )
305 IF( n.GE.mnthr )
THEN
311 CALL zgelqf( m, n, a, lda, dum(1), dum(1),
313 lwork_zgelqf = dble( dum(1) )
315 CALL zgebrd( m, m, a, lda, s, s, dum(1), dum(1),
317 lwork_zgebrd = dble( dum(1) )
319 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda,
320 $ dum(1), b, ldb, dum(1), -1, info )
321 lwork_zunmbr = dble( dum(1) )
323 CALL zungbr(
'P', m, m, m, a, lda, dum(1),
325 lwork_zungbr = dble( dum(1) )
327 CALL zunmlq(
'L',
'C', n, nrhs, m, a, lda, dum(1),
328 $ b, ldb, dum(1), -1, info )
329 lwork_zunmlq = dble( dum(1) )
331 maxwrk = m + lwork_zgelqf
332 maxwrk =
max( maxwrk, 3*m + m*m + lwork_zgebrd )
333 maxwrk =
max( maxwrk, 3*m + m*m + lwork_zunmbr )
334 maxwrk =
max( maxwrk, 3*m + m*m + lwork_zungbr )
336 maxwrk =
max( maxwrk, m*m + m + m*nrhs )
338 maxwrk =
max( maxwrk, m*m + 2*m )
340 maxwrk =
max( maxwrk, m + lwork_zunmlq )
346 CALL zgebrd( m, n, a, lda, s, s, dum(1), dum(1),
348 lwork_zgebrd = dble( dum(1) )
350 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, m, a, lda,
351 $ dum(1), b, ldb, dum(1), -1, info )
352 lwork_zunmbr = dble( dum(1) )
354 CALL zungbr(
'P', m, n, m, a, lda, dum(1),
356 lwork_zungbr = dble( dum(1) )
357 maxwrk = 2*m + lwork_zgebrd
358 maxwrk =
max( maxwrk, 2*m + lwork_zunmbr )
359 maxwrk =
max( maxwrk, 2*m + lwork_zungbr )
360 maxwrk =
max( maxwrk, n*nrhs )
363 maxwrk =
max( minwrk, maxwrk )
367 IF( lwork.LT.minwrk .AND. .NOT.lquery )
372 CALL xerbla(
'ZGELSS', -info )
380 IF( m.EQ.0 .OR. n.EQ.0 )
THEN
388 sfmin = dlamch(
'S' )
390 bignum = one / smlnum
391 CALL dlabad( smlnum, bignum )
395 anrm = zlange(
'M', m, n, a, lda, rwork )
397 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
401 CALL zlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
403 ELSE IF( anrm.GT.bignum )
THEN
407 CALL zlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
409 ELSE IF( anrm.EQ.zero )
THEN
413 CALL zlaset(
'F',
max( m, n ), nrhs, czero, czero, b, ldb )
414 CALL dlaset(
'F', minmn, 1, zero, zero, s, minmn )
421 bnrm = zlange(
'M', m, nrhs, b, ldb, rwork )
423 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
427 CALL zlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
429 ELSE IF( bnrm.GT.bignum )
THEN
433 CALL zlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
444 IF( m.GE.mnthr )
THEN
457 $ lwork-iwork+1, info )
463 CALL zunmqr(
'L',
'C', m, nrhs, n, a, lda, work( itau ), b,
464 $ ldb, work( iwork ), lwork-iwork+1, info )
469 $
CALL zlaset(
'L', n-1, n-1, czero, czero, a( 2, 1 ),
482 CALL zgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
483 $ work( itaup ), work( iwork ), lwork-iwork+1,
490 CALL zunmbr(
'Q',
'L',
'C', mm, nrhs, n, a, lda, work( itauq ),
491 $ b, ldb, work( iwork ), lwork-iwork+1, info )
497 CALL zungbr(
'P', n, n, n, a, lda, work( itaup ),
498 $ work( iwork ), lwork-iwork+1, info )
507 CALL zbdsqr(
'U', n, n, 0, nrhs, s, rwork( ie ), a, lda, dum,
508 $ 1, b, ldb, rwork( irwork ), info )
514 thr =
max( rcond*s( 1 ), sfmin )
516 $ thr =
max( eps*s( 1 ), sfmin )
519 IF( s( i ).GT.thr )
THEN
520 CALL zdrscl( nrhs, s( i ), b( i,
523 CALL zlaset(
'F', 1, nrhs, czero, czero, b( i, 1 ), ldb )
531 IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 )
THEN
532 CALL zgemm(
'C',
'N', n, nrhs, n, cone, a, lda, b, ldb,
534 CALL zlacpy(
'G', n, nrhs, work, ldb, b, ldb )
535 ELSE IF( nrhs.GT.1 )
THEN
537 DO 20 i = 1, nrhs, chunk
538 bl =
min( nrhs-i+1, chunk )
539 CALL zgemm(
'C',
'N', n, bl, n, cone, a, lda, b( 1, i ),
540 $ ldb, czero, work, n )
541 CALL zlacpy(
'G', n, bl, work, n, b( 1, i ), ldb )
544 CALL zgemv(
'C', n, n, cone, a, lda, b, 1, czero, work, 1 )
545 CALL zcopy( n, work, 1, b, 1 )
548 ELSE IF( n.GE.mnthr .AND. lwork.GE.3*m+m*m+
max( m, nrhs, n-2*m ) )
557 IF( lwork.GE.3*m+m*lda+
max( m, nrhs, n-2*m ) )
566 CALL zgelqf( m, n, a, lda, work( itau ), work( iwork ),
567 $ lwork-iwork+1, info )
572 CALL zlacpy(
'L', m, m, a, lda, work( il ), ldwork )
573 CALL zlaset(
'U', m-1, m-1, czero, czero, work( il+ldwork ),
576 itauq = il + ldwork*m
584 CALL zgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
585 $ work( itauq ), work( itaup ), work( iwork ),
586 $ lwork-iwork+1, info )
592 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, m, work( il ), ldwork,
593 $ work( itauq ), b, ldb, work( iwork ),
594 $ lwork-iwork+1, info )
600 CALL zungbr(
'P', m, m, m, work( il ), ldwork, work( itaup ),
601 $ work( iwork ), lwork-iwork+1, info )
610 CALL zbdsqr(
'U', m, m, 0, nrhs, s, rwork( ie ), work( il ),
611 $ ldwork, a, lda, b, ldb, rwork( irwork ), info )
617 thr =
max( rcond*s( 1 ), sfmin )
619 $ thr =
max( eps*s( 1 ), sfmin )
622 IF( s( i ).GT.thr )
THEN
623 CALL zdrscl( nrhs, s( i ), b( i, 1 ), ldb )
626 CALL zlaset(
'F', 1, nrhs, czero, czero, b( i, 1 ), ldb )
629 iwork = il + m*ldwork
635 IF( lwork.GE.ldb*nrhs+iwork-1 .AND. nrhs.GT.1 )
THEN
636 CALL zgemm(
'C',
'N', m, nrhs, m, cone, work( il ), ldwork,
637 $ b, ldb, czero, work( iwork ), ldb )
638 CALL zlacpy(
'G', m, nrhs, work( iwork ), ldb, b, ldb )
639 ELSE IF( nrhs.GT.1 )
THEN
640 chunk = ( lwork-iwork+1 ) / m
641 DO 40 i = 1, nrhs, chunk
642 bl =
min( nrhs-i+1, chunk )
645 CALL zlacpy(
'G', m, bl, work( iwork ), m, b( 1, i ),
649 CALL zgemv(
'C', m, m, cone, work( il ), ldwork, b( 1, 1 ),
650 $ 1, czero, work( iwork ), 1 )
651 CALL zcopy( m, work( iwork ), 1, b( 1, 1 ), 1 )
656 CALL zlaset(
'F', n-m, nrhs, czero, czero, b( m+1, 1 ), ldb )
664 $ ldb, work( iwork ), lwork-iwork+1, info )
679 CALL zgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
680 $ work( itaup ), work( iwork ), lwork-iwork+1,
687 CALL zunmbr(
'Q',
'L',
'C', m, nrhs, n, a, lda, work
688 $ b, ldb, work( iwork ), lwork-iwork+1, info )
694 CALL zungbr(
'P', m, n, m, a, lda, work( itaup ),
695 $ work( iwork ), lwork-iwork+1, info )
704 CALL zbdsqr(
'L', m, n, 0, nrhs, s, rwork( ie ), a, lda, dum,
705 $ 1, b, ldb, rwork( irwork ), info )
711 thr =
max( rcond*s( 1 ), sfmin )
713 $ thr =
max( eps*s( 1 ), sfmin )
716 IF( s( i ).GT.thr )
THEN
717 CALL zdrscl( nrhs, s( i ), b( i, 1 ), ldb )
720 CALL zlaset(
'F', 1, nrhs, czero, czero, b( i, 1
728 IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 )
THEN
729 CALL zgemm(
'C',
'N', n, nrhs, m, cone, a, lda, b, ldb,
731 CALL zlacpy(
'G', n, nrhs, work, ldb, b, ldb )
732 ELSE IF( nrhs.GT.1 )
THEN
734 DO 60 i = 1, nrhs, chunk
735 bl =
min( nrhs-i+1, chunk )
736 CALL zgemm(
'C',
'N', n, bl, m, cone, a, lda, b( 1, i ),
737 $ ldb, czero, work, n )
738 CALL zlacpy(
'F', n, bl, work, n, b( 1, i ), ldb )
741 CALL zgemv(
'C', m, n, cone, a, lda, b, 1, czero, work, 1 )
742 CALL zcopy( n, work, 1, b, 1 )
748 IF( iascl.EQ.1 )
THEN
749 CALL zlascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
750 CALL dlascl(
'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
752 ELSE IF( iascl.EQ.2 )
THEN
753 CALL zlascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
754 CALL dlascl(
'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
757 IF( ibscl.EQ.1 )
THEN
758 CALL zlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
759 ELSE IF( ibscl.EQ.2 )
THEN
760 CALL zlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )