LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages

◆ zgels()

subroutine zgels ( character trans,
integer m,
integer n,
integer nrhs,
complex*16, dimension( lda, * ) a,
integer lda,
complex*16, dimension( ldb, * ) b,
integer ldb,
complex*16, dimension( * ) work,
integer lwork,
integer info )

ZGELS solves overdetermined or underdetermined systems for GE matrices

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

Purpose:
!> !> ZGELS solves overdetermined or underdetermined complex linear systems !> involving an M-by-N matrix A, or its conjugate-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 = 'C' and m >= n: find the minimum norm solution of !> an underdetermined system A**H * X = B. !> !> 4. If TRANS = 'C' and m < n: find the least squares solution of !> an overdetermined system, i.e., solve the least squares problem !> minimize || B - A**H * 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; !> = 'C': the linear system involves A**H. !>
[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 COMPLEX*16 array, dimension (LDA,N) !> On entry, the M-by-N matrix A. !> if M >= N, A is overwritten by details of its QR !> factorization as returned by ZGEQRF; !> if M < N, A is overwritten by details of its LQ !> factorization as returned by ZGELQF. !>
[in]LDA
!> LDA is INTEGER !> The leading dimension of the array A. LDA >= max(1,M). !>
[in,out]B
!> B is COMPLEX*16 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 = 'C'. !> 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 the !> modulus 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 = 'C' and m >= n, rows 1 to M of B contain the !> minimum norm solution vectors; !> if TRANS = 'C' 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 the modulus 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 COMPLEX*16 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 188 of file zgels.f.

191*
192* -- LAPACK driver routine --
193* -- LAPACK is a software package provided by Univ. of Tennessee, --
194* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
195*
196* .. Scalar Arguments ..
197 CHARACTER TRANS
198 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
199* ..
200* .. Array Arguments ..
201 COMPLEX*16 A( LDA, * ), B( LDB, * ), WORK( * )
202* ..
203*
204* =====================================================================
205*
206* .. Parameters ..
207 DOUBLE PRECISION ZERO, ONE
208 parameter( zero = 0.0d+0, one = 1.0d+0 )
209 COMPLEX*16 CZERO
210 parameter( czero = ( 0.0d+0, 0.0d+0 ) )
211* ..
212* .. Local Scalars ..
213 LOGICAL LQUERY, TPSD
214 INTEGER BROW, I, IASCL, IBSCL, J, MN, NB, SCLLEN, WSIZE
215 DOUBLE PRECISION ANRM, BIGNUM, BNRM, SMLNUM
216* ..
217* .. Local Arrays ..
218 DOUBLE PRECISION RWORK( 1 )
219* ..
220* .. External Functions ..
221 LOGICAL LSAME
222 INTEGER ILAENV
223 DOUBLE PRECISION DLAMCH, ZLANGE
224 EXTERNAL lsame, ilaenv, dlamch, zlange
225* ..
226* .. External Subroutines ..
227 EXTERNAL xerbla, zgelqf, zgeqrf, zlascl,
228 $ zlaset,
230* ..
231* .. Intrinsic Functions ..
232 INTRINSIC dble, 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, 'C' ) ) ) 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. .NOT.lquery )
255 $ 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, 'ZGEQRF', ' ', m, n, -1, -1 )
269 IF( tpsd ) THEN
270 nb = max( nb, ilaenv( 1, 'ZUNMQR', 'LN', m, nrhs, n,
271 $ -1 ) )
272 ELSE
273 nb = max( nb, ilaenv( 1, 'ZUNMQR', 'LC', m, nrhs, n,
274 $ -1 ) )
275 END IF
276 ELSE
277 nb = ilaenv( 1, 'ZGELQF', ' ', m, n, -1, -1 )
278 IF( tpsd ) THEN
279 nb = max( nb, ilaenv( 1, 'ZUNMLQ', 'LC', n, nrhs, m,
280 $ -1 ) )
281 ELSE
282 nb = max( nb, ilaenv( 1, 'ZUNMLQ', '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 ) = dble( wsize )
289*
290 END IF
291*
292 IF( info.NE.0 ) THEN
293 CALL xerbla( 'ZGELS ', -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 zlaset( 'Full', max( m, n ), nrhs, czero, czero, b,
303 $ ldb )
304 RETURN
305 END IF
306*
307* Get machine parameters
308*
309 smlnum = dlamch( 'S' ) / dlamch( 'P' )
310 bignum = one / smlnum
311*
312* Scale A, B if max element outside range [SMLNUM,BIGNUM]
313*
314 anrm = zlange( 'M', m, n, a, lda, rwork )
315 iascl = 0
316 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
317*
318* Scale matrix norm up to SMLNUM
319*
320 CALL zlascl( 'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
321 iascl = 1
322 ELSE IF( anrm.GT.bignum ) THEN
323*
324* Scale matrix norm down to BIGNUM
325*
326 CALL zlascl( 'G', 0, 0, anrm, bignum, m, n, a, lda, info )
327 iascl = 2
328 ELSE IF( anrm.EQ.zero ) THEN
329*
330* Matrix all zero. Return zero solution.
331*
332 CALL zlaset( 'F', max( m, n ), nrhs, czero, czero, b, ldb )
333 GO TO 50
334 END IF
335*
336 brow = m
337 IF( tpsd )
338 $ brow = n
339 bnrm = zlange( 'M', brow, nrhs, b, ldb, rwork )
340 ibscl = 0
341 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
342*
343* Scale matrix norm up to SMLNUM
344*
345 CALL zlascl( 'G', 0, 0, bnrm, smlnum, brow, nrhs, b, ldb,
346 $ info )
347 ibscl = 1
348 ELSE IF( bnrm.GT.bignum ) THEN
349*
350* Scale matrix norm down to BIGNUM
351*
352 CALL zlascl( 'G', 0, 0, bnrm, bignum, brow, nrhs, b, ldb,
353 $ info )
354 ibscl = 2
355 END IF
356*
357 IF( m.GE.n ) THEN
358*
359* compute QR factorization of A
360*
361 CALL zgeqrf( m, n, a, lda, work( 1 ), work( mn+1 ),
362 $ lwork-mn,
363 $ info )
364*
365* workspace at least N, optimally N*NB
366*
367 IF( .NOT.tpsd ) THEN
368*
369* Least-Squares Problem min || A * X - B ||
370*
371* B(1:M,1:NRHS) := Q**H * B(1:M,1:NRHS)
372*
373 CALL zunmqr( 'Left', 'Conjugate transpose', m, nrhs, n,
374 $ a,
375 $ lda, work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
376 $ info )
377*
378* workspace at least NRHS, optimally NRHS*NB
379*
380* B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
381*
382 CALL ztrtrs( 'Upper', 'No transpose', 'Non-unit', n,
383 $ nrhs,
384 $ a, lda, b, ldb, info )
385*
386 IF( info.GT.0 ) THEN
387 RETURN
388 END IF
389*
390 scllen = n
391*
392 ELSE
393*
394* Underdetermined system of equations A**T * X = B
395*
396* B(1:N,1:NRHS) := inv(R**H) * B(1:N,1:NRHS)
397*
398 CALL ztrtrs( 'Upper', 'Conjugate transpose','Non-unit',
399 $ n, nrhs, a, lda, b, ldb, info )
400*
401 IF( info.GT.0 ) THEN
402 RETURN
403 END IF
404*
405* B(N+1:M,1:NRHS) = ZERO
406*
407 DO 20 j = 1, nrhs
408 DO 10 i = n + 1, m
409 b( i, j ) = czero
410 10 CONTINUE
411 20 CONTINUE
412*
413* B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)
414*
415 CALL zunmqr( 'Left', 'No transpose', m, nrhs, n, a, lda,
416 $ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
417 $ info )
418*
419* workspace at least NRHS, optimally NRHS*NB
420*
421 scllen = m
422*
423 END IF
424*
425 ELSE
426*
427* Compute LQ factorization of A
428*
429 CALL zgelqf( m, n, a, lda, work( 1 ), work( mn+1 ),
430 $ lwork-mn,
431 $ info )
432*
433* workspace at least M, optimally M*NB.
434*
435 IF( .NOT.tpsd ) THEN
436*
437* underdetermined system of equations A * X = B
438*
439* B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
440*
441 CALL ztrtrs( 'Lower', 'No transpose', 'Non-unit', m,
442 $ nrhs,
443 $ a, lda, b, ldb, info )
444*
445 IF( info.GT.0 ) THEN
446 RETURN
447 END IF
448*
449* B(M+1:N,1:NRHS) = 0
450*
451 DO 40 j = 1, nrhs
452 DO 30 i = m + 1, n
453 b( i, j ) = czero
454 30 CONTINUE
455 40 CONTINUE
456*
457* B(1:N,1:NRHS) := Q(1:N,:)**H * B(1:M,1:NRHS)
458*
459 CALL zunmlq( 'Left', 'Conjugate transpose', n, nrhs, m,
460 $ a,
461 $ lda, work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
462 $ info )
463*
464* workspace at least NRHS, optimally NRHS*NB
465*
466 scllen = n
467*
468 ELSE
469*
470* overdetermined system min || A**H * X - B ||
471*
472* B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)
473*
474 CALL zunmlq( 'Left', 'No transpose', n, nrhs, m, a, lda,
475 $ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
476 $ info )
477*
478* workspace at least NRHS, optimally NRHS*NB
479*
480* B(1:M,1:NRHS) := inv(L**H) * B(1:M,1:NRHS)
481*
482 CALL ztrtrs( 'Lower', 'Conjugate transpose', 'Non-unit',
483 $ m, nrhs, a, lda, b, ldb, info )
484*
485 IF( info.GT.0 ) THEN
486 RETURN
487 END IF
488*
489 scllen = m
490*
491 END IF
492*
493 END IF
494*
495* Undo scaling
496*
497 IF( iascl.EQ.1 ) THEN
498 CALL zlascl( 'G', 0, 0, anrm, smlnum, scllen, nrhs, b, ldb,
499 $ info )
500 ELSE IF( iascl.EQ.2 ) THEN
501 CALL zlascl( 'G', 0, 0, anrm, bignum, scllen, nrhs, b, ldb,
502 $ info )
503 END IF
504 IF( ibscl.EQ.1 ) THEN
505 CALL zlascl( 'G', 0, 0, smlnum, bnrm, scllen, nrhs, b, ldb,
506 $ info )
507 ELSE IF( ibscl.EQ.2 ) THEN
508 CALL zlascl( 'G', 0, 0, bignum, bnrm, scllen, nrhs, b, ldb,
509 $ info )
510 END IF
511*
512 50 CONTINUE
513 work( 1 ) = dble( wsize )
514*
515 RETURN
516*
517* End of ZGELS
518*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zgelqf(m, n, a, lda, tau, work, lwork, info)
ZGELQF
Definition zgelqf.f:142
subroutine zgeqrf(m, n, a, lda, tau, work, lwork, info)
ZGEQRF
Definition zgeqrf.f:144
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 zlange(norm, m, n, a, lda, work)
ZLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
Definition zlange.f:113
subroutine zlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition zlascl.f:142
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition zlaset.f:104
logical function lsame(ca, cb)
LSAME
Definition lsame.f:48
subroutine ztrtrs(uplo, trans, diag, n, nrhs, a, lda, b, ldb, info)
ZTRTRS
Definition ztrtrs.f:144
subroutine zunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMLQ
Definition zunmlq.f:165
subroutine zunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMQR
Definition zunmqr.f:165
Here is the call graph for this function:
Here is the caller graph for this function: