202 SUBROUTINE sgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND,
204 $ WORK, LWORK, INFO )
211 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
216 REAL A( LDA, * ), B( LDB, * ), WORK( * )
223 PARAMETER ( IMAX = 1, imin = 2 )
225 parameter( zero = 0.0e+0, one = 1.0e+0 )
229 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
230 $ lwkopt, mn, nb, nb1, nb2, nb3, nb4
231 REAL ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
232 $ SMAXPR, SMIN, SMINPR, SMLNUM, WSIZE
236 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
237 EXTERNAL ilaenv, slamch, slange,
246 INTRINSIC abs, max, min
257 lquery = ( lwork.EQ.-1 )
260 ELSE IF( n.LT.0 )
THEN
262 ELSE IF( nrhs.LT.0 )
THEN
264 ELSE IF( lda.LT.max( 1, m ) )
THEN
266 ELSE IF( ldb.LT.max( 1, m, n ) )
THEN
273 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
277 nb1 = ilaenv( 1,
'SGEQRF',
' ', m, n, -1, -1 )
278 nb2 = ilaenv( 1,
'SGERQF',
' ', m, n, -1, -1 )
279 nb3 = ilaenv( 1,
'SORMQR',
' ', m, n, nrhs, -1 )
280 nb4 = ilaenv( 1,
'SORMRQ',
' ', m, n, nrhs, -1 )
281 nb = max( nb1, nb2, nb3, nb4 )
282 lwkmin = mn + max( 2*mn, n + 1, mn + nrhs )
283 lwkopt = max( lwkmin,
284 $ mn + 2*n + nb*( n + 1 ), 2*mn + nb*nrhs )
286 work( 1 ) = sroundup_lwork(lwkopt)
288 IF( lwork.LT.lwkmin .AND. .NOT.lquery )
THEN
294 CALL xerbla(
'SGELSY', -info )
296 ELSE IF( lquery )
THEN
302 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
309 smlnum = slamch(
'S' ) / slamch(
'P' )
310 bignum = one / smlnum
314 anrm = slange(
'M', m, n, a, lda, work )
316 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
320 CALL slascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
322 ELSE IF( anrm.GT.bignum )
THEN
326 CALL slascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
328 ELSE IF( anrm.EQ.zero )
THEN
332 CALL slaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
337 bnrm = slange(
'M', m, nrhs, b, ldb, work )
339 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
343 CALL slascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb,
346 ELSE IF( bnrm.GT.bignum )
THEN
350 CALL slascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb,
358 CALL sgeqp3( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ),
360 wsize = real( mn ) + work( mn+1 )
369 smax = abs( a( 1, 1 ) )
371 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
373 CALL slaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
380 IF( rank.LT.mn )
THEN
382 CALL slaic1( imin, rank, work( ismin ), smin, a( 1, i ),
383 $ a( i, i ), sminpr, s1, c1 )
384 CALL slaic1( imax, rank, work( ismax ), smax, a( 1, i ),
385 $ a( i, i ), smaxpr, s2, c2 )
387 IF( smaxpr*rcond.LE.sminpr )
THEN
389 work( ismin+i-1 ) = s1*work( ismin+i-1 )
390 work( ismax+i-1 ) = s2*work( ismax+i-1 )
392 work( ismin+rank ) = c1
393 work( ismax+rank ) = c2
410 $
CALL stzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
418 CALL sormqr(
'Left',
'Transpose', m, nrhs, mn, a, lda,
420 $ b, ldb, work( 2*mn+1 ), lwork-2*mn, info )
421 wsize = max( wsize, real( 2*mn )+work( 2*mn+1 ) )
427 CALL strsm(
'Left',
'Upper',
'No transpose',
'Non-unit', rank,
428 $ nrhs, one, a, lda, b, ldb )
431 DO 30 i = rank + 1, n
439 CALL sormrz(
'Left',
'Transpose', n, nrhs, rank, n-rank, a,
440 $ lda, work( mn+1 ), b, ldb, work( 2*mn+1 ),
450 work( jpvt( i ) ) = b( i, j )
452 CALL scopy( n, work( 1 ), 1, b( 1, j ), 1 )
459 IF( iascl.EQ.1 )
THEN
460 CALL slascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb,
462 CALL slascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
464 ELSE IF( iascl.EQ.2 )
THEN
465 CALL slascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb,
467 CALL slascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
470 IF( ibscl.EQ.1 )
THEN
471 CALL slascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb,
473 ELSE IF( ibscl.EQ.2 )
THEN
474 CALL slascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb,
479 work( 1 ) = sroundup_lwork(lwkopt)