202 SUBROUTINE dgelsy( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
203 $ WORK, LWORK, INFO )
210 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
211 DOUBLE PRECISION RCOND
215 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
222 PARAMETER ( imax = 1, imin = 2 )
223 DOUBLE PRECISION ZERO, ONE
224 parameter( zero = 0.0d+0, one = 1.0d+0 )
228 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, LWKMIN,
229 $ lwkopt, mn, nb, nb1, nb2, nb3, nb4
230 DOUBLE PRECISION ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
231 $ smaxpr, smin, sminpr, smlnum, wsize
235 DOUBLE PRECISION DLAMCH, DLANGE
236 EXTERNAL ilaenv, dlamch, dlange
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,
'DGEQRF',
' ', m, n, -1, -1 )
275 nb2 = ilaenv( 1,
'DGERQF',
' ', m, n, -1, -1 )
276 nb3 = ilaenv( 1,
'DORMQR',
' ', m, n, nrhs, -1 )
277 nb4 = ilaenv( 1,
'DORMRQ',
' ', 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(
'DGELSY', -info )
293 ELSE IF( lquery )
THEN
299 IF( mn.EQ.0 .OR. nrhs.EQ.0 )
THEN
306 smlnum = dlamch(
'S' ) / dlamch(
'P' )
307 bignum = one / smlnum
308 CALL dlabad( smlnum, bignum )
312 anrm = dlange(
'M', m, n, a, lda, work )
314 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
318 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
320 ELSE IF( anrm.GT.bignum )
THEN
324 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
326 ELSE IF( anrm.EQ.zero )
THEN
335 bnrm = dlange(
'M', m, nrhs, b, ldb, work )
337 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum
THEN
341 CALL dlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
343 ELSE IF( bnrm.GT.bignum
THEN
347 CALL dlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
354 CALL dgeqp3( 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 dlaset(
'F',
max( m, n ), nrhs, zero, zero, b, ldb )
376 IF( rank.LT.mn )
THEN
378 CALL dlaic1( imin, rank, work( ismin ), smin, a( 1, i ),
379 $ a( i, i ), sminpr, s1, c1 )
380 CALL dlaic1( imax, rank, work( ismax ), smax, a( 1, i ),
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 dtzrzf( rank, n, a, lda, work( mn+1 ), work( 2*mn+1 ),
414 CALL dormqr(
'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 dtrsm'Left',
'Upper',
'No transpose',
'Non-unit', rank,
423 $ nrhs, one, a, lda, b, ldb )
426 DO 30 i = rank + 1, n
434 CALL dormrz(
'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 dcopy( n, work( 1 ), 1, b( 1, j ), 1 )
454 IF( iascl.EQ.1 )
THEN
455 CALL dlascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
456 CALL dlascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
458 ELSE IF( iascl.EQ.2 )
THEN
459 CALL dlascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
460 CALL dlascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
463 IF( ibscl.EQ.1 )
THEN
464 CALL dlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
465 ELSE IF( ibscl.EQ.2 )
THEN
466 CALL dlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )