1 *> \brief <b> SGELS solves overdetermined or underdetermined systems for GE matrices</b>
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download SGELS + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sgels.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sgels.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sgels.f">
21 * SUBROUTINE SGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
24 * .. Scalar Arguments ..
26 * INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
28 * .. Array Arguments ..
29 * REAL A( LDA, * ), B( LDB, * ), WORK( * )
38 *> SGELS solves overdetermined or underdetermined real linear systems
39 *> involving an M-by-N matrix A, or its transpose, using a QR or LQ
40 *> factorization of A. It is assumed that A has full rank.
42 *> The following options are provided:
44 *> 1. If TRANS = 'N' and m >= n: find the least squares solution of
45 *> an overdetermined system, i.e., solve the least squares problem
46 *> minimize || B - A*X ||.
48 *> 2. If TRANS = 'N' and m < n: find the minimum norm solution of
49 *> an underdetermined system A * X = B.
51 *> 3. If TRANS = 'T' and m >= n: find the minimum norm solution of
52 *> an undetermined system A**T * X = B.
54 *> 4. If TRANS = 'T' and m < n: find the least squares solution of
55 *> an overdetermined system, i.e., solve the least squares problem
56 *> minimize || B - A**T * X ||.
58 *> Several right hand side vectors b and solution vectors x can be
59 *> handled in a single call; they are stored as the columns of the
60 *> M-by-NRHS right hand side matrix B and the N-by-NRHS solution
69 *> TRANS is CHARACTER*1
70 *> = 'N': the linear system involves A;
71 *> = 'T': the linear system involves A**T.
77 *> The number of rows of the matrix A. M >= 0.
83 *> The number of columns of the matrix A. N >= 0.
89 *> The number of right hand sides, i.e., the number of
90 *> columns of the matrices B and X. NRHS >=0.
95 *> A is REAL array, dimension (LDA,N)
96 *> On entry, the M-by-N matrix A.
98 *> if M >= N, A is overwritten by details of its QR
99 *> factorization as returned by SGEQRF;
100 *> if M < N, A is overwritten by details of its LQ
101 *> factorization as returned by SGELQF.
107 *> The leading dimension of the array A. LDA >= max(1,M).
112 *> B is REAL array, dimension (LDB,NRHS)
113 *> On entry, the matrix B of right hand side vectors, stored
114 *> columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS
116 *> On exit, if INFO = 0, B is overwritten by the solution
117 *> vectors, stored columnwise:
118 *> if TRANS = 'N' and m >= n, rows 1 to n of B contain the least
119 *> squares solution vectors; the residual sum of squares for the
120 *> solution in each column is given by the sum of squares of
121 *> elements N+1 to M in that column;
122 *> if TRANS = 'N' and m < n, rows 1 to N of B contain the
123 *> minimum norm solution vectors;
124 *> if TRANS = 'T' and m >= n, rows 1 to M of B contain the
125 *> minimum norm solution vectors;
126 *> if TRANS = 'T' and m < n, rows 1 to M of B contain the
127 *> least squares solution vectors; the residual sum of squares
128 *> for the solution in each column is given by the sum of
129 *> squares of elements M+1 to N in that column.
135 *> The leading dimension of the array B. LDB >= MAX(1,M,N).
140 *> WORK is REAL array, dimension (MAX(1,LWORK))
141 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
147 *> The dimension of the array WORK.
148 *> LWORK >= max( 1, MN + max( MN, NRHS ) ).
149 *> For optimal performance,
150 *> LWORK >= max( 1, MN + max( MN, NRHS )*NB ).
151 *> where MN = min(M,N) and NB is the optimum block size.
153 *> If LWORK = -1, then a workspace query is assumed; the routine
154 *> only calculates the optimal size of the WORK array, returns
155 *> this value as the first entry of the WORK array, and no error
156 *> message related to LWORK is issued by XERBLA.
162 *> = 0: successful exit
163 *> < 0: if INFO = -i, the i-th argument had an illegal value
164 *> > 0: if INFO = i, the i-th diagonal element of the
165 *> triangular factor of A is zero, so that A does not have
166 *> full rank; the least squares solution could not be
173 *> \author Univ. of Tennessee
174 *> \author Univ. of California Berkeley
175 *> \author Univ. of Colorado Denver
178 *> \date November 2011
180 *> \ingroup realGEsolve
182 * =====================================================================
183 SUBROUTINE SGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
186 * -- LAPACK driver routine (version 3.4.0) --
187 * -- LAPACK is a software package provided by Univ. of Tennessee, --
188 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
191 * .. Scalar Arguments ..
193 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
195 * .. Array Arguments ..
196 REAL A( LDA, * ), B( LDB, * ), WORK( * )
199 * =====================================================================
203 PARAMETER ( ZERO = 0.0E0, ONE = 1.0E0 )
205 * .. Local Scalars ..
207 INTEGER BROW, I, IASCL, IBSCL, J, MN, NB, SCLLEN, WSIZE
208 REAL ANRM, BIGNUM, BNRM, SMLNUM
213 * .. External Functions ..
217 EXTERNAL LSAME, ILAENV, SLAMCH, SLANGE
219 * .. External Subroutines ..
220 EXTERNAL SGELQF, SGEQRF, SLABAD, SLASCL, SLASET, SORMLQ,
221 $ SORMQR, STRTRS, XERBLA
223 * .. Intrinsic Functions ..
224 INTRINSIC MAX, MIN, REAL
226 * .. Executable Statements ..
228 * Test the input arguments.
232 LQUERY = ( LWORK.EQ.-1 )
233 IF( .NOT.( LSAME( TRANS, 'N' ) .OR. LSAME( TRANS, 'T' ) ) ) THEN
235 ELSE IF( M.LT.0 ) THEN
237 ELSE IF( N.LT.0 ) THEN
239 ELSE IF( NRHS.LT.0 ) THEN
241 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
243 ELSE IF( LDB.LT.MAX( 1, M, N ) ) THEN
245 ELSE IF( LWORK.LT.MAX( 1, MN + MAX( MN, NRHS ) ) .AND.
250 * Figure out optimal block size
252 IF( INFO.EQ.0 .OR. INFO.EQ.-10 ) THEN
255 IF( LSAME( TRANS, 'N' ) )
259 NB = ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
261 NB = MAX( NB, ILAENV( 1, 'SORMQR', 'LN', M, NRHS, N,
264 NB = MAX( NB, ILAENV( 1, 'SORMQR', 'LT', M, NRHS, N,
268 NB = ILAENV( 1, 'SGELQF', ' ', M, N, -1, -1 )
270 NB = MAX( NB, ILAENV( 1, 'SORMLQ', 'LT', N, NRHS, M,
273 NB = MAX( NB, ILAENV( 1, 'SORMLQ', 'LN', N, NRHS, M,
278 WSIZE = MAX( 1, MN + MAX( MN, NRHS )*NB )
279 WORK( 1 ) = REAL( WSIZE )
284 CALL XERBLA( 'SGELS ', -INFO )
286 ELSE IF( LQUERY ) THEN
290 * Quick return if possible
292 IF( MIN( M, N, NRHS ).EQ.0 ) THEN
293 CALL SLASET( 'Full', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
297 * Get machine parameters
299 SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
300 BIGNUM = ONE / SMLNUM
301 CALL SLABAD( SMLNUM, BIGNUM )
303 * Scale A, B if max element outside range [SMLNUM,BIGNUM]
305 ANRM = SLANGE( 'M', M, N, A, LDA, RWORK )
307 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
309 * Scale matrix norm up to SMLNUM
311 CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
313 ELSE IF( ANRM.GT.BIGNUM ) THEN
315 * Scale matrix norm down to BIGNUM
317 CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
319 ELSE IF( ANRM.EQ.ZERO ) THEN
321 * Matrix all zero. Return zero solution.
323 CALL SLASET( 'F', MAX( M, N ), NRHS, ZERO, ZERO, B, LDB )
330 BNRM = SLANGE( 'M', BROW, NRHS, B, LDB, RWORK )
332 IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
334 * Scale matrix norm up to SMLNUM
336 CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, BROW, NRHS, B, LDB,
339 ELSE IF( BNRM.GT.BIGNUM ) THEN
341 * Scale matrix norm down to BIGNUM
343 CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, BROW, NRHS, B, LDB,
350 * compute QR factorization of A
352 CALL SGEQRF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,
355 * workspace at least N, optimally N*NB
359 * Least-Squares Problem min || A * X - B ||
361 * B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)
363 CALL SORMQR( 'Left', 'Transpose', M, NRHS, N, A, LDA,
364 $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
367 * workspace at least NRHS, optimally NRHS*NB
369 * B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
371 CALL STRTRS( 'Upper', 'No transpose', 'Non-unit', N, NRHS,
372 $ A, LDA, B, LDB, INFO )
382 * Overdetermined system of equations A**T * X = B
384 * B(1:N,1:NRHS) := inv(R**T) * B(1:N,1:NRHS)
386 CALL STRTRS( 'Upper', 'Transpose', 'Non-unit', N, NRHS,
387 $ A, LDA, B, LDB, INFO )
393 * B(N+1:M,1:NRHS) = ZERO
401 * B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)
403 CALL SORMQR( 'Left', 'No transpose', M, NRHS, N, A, LDA,
404 $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
407 * workspace at least NRHS, optimally NRHS*NB
415 * Compute LQ factorization of A
417 CALL SGELQF( M, N, A, LDA, WORK( 1 ), WORK( MN+1 ), LWORK-MN,
420 * workspace at least M, optimally M*NB.
424 * underdetermined system of equations A * X = B
426 * B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
428 CALL STRTRS( 'Lower', 'No transpose', 'Non-unit', M, NRHS,
429 $ A, LDA, B, LDB, INFO )
435 * B(M+1:N,1:NRHS) = 0
443 * B(1:N,1:NRHS) := Q(1:N,:)**T * B(1:M,1:NRHS)
445 CALL SORMLQ( 'Left', 'Transpose', N, NRHS, M, A, LDA,
446 $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
449 * workspace at least NRHS, optimally NRHS*NB
455 * overdetermined system min || A**T * X - B ||
457 * B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)
459 CALL SORMLQ( 'Left', 'No transpose', N, NRHS, M, A, LDA,
460 $ WORK( 1 ), B, LDB, WORK( MN+1 ), LWORK-MN,
463 * workspace at least NRHS, optimally NRHS*NB
465 * B(1:M,1:NRHS) := inv(L**T) * B(1:M,1:NRHS)
467 CALL STRTRS( 'Lower', 'Transpose', 'Non-unit', M, NRHS,
468 $ A, LDA, B, LDB, INFO )
482 IF( IASCL.EQ.1 ) THEN
483 CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, SCLLEN, NRHS, B, LDB,
485 ELSE IF( IASCL.EQ.2 ) THEN
486 CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, SCLLEN, NRHS, B, LDB,
489 IF( IBSCL.EQ.1 ) THEN
490 CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, SCLLEN, NRHS, B, LDB,
492 ELSE IF( IBSCL.EQ.2 ) THEN
493 CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, SCLLEN, NRHS, B, LDB,
498 WORK( 1 ) = REAL( WSIZE )