LAPACK  3.4.2 LAPACK: Linear Algebra PACKage
cgels.f
Go to the documentation of this file.
1 *> \brief <b> CGELS solves overdetermined or underdetermined systems for GE matrices</b>
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgels.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgels.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgels.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE CGELS( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
22 * INFO )
23 *
24 * .. Scalar Arguments ..
25 * CHARACTER TRANS
26 * INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS
27 * ..
28 * .. Array Arguments ..
29 * COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
30 * ..
31 *
32 *
33 *> \par Purpose:
34 * =============
35 *>
36 *> \verbatim
37 *>
38 *> CGELS solves overdetermined or underdetermined complex linear systems
39 *> involving an M-by-N matrix A, or its conjugate-transpose, using a QR
40 *> or LQ factorization of A. It is assumed that A has full rank.
41 *>
42 *> The following options are provided:
43 *>
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 ||.
47 *>
48 *> 2. If TRANS = 'N' and m < n: find the minimum norm solution of
49 *> an underdetermined system A * X = B.
50 *>
51 *> 3. If TRANS = 'C' and m >= n: find the minimum norm solution of
52 *> an undetermined system A**H * X = B.
53 *>
54 *> 4. If TRANS = 'C' and m < n: find the least squares solution of
55 *> an overdetermined system, i.e., solve the least squares problem
56 *> minimize || B - A**H * X ||.
57 *>
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
61 *> matrix X.
62 *> \endverbatim
63 *
64 * Arguments:
65 * ==========
66 *
67 *> \param[in] TRANS
68 *> \verbatim
69 *> TRANS is CHARACTER*1
70 *> = 'N': the linear system involves A;
71 *> = 'C': the linear system involves A**H.
72 *> \endverbatim
73 *>
74 *> \param[in] M
75 *> \verbatim
76 *> M is INTEGER
77 *> The number of rows of the matrix A. M >= 0.
78 *> \endverbatim
79 *>
80 *> \param[in] N
81 *> \verbatim
82 *> N is INTEGER
83 *> The number of columns of the matrix A. N >= 0.
84 *> \endverbatim
85 *>
86 *> \param[in] NRHS
87 *> \verbatim
88 *> NRHS is INTEGER
89 *> The number of right hand sides, i.e., the number of
90 *> columns of the matrices B and X. NRHS >= 0.
91 *> \endverbatim
92 *>
93 *> \param[in,out] A
94 *> \verbatim
95 *> A is COMPLEX array, dimension (LDA,N)
96 *> On entry, the M-by-N matrix A.
97 *> if M >= N, A is overwritten by details of its QR
98 *> factorization as returned by CGEQRF;
99 *> if M < N, A is overwritten by details of its LQ
100 *> factorization as returned by CGELQF.
101 *> \endverbatim
102 *>
103 *> \param[in] LDA
104 *> \verbatim
105 *> LDA is INTEGER
106 *> The leading dimension of the array A. LDA >= max(1,M).
107 *> \endverbatim
108 *>
109 *> \param[in,out] B
110 *> \verbatim
111 *> B is COMPLEX array, dimension (LDB,NRHS)
112 *> On entry, the matrix B of right hand side vectors, stored
113 *> columnwise; B is M-by-NRHS if TRANS = 'N', or N-by-NRHS
114 *> if TRANS = 'C'.
115 *> On exit, if INFO = 0, B is overwritten by the solution
116 *> vectors, stored columnwise:
117 *> if TRANS = 'N' and m >= n, rows 1 to n of B contain the least
118 *> squares solution vectors; the residual sum of squares for the
119 *> solution in each column is given by the sum of squares of the
120 *> modulus of elements N+1 to M in that column;
121 *> if TRANS = 'N' and m < n, rows 1 to N of B contain the
122 *> minimum norm solution vectors;
123 *> if TRANS = 'C' and m >= n, rows 1 to M of B contain the
124 *> minimum norm solution vectors;
125 *> if TRANS = 'C' and m < n, rows 1 to M of B contain the
126 *> least squares solution vectors; the residual sum of squares
127 *> for the solution in each column is given by the sum of
128 *> squares of the modulus of elements M+1 to N in that column.
129 *> \endverbatim
130 *>
131 *> \param[in] LDB
132 *> \verbatim
133 *> LDB is INTEGER
134 *> The leading dimension of the array B. LDB >= MAX(1,M,N).
135 *> \endverbatim
136 *>
137 *> \param[out] WORK
138 *> \verbatim
139 *> WORK is COMPLEX array, dimension (MAX(1,LWORK))
140 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
141 *> \endverbatim
142 *>
143 *> \param[in] LWORK
144 *> \verbatim
145 *> LWORK is INTEGER
146 *> The dimension of the array WORK.
147 *> LWORK >= max( 1, MN + max( MN, NRHS ) ).
148 *> For optimal performance,
149 *> LWORK >= max( 1, MN + max( MN, NRHS )*NB ).
150 *> where MN = min(M,N) and NB is the optimum block size.
151 *>
152 *> If LWORK = -1, then a workspace query is assumed; the routine
153 *> only calculates the optimal size of the WORK array, returns
154 *> this value as the first entry of the WORK array, and no error
155 *> message related to LWORK is issued by XERBLA.
156 *> \endverbatim
157 *>
158 *> \param[out] INFO
159 *> \verbatim
160 *> INFO is INTEGER
161 *> = 0: successful exit
162 *> < 0: if INFO = -i, the i-th argument had an illegal value
163 *> > 0: if INFO = i, the i-th diagonal element of the
164 *> triangular factor of A is zero, so that A does not have
165 *> full rank; the least squares solution could not be
166 *> computed.
167 *> \endverbatim
168 *
169 * Authors:
170 * ========
171 *
172 *> \author Univ. of Tennessee
173 *> \author Univ. of California Berkeley
174 *> \author Univ. of Colorado Denver
175 *> \author NAG Ltd.
176 *
177 *> \date November 2011
178 *
179 *> \ingroup complexGEsolve
180 *
181 * =====================================================================
182  SUBROUTINE cgels( TRANS, M, N, NRHS, A, LDA, B, LDB, WORK, LWORK,
183  \$ info )
184 *
185 * -- LAPACK driver routine (version 3.4.0) --
186 * -- LAPACK is a software package provided by Univ. of Tennessee, --
187 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
188 * November 2011
189 *
190 * .. Scalar Arguments ..
191  CHARACTER trans
192  INTEGER info, lda, ldb, lwork, m, n, nrhs
193 * ..
194 * .. Array Arguments ..
195  COMPLEX a( lda, * ), b( ldb, * ), work( * )
196 * ..
197 *
198 * =====================================================================
199 *
200 * .. Parameters ..
201  REAL zero, one
202  parameter( zero = 0.0e+0, one = 1.0e+0 )
203  COMPLEX czero
204  parameter( czero = ( 0.0e+0, 0.0e+0 ) )
205 * ..
206 * .. Local Scalars ..
207  LOGICAL lquery, tpsd
208  INTEGER brow, i, iascl, ibscl, j, mn, nb, scllen, wsize
209  REAL anrm, bignum, bnrm, smlnum
210 * ..
211 * .. Local Arrays ..
212  REAL rwork( 1 )
213 * ..
214 * .. External Functions ..
215  LOGICAL lsame
216  INTEGER ilaenv
217  REAL clange, slamch
218  EXTERNAL lsame, ilaenv, clange, slamch
219 * ..
220 * .. External Subroutines ..
221  EXTERNAL cgelqf, cgeqrf, clascl, claset, ctrtrs, cunmlq,
222  \$ cunmqr, slabad, xerbla
223 * ..
224 * .. Intrinsic Functions ..
225  INTRINSIC max, min, real
226 * ..
227 * .. Executable Statements ..
228 *
229 * Test the input arguments.
230 *
231  info = 0
232  mn = min( m, n )
233  lquery = ( lwork.EQ.-1 )
234  IF( .NOT.( lsame( trans, 'N' ) .OR. lsame( trans, 'C' ) ) ) THEN
235  info = -1
236  ELSE IF( m.LT.0 ) THEN
237  info = -2
238  ELSE IF( n.LT.0 ) THEN
239  info = -3
240  ELSE IF( nrhs.LT.0 ) THEN
241  info = -4
242  ELSE IF( lda.LT.max( 1, m ) ) THEN
243  info = -6
244  ELSE IF( ldb.LT.max( 1, m, n ) ) THEN
245  info = -8
246  ELSE IF( lwork.LT.max( 1, mn+max( mn, nrhs ) ) .AND.
247  \$ .NOT.lquery ) THEN
248  info = -10
249  END IF
250 *
251 * Figure out optimal block size
252 *
253  IF( info.EQ.0 .OR. info.EQ.-10 ) THEN
254 *
255  tpsd = .true.
256  IF( lsame( trans, 'N' ) )
257  \$ tpsd = .false.
258 *
259  IF( m.GE.n ) THEN
260  nb = ilaenv( 1, 'CGEQRF', ' ', m, n, -1, -1 )
261  IF( tpsd ) THEN
262  nb = max( nb, ilaenv( 1, 'CUNMQR', 'LN', m, nrhs, n,
263  \$ -1 ) )
264  ELSE
265  nb = max( nb, ilaenv( 1, 'CUNMQR', 'LC', m, nrhs, n,
266  \$ -1 ) )
267  END IF
268  ELSE
269  nb = ilaenv( 1, 'CGELQF', ' ', m, n, -1, -1 )
270  IF( tpsd ) THEN
271  nb = max( nb, ilaenv( 1, 'CUNMLQ', 'LC', n, nrhs, m,
272  \$ -1 ) )
273  ELSE
274  nb = max( nb, ilaenv( 1, 'CUNMLQ', 'LN', n, nrhs, m,
275  \$ -1 ) )
276  END IF
277  END IF
278 *
279  wsize = max( 1, mn + max( mn, nrhs )*nb )
280  work( 1 ) = REAL( wsize )
281 *
282  END IF
283 *
284  IF( info.NE.0 ) THEN
285  CALL xerbla( 'CGELS ', -info )
286  return
287  ELSE IF( lquery ) THEN
288  return
289  END IF
290 *
291 * Quick return if possible
292 *
293  IF( min( m, n, nrhs ).EQ.0 ) THEN
294  CALL claset( 'Full', max( m, n ), nrhs, czero, czero, b, ldb )
295  return
296  END IF
297 *
298 * Get machine parameters
299 *
300  smlnum = slamch( 'S' ) / slamch( 'P' )
301  bignum = one / smlnum
302  CALL slabad( smlnum, bignum )
303 *
304 * Scale A, B if max element outside range [SMLNUM,BIGNUM]
305 *
306  anrm = clange( 'M', m, n, a, lda, rwork )
307  iascl = 0
308  IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
309 *
310 * Scale matrix norm up to SMLNUM
311 *
312  CALL clascl( 'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
313  iascl = 1
314  ELSE IF( anrm.GT.bignum ) THEN
315 *
316 * Scale matrix norm down to BIGNUM
317 *
318  CALL clascl( 'G', 0, 0, anrm, bignum, m, n, a, lda, info )
319  iascl = 2
320  ELSE IF( anrm.EQ.zero ) THEN
321 *
322 * Matrix all zero. Return zero solution.
323 *
324  CALL claset( 'F', max( m, n ), nrhs, czero, czero, b, ldb )
325  go to 50
326  END IF
327 *
328  brow = m
329  IF( tpsd )
330  \$ brow = n
331  bnrm = clange( 'M', brow, nrhs, b, ldb, rwork )
332  ibscl = 0
333  IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
334 *
335 * Scale matrix norm up to SMLNUM
336 *
337  CALL clascl( 'G', 0, 0, bnrm, smlnum, brow, nrhs, b, ldb,
338  \$ info )
339  ibscl = 1
340  ELSE IF( bnrm.GT.bignum ) THEN
341 *
342 * Scale matrix norm down to BIGNUM
343 *
344  CALL clascl( 'G', 0, 0, bnrm, bignum, brow, nrhs, b, ldb,
345  \$ info )
346  ibscl = 2
347  END IF
348 *
349  IF( m.GE.n ) THEN
350 *
351 * compute QR factorization of A
352 *
353  CALL cgeqrf( m, n, a, lda, work( 1 ), work( mn+1 ), lwork-mn,
354  \$ info )
355 *
356 * workspace at least N, optimally N*NB
357 *
358  IF( .NOT.tpsd ) THEN
359 *
360 * Least-Squares Problem min || A * X - B ||
361 *
362 * B(1:M,1:NRHS) := Q**H * B(1:M,1:NRHS)
363 *
364  CALL cunmqr( 'Left', 'Conjugate transpose', m, nrhs, n, a,
365  \$ lda, work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
366  \$ info )
367 *
368 * workspace at least NRHS, optimally NRHS*NB
369 *
370 * B(1:N,1:NRHS) := inv(R) * B(1:N,1:NRHS)
371 *
372  CALL ctrtrs( 'Upper', 'No transpose', 'Non-unit', n, nrhs,
373  \$ a, lda, b, ldb, info )
374 *
375  IF( info.GT.0 ) THEN
376  return
377  END IF
378 *
379  scllen = n
380 *
381  ELSE
382 *
383 * Overdetermined system of equations A**H * X = B
384 *
385 * B(1:N,1:NRHS) := inv(R**H) * B(1:N,1:NRHS)
386 *
387  CALL ctrtrs( 'Upper', 'Conjugate transpose','Non-unit',
388  \$ n, nrhs, a, lda, b, ldb, info )
389 *
390  IF( info.GT.0 ) THEN
391  return
392  END IF
393 *
394 * B(N+1:M,1:NRHS) = ZERO
395 *
396  DO 20 j = 1, nrhs
397  DO 10 i = n + 1, m
398  b( i, j ) = czero
399  10 continue
400  20 continue
401 *
402 * B(1:M,1:NRHS) := Q(1:N,:) * B(1:N,1:NRHS)
403 *
404  CALL cunmqr( 'Left', 'No transpose', m, nrhs, n, a, lda,
405  \$ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
406  \$ info )
407 *
408 * workspace at least NRHS, optimally NRHS*NB
409 *
410  scllen = m
411 *
412  END IF
413 *
414  ELSE
415 *
416 * Compute LQ factorization of A
417 *
418  CALL cgelqf( m, n, a, lda, work( 1 ), work( mn+1 ), lwork-mn,
419  \$ info )
420 *
421 * workspace at least M, optimally M*NB.
422 *
423  IF( .NOT.tpsd ) THEN
424 *
425 * underdetermined system of equations A * X = B
426 *
427 * B(1:M,1:NRHS) := inv(L) * B(1:M,1:NRHS)
428 *
429  CALL ctrtrs( 'Lower', 'No transpose', 'Non-unit', m, nrhs,
430  \$ a, lda, b, ldb, info )
431 *
432  IF( info.GT.0 ) THEN
433  return
434  END IF
435 *
436 * B(M+1:N,1:NRHS) = 0
437 *
438  DO 40 j = 1, nrhs
439  DO 30 i = m + 1, n
440  b( i, j ) = czero
441  30 continue
442  40 continue
443 *
444 * B(1:N,1:NRHS) := Q(1:N,:)**H * B(1:M,1:NRHS)
445 *
446  CALL cunmlq( 'Left', 'Conjugate transpose', n, nrhs, m, a,
447  \$ lda, work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
448  \$ info )
449 *
450 * workspace at least NRHS, optimally NRHS*NB
451 *
452  scllen = n
453 *
454  ELSE
455 *
456 * overdetermined system min || A**H * X - B ||
457 *
458 * B(1:N,1:NRHS) := Q * B(1:N,1:NRHS)
459 *
460  CALL cunmlq( 'Left', 'No transpose', n, nrhs, m, a, lda,
461  \$ work( 1 ), b, ldb, work( mn+1 ), lwork-mn,
462  \$ info )
463 *
464 * workspace at least NRHS, optimally NRHS*NB
465 *
466 * B(1:M,1:NRHS) := inv(L**H) * B(1:M,1:NRHS)
467 *
468  CALL ctrtrs( 'Lower', 'Conjugate transpose', 'Non-unit',
469  \$ m, nrhs, a, lda, b, ldb, info )
470 *
471  IF( info.GT.0 ) THEN
472  return
473  END IF
474 *
475  scllen = m
476 *
477  END IF
478 *
479  END IF
480 *
481 * Undo scaling
482 *
483  IF( iascl.EQ.1 ) THEN
484  CALL clascl( 'G', 0, 0, anrm, smlnum, scllen, nrhs, b, ldb,
485  \$ info )
486  ELSE IF( iascl.EQ.2 ) THEN
487  CALL clascl( 'G', 0, 0, anrm, bignum, scllen, nrhs, b, ldb,
488  \$ info )
489  END IF
490  IF( ibscl.EQ.1 ) THEN
491  CALL clascl( 'G', 0, 0, smlnum, bnrm, scllen, nrhs, b, ldb,
492  \$ info )
493  ELSE IF( ibscl.EQ.2 ) THEN
494  CALL clascl( 'G', 0, 0, bignum, bnrm, scllen, nrhs, b, ldb,
495  \$ info )
496  END IF
497 *
498  50 continue
499  work( 1 ) = REAL( wsize )
500 *
501  return
502 *
503 * End of CGELS
504 *
505  END