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
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,
'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
330 CALL dlaset(
'F', max( m, n ), nrhs, zero, zero, b, ldb )
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 ),
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 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 )
subroutine dlabad(SMALL, LARGE)
DLABAD
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 xerbla(SRNAME, INFO)
XERBLA
subroutine dcopy(N, DX, INCX, DY, INCY)
DCOPY
subroutine dtrsm(SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA, A, LDA, B, LDB)
DTRSM
subroutine dgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, INFO)
DGEQP3
subroutine dgelsy(M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK, WORK, LWORK, INFO)
DGELSY solves overdetermined or underdetermined systems for GE matrices
subroutine dlaic1(JOB, J, X, SEST, W, GAMMA, SESTPR, S, C)
DLAIC1 applies one step of incremental condition estimation.
subroutine dormqr(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMQR
subroutine dtzrzf(M, N, A, LDA, TAU, WORK, LWORK, INFO)
DTZRZF
subroutine dormrz(SIDE, TRANS, M, N, K, L, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
DORMRZ