202 SUBROUTINE sgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
203 $ WORK, LWORK, INFO )
210 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
215 REAL A( LDA, * ), B( LDB, * ), WORK( * )
222 parameter( imax = 1, imin = 2 )
224 parameter( zero = 0.0e+0, one = 1.0e+0 )
228 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
229 $ lwkopt, mn, nb, nb1, nb2, nb3, nb4
230 REAL ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
231 $ smaxpr, smin, sminpr, smlnum, wsize
236 EXTERNAL ilaenv, slamch, slange
243 INTRINSIC abs, max, min
254 lquery = ( lwork.EQ.-1 )
257 ELSE IF( n.LT.0 )
THEN
259 ELSE IF( nrhs.LT.0 )
THEN
261 ELSE IF( lda.LT.max( 1, m ) )
THEN
263 ELSE IF( ldb.LT.max( 1, m, n ) )
THEN
270 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
274 nb1 = ilaenv( 1,
'SGEQRF',
' ', m, n, -1, -1 )
275 nb2 = ilaenv( 1,
'SGERQF',
' ', m, n, -1, -1 )
276 nb3 = ilaenv( 1,
'SORMQR',
' ', m, n, nrhs, -1 )
277 nb4 = ilaenv( 1,
'SORMRQ',
' ', m, n, nrhs, -1 )
278 nb = max( nb1, nb2, nb3, nb4 )
279 lwkmin = mn + max( 2*mn, n + 1, mn + nrhs )
280 lwkopt = max( lwkmin,
281 $ mn + 2*n + nb*( n + 1 ), 2*mn + nb*nrhs )
285 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
291 CALL xerbla(
'SGELSY', -info )
293 ELSE IF( lquery )
THEN
299 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
306 smlnum = slamch(
'S' ) / slamch(
'P' )
307 bignum = one / smlnum
308 CALL slabad( smlnum, bignum )
312 anrm = slange(
'M', m, n, a, lda, work )
314 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
318 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
320 ELSE IF( anrm.GT.bignum )
THEN
324 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
326 ELSE IF( anrm.EQ.zero )
THEN
330 CALL slaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
335 bnrm = slange(
'M', m, nrhs, b, ldb, work )
337 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
341 CALL slascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
343 ELSE IF( bnrm.GT.bignum )
THEN
347 CALL slascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
354 CALL sgeqp3( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ),
356 wsize = mn + work( mn+1 )
365 smax = abs( a( 1, 1 ) )
367 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
369 CALL slaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
376 IF( rank.LT.mn )
THEN
378 CALL slaic1( imin, rank, work( ismin ), smin, a( 1, i ),
379 $ a( i, i ), sminpr, s1, c1 )
380 CALL slaic1( imax, rank, work( ismax ), smax, a( 1, i ),
381 $ a( i, i ), smaxpr, s2, c2 )
383 IF( smaxpr*rcond.LE.sminpr )
THEN
385 work( ismin+i-1 ) = s1*work( ismin+i-1 )
386 work( ismax+i-1 ) = s2*work( ismax+i-1 )
388 work( ismin+rank ) = c1
389 work( ismax+rank ) = c2
406 $
CALL stzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
414 CALL sormqr(
'Left',
'Transpose', m, nrhs, mn, a, lda, work( 1 ),
415 $ b, ldb, work( 2*mn+1 ), lwork-2*mn, info )
416 wsize = max( wsize, 2*mn+work( 2*mn+1 ) )
422 CALL strsm(
'Left',
'Upper',
'No transpose',
'Non-unit', rank,
423 $ nrhs, one, a, lda, b, ldb )
426 DO 30 i = rank + 1, n
434 CALL sormrz(
'Left',
'Transpose', n, nrhs, rank, n-rank, a,
435 $ lda, work( mn+1 ), b, ldb, work( 2*mn+1 ),
445 work( jpvt( i ) ) = b( i, j )
447 CALL scopy( n, work( 1 ), 1, b( 1, j ), 1 )
454 IF( iascl.EQ.1 )
THEN
455 CALL slascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
456 CALL slascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
458 ELSE IF( iascl.EQ.2 )
THEN
459 CALL slascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
460 CALL slascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
463 IF( ibscl.EQ.1 )
THEN
464 CALL slascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
465 ELSE IF( ibscl.EQ.2 )
THEN
466 CALL slascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
subroutine slabad(SMALL, LARGE)
SLABAD
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 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 xerbla(SRNAME, INFO)
XERBLA
subroutine sgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO)
SGEQP3
subroutine sgelsy(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK, WORK, LWORK, INFO)
SGELSY solves overdetermined or underdetermined systems for GE matrices
subroutine slaic1(JOB, J, X, SEST, W, GAMMA, SESTPR, S, C)
SLAIC1 applies one step of incremental condition estimation.
subroutine stzrzf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
STZRZF
subroutine sormrz(SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMRZ
subroutine sormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
SORMQR
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY
subroutine strsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
STRSM