160 SUBROUTINE dgetsls( TRANS, M, N, NRHS, A, LDA, B, LDB,
161 $ WORK, LWORK, INFO )
169 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
172 DOUBLE PRECISION A( lda, * ), B( ldb, * ), WORK( * )
179 DOUBLE PRECISION ZERO, ONE
180 parameter( zero = 0.0d0, one = 1.0d0 )
184 INTEGER I, IASCL, IBSCL, J, MAXMN, BROW,
185 $ scllen, tszo, tszm, lwo, lwm, lw1, lw2,
186 $ wsizeo, wsizem, info2
187 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM, TQ( 5 ), WORKQ( 1 )
191 DOUBLE PRECISION DLAMCH, DLANGE
192 EXTERNAL lsame,
dlabad, dlamch, dlange
199 INTRINSIC dble, max, min, int
207 tran = lsame( trans,
'T' )
209 lquery = ( lwork.EQ.-1 .OR. lwork.EQ.-2 )
210 IF( .NOT.( lsame( trans,
'N' ) .OR.
211 $ lsame( trans,
'T' ) ) )
THEN 213 ELSE IF( m.LT.0 )
THEN 215 ELSE IF( n.LT.0 )
THEN 217 ELSE IF( nrhs.LT.0 )
THEN 219 ELSE IF( lda.LT.max( 1, m ) )
THEN 221 ELSE IF( ldb.LT.max( 1, m, n ) )
THEN 230 CALL dgeqr( m, n, a, lda, tq, -1, workq, -1, info2 )
231 tszo = int( tq( 1 ) )
232 lwo = int( workq( 1 ) )
233 CALL dgemqr(
'L', trans, m, nrhs, n, a, lda, tq,
234 $ tszo, b, ldb, workq, -1, info2 )
235 lwo = max( lwo, int( workq( 1 ) ) )
236 CALL dgeqr( m, n, a, lda, tq, -2, workq, -2, info2 )
237 tszm = int( tq( 1 ) )
238 lwm = int( workq( 1 ) )
239 CALL dgemqr(
'L', trans, m, nrhs, n, a, lda, tq,
240 $ tszm, b, ldb, workq, -1, info2 )
241 lwm = max( lwm, int( workq( 1 ) ) )
245 CALL dgelq( m, n, a, lda, tq, -1, workq, -1, info2 )
246 tszo = int( tq( 1 ) )
247 lwo = int( workq( 1 ) )
248 CALL dgemlq(
'L', trans, n, nrhs, m, a, lda, tq,
249 $ tszo, b, ldb, workq, -1, info2 )
250 lwo = max( lwo, int( workq( 1 ) ) )
251 CALL dgelq( m, n, a, lda, tq, -2, workq, -2, info2 )
252 tszm = int( tq( 1 ) )
253 lwm = int( workq( 1 ) )
254 CALL dgemlq(
'L', trans, n, nrhs, m, a, lda, tq,
255 $ tszm, b, ldb, workq, -1, info2 )
256 lwm = max( lwm, int( workq( 1 ) ) )
261 IF( ( lwork.LT.wsizem ).AND.( .NOT.lquery ) )
THEN 265 work( 1 ) = dble( wsizeo )
270 CALL xerbla(
'DGETSLS', -info )
274 IF( lwork.EQ.-2 ) work( 1 ) = dble( wsizem )
277 IF( lwork.LT.wsizeo )
THEN 287 IF( min( m, n, nrhs ).EQ.0 )
THEN 288 CALL dlaset(
'FULL', max( m, n ), nrhs, zero, zero,
295 smlnum = dlamch(
'S' ) / dlamch(
'P' )
296 bignum = one / smlnum
297 CALL dlabad( smlnum, bignum )
301 anrm = dlange(
'M', m, n, a, lda, work )
303 IF( anrm.GT.zero .AND. anrm.LT.smlnum )
THEN 307 CALL dlascl(
'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
309 ELSE IF( anrm.GT.bignum )
THEN 313 CALL dlascl(
'G', 0, 0, anrm, bignum, m, n, a, lda, info )
315 ELSE IF( anrm.EQ.zero )
THEN 319 CALL dlaset(
'F', maxmn, nrhs, zero, zero, b, ldb )
327 bnrm = dlange(
'M', brow, nrhs, b, ldb, work )
329 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum )
THEN 333 CALL dlascl(
'G', 0, 0, bnrm, smlnum, brow, nrhs, b, ldb,
336 ELSE IF( bnrm.GT.bignum )
THEN 340 CALL dlascl(
'G', 0, 0, bnrm, bignum, brow, nrhs, b, ldb,
349 CALL dgeqr( m, n, a, lda, work( lw2+1 ), lw1,
350 $ work( 1 ), lw2, info )
351 IF ( .NOT.tran )
THEN 357 CALL dgemqr(
'L' ,
'T', m, nrhs, n, a, lda,
358 $ work( lw2+1 ), lw1, b, ldb, work( 1 ), lw2,
363 CALL dtrtrs(
'U',
'N',
'N', n, nrhs,
364 $ a, lda, b, ldb, info )
375 CALL dtrtrs(
'U',
'T',
'N', n, nrhs,
376 $ a, lda, b, ldb, info )
392 CALL dgemqr(
'L',
'N', m, nrhs, n, a, lda,
393 $ work( lw2+1 ), lw1, b, ldb, work( 1 ), lw2,
404 CALL dgelq( m, n, a, lda, work( lw2+1 ), lw1,
405 $ work( 1 ), lw2, info )
415 CALL dtrtrs(
'L',
'N',
'N', m, nrhs,
416 $ a, lda, b, ldb, info )
432 CALL dgemlq(
'L',
'T', n, nrhs, m, a, lda,
433 $ work( lw2+1 ), lw1, b, ldb, work( 1 ), lw2,
446 CALL dgemlq(
'L',
'N', n, nrhs, m, a, lda,
447 $ work( lw2+1 ), lw1, b, ldb, work( 1 ), lw2,
454 CALL dtrtrs(
'Lower',
'Transpose',
'Non-unit', m, nrhs,
455 $ a, lda, b, ldb, info )
469 IF( iascl.EQ.1 )
THEN 470 CALL dlascl(
'G', 0, 0, anrm, smlnum, scllen, nrhs, b, ldb,
472 ELSE IF( iascl.EQ.2 )
THEN 473 CALL dlascl(
'G', 0, 0, anrm, bignum, scllen, nrhs, b, ldb,
476 IF( ibscl.EQ.1 )
THEN 477 CALL dlascl(
'G', 0, 0, smlnum, bnrm, scllen, nrhs, b, ldb,
479 ELSE IF( ibscl.EQ.2 )
THEN 480 CALL dlascl(
'G', 0, 0, bignum, bnrm, scllen, nrhs, b, ldb,
485 work( 1 ) = dble( tszo + lwo )
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine dgelq(M, N, A, LDA, T, TSIZE, WORK, LWORK, INFO)
DGELQ
subroutine dgetsls(TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK, INFO)
DGETSLS
subroutine dtrtrs(UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB, INFO)
DTRTRS
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 dgeqr(M, N, A, LDA, T, TSIZE, WORK, LWORK, INFO)
DGEQR
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 dlabad(SMALL, LARGE)
DLABAD