4 * SUBROUTINE SGETSLS( TRANS, M, N, NRHS, A, LDA, B, LDB
5 * $ , WORK, LWORK, INFO )
8 * .. Scalar Arguments ..
10 * INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
12 * .. Array Arguments ..
13 * REAL A( LDA, * ), B( LDB, * ), WORK( * )
22 *> SGETSLS solves overdetermined or underdetermined real linear systems
23 *> involving an M-by-N matrix A, using a tall skinny QR or short wide LQ
24 *> factorization of A. It is assumed that A has full rank.
28 *> The following options are provided:
30 *> 1. If TRANS = 'N' and m >= n: find the least squares solution of
31 *> an overdetermined system, i.e., solve the least squares problem
32 *> minimize || B - A*X ||.
34 *> 2. If TRANS = 'N' and m < n: find the minimum norm solution of
35 *> an underdetermined system A * X = B.
37 *> 3. If TRANS = 'T' and m >= n: find the minimum norm solution of
38 *> an undetermined system A**T * X = B.
40 *> 4. If TRANS = 'T' and m < n: find the least squares solution of
41 *> an overdetermined system, i.e., solve the least squares problem
42 *> minimize || B - A**T * X ||.
50 *> TRANS is CHARACTER*1
51 *> = 'N': the linear system involves A;
52 *> = 'T': the linear system involves A**T.
58 *> The number of rows of the matrix A. M >= 0.
64 *> The number of columns of the matrix A. N >= 0.
70 *> The number of right hand sides, i.e., the number of
71 *> columns of the matrices B and X. NRHS >=0.
76 *> A is REAL array, dimension (LDA,N)
77 *> On entry, the M-by-N matrix A.
79 *> A is overwritten by details of its QR or LQ
80 *> factorization as returned by DGETSQR.
86 *> The leading dimension of the array A. LDA >= max(1,M).
91 *> B is REAL array, dimension (LDB,NRHS)
92 *> On entry, the matrix B of right hand side vectors, stored
93 *> columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS
95 *> On exit, if INFO = 0, B is overwritten by the solution
96 *> vectors, stored columnwise:
97 *> if TRANS = 'N' and m >= n, rows 1 to n of B contain the least
98 *> squares solution vectors.
99 *> if TRANS = 'N' and m < n, rows 1 to N of B contain the
100 *> minimum norm solution vectors;
101 *> if TRANS = 'T' and m >= n, rows 1 to M of B contain the
102 *> minimum norm solution vectors;
103 *> if TRANS = 'T' and m < n, rows 1 to M of B contain the
104 *> least squares solution vectors.
110 *> The leading dimension of the array B. LDB >= MAX(1,M,N).
115 *> WORK is REAL array, dimension (MAX(1,LWORK))
116 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK,
117 *> and WORK(2) returns the minimum LWORK.
123 *> The dimension of the array WORK.
124 *> IF LWORK=-1, workspace query is assumed, and
125 *> WORK(1) returns the optimal LWORK,
126 *> and WORK(2) returns the minimum LWORK.
132 *> = 0: successful exit
133 *> < 0: if INFO = -i, the i-th argument had an illegal value
134 *> > 0: if INFO = i, the i-th diagonal element of the
135 *> triangular factor of A is zero, so that A does not have
136 *> full rank; the least squares solution could not be
143 *> \author Univ. of Tennessee
144 *> \author Univ. of California Berkeley
145 *> \author Univ. of Colorado Denver
148 *> \date November 2011
150 *> \ingroup doubleGEsolve
152 * =====================================================================
153 SUBROUTINE SGETSLS( TRANS, M, N, NRHS, A, LDA, B, LDB
154 $ , WORK, LWORK, INFO )
156 * -- LAPACK driver routine (version 3.4.0) --
157 * -- LAPACK is a software package provided by Univ. of Tennessee, --
158 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
161 * .. Scalar Arguments ..
163 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, MB
165 * .. Array Arguments ..
166 REAL A( LDA, * ), B( LDB, * ), WORK( * )
170 * =====================================================================
174 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
176 * .. Local Scalars ..
178 INTEGER I, IASCL, IBSCL, J, MINMN, MAXMN, BROW, LW,
179 $ SCLLEN, MNK, WSIZEO, WSIZEM, LW1, LW2, INFO2,
181 REAL ANRM, BIGNUM, BNRM, SMLNUM
183 * .. External Functions ..
187 EXTERNAL LSAME, ILAENV, SLABAD, SLAMCH, SLANGE
189 * .. External Subroutines ..
190 EXTERNAL SGEQR, SGEMQR, SLASCL, SLASET,
191 $ STRTRS, XERBLA, SGELQ, SGEMLQ
193 * .. Intrinsic Functions ..
194 INTRINSIC REAL, MAX, MIN
196 * .. Executable Statements ..
198 * Test the input arguments.
203 MNK = MAX(MINMN,NRHS)
204 TRAN = LSAME( TRANS, 'T' )
206 LQUERY = ( LWORK.EQ.-1 )
207 IF( .NOT.( LSAME( TRANS, 'N' ) .OR.
208 $ LSAME( TRANS, 'T' ) ) ) THEN
210 ELSE IF( M.LT.0 ) THEN
212 ELSE IF( N.LT.0 ) THEN
214 ELSE IF( NRHS.LT.0 ) THEN
216 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
218 ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
224 * Determine the block size and minimum LWORK
227 CALL SGEQR( M, N, A, LDA, WORK(1), -1, WORK(6), -1,
232 CALL SGEMQR( 'L', TRANS, M, NRHS, N, A, LDA, WORK(1),
233 $ INT(WORK(2)), B, LDB, WORK(6), -1 , INFO2 )
234 WSIZEO = INT(WORK(2))+MAX(LW,INT(WORK(6)))
235 WSIZEM = INT(WORK(3))+MAX(LW,INT(WORK(6)))
237 CALL SGELQ( M, N, A, LDA, WORK(1), -1, WORK(6), -1,
242 CALL SGEMLQ( 'L', TRANS, N, NRHS, M, A, LDA, WORK(1),
243 $ INT(WORK(2)), B, LDB, WORK(6), -1 , INFO2 )
244 WSIZEO = INT(WORK(2))+MAX(LW,INT(WORK(6)))
245 WSIZEM = INT(WORK(3))+MAX(LW,INT(WORK(6)))
248 IF((LWORK.LT.WSIZEO).AND.(.NOT.LQUERY)) THEN
254 CALL XERBLA( 'SGETSLS', -INFO )
255 WORK( 1 ) = REAL( WSIZEO )
256 WORK( 2 ) = REAL( WSIZEM )
258 ELSE IF (LQUERY) THEN
259 WORK( 1 ) = REAL( WSIZEO )
260 WORK( 2 ) = REAL( WSIZEM )
263 IF(LWORK.LT.WSIZEO) THEN
265 LW2=MAX(LW,INT(WORK(6)))
268 LW2=MAX(LW,INT(WORK(6)))
271 * Quick return if possible
273 IF( MIN( M, N, NRHS ).EQ.0 ) THEN
274 CALL SLASET( 'FULL', MAX( M, N ), NRHS, ZERO, ZERO,
279 * Get machine parameters
281 SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
282 BIGNUM = ONE / SMLNUM
283 CALL SLABAD( SMLNUM, BIGNUM )
285 * Scale A, B if max element outside range [SMLNUM,BIGNUM]
287 ANRM = SLANGE( 'M', M, N, A, LDA, WORK )
289 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
291 * Scale matrix norm up to SMLNUM
293 CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
295 ELSE IF( ANRM.GT.BIGNUM ) THEN
297 * Scale matrix norm down to BIGNUM
299 CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
301 ELSE IF( ANRM.EQ.ZERO ) THEN
303 * Matrix all zero. Return zero solution.
305 CALL SLASET( 'F', MAXMN, NRHS, ZERO, ZERO, B, LDB )
313 BNRM = SLANGE( 'M', BROW, NRHS, B, LDB, WORK )
315 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
317 * Scale matrix norm up to SMLNUM
319 CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, BROW, NRHS, B, LDB,
322 ELSE IF( BNRM.GT.BIGNUM ) THEN
324 * Scale matrix norm down to BIGNUM
326 CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, BROW, NRHS, B, LDB,
333 * compute QR factorization of A
335 CALL SGEQR( M, N, A, LDA, WORK(LW2+1), LW1
336 $ , WORK(1), LW2, INFO )
339 * Least-Squares Problem min || A * X - B ||
341 * B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)
343 CALL SGEMQR( 'L' , 'T', M, NRHS, N, A, LDA,
344 $ WORK(LW2+1), LW1, B, LDB, WORK(1), LW2, INFO )
346 * B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
348 CALL STRTRS( 'U', 'N', 'N', N, NRHS,
349 $ A, LDA, B, LDB, INFO )
356 * Overdetermined system of equations A**T * X = B
358 * B(1:N,1:NRHS) := inv(R**T) * B(1:N,1:NRHS)
360 CALL STRTRS( 'U', 'T', 'N', N, NRHS,
361 $ A, LDA, B, LDB, INFO )
367 * B(N+1:M,1:NRHS) = ZERO
375 * B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)
377 CALL SGEMQR( 'L', 'N', M, NRHS, N, A, LDA,
378 $ WORK( LW2+1), LW1, B, LDB, WORK( 1 ), LW2,
387 * Compute LQ factorization of A
389 CALL SGELQ( M, N, A, LDA, WORK(LW2+1), LW1
390 $ , WORK(1), LW2, INFO )
392 * workspace at least M, optimally M*NB.
396 * underdetermined system of equations A * X = B
398 * B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
400 CALL STRTRS( 'L', 'N', 'N', M, NRHS,
401 $ A, LDA, B, LDB, INFO )
407 * B(M+1:N,1:NRHS) = 0
415 * B(1:N,1:NRHS) := Q(1:N,:)**T * B(1:M,1:NRHS)
417 CALL SGEMLQ( 'L', 'T', N, NRHS, M, A, LDA,
418 $ WORK( LW2+1), LW1, B, LDB, WORK( 1 ), LW2,
421 * workspace at least NRHS, optimally NRHS*NB
427 * overdetermined system min || A**T * X - B ||
429 * B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)
431 CALL SGEMLQ( 'L', 'N', N, NRHS, M, A, LDA,
432 $ WORK( LW2+1), LW1, B, LDB, WORK( 1 ), LW2,
435 * workspace at least NRHS, optimally NRHS*NB
437 * B(1:M,1:NRHS) := inv(L**T) * B(1:M,1:NRHS)
439 CALL STRTRS( 'Lower', 'Transpose', 'Non-unit', M, NRHS,
440 $ A, LDA, B, LDB, INFO )
454 IF( IASCL.EQ.1 ) THEN
455 CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,
457 ELSE IF( IASCL.EQ.2 ) THEN
458 CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,
461 IF( IBSCL.EQ.1 ) THEN
462 CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,
464 ELSE IF( IBSCL.EQ.2 ) THEN
465 CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,
470 WORK( 1 ) = REAL( WSIZEO )
471 WORK( 2 ) = REAL( WSIZEM )