204 SUBROUTINE sgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
205 $ WORK, LWORK, INFO )
212 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
217 REAL A( LDA, * ), B( LDB, * ), WORK( * )
224 parameter( imax = 1, imin = 2 )
226 parameter( zero = 0.0e+0, one = 1.0e+0 )
230 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
231 $ lwkopt, mn, nb, nb1, nb2, nb3, nb4
232 REAL ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
233 $ smaxpr, smin, sminpr, smlnum, wsize
237 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
238 EXTERNAL ilaenv, slamch, slange, sroundup_lwork
245 INTRINSIC abs, max, min
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, m, n ) )
THEN
272 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
276 nb1 = ilaenv( 1,
'SGEQRF',
' ', m, n, -1, -1 )
277 nb2 = ilaenv( 1,
'SGERQF',
' ', m, n, -1, -1 )
278 nb3 = ilaenv( 1,
'SORMQR',
' ', m, n, nrhs, -1 )
279 nb4 = ilaenv( 1,
'SORMRQ',
' ', m, n, nrhs, -1 )
280 nb = max( nb1, nb2, nb3, nb4 )
281 lwkmin = mn + max( 2*mn, n + 1, mn + nrhs )
282 lwkopt = max( lwkmin,
283 $ mn + 2*n + nb*( n + 1 ), 2*mn + nb*nrhs )
285 work( 1 ) = sroundup_lwork(lwkopt)
287 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
293 CALL xerbla(
'SGELSY', -info )
295 ELSE IF( lquery )
THEN
301 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
308 smlnum = slamch(
'S' ) / slamch(
'P' )
309 bignum = one / smlnum
313 anrm = slange(
'M', m, n, a, lda, work )
315 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
319 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
321 ELSE IF( anrm.GT.bignum )
THEN
325 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
327 ELSE IF( anrm.EQ.zero )
THEN
331 CALL slaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
336 bnrm = slange(
'M', m, nrhs, b, ldb, work )
338 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
342 CALL slascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
344 ELSE IF( bnrm.GT.bignum )
THEN
348 CALL slascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
355 CALL sgeqp3( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ),
357 wsize = mn + work( mn+1 )
366 smax = abs( a( 1, 1 ) )
368 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
370 CALL slaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
377 IF( rank.LT.mn )
THEN
379 CALL slaic1( imin, rank, work( ismin ), smin, a( 1, i ),
380 $ a( i, i ), sminpr, s1, c1 )
381 CALL slaic1( imax, rank, work( ismax ), smax, a( 1, i ),
382 $ a( i, i ), smaxpr, s2, c2 )
384 IF( smaxpr*rcond.LE.sminpr )
THEN
386 work( ismin+i-1 ) = s1*work( ismin+i-1 )
387 work( ismax+i-1 ) = s2*work( ismax+i-1 )
389 work( ismin+rank ) = c1
390 work( ismax+rank ) = c2
407 $
CALL stzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
415 CALL sormqr(
'Left',
'Transpose', m, nrhs, mn, a, lda, work( 1 ),
416 $ b, ldb, work( 2*mn+1 ), lwork-2*mn, info )
417 wsize = max( wsize, 2*mn+work( 2*mn+1 ) )
423 CALL strsm(
'Left',
'Upper',
'No transpose',
'Non-unit', rank,
424 $ nrhs, one, a, lda, b, ldb )
427 DO 30 i = rank + 1, n
435 CALL sormrz(
'Left',
'Transpose', n, nrhs, rank, n-rank, a,
436 $ lda, work( mn+1 ), b, ldb, work( 2*mn+1 ),
446 work( jpvt( i ) ) = b( i, j )
448 CALL scopy( n, work( 1 ), 1, b( 1, j ), 1 )
455 IF( iascl.EQ.1 )
THEN
456 CALL slascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
457 CALL slascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
459 ELSE IF( iascl.EQ.2 )
THEN
460 CALL slascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
461 CALL slascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
464 IF( ibscl.EQ.1 )
THEN
465 CALL slascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
466 ELSE IF( ibscl.EQ.2 )
THEN
467 CALL slascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
471 work( 1 ) = sroundup_lwork(lwkopt)
subroutine xerbla(srname, info)
subroutine scopy(n, sx, incx, sy, incy)
SCOPY
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 sgeqp3(m, n, a, lda, jpvt, tau, work, lwork, info)
SGEQP3
subroutine slaic1(job, j, x, sest, w, gamma, sestpr, s, c)
SLAIC1 applies one step of incremental condition estimation.
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 strsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
STRSM
subroutine stzrzf(m, n, a, lda, tau, work, lwork, info)
STZRZF
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR
subroutine sormrz(side, trans, m, n, k, l, a, lda, tau, c, ldc, work, lwork, info)
SORMRZ