208 SUBROUTINE sgelsd( M, N, NRHS, A, LDA, B, LDB, S, RCOND,
209 $ RANK, WORK, LWORK, IWORK, INFO )
216 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
221 REAL A( LDA, * ), B( LDB, * ), S( * ), WORK( * )
228 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0 )
232 INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
233 $ ldwork, liwork, maxmn, maxwrk, minmn, minwrk,
234 $ mm, mnthr, nlvl, nwork, smlsiz, wlalsd
235 REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
244 EXTERNAL slamch, slange, ilaenv
247 INTRINSIC int, log,
max,
min, real
256 lquery = ( lwork.EQ.-1 )
259 ELSE IF( n.LT.0 )
THEN
261 ELSE IF( nrhs.LT.0 )
THEN
263 ELSE IF( lda.LT.
max( 1, m ) )
THEN
265 ELSE IF( ldb.LT.
max( 1, maxmn ) )
THEN
280 IF( minmn.GT.0 )
THEN
281 smlsiz = ilaenv( 9,
'SGELSD',
' ', 0, 0, 0, 0 )
282 mnthr = ilaenv( 6,
'SGELSD',
' ', m, n, nrhs, -1 )
284 $ log( two ) ) + 1, 0 )
285 liwork = 3*minmn*nlvl + 11*minmn
287 IF( m.GE.n .AND. m.GE.mnthr )
THEN
293 maxwrk =
max( maxwrk, n + n*ilaenv( 1,
'SGEQRF',
' ', m,
295 maxwrk =
max( maxwrk, n + nrhs*ilaenv( 1, '
sormqr', 'lt
',
302 MAXWRK = MAX( MAXWRK, 3*N + ( MM + N )*ILAENV( 1,
303 $ 'sgebrd', ' ', MM, N, -1, -1 ) )
304 MAXWRK = MAX( MAXWRK, 3*N + NRHS*ILAENV( 1, 'sormbr',
305 $ 'qlt
', MM, NRHS, N, -1 ) )
306 MAXWRK = MAX( MAXWRK, 3*N + ( N - 1 )*ILAENV( 1,
307 $ 'sormbr', 'pln
', N, NRHS, N, -1 ) )
308 WLALSD = 9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS +
310 MAXWRK = MAX( MAXWRK, 3*N + WLALSD )
311 MINWRK = MAX( 3*N + MM, 3*N + NRHS, 3*N + WLALSD )
314 WLALSD = 9*M + 2*M*SMLSIZ + 8*M*NLVL + M*NRHS +
316.GE.
IF( NMNTHR ) THEN
321 MAXWRK = M + M*ILAENV( 1, 'sgelqf', ' ', M, N, -1,
323 MAXWRK = MAX( MAXWRK, M*M + 4*M + 2*M*ILAENV( 1,
324 $ 'sgebrd', ' ', M, M, -1, -1 ) )
325 MAXWRK = MAX( MAXWRK, M*M + 4*M + NRHS*ILAENV( 1,
326 $ 'sormbr', 'qlt
', M, NRHS, M, -1 ) )
327 MAXWRK = MAX( MAXWRK, M*M + 4*M + ( M - 1 )*ILAENV( 1,
328 $ 'sormbr', 'pln
', M, NRHS, M, -1 ) )
330 MAXWRK = MAX( MAXWRK, M*M + M + M*NRHS )
332 MAXWRK = MAX( MAXWRK, M*M + 2*M )
334 MAXWRK = MAX( MAXWRK, M + NRHS*ILAENV( 1, 'sormlq',
335 $ 'lt
', N, NRHS, M, -1 ) )
336 MAXWRK = MAX( MAXWRK, M*M + 4*M + WLALSD )
337! XXX: Ensure the Path 2a case below is triggered. The workspace
338! calculation should use queries for all routines eventually.
339 MAXWRK = MAX( MAXWRK,
340 $ 4*M+M*M+MAX( M, 2*M-4, NRHS, N-3*M ) )
345 MAXWRK = 3*M + ( N + M )*ILAENV( 1, 'sgebrd', ' ', M,
347 MAXWRK = MAX( MAXWRK, 3*M + NRHS*ILAENV( 1, 'sormbr',
348 $ 'qlt
', M, NRHS, N, -1 ) )
349 MAXWRK = MAX( MAXWRK, 3*M + M*ILAENV( 1, 'sormbr',
350 $ 'pln
', N, NRHS, M, -1 ) )
351 MAXWRK = MAX( MAXWRK, 3*M + WLALSD )
353 MINWRK = MAX( 3*M + NRHS, 3*M + M, 3*M + WLALSD )
356 MINWRK = MIN( MINWRK, MAXWRK )
360.LT..AND..NOT.
IF( LWORKMINWRK LQUERY ) THEN
366 CALL XERBLA( 'sgelsd', -INFO )
368 ELSE IF( LQUERY ) THEN
374.EQ..OR..EQ.
IF( M0 N0 ) THEN
382 SFMIN = SLAMCH( 's
' )
384 BIGNUM = ONE / SMLNUM
385 CALL SLABAD( SMLNUM, BIGNUM )
389 ANRM = SLANGE( 'm
', M, N, A, LDA, WORK )
391.GT..AND..LT.
IF( ANRMZERO ANRMSMLNUM ) THEN
395 CALL SLASCL( 'g
', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
397.GT.
ELSE IF( ANRMBIGNUM ) THEN
401 CALL SLASCL( 'g
', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
403.EQ.
ELSE IF( ANRMZERO ) THEN
407 CALL SLASET( 'f
', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
408 CALL SLASET( 'f
', MINMN, 1, ZERO, ZERO, S, 1 )
415 BNRM = SLANGE( 'm
', M, NRHS, B, LDB, WORK )
417.GT..AND..LT.
IF( BNRMZERO BNRMSMLNUM ) THEN
421 CALL SLASCL( 'g
', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
423.GT.
ELSE IF( BNRMBIGNUM ) THEN
427 CALL SLASCL( 'g
', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
434 $ CALL SLASET( 'f
', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
443.GE.
IF( MMNTHR ) THEN
454 CALL SGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
455 $ LWORK-NWORK+1, INFO )
460 CALL SORMQR( 'l
', 't
', M, NRHS, N, A, LDA, WORK( ITAU ), B,
461 $ LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
466 CALL SLASET( 'l
', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
478 CALL SGEBRD( MM, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
479 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
485 CALL SORMBR( 'q
', 'l
', 't
', MM, NRHS, N, A, LDA, WORK( ITAUQ ),
486 $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
490 CALL SLALSD( 'u
', SMLSIZ, N, NRHS, S, WORK( IE ), B, LDB,
491 $ RCOND, RANK, WORK( NWORK ), IWORK, INFO )
498 CALL SORMBR( 'p
', 'l
', 'n
', N, NRHS, N, A, LDA, WORK( ITAUP ),
499 $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
501.GE..AND..GE.
ELSE IF( NMNTHR LWORK4*M+M*M+
502 $ MAX( M, 2*M-4, NRHS, N-3*M, WLALSD ) ) THEN
508.GE.
IF( LWORKMAX( 4*M+M*LDA+MAX( M, 2*M-4, NRHS, N-3*M ),
509 $ M*LDA+M+M*NRHS, 4*M+M*LDA+WLALSD ) )LDWORK = LDA
516 CALL SGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
517 $ LWORK-NWORK+1, INFO )
522 CALL SLACPY( 'l
', M, M, A, LDA, WORK( IL ), LDWORK )
523 CALL SLASET( 'u
', M-1, M-1, ZERO, ZERO, WORK( IL+LDWORK ),
533 CALL SGEBRD( M, M, WORK( IL ), LDWORK, S, WORK( IE ),
534 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
535 $ LWORK-NWORK+1, INFO )
540 CALL SORMBR( 'q
', 'l
', 't
', M, NRHS, M, WORK( IL ), LDWORK,
541 $ WORK( ITAUQ ), B, LDB, WORK( NWORK ),
542 $ LWORK-NWORK+1, INFO )
546 CALL SLALSD( 'u
', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
547 $ RCOND, RANK, WORK( NWORK ), IWORK, INFO )
554 CALL SORMBR( 'p
', 'l
', 'n
', M, NRHS, M, WORK( IL ), LDWORK,
555 $ WORK( ITAUP ), B, LDB, WORK( NWORK ),
556 $ LWORK-NWORK+1, INFO )
560 CALL SLASET( 'f
', N-M, NRHS, ZERO, ZERO, B( M+1, 1 ), LDB )
566 CALL SORMLQ( 'l
', 't
', N, NRHS, M, A, LDA, WORK( ITAU ), B,
567 $ LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
581 CALL SGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
582 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
588 CALL SORMBR( 'q
', 'l
', 't
', M, NRHS, N, A, LDA, WORK( ITAUQ ),
589 $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
593 CALL SLALSD( 'l
', SMLSIZ, M, NRHS, S, WORK( IE ), B, LDB,
594 $ RCOND, RANK, WORK( NWORK ), IWORK, INFO )
601 CALL SORMBR( 'p
', 'l
', 'n
', N, NRHS, M, A, LDA, WORK( ITAUP ),
602 $ B, LDB, WORK( NWORK ), LWORK-NWORK+1, INFO )
608.EQ.
IF( IASCL1 ) THEN
609 CALL SLASCL( 'g
', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
610 CALL SLASCL( 'g
', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
612.EQ.
ELSE IF( IASCL2 ) THEN
613 CALL SLASCL( 'g
', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
614 CALL SLASCL( 'g
', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
617.EQ.
IF( IBSCL1 ) THEN
618 CALL SLASCL( 'g
', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
619.EQ.
ELSE IF( IBSCL2 ) THEN
620 CALL SLASCL( 'g
', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
subroutine slabad(small, large)
SLABAD
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine xerbla(srname, info)
XERBLA
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
subroutine sgelqf(m, n, a, lda, tau, work, lwork, info)
SGELQF
subroutine sgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
SGEBRD
subroutine sgelsd(m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, iwork, info)
SGELSD computes the minimum-norm solution to a linear least squares problem for GE matrices
subroutine sormbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMBR
subroutine slalsd(uplo, smlsiz, n, nrhs, d, e, b, ldb, rcond, rank, work, iwork, info)
SLALSD uses the singular value decomposition of A to solve the least squares problem.
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR
subroutine sormlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMLQ