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,
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,
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
485 work( 1 ) = dble( tszo + lwo )