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 )
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.GT.
ELSE IF( ANRMBIGNUM ) THEN
313 CALL DLASCL( 'g
', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
315.EQ.
ELSE IF( ANRMZERO ) THEN
319 CALL DLASET( 'f
', MAXMN, NRHS, ZERO, ZERO, B, LDB )
327 BNRM = DLANGE( 'm
', BROW, NRHS, B, LDB, WORK )
329.GT..AND..LT.
IF( BNRMZERO BNRMSMLNUM ) THEN
333 CALL DLASCL( 'g
', 0, 0, BNRM, SMLNUM, BROW, NRHS, B, LDB,
336.GT.
ELSE IF( BNRMBIGNUM ) 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.NOT.
IF ( 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.EQ.
IF( IASCL1 ) THEN
470 CALL DLASCL( 'g
', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,
472.EQ.
ELSE IF( IASCL2 ) THEN
473 CALL DLASCL( 'g
', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,
476.EQ.
IF( IBSCL1 ) THEN
477 CALL DLASCL( 'g
', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,
479.EQ.
ELSE IF( IBSCL2 ) THEN
480 CALL DLASCL( 'g
', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,
485 WORK( 1 ) = DBLE( TSZO + LWO )