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( , * ), 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.EQ.
IF( IASCL1 ) 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.EQ.
ELSE IF( IASCL2 ) 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.EQ.
IF( IBSCL1 ) THEN
649 CALL ZLASCL( 'g
', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
650.EQ.
ELSE IF( IBSCL2 ) THEN
651 CALL ZLASCL( 'g
', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )