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

◆ dgelst()

subroutine dgelst ( character trans,
integer m,
integer n,
integer nrhs,
double precision, dimension( lda, * ) a,
integer lda,
double precision, dimension( ldb, * ) b,
integer ldb,
double precision, dimension( * ) work,
integer lwork,
integer info )

DGELST solves overdetermined or underdetermined systems for GE matrices using QR or LQ factorization with compact WY representation of Q.

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

Purpose:
!>
!> DGELST 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 with compact WY representation of Q.
!>
!> 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 DOUBLE PRECISION 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 DGEQRT;
!>            if M <  N, A is overwritten by details of its LQ
!>                       factorization as returned by DGELQT.
!> 
[in]LDA
!>          LDA is INTEGER
!>          The leading dimension of the array A.  LDA >= max(1,M).
!> 
[in,out]B
!>          B is DOUBLE PRECISION 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 DOUBLE PRECISION 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.
Contributors:
!>
!>  November 2022,  Igor Kozachenko,
!>                  Computer Science Division,
!>                  University of California, Berkeley
!> 

Definition at line 199 of file dgelst.f.

202*
203* -- LAPACK driver routine --
204* -- LAPACK is a software package provided by Univ. of Tennessee, --
205* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
206*
207* .. Scalar Arguments ..
208 CHARACTER TRANS
209 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
210* ..
211* .. Array Arguments ..
212 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), WORK( * )
213* ..
214*
215* =====================================================================
216*
217* .. Parameters ..
218 DOUBLE PRECISION ZERO, ONE
219 parameter( zero = 0.0d+0, one = 1.0d+0 )
220* ..
221* .. Local Scalars ..
222 LOGICAL LQUERY, TPSD
223 INTEGER BROW, I, IASCL, IBSCL, J, LWOPT, MN, MNNRHS,
224 $ NB, NBMIN, SCLLEN
225 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM
226* ..
227* .. Local Arrays ..
228 DOUBLE PRECISION RWORK( 1 )
229* ..
230* .. External Functions ..
231 LOGICAL LSAME
232 INTEGER ILAENV
233 DOUBLE PRECISION DLAMCH, DLANGE
234 EXTERNAL lsame, ilaenv, dlamch, dlange
235* ..
236* .. External Subroutines ..
237 EXTERNAL dgelqt, dgeqrt, dgemlqt, dgemqrt,
238 $ dlascl,
240* ..
241* .. Intrinsic Functions ..
242 INTRINSIC dble, max, min
243* ..
244* .. Executable Statements ..
245*
246* Test the input arguments.
247*
248 info = 0
249 mn = min( m, n )
250 lquery = ( lwork.EQ.-1 )
251 IF( .NOT.( lsame( trans, 'N' ) .OR.
252 $ lsame( trans, 'T' ) ) ) THEN
253 info = -1
254 ELSE IF( m.LT.0 ) THEN
255 info = -2
256 ELSE IF( n.LT.0 ) THEN
257 info = -3
258 ELSE IF( nrhs.LT.0 ) THEN
259 info = -4
260 ELSE IF( lda.LT.max( 1, m ) ) THEN
261 info = -6
262 ELSE IF( ldb.LT.max( 1, m, n ) ) THEN
263 info = -8
264 ELSE IF( lwork.LT.max( 1, mn+max( mn, nrhs ) ) .AND. .NOT.lquery )
265 $ THEN
266 info = -10
267 END IF
268*
269* Figure out optimal block size and optimal workspace size
270*
271 IF( info.EQ.0 .OR. info.EQ.-10 ) THEN
272*
273 tpsd = .true.
274 IF( lsame( trans, 'N' ) )
275 $ tpsd = .false.
276*
277 nb = ilaenv( 1, 'DGELST', ' ', m, n, -1, -1 )
278*
279 mnnrhs = max( mn, nrhs )
280 lwopt = max( 1, (mn+mnnrhs)*nb )
281 work( 1 ) = dble( lwopt )
282*
283 END IF
284*
285 IF( info.NE.0 ) THEN
286 CALL xerbla( 'DGELST ', -info )
287 RETURN
288 ELSE IF( lquery ) THEN
289 RETURN
290 END IF
291*
292* Quick return if possible
293*
294 IF( min( m, n, nrhs ).EQ.0 ) THEN
295 CALL dlaset( 'Full', max( m, n ), nrhs, zero, zero, b, ldb )
296 work( 1 ) = dble( lwopt )
297 RETURN
298 END IF
299*
300* *GEQRT and *GELQT routines cannot accept NB larger than min(M,N)
301*
302 IF( nb.GT.mn ) nb = mn
303*
304* Determine the block size from the supplied LWORK
305* ( at this stage we know that LWORK >= (minimum required workspace,
306* but it may be less than optimal)
307*
308 nb = min( nb, lwork/( mn + mnnrhs ) )
309*
310* The minimum value of NB, when blocked code is used
311*
312 nbmin = max( 2, ilaenv( 2, 'DGELST', ' ', m, n, -1, -1 ) )
313*
314 IF( nb.LT.nbmin ) THEN
315 nb = 1
316 END IF
317*
318* Get machine parameters
319*
320 smlnum = dlamch( 'S' ) / dlamch( 'P' )
321 bignum = one / smlnum
322*
323* Scale A, B if max element outside range [SMLNUM,BIGNUM]
324*
325 anrm = dlange( 'M', m, n, a, lda, rwork )
326 iascl = 0
327 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
328*
329* Scale matrix norm up to SMLNUM
330*
331 CALL dlascl( 'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
332 iascl = 1
333 ELSE IF( anrm.GT.bignum ) THEN
334*
335* Scale matrix norm down to BIGNUM
336*
337 CALL dlascl( 'G', 0, 0, anrm, bignum, m, n, a, lda, info )
338 iascl = 2
339 ELSE IF( anrm.EQ.zero ) THEN
340*
341* Matrix all zero. Return zero solution.
342*
343 CALL dlaset( 'Full', max( m, n ), nrhs, zero, zero, b, ldb )
344 work( 1 ) = dble( lwopt )
345 RETURN
346 END IF
347*
348 brow = m
349 IF( tpsd )
350 $ brow = n
351 bnrm = dlange( 'M', brow, nrhs, b, ldb, rwork )
352 ibscl = 0
353 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
354*
355* Scale matrix norm up to SMLNUM
356*
357 CALL dlascl( 'G', 0, 0, bnrm, smlnum, brow, nrhs, b, ldb,
358 $ info )
359 ibscl = 1
360 ELSE IF( bnrm.GT.bignum ) THEN
361*
362* Scale matrix norm down to BIGNUM
363*
364 CALL dlascl( 'G', 0, 0, bnrm, bignum, brow, nrhs, b, ldb,
365 $ info )
366 ibscl = 2
367 END IF
368*
369 IF( m.GE.n ) THEN
370*
371* M > N:
372* Compute the blocked QR factorization of A,
373* using the compact WY representation of Q,
374* workspace at least N, optimally N*NB.
375*
376 CALL dgeqrt( m, n, nb, a, lda, work( 1 ), nb,
377 $ work( mn*nb+1 ), info )
378*
379 IF( .NOT.tpsd ) THEN
380*
381* M > N, A is not transposed:
382* Overdetermined system of equations,
383* least-squares problem, min || A * X - B ||.
384*
385* Compute B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS),
386* using the compact WY representation of Q,
387* workspace at least NRHS, optimally NRHS*NB.
388*
389 CALL dgemqrt( 'Left', 'Transpose', m, nrhs, n, nb, a,
390 $ lda,
391 $ work( 1 ), nb, b, ldb, work( mn*nb+1 ),
392 $ info )
393*
394* Compute B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
395*
396 CALL dtrtrs( 'Upper', 'No transpose', 'Non-unit', n,
397 $ nrhs,
398 $ a, lda, b, ldb, info )
399*
400 IF( info.GT.0 ) THEN
401 RETURN
402 END IF
403*
404 scllen = n
405*
406 ELSE
407*
408* M > N, A is transposed:
409* Underdetermined system of equations,
410* minimum norm solution of A**T * X = B.
411*
412* Compute B := inv(R**T) * B in two row blocks of B.
413*
414* Block 1: B(1:N,1:NRHS) := inv(R**T) * B(1:N,1:NRHS)
415*
416 CALL dtrtrs( 'Upper', 'Transpose', 'Non-unit', n, nrhs,
417 $ a, lda, b, ldb, info )
418*
419 IF( info.GT.0 ) THEN
420 RETURN
421 END IF
422*
423* Block 2: Zero out all rows below the N-th row in B:
424* B(N+1:M,1:NRHS) = ZERO
425*
426 DO j = 1, nrhs
427 DO i = n + 1, m
428 b( i, j ) = zero
429 END DO
430 END DO
431*
432* Compute B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS),
433* using the compact WY representation of Q,
434* workspace at least NRHS, optimally NRHS*NB.
435*
436 CALL dgemqrt( 'Left', 'No transpose', m, nrhs, n, nb,
437 $ a, lda, work( 1 ), nb, b, ldb,
438 $ work( mn*nb+1 ), info )
439*
440 scllen = m
441*
442 END IF
443*
444 ELSE
445*
446* M < N:
447* Compute the blocked LQ factorization of A,
448* using the compact WY representation of Q,
449* workspace at least M, optimally M*NB.
450*
451 CALL dgelqt( m, n, nb, a, lda, work( 1 ), nb,
452 $ work( mn*nb+1 ), info )
453*
454 IF( .NOT.tpsd ) THEN
455*
456* M < N, A is not transposed:
457* Underdetermined system of equations,
458* minimum norm solution of A * X = B.
459*
460* Compute B := inv(L) * B in two row blocks of B.
461*
462* Block 1: B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
463*
464 CALL dtrtrs( 'Lower', 'No transpose', 'Non-unit', m,
465 $ nrhs,
466 $ a, lda, b, ldb, info )
467*
468 IF( info.GT.0 ) THEN
469 RETURN
470 END IF
471*
472* Block 2: Zero out all rows below the M-th row in B:
473* B(M+1:N,1:NRHS) = ZERO
474*
475 DO j = 1, nrhs
476 DO i = m + 1, n
477 b( i, j ) = zero
478 END DO
479 END DO
480*
481* Compute B(1:N,1:NRHS) := Q(1:N,:)**T * B(1:M,1:NRHS),
482* using the compact WY representation of Q,
483* workspace at least NRHS, optimally NRHS*NB.
484*
485 CALL dgemlqt( 'Left', 'Transpose', n, nrhs, m, nb, a,
486 $ lda,
487 $ work( 1 ), nb, b, ldb,
488 $ work( mn*nb+1 ), info )
489*
490 scllen = n
491*
492 ELSE
493*
494* M < N, A is transposed:
495* Overdetermined system of equations,
496* least-squares problem, min || A**T * X - B ||.
497*
498* Compute B(1:N,1:NRHS) := Q * B(1:N,1:NRHS),
499* using the compact WY representation of Q,
500* workspace at least NRHS, optimally NRHS*NB.
501*
502 CALL dgemlqt( 'Left', 'No transpose', n, nrhs, m, nb,
503 $ a, lda, work( 1 ), nb, b, ldb,
504 $ work( mn*nb+1), info )
505*
506* Compute B(1:M,1:NRHS) := inv(L**T) * B(1:M,1:NRHS)
507*
508 CALL dtrtrs( 'Lower', 'Transpose', 'Non-unit', m, nrhs,
509 $ a, lda, b, ldb, info )
510*
511 IF( info.GT.0 ) THEN
512 RETURN
513 END IF
514*
515 scllen = m
516*
517 END IF
518*
519 END IF
520*
521* Undo scaling
522*
523 IF( iascl.EQ.1 ) THEN
524 CALL dlascl( 'G', 0, 0, anrm, smlnum, scllen, nrhs, b, ldb,
525 $ info )
526 ELSE IF( iascl.EQ.2 ) THEN
527 CALL dlascl( 'G', 0, 0, anrm, bignum, scllen, nrhs, b, ldb,
528 $ info )
529 END IF
530 IF( ibscl.EQ.1 ) THEN
531 CALL dlascl( 'G', 0, 0, smlnum, bnrm, scllen, nrhs, b, ldb,
532 $ info )
533 ELSE IF( ibscl.EQ.2 ) THEN
534 CALL dlascl( 'G', 0, 0, bignum, bnrm, scllen, nrhs, b, ldb,
535 $ info )
536 END IF
537*
538 work( 1 ) = dble( lwopt )
539*
540 RETURN
541*
542* End of DGELST
543*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dgelqt(m, n, mb, a, lda, t, ldt, work, info)
DGELQT
Definition dgelqt.f:137
subroutine dgemlqt(side, trans, m, n, k, mb, v, ldv, t, ldt, c, ldc, work, info)
DGEMLQT
Definition dgemlqt.f:166
subroutine dgemqrt(side, trans, m, n, k, nb, v, ldv, t, ldt, c, ldc, work, info)
DGEMQRT
Definition dgemqrt.f:166
subroutine dgeqrt(m, n, nb, a, lda, t, ldt, work, info)
DGEQRT
Definition dgeqrt.f:139
integer function ilaenv(ispec, name, opts, n1, n2, n3, n4)
ILAENV
Definition ilaenv.f:160
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
double precision function dlange(norm, m, n, a, lda, work)
DLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
Definition dlange.f:112
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition dlascl.f:142
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:108
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine dtrtrs(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info)
DTRTRS
Definition dtrtrs.f:144
Here is the call graph for this function:
Here is the caller graph for this function: