LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ sgels()

subroutine sgels ( character trans,
integer m,
integer n,
integer nrhs,
real, dimension( lda, * ) a,
integer lda,
real, dimension( ldb, * ) b,
integer ldb,
real, dimension( * ) work,
integer lwork,
integer info )

SGELS solves overdetermined or underdetermined systems for GE matrices

Download SGELS + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> SGELS solves overdetermined or underdetermined real linear systems
!> involving an M-by-N matrix A, or its transpose, using a QR or LQ
!> factorization of A.
!>
!> It is assumed that A has full rank, and only a rudimentary protection
!> against rank-deficient matrices is provided. This subroutine only detects
!> exact rank-deficiency, where a diagonal element of the triangular factor
!> of A is exactly zero.
!>
!> It is conceivable for one (or more) of the diagonal elements of the triangular
!> factor of A to be subnormally tiny numbers without this subroutine signalling
!> an error. The solutions computed for such almost-rank-deficient matrices may
!> be less accurate due to a loss of numerical precision.
!>
!> The following options are provided:
!>
!> 1. If TRANS = 'N' and m >= n:  find the least squares solution of
!>    an overdetermined system, i.e., solve the least squares problem
!>                 minimize || B - A*X ||.
!>
!> 2. If TRANS = 'N' and m < n:  find the minimum norm solution of
!>    an underdetermined system A * X = B.
!>
!> 3. If TRANS = 'T' and m >= n:  find the minimum norm solution of
!>    an underdetermined system A**T * X = B.
!>
!> 4. If TRANS = 'T' and m < n:  find the least squares solution of
!>    an overdetermined system, i.e., solve the least squares problem
!>                 minimize || B - A**T * X ||.
!>
!> Several right hand side vectors b and solution vectors x can be
!> handled in a single call; they are stored as the columns of the
!> M-by-NRHS right hand side matrix B and the N-by-NRHS solution
!> matrix X.
!> 
Parameters
[in]TRANS
!>          TRANS is CHARACTER*1
!>          = 'N': the linear system involves A;
!>          = 'T': the linear system involves A**T.
!> 
[in]M
!>          M is INTEGER
!>          The number of rows of the matrix A.  M >= 0.
!> 
[in]N
!>          N is INTEGER
!>          The number of columns of the matrix A.  N >= 0.
!> 
[in]NRHS
!>          NRHS is INTEGER
!>          The number of right hand sides, i.e., the number of
!>          columns of the matrices B and X. NRHS >=0.
!> 
[in,out]A
!>          A is REAL array, dimension (LDA,N)
!>          On entry, the M-by-N matrix A.
!>          On exit,
!>            if M >= N, A is overwritten by details of its QR
!>                       factorization as returned by SGEQRF;
!>            if M <  N, A is overwritten by details of its LQ
!>                       factorization as returned by SGELQF.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
[in,out]B
!>          B is REAL array, dimension (LDB,NRHS)
!>          On entry, the matrix B of right hand side vectors, stored
!>          columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS
!>          if TRANS = 'T'.
!>          On exit, if INFO = 0, B is overwritten by the solution
!>          vectors, stored columnwise:
!>          if TRANS = 'N' and m >= n, rows 1 to n of B contain the least
!>          squares solution vectors; the residual sum of squares for the
!>          solution in each column is given by the sum of squares of
!>          elements N+1 to M in that column;
!>          if TRANS = 'N' and m < n, rows 1 to N of B contain the
!>          minimum norm solution vectors;
!>          if TRANS = 'T' and m >= n, rows 1 to M of B contain the
!>          minimum norm solution vectors;
!>          if TRANS = 'T' and m < n, rows 1 to M of B contain the
!>          least squares solution vectors; the residual sum of squares
!>          for the solution in each column is given by the sum of
!>          squares of elements M+1 to N in that column.
!> 
[in]LDB
!>          LDB is INTEGER
!>          The leading dimension of the array B. LDB >= MAX(1,M,N).
!> 
[out]WORK
!>          WORK is REAL array, dimension (MAX(1,LWORK))
!>          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
!> 
[in]LWORK
!>          LWORK is INTEGER
!>          The dimension of the array WORK.
!>          LWORK >= max( 1, MN + max( MN, NRHS ) ).
!>          For optimal performance,
!>          LWORK >= max( 1, MN + max( MN, NRHS )*NB ).
!>          where MN = min(M,N) and NB is the optimum block size.
!>
!>          If LWORK = -1, then a workspace query is assumed; the routine
!>          only calculates the optimal size of the WORK array, returns
!>          this value as the first entry of the WORK array, and no error
!>          message related to LWORK is issued by XERBLA.
!> 
[out]INFO
!>          INFO is INTEGER
!>          = 0:  successful exit
!>          < 0:  if INFO = -i, the i-th argument had an illegal value
!>          > 0:  if INFO =  i, the i-th diagonal element of the
!>                triangular factor of A is exactly zero, so that A does not have
!>                full rank; the least squares solution could not be
!>                computed.
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.

Definition at line 189 of file sgels.f.

192*
193* -- LAPACK driver routine --
194* -- LAPACK is a software package provided by Univ. of Tennessee, --
195* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
196*
197* .. Scalar Arguments ..
198 CHARACTER TRANS
199 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
200* ..
201* .. Array Arguments ..
202 REAL A( LDA, * ), B( LDB, * ), WORK( * )
203* ..
204*
205* =====================================================================
206*
207* .. Parameters ..
208 REAL ZERO, ONE
209 parameter( zero = 0.0e0, one = 1.0e0 )
210* ..
211* .. Local Scalars ..
212 LOGICAL LQUERY, TPSD
213 INTEGER BROW, I, IASCL, IBSCL, J, MN, NB, SCLLEN, WSIZE
214 REAL ANRM, BIGNUM, BNRM, SMLNUM
215* ..
216* .. Local Arrays ..
217 REAL RWORK( 1 )
218* ..
219* .. External Functions ..
220 LOGICAL LSAME
221 INTEGER ILAENV
222 REAL SLAMCH, SLANGE, SROUNDUP_LWORK
223 EXTERNAL lsame, ilaenv, slamch, slange,
225* ..
226* .. External Subroutines ..
227 EXTERNAL sgelqf, sgeqrf, slascl, slaset,
228 $ sormlq,
230* ..
231* .. Intrinsic Functions ..
232 INTRINSIC max, min
233* ..
234* .. Executable Statements ..
235*
236* Test the input arguments.
237*
238 info = 0
239 mn = min( m, n )
240 lquery = ( lwork.EQ.-1 )
241 IF( .NOT.( lsame( trans, 'N' ) .OR.
242 $ lsame( trans, 'T' ) ) ) THEN
243 info = -1
244 ELSE IF( m.LT.0 ) THEN
245 info = -2
246 ELSE IF( n.LT.0 ) THEN
247 info = -3
248 ELSE IF( nrhs.LT.0 ) THEN
249 info = -4
250 ELSE IF( lda.LT.max( 1, m ) ) THEN
251 info = -6
252 ELSE IF( ldb.LT.max( 1, m, n ) ) THEN
253 info = -8
254 ELSE IF( lwork.LT.max( 1, mn + max( mn, nrhs ) ) .AND.
255 $ .NOT.lquery ) THEN
256 info = -10
257 END IF
258*
259* Figure out optimal block size
260*
261 IF( info.EQ.0 .OR. info.EQ.-10 ) THEN
262*
263 tpsd = .true.
264 IF( lsame( trans, 'N' ) )
265 $ tpsd = .false.
266*
267 IF( m.GE.n ) THEN
268 nb = ilaenv( 1, 'SGEQRF', ' ', m, n, -1, -1 )
269 IF( tpsd ) THEN
270 nb = max( nb, ilaenv( 1, 'SORMQR', 'LN', m, nrhs, n,
271 $ -1 ) )
272 ELSE
273 nb = max( nb, ilaenv( 1, 'SORMQR', 'LT', m, nrhs, n,
274 $ -1 ) )
275 END IF
276 ELSE
277 nb = ilaenv( 1, 'SGELQF', ' ', m, n, -1, -1 )
278 IF( tpsd ) THEN
279 nb = max( nb, ilaenv( 1, 'SORMLQ', 'LT', n, nrhs, m,
280 $ -1 ) )
281 ELSE
282 nb = max( nb, ilaenv( 1, 'SORMLQ', 'LN', n, nrhs, m,
283 $ -1 ) )
284 END IF
285 END IF
286*
287 wsize = max( 1, mn + max( mn, nrhs )*nb )
288 work( 1 ) = sroundup_lwork( wsize )
289*
290 END IF
291*
292 IF( info.NE.0 ) THEN
293 CALL xerbla( 'SGELS ', -info )
294 RETURN
295 ELSE IF( lquery ) THEN
296 RETURN
297 END IF
298*
299* Quick return if possible
300*
301 IF( min( m, n, nrhs ).EQ.0 ) THEN
302 CALL slaset( 'Full', max( m, n ), nrhs, zero, zero, b, ldb )
303 RETURN
304 END IF
305*
306* Get machine parameters
307*
308 smlnum = slamch( 'S' ) / slamch( 'P' )
309 bignum = one / smlnum
310*
311* Scale A, B if max element outside range [SMLNUM,BIGNUM]
312*
313 anrm = slange( 'M', m, n, a, lda, rwork )
314 iascl = 0
315 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
316*
317* Scale matrix norm up to SMLNUM
318*
319 CALL slascl( 'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
320 iascl = 1
321 ELSE IF( anrm.GT.bignum ) THEN
322*
323* Scale matrix norm down to BIGNUM
324*
325 CALL slascl( 'G', 0, 0, anrm, bignum, m, n, a, lda, info )
326 iascl = 2
327 ELSE IF( anrm.EQ.zero ) THEN
328*
329* Matrix all zero. Return zero solution.
330*
331 CALL slaset( 'F', max( m, n ), nrhs, zero, zero, b, ldb )
332 GO TO 50
333 END IF
334*
335 brow = m
336 IF( tpsd )
337 $ brow = n
338 bnrm = slange( 'M', brow, nrhs, b, ldb, rwork )
339 ibscl = 0
340 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
341*
342* Scale matrix norm up to SMLNUM
343*
344 CALL slascl( 'G', 0, 0, bnrm, smlnum, brow, nrhs, b, ldb,
345 $ info )
346 ibscl = 1
347 ELSE IF( bnrm.GT.bignum ) THEN
348*
349* Scale matrix norm down to BIGNUM
350*
351 CALL slascl( 'G', 0, 0, bnrm, bignum, brow, nrhs, b, ldb,
352 $ info )
353 ibscl = 2
354 END IF
355*
356 IF( m.GE.n ) THEN
357*
358* compute QR factorization of A
359*
360 CALL sgeqrf( m, n, a, lda, work( 1 ), work( mn+1 ),
361 $ lwork-mn,
362 $ info )
363*
364* workspace at least N, optimally N*NB
365*
366 IF( .NOT.tpsd ) THEN
367*
368* Least-Squares Problem min || A * X - B ||
369*
370* B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)
371*
372 CALL sormqr( 'Left', 'Transpose', m, nrhs, n, a, lda,
373 $ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
374 $ info )
375*
376* workspace at least NRHS, optimally NRHS*NB
377*
378* B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
379*
380 CALL strtrs( 'Upper', 'No transpose', 'Non-unit', n,
381 $ nrhs,
382 $ a, lda, b, ldb, info )
383*
384 IF( info.GT.0 ) THEN
385 RETURN
386 END IF
387*
388 scllen = n
389*
390 ELSE
391*
392* Underdetermined system of equations A**T * X = B
393*
394* B(1:N,1:NRHS) := inv(R**T) * B(1:N,1:NRHS)
395*
396 CALL strtrs( 'Upper', 'Transpose', 'Non-unit', n, nrhs,
397 $ a, lda, b, ldb, info )
398*
399 IF( info.GT.0 ) THEN
400 RETURN
401 END IF
402*
403* B(N+1:M,1:NRHS) = ZERO
404*
405 DO 20 j = 1, nrhs
406 DO 10 i = n + 1, m
407 b( i, j ) = zero
408 10 CONTINUE
409 20 CONTINUE
410*
411* B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)
412*
413 CALL sormqr( 'Left', 'No transpose', m, nrhs, n, a, lda,
414 $ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
415 $ info )
416*
417* workspace at least NRHS, optimally NRHS*NB
418*
419 scllen = m
420*
421 END IF
422*
423 ELSE
424*
425* Compute LQ factorization of A
426*
427 CALL sgelqf( m, n, a, lda, work( 1 ), work( mn+1 ),
428 $ lwork-mn,
429 $ info )
430*
431* workspace at least M, optimally M*NB.
432*
433 IF( .NOT.tpsd ) THEN
434*
435* underdetermined system of equations A * X = B
436*
437* B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
438*
439 CALL strtrs( 'Lower', 'No transpose', 'Non-unit', m,
440 $ nrhs,
441 $ a, lda, b, ldb, info )
442*
443 IF( info.GT.0 ) THEN
444 RETURN
445 END IF
446*
447* B(M+1:N,1:NRHS) = 0
448*
449 DO 40 j = 1, nrhs
450 DO 30 i = m + 1, n
451 b( i, j ) = zero
452 30 CONTINUE
453 40 CONTINUE
454*
455* B(1:N,1:NRHS) := Q(1:N,:)**T * B(1:M,1:NRHS)
456*
457 CALL sormlq( 'Left', 'Transpose', n, nrhs, m, a, lda,
458 $ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
459 $ info )
460*
461* workspace at least NRHS, optimally NRHS*NB
462*
463 scllen = n
464*
465 ELSE
466*
467* overdetermined system min || A**T * X - B ||
468*
469* B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)
470*
471 CALL sormlq( 'Left', 'No transpose', n, nrhs, m, a, lda,
472 $ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
473 $ info )
474*
475* workspace at least NRHS, optimally NRHS*NB
476*
477* B(1:M,1:NRHS) := inv(L**T) * B(1:M,1:NRHS)
478*
479 CALL strtrs( 'Lower', 'Transpose', 'Non-unit', m, nrhs,
480 $ a, lda, b, ldb, info )
481*
482 IF( info.GT.0 ) THEN
483 RETURN
484 END IF
485*
486 scllen = m
487*
488 END IF
489*
490 END IF
491*
492* Undo scaling
493*
494 IF( iascl.EQ.1 ) THEN
495 CALL slascl( 'G', 0, 0, anrm, smlnum, scllen, nrhs, b, ldb,
496 $ info )
497 ELSE IF( iascl.EQ.2 ) THEN
498 CALL slascl( 'G', 0, 0, anrm, bignum, scllen, nrhs, b, ldb,
499 $ info )
500 END IF
501 IF( ibscl.EQ.1 ) THEN
502 CALL slascl( 'G', 0, 0, smlnum, bnrm, scllen, nrhs, b, ldb,
503 $ info )
504 ELSE IF( ibscl.EQ.2 ) THEN
505 CALL slascl( 'G', 0, 0, bignum, bnrm, scllen, nrhs, b, ldb,
506 $ info )
507 END IF
508*
509 50 CONTINUE
510 work( 1 ) = sroundup_lwork( wsize )
511*
512 RETURN
513*
514* End of SGELS
515*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine sgelqf(m, n, a, lda, tau, work, lwork, info)
SGELQF
Definition sgelqf.f:142
subroutine sgeqrf(m, n, a, lda, tau, work, lwork, info)
SGEQRF
Definition sgeqrf.f:144
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
real function slamch(cmach)
SLAMCH
Definition slamch.f:68
real function slange(norm, m, n, a, lda, work)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
Definition slange.f:112
subroutine slascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition slascl.f:142
subroutine slaset(uplo, m, n, alpha, beta, a, lda)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition slaset.f:108
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
real function sroundup_lwork(lwork)
SROUNDUP_LWORK
subroutine strtrs(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info)
STRTRS
Definition strtrs.f:144
subroutine sormlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMLQ
Definition sormlq.f:166
subroutine sormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
SORMQR
Definition sormqr.f:166
Here is the call graph for this function:
Here is the caller graph for this function: