176 SUBROUTINE dgelsx( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
184 INTEGER INFO, LDA, LDB, M, N, NRHS, RANK
185 DOUBLE PRECISION RCOND
189 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
196 parameter( imax = 1, imin = 2 )
197 DOUBLE PRECISION ZERO, ONE, DONE, NTDONE
198 parameter( zero = 0.0d0, one = 1.0d0, done = zero,
202 INTEGER I, IASCL, IBSCL, ISMAX, ISMIN, J, K, MN
203 DOUBLE PRECISION ANRM, BIGNUM, BNRM, C1, C2, S1, S2, SMAX,
204 $ smaxpr, smin, sminpr, smlnum, t1, t2
207 DOUBLE PRECISION DLAMCH, DLANGE
208 EXTERNAL dlamch, dlange
215 INTRINSIC abs, max, min
228 ELSE IF( n.LT.0 )
THEN
230 ELSE IF( nrhs.LT.0 )
THEN
232 ELSE IF( lda.LT.max( 1, m ) )
THEN
234 ELSE IF( ldb.LT.max( 1, m, n ) )
THEN
239 CALL xerbla(
'DGELSX', -info )
245 IF( min( m, n, nrhs ).EQ.0 )
THEN
252 smlnum = dlamch(
'S' ) / dlamch(
'P' )
253 bignum = one / smlnum
257 anrm = dlange(
'M', m, n, a, lda, work )
259 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN
263 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
265 ELSE IF( anrm.GT.bignum )
THEN
269 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
271 ELSE IF( anrm.EQ.zero )
THEN
275 CALL dlaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
280 bnrm = dlange(
'M', m, nrhs, b, ldb, work )
282 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN
286 CALL dlascl(
'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb, info )
288 ELSE IF( bnrm.GT.bignum )
THEN
292 CALL dlascl(
'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb, info )
299 CALL dgeqpf( m, n, a, lda, jpvt, work( 1 ), work( mn+1 ), info )
308 smax = abs( a( 1, 1 ) )
310 IF( abs( a( 1, 1 ) ).EQ.zero )
THEN
312 CALL dlaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
319 IF( rank.LT.mn )
THEN
321 CALL dlaic1( imin, rank, work( ismin ), smin, a( 1, i ),
322 $ a( i, i ), sminpr, s1, c1 )
323 CALL dlaic1( imax, rank, work( ismax ), smax, a( 1, i ),
324 $ a( i, i ), smaxpr, s2, c2 )
326 IF( smaxpr*rcond.LE.sminpr )
THEN
328 work( ismin+i-1 ) = s1*work( ismin+i-1 )
329 work( ismax+i-1 ) = s2*work( ismax+i-1 )
331 work( ismin+rank ) = c1
332 work( ismax+rank ) = c2
347 $
CALL dtzrqf( rank, n, a, lda, work( mn+1 ), info )
353 CALL dorm2r(
'Left',
'Transpose', m, nrhs, mn, a, lda, work( 1 ),
354 $ b, ldb, work( 2*mn+1 ), info )
360 CALL dtrsm(
'Left',
'Upper',
'No transpose',
'Non-unit', rank,
361 $ nrhs, one, a, lda, b, ldb )
363 DO 40 i = rank + 1, n
373 CALL dlatzm(
'Left', n-rank+1, nrhs, a( i, rank+1 ), lda,
374 $ work( mn+i ), b( i, 1 ), b( rank+1, 1 ), ldb,
385 work( 2*mn+i ) = ntdone
388 IF( work( 2*mn+i ).EQ.ntdone )
THEN
389 IF( jpvt( i ).NE.i )
THEN
392 t2 = b( jpvt( k ), j )
394 b( jpvt( k ), j ) = t1
395 work( 2*mn+k ) = done
398 t2 = b( jpvt( k ), j )
402 work( 2*mn+k ) = done
410 IF( iascl.EQ.1 )
THEN
411 CALL dlascl(
'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb, info )
412 CALL dlascl(
'U', 0, 0, smlnum, anrm, rank, rank, a, lda,
414 ELSE IF( iascl.EQ.2 )
THEN
415 CALL dlascl(
'G', 0, 0, anrm, bignum, n, nrhs, b, ldb, info )
416 CALL dlascl(
'U', 0, 0, bignum, anrm, rank, rank, a, lda,
419 IF( ibscl.EQ.1 )
THEN
420 CALL dlascl(
'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb, info )
421 ELSE IF( ibscl.EQ.2 )
THEN
422 CALL dlascl(
'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb, info )
subroutine xerbla(srname, info)
subroutine dgelsx(m, n, nrhs, a, lda, b, ldb, jpvt, rcond, rank, work, info)
DGELSX solves overdetermined or underdetermined systems for GE matrices
subroutine dgeqpf(m, n, a, lda, jpvt, tau, work, info)
DGEQPF
subroutine dlatzm(side, m, n, v, incv, tau, c1, c2, ldc, work)
DLATZM
subroutine dtzrqf(m, n, a, lda, tau, info)
DTZRQF
subroutine dlaic1(job, j, x, sest, w, gamma, sestpr, s, c)
DLAIC1 applies one step of incremental condition estimation.
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dtrsm(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb)
DTRSM
subroutine dorm2r(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
DORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sge...