LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
cgelss.f
Go to the documentation of this file.
1*> \brief <b> CGELSS 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*> Download CGELSS + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgelss.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgelss.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgelss.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE CGELSS( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
20* WORK, LWORK, RWORK, INFO )
21*
22* .. Scalar Arguments ..
23* INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
24* REAL RCOND
25* ..
26* .. Array Arguments ..
27* REAL RWORK( * ), S( * )
28* COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
29* ..
30*
31*
32*> \par Purpose:
33* =============
34*>
35*> \verbatim
36*>
37*> CGELSS computes the minimum norm solution to a complex linear
38*> least squares problem:
39*>
40*> Minimize 2-norm(| b - A*x |).
41*>
42*> using the singular value decomposition (SVD) of A. A is an M-by-N
43*> matrix which may be rank-deficient.
44*>
45*> Several right hand side vectors b and solution vectors x can be
46*> handled in a single call; they are stored as the columns of the
47*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution matrix
48*> X.
49*>
50*> The effective rank of A is determined by treating as zero those
51*> singular values which are less than RCOND times the largest singular
52*> value.
53*> \endverbatim
54*
55* Arguments:
56* ==========
57*
58*> \param[in] M
59*> \verbatim
60*> M is INTEGER
61*> The number of rows of the matrix A. M >= 0.
62*> \endverbatim
63*>
64*> \param[in] N
65*> \verbatim
66*> N is INTEGER
67*> The number of columns of the matrix A. N >= 0.
68*> \endverbatim
69*>
70*> \param[in] NRHS
71*> \verbatim
72*> NRHS is INTEGER
73*> The number of right hand sides, i.e., the number of columns
74*> of the matrices B and X. NRHS >= 0.
75*> \endverbatim
76*>
77*> \param[in,out] A
78*> \verbatim
79*> A is COMPLEX array, dimension (LDA,N)
80*> On entry, the M-by-N matrix A.
81*> On exit, the first min(m,n) rows of A are overwritten with
82*> its right singular vectors, stored rowwise.
83*> \endverbatim
84*>
85*> \param[in] LDA
86*> \verbatim
87*> LDA is INTEGER
88*> The leading dimension of the array A. LDA >= max(1,M).
89*> \endverbatim
90*>
91*> \param[in,out] B
92*> \verbatim
93*> B is COMPLEX array, dimension (LDB,NRHS)
94*> On entry, the M-by-NRHS right hand side matrix B.
95*> On exit, B is overwritten by the N-by-NRHS solution matrix X.
96*> If m >= n and RANK = n, the residual sum-of-squares for
97*> the solution in the i-th column is given by the sum of
98*> squares of the modulus of elements n+1:m in that column.
99*> \endverbatim
100*>
101*> \param[in] LDB
102*> \verbatim
103*> LDB is INTEGER
104*> The leading dimension of the array B. LDB >= max(1,M,N).
105*> \endverbatim
106*>
107*> \param[out] S
108*> \verbatim
109*> S is REAL array, dimension (min(M,N))
110*> The singular values of A in decreasing order.
111*> The condition number of A in the 2-norm = S(1)/S(min(m,n)).
112*> \endverbatim
113*>
114*> \param[in] RCOND
115*> \verbatim
116*> RCOND is REAL
117*> RCOND is used to determine the effective rank of A.
118*> Singular values S(i) <= RCOND*S(1) are treated as zero.
119*> If RCOND < 0, machine precision is used instead.
120*> \endverbatim
121*>
122*> \param[out] RANK
123*> \verbatim
124*> RANK is INTEGER
125*> The effective rank of A, i.e., the number of singular values
126*> which are greater than RCOND*S(1).
127*> \endverbatim
128*>
129*> \param[out] WORK
130*> \verbatim
131*> WORK is COMPLEX array, dimension (MAX(1,LWORK))
132*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
133*> \endverbatim
134*>
135*> \param[in] LWORK
136*> \verbatim
137*> LWORK is INTEGER
138*> The dimension of the array WORK. LWORK >= 1, and also:
139*> LWORK >= 2*min(M,N) + max(M,N,NRHS)
140*> For good performance, LWORK should generally be larger.
141*>
142*> If LWORK = -1, then a workspace query is assumed; the routine
143*> only calculates the optimal size of the WORK array, returns
144*> this value as the first entry of the WORK array, and no error
145*> message related to LWORK is issued by XERBLA.
146*> \endverbatim
147*>
148*> \param[out] RWORK
149*> \verbatim
150*> RWORK is REAL array, dimension (5*min(M,N))
151*> \endverbatim
152*>
153*> \param[out] INFO
154*> \verbatim
155*> INFO is INTEGER
156*> = 0: successful exit
157*> < 0: if INFO = -i, the i-th argument had an illegal value.
158*> > 0: the algorithm for computing the SVD failed to converge;
159*> if INFO = i, i off-diagonal elements of an intermediate
160*> bidiagonal form did not converge to zero.
161*> \endverbatim
162*
163* Authors:
164* ========
165*
166*> \author Univ. of Tennessee
167*> \author Univ. of California Berkeley
168*> \author Univ. of Colorado Denver
169*> \author NAG Ltd.
170*
171*> \ingroup gelss
172*
173* =====================================================================
174 SUBROUTINE cgelss( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
175 $ WORK, LWORK, RWORK, INFO )
176*
177* -- LAPACK driver routine --
178* -- LAPACK is a software package provided by Univ. of Tennessee, --
179* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
180*
181* .. Scalar Arguments ..
182 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
183 REAL RCOND
184* ..
185* .. Array Arguments ..
186 REAL RWORK( * ), S( * )
187 COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
188* ..
189*
190* =====================================================================
191*
192* .. Parameters ..
193 REAL ZERO, ONE
194 parameter( zero = 0.0e+0, one = 1.0e+0 )
195 COMPLEX CZERO, CONE
196 parameter( czero = ( 0.0e+0, 0.0e+0 ),
197 $ cone = ( 1.0e+0, 0.0e+0 ) )
198* ..
199* .. Local Scalars ..
200 LOGICAL LQUERY
201 INTEGER BL, CHUNK, I, IASCL, IBSCL, IE, IL, IRWORK,
202 $ itau, itaup, itauq, iwork, ldwork, maxmn,
203 $ maxwrk, minmn, minwrk, mm, mnthr
204 INTEGER LWORK_CGEQRF, LWORK_CUNMQR, LWORK_CGEBRD,
205 $ lwork_cunmbr, lwork_cungbr, lwork_cunmlq,
206 $ lwork_cgelqf
207 REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM, THR
208* ..
209* .. Local Arrays ..
210 COMPLEX DUM( 1 )
211* ..
212* .. External Subroutines ..
213 EXTERNAL cbdsqr, ccopy, cgebrd, cgelqf, cgemm,
214 $ cgemv,
217* ..
218* .. External Functions ..
219 INTEGER ILAENV
220 REAL CLANGE, SLAMCH, SROUNDUP_LWORK
221 EXTERNAL ilaenv, clange, slamch,
222 $ sroundup_lwork
223* ..
224* .. Intrinsic Functions ..
225 INTRINSIC max, min
226* ..
227* .. Executable Statements ..
228*
229* Test the input arguments
230*
231 info = 0
232 minmn = min( m, n )
233 maxmn = max( m, n )
234 lquery = ( lwork.EQ.-1 )
235 IF( m.LT.0 ) THEN
236 info = -1
237 ELSE IF( n.LT.0 ) THEN
238 info = -2
239 ELSE IF( nrhs.LT.0 ) THEN
240 info = -3
241 ELSE IF( lda.LT.max( 1, m ) ) THEN
242 info = -5
243 ELSE IF( ldb.LT.max( 1, maxmn ) ) THEN
244 info = -7
245 END IF
246*
247* Compute workspace
248* (Note: Comments in the code beginning "Workspace:" describe the
249* minimal amount of workspace needed at that point in the code,
250* as well as the preferred amount for good performance.
251* CWorkspace refers to complex workspace, and RWorkspace refers
252* to real workspace. NB refers to the optimal block size for the
253* immediately following subroutine, as returned by ILAENV.)
254*
255 IF( info.EQ.0 ) THEN
256 minwrk = 1
257 maxwrk = 1
258 IF( minmn.GT.0 ) THEN
259 mm = m
260 mnthr = ilaenv( 6, 'CGELSS', ' ', m, n, nrhs, -1 )
261 IF( m.GE.n .AND. m.GE.mnthr ) THEN
262*
263* Path 1a - overdetermined, with many more rows than
264* columns
265*
266* Compute space needed for CGEQRF
267 CALL cgeqrf( m, n, a, lda, dum(1), dum(1), -1, info )
268 lwork_cgeqrf = int( dum(1) )
269* Compute space needed for CUNMQR
270 CALL cunmqr( 'L', 'C', m, nrhs, n, a, lda, dum(1), b,
271 $ ldb, dum(1), -1, info )
272 lwork_cunmqr = int( dum(1) )
273 mm = n
274 maxwrk = max( maxwrk, n + n*ilaenv( 1, 'CGEQRF', ' ',
275 $ m,
276 $ n, -1, -1 ) )
277 maxwrk = max( maxwrk, n + nrhs*ilaenv( 1, 'CUNMQR',
278 $ 'LC',
279 $ m, nrhs, n, -1 ) )
280 END IF
281 IF( m.GE.n ) THEN
282*
283* Path 1 - overdetermined or exactly determined
284*
285* Compute space needed for CGEBRD
286 CALL cgebrd( mm, n, a, lda, s, s, dum(1), dum(1),
287 $ dum(1),
288 $ -1, info )
289 lwork_cgebrd = int( dum(1) )
290* Compute space needed for CUNMBR
291 CALL cunmbr( 'Q', 'L', 'C', mm, nrhs, n, a, lda,
292 $ dum(1),
293 $ b, ldb, dum(1), -1, info )
294 lwork_cunmbr = int( dum(1) )
295* Compute space needed for CUNGBR
296 CALL cungbr( 'P', n, n, n, a, lda, dum(1),
297 $ dum(1), -1, info )
298 lwork_cungbr = int( dum(1) )
299* Compute total workspace needed
300 maxwrk = max( maxwrk, 2*n + lwork_cgebrd )
301 maxwrk = max( maxwrk, 2*n + lwork_cunmbr )
302 maxwrk = max( maxwrk, 2*n + lwork_cungbr )
303 maxwrk = max( maxwrk, n*nrhs )
304 minwrk = 2*n + max( nrhs, m )
305 END IF
306 IF( n.GT.m ) THEN
307 minwrk = 2*m + max( nrhs, n )
308 IF( n.GE.mnthr ) THEN
309*
310* Path 2a - underdetermined, with many more columns
311* than rows
312*
313* Compute space needed for CGELQF
314 CALL cgelqf( m, n, a, lda, dum(1), dum(1),
315 $ -1, info )
316 lwork_cgelqf = int( dum(1) )
317* Compute space needed for CGEBRD
318 CALL cgebrd( m, m, a, lda, s, s, dum(1), dum(1),
319 $ dum(1), -1, info )
320 lwork_cgebrd = int( dum(1) )
321* Compute space needed for CUNMBR
322 CALL cunmbr( 'Q', 'L', 'C', m, nrhs, n, a, lda,
323 $ dum(1), b, ldb, dum(1), -1, info )
324 lwork_cunmbr = int( dum(1) )
325* Compute space needed for CUNGBR
326 CALL cungbr( 'P', m, m, m, a, lda, dum(1),
327 $ dum(1), -1, info )
328 lwork_cungbr = int( dum(1) )
329* Compute space needed for CUNMLQ
330 CALL cunmlq( 'L', 'C', n, nrhs, m, a, lda, dum(1),
331 $ b, ldb, dum(1), -1, info )
332 lwork_cunmlq = int( dum(1) )
333* Compute total workspace needed
334 maxwrk = m + lwork_cgelqf
335 maxwrk = max( maxwrk, 3*m + m*m + lwork_cgebrd )
336 maxwrk = max( maxwrk, 3*m + m*m + lwork_cunmbr )
337 maxwrk = max( maxwrk, 3*m + m*m + lwork_cungbr )
338 IF( nrhs.GT.1 ) THEN
339 maxwrk = max( maxwrk, m*m + m + m*nrhs )
340 ELSE
341 maxwrk = max( maxwrk, m*m + 2*m )
342 END IF
343 maxwrk = max( maxwrk, m + lwork_cunmlq )
344 ELSE
345*
346* Path 2 - underdetermined
347*
348* Compute space needed for CGEBRD
349 CALL cgebrd( m, n, a, lda, s, s, dum(1), dum(1),
350 $ dum(1), -1, info )
351 lwork_cgebrd = int( dum(1) )
352* Compute space needed for CUNMBR
353 CALL cunmbr( 'Q', 'L', 'C', m, nrhs, m, a, lda,
354 $ dum(1), b, ldb, dum(1), -1, info )
355 lwork_cunmbr = int( dum(1) )
356* Compute space needed for CUNGBR
357 CALL cungbr( 'P', m, n, m, a, lda, dum(1),
358 $ dum(1), -1, info )
359 lwork_cungbr = int( dum(1) )
360 maxwrk = 2*m + lwork_cgebrd
361 maxwrk = max( maxwrk, 2*m + lwork_cunmbr )
362 maxwrk = max( maxwrk, 2*m + lwork_cungbr )
363 maxwrk = max( maxwrk, n*nrhs )
364 END IF
365 END IF
366 maxwrk = max( minwrk, maxwrk )
367 END IF
368 work( 1 ) = sroundup_lwork(maxwrk)
369*
370 IF( lwork.LT.minwrk .AND. .NOT.lquery )
371 $ info = -12
372 END IF
373*
374 IF( info.NE.0 ) THEN
375 CALL xerbla( 'CGELSS', -info )
376 RETURN
377 ELSE IF( lquery ) THEN
378 RETURN
379 END IF
380*
381* Quick return if possible
382*
383 IF( m.EQ.0 .OR. n.EQ.0 ) THEN
384 rank = 0
385 RETURN
386 END IF
387*
388* Get machine parameters
389*
390 eps = slamch( 'P' )
391 sfmin = slamch( 'S' )
392 smlnum = sfmin / eps
393 bignum = one / smlnum
394*
395* Scale A if max element outside range [SMLNUM,BIGNUM]
396*
397 anrm = clange( 'M', m, n, a, lda, rwork )
398 iascl = 0
399 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
400*
401* Scale matrix norm up to SMLNUM
402*
403 CALL clascl( 'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
404 iascl = 1
405 ELSE IF( anrm.GT.bignum ) THEN
406*
407* Scale matrix norm down to BIGNUM
408*
409 CALL clascl( 'G', 0, 0, anrm, bignum, m, n, a, lda, info )
410 iascl = 2
411 ELSE IF( anrm.EQ.zero ) THEN
412*
413* Matrix all zero. Return zero solution.
414*
415 CALL claset( 'F', max( m, n ), nrhs, czero, czero, b, ldb )
416 CALL slaset( 'F', minmn, 1, zero, zero, s, minmn )
417 rank = 0
418 GO TO 70
419 END IF
420*
421* Scale B if max element outside range [SMLNUM,BIGNUM]
422*
423 bnrm = clange( 'M', m, nrhs, b, ldb, rwork )
424 ibscl = 0
425 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
426*
427* Scale matrix norm up to SMLNUM
428*
429 CALL clascl( 'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb,
430 $ info )
431 ibscl = 1
432 ELSE IF( bnrm.GT.bignum ) THEN
433*
434* Scale matrix norm down to BIGNUM
435*
436 CALL clascl( 'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb,
437 $ info )
438 ibscl = 2
439 END IF
440*
441* Overdetermined case
442*
443 IF( m.GE.n ) THEN
444*
445* Path 1 - overdetermined or exactly determined
446*
447 mm = m
448 IF( m.GE.mnthr ) THEN
449*
450* Path 1a - overdetermined, with many more rows than columns
451*
452 mm = n
453 itau = 1
454 iwork = itau + n
455*
456* Compute A=Q*R
457* (CWorkspace: need 2*N, prefer N+N*NB)
458* (RWorkspace: none)
459*
460 CALL cgeqrf( m, n, a, lda, work( itau ), work( iwork ),
461 $ lwork-iwork+1, info )
462*
463* Multiply B by transpose(Q)
464* (CWorkspace: need N+NRHS, prefer N+NRHS*NB)
465* (RWorkspace: none)
466*
467 CALL cunmqr( 'L', 'C', m, nrhs, n, a, lda, work( itau ),
468 $ b,
469 $ ldb, work( iwork ), lwork-iwork+1, info )
470*
471* Zero out below R
472*
473 IF( n.GT.1 )
474 $ CALL claset( 'L', n-1, n-1, czero, czero, a( 2, 1 ),
475 $ lda )
476 END IF
477*
478 ie = 1
479 itauq = 1
480 itaup = itauq + n
481 iwork = itaup + n
482*
483* Bidiagonalize R in A
484* (CWorkspace: need 2*N+MM, prefer 2*N+(MM+N)*NB)
485* (RWorkspace: need N)
486*
487 CALL cgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
488 $ work( itaup ), work( iwork ), lwork-iwork+1,
489 $ info )
490*
491* Multiply B by transpose of left bidiagonalizing vectors of R
492* (CWorkspace: need 2*N+NRHS, prefer 2*N+NRHS*NB)
493* (RWorkspace: none)
494*
495 CALL cunmbr( 'Q', 'L', 'C', mm, nrhs, n, a, lda,
496 $ work( itauq ),
497 $ b, ldb, work( iwork ), lwork-iwork+1, info )
498*
499* Generate right bidiagonalizing vectors of R in A
500* (CWorkspace: need 3*N-1, prefer 2*N+(N-1)*NB)
501* (RWorkspace: none)
502*
503 CALL cungbr( 'P', n, n, n, a, lda, work( itaup ),
504 $ work( iwork ), lwork-iwork+1, info )
505 irwork = ie + n
506*
507* Perform bidiagonal QR iteration
508* multiply B by transpose of left singular vectors
509* compute right singular vectors in A
510* (CWorkspace: none)
511* (RWorkspace: need BDSPAC)
512*
513 CALL cbdsqr( 'U', n, n, 0, nrhs, s, rwork( ie ), a, lda,
514 $ dum,
515 $ 1, b, ldb, rwork( irwork ), info )
516 IF( info.NE.0 )
517 $ GO TO 70
518*
519* Multiply B by reciprocals of singular values
520*
521 thr = max( rcond*s( 1 ), sfmin )
522 IF( rcond.LT.zero )
523 $ thr = max( eps*s( 1 ), sfmin )
524 rank = 0
525 DO 10 i = 1, n
526 IF( s( i ).GT.thr ) THEN
527 CALL csrscl( nrhs, s( i ), b( i, 1 ), ldb )
528 rank = rank + 1
529 ELSE
530 CALL claset( 'F', 1, nrhs, czero, czero, b( i, 1 ),
531 $ ldb )
532 END IF
533 10 CONTINUE
534*
535* Multiply B by right singular vectors
536* (CWorkspace: need N, prefer N*NRHS)
537* (RWorkspace: none)
538*
539 IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 ) THEN
540 CALL cgemm( 'C', 'N', n, nrhs, n, cone, a, lda, b, ldb,
541 $ czero, work, ldb )
542 CALL clacpy( 'G', n, nrhs, work, ldb, b, ldb )
543 ELSE IF( nrhs.GT.1 ) THEN
544 chunk = lwork / n
545 DO 20 i = 1, nrhs, chunk
546 bl = min( nrhs-i+1, chunk )
547 CALL cgemm( 'C', 'N', n, bl, n, cone, a, lda, b( 1,
548 $ i ),
549 $ ldb, czero, work, n )
550 CALL clacpy( 'G', n, bl, work, n, b( 1, i ), ldb )
551 20 CONTINUE
552 ELSE IF( nrhs.EQ.1 ) THEN
553 CALL cgemv( 'C', n, n, cone, a, lda, b, 1, czero, work,
554 $ 1 )
555 CALL ccopy( n, work, 1, b, 1 )
556 END IF
557*
558 ELSE IF( n.GE.mnthr .AND. lwork.GE.3*m+m*m+max( m, nrhs, n-2*m ) )
559 $ THEN
560*
561* Underdetermined case, M much less than N
562*
563* Path 2a - underdetermined, with many more columns than rows
564* and sufficient workspace for an efficient algorithm
565*
566 ldwork = m
567 IF( lwork.GE.3*m+m*lda+max( m, nrhs, n-2*m ) )
568 $ ldwork = lda
569 itau = 1
570 iwork = m + 1
571*
572* Compute A=L*Q
573* (CWorkspace: need 2*M, prefer M+M*NB)
574* (RWorkspace: none)
575*
576 CALL cgelqf( m, n, a, lda, work( itau ), work( iwork ),
577 $ lwork-iwork+1, info )
578 il = iwork
579*
580* Copy L to WORK(IL), zeroing out above it
581*
582 CALL clacpy( 'L', m, m, a, lda, work( il ), ldwork )
583 CALL claset( 'U', m-1, m-1, czero, czero, work( il+ldwork ),
584 $ ldwork )
585 ie = 1
586 itauq = il + ldwork*m
587 itaup = itauq + m
588 iwork = itaup + m
589*
590* Bidiagonalize L in WORK(IL)
591* (CWorkspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
592* (RWorkspace: need M)
593*
594 CALL cgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
595 $ work( itauq ), work( itaup ), work( iwork ),
596 $ lwork-iwork+1, info )
597*
598* Multiply B by transpose of left bidiagonalizing vectors of L
599* (CWorkspace: need M*M+3*M+NRHS, prefer M*M+3*M+NRHS*NB)
600* (RWorkspace: none)
601*
602 CALL cunmbr( 'Q', 'L', 'C', m, nrhs, m, work( il ), ldwork,
603 $ work( itauq ), b, ldb, work( iwork ),
604 $ lwork-iwork+1, info )
605*
606* Generate right bidiagonalizing vectors of R in WORK(IL)
607* (CWorkspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
608* (RWorkspace: none)
609*
610 CALL cungbr( 'P', m, m, m, work( il ), ldwork,
611 $ work( itaup ),
612 $ work( iwork ), lwork-iwork+1, info )
613 irwork = ie + m
614*
615* Perform bidiagonal QR iteration, computing right singular
616* vectors of L in WORK(IL) and multiplying B by transpose of
617* left singular vectors
618* (CWorkspace: need M*M)
619* (RWorkspace: need BDSPAC)
620*
621 CALL cbdsqr( 'U', m, m, 0, nrhs, s, rwork( ie ), work( il ),
622 $ ldwork, a, lda, b, ldb, rwork( irwork ), info )
623 IF( info.NE.0 )
624 $ GO TO 70
625*
626* Multiply B by reciprocals of singular values
627*
628 thr = max( rcond*s( 1 ), sfmin )
629 IF( rcond.LT.zero )
630 $ thr = max( eps*s( 1 ), sfmin )
631 rank = 0
632 DO 30 i = 1, m
633 IF( s( i ).GT.thr ) THEN
634 CALL csrscl( nrhs, s( i ), b( i, 1 ), ldb )
635 rank = rank + 1
636 ELSE
637 CALL claset( 'F', 1, nrhs, czero, czero, b( i, 1 ),
638 $ ldb )
639 END IF
640 30 CONTINUE
641 iwork = il + m*ldwork
642*
643* Multiply B by right singular vectors of L in WORK(IL)
644* (CWorkspace: need M*M+2*M, prefer M*M+M+M*NRHS)
645* (RWorkspace: none)
646*
647 IF( lwork.GE.ldb*nrhs+iwork-1 .AND. nrhs.GT.1 ) THEN
648 CALL cgemm( 'C', 'N', m, nrhs, m, cone, work( il ),
649 $ ldwork,
650 $ b, ldb, czero, work( iwork ), ldb )
651 CALL clacpy( 'G', m, nrhs, work( iwork ), ldb, b, ldb )
652 ELSE IF( nrhs.GT.1 ) THEN
653 chunk = ( lwork-iwork+1 ) / m
654 DO 40 i = 1, nrhs, chunk
655 bl = min( nrhs-i+1, chunk )
656 CALL cgemm( 'C', 'N', m, bl, m, cone, work( il ),
657 $ ldwork,
658 $ b( 1, i ), ldb, czero, work( iwork ), m )
659 CALL clacpy( 'G', m, bl, work( iwork ), m, b( 1, i ),
660 $ ldb )
661 40 CONTINUE
662 ELSE IF( nrhs.EQ.1 ) THEN
663 CALL cgemv( 'C', m, m, cone, work( il ), ldwork, b( 1,
664 $ 1 ), 1, czero, work( iwork ), 1 )
665 CALL ccopy( m, work( iwork ), 1, b( 1, 1 ), 1 )
666 END IF
667*
668* Zero out below first M rows of B
669*
670 CALL claset( 'F', n-m, nrhs, czero, czero, b( m+1, 1 ),
671 $ ldb )
672 iwork = itau + m
673*
674* Multiply transpose(Q) by B
675* (CWorkspace: need M+NRHS, prefer M+NHRS*NB)
676* (RWorkspace: none)
677*
678 CALL cunmlq( 'L', 'C', n, nrhs, m, a, lda, work( itau ), b,
679 $ ldb, work( iwork ), lwork-iwork+1, info )
680*
681 ELSE
682*
683* Path 2 - remaining underdetermined cases
684*
685 ie = 1
686 itauq = 1
687 itaup = itauq + m
688 iwork = itaup + m
689*
690* Bidiagonalize A
691* (CWorkspace: need 3*M, prefer 2*M+(M+N)*NB)
692* (RWorkspace: need N)
693*
694 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
695 $ work( itaup ), work( iwork ), lwork-iwork+1,
696 $ info )
697*
698* Multiply B by transpose of left bidiagonalizing vectors
699* (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)
700* (RWorkspace: none)
701*
702 CALL cunmbr( 'Q', 'L', 'C', m, nrhs, n, a, lda,
703 $ work( itauq ),
704 $ b, ldb, work( iwork ), lwork-iwork+1, info )
705*
706* Generate right bidiagonalizing vectors in A
707* (CWorkspace: need 3*M, prefer 2*M+M*NB)
708* (RWorkspace: none)
709*
710 CALL cungbr( 'P', m, n, m, a, lda, work( itaup ),
711 $ work( iwork ), lwork-iwork+1, info )
712 irwork = ie + m
713*
714* Perform bidiagonal QR iteration,
715* computing right singular vectors of A in A and
716* multiplying B by transpose of left singular vectors
717* (CWorkspace: none)
718* (RWorkspace: need BDSPAC)
719*
720 CALL cbdsqr( 'L', m, n, 0, nrhs, s, rwork( ie ), a, lda,
721 $ dum,
722 $ 1, b, ldb, rwork( irwork ), info )
723 IF( info.NE.0 )
724 $ GO TO 70
725*
726* Multiply B by reciprocals of singular values
727*
728 thr = max( rcond*s( 1 ), sfmin )
729 IF( rcond.LT.zero )
730 $ thr = max( eps*s( 1 ), sfmin )
731 rank = 0
732 DO 50 i = 1, m
733 IF( s( i ).GT.thr ) THEN
734 CALL csrscl( nrhs, s( i ), b( i, 1 ), ldb )
735 rank = rank + 1
736 ELSE
737 CALL claset( 'F', 1, nrhs, czero, czero, b( i, 1 ),
738 $ ldb )
739 END IF
740 50 CONTINUE
741*
742* Multiply B by right singular vectors of A
743* (CWorkspace: need N, prefer N*NRHS)
744* (RWorkspace: none)
745*
746 IF( lwork.GE.ldb*nrhs .AND. nrhs.GT.1 ) THEN
747 CALL cgemm( 'C', 'N', n, nrhs, m, cone, a, lda, b, ldb,
748 $ czero, work, ldb )
749 CALL clacpy( 'G', n, nrhs, work, ldb, b, ldb )
750 ELSE IF( nrhs.GT.1 ) THEN
751 chunk = lwork / n
752 DO 60 i = 1, nrhs, chunk
753 bl = min( nrhs-i+1, chunk )
754 CALL cgemm( 'C', 'N', n, bl, m, cone, a, lda, b( 1,
755 $ i ),
756 $ ldb, czero, work, n )
757 CALL clacpy( 'F', n, bl, work, n, b( 1, i ), ldb )
758 60 CONTINUE
759 ELSE IF( nrhs.EQ.1 ) THEN
760 CALL cgemv( 'C', m, n, cone, a, lda, b, 1, czero, work,
761 $ 1 )
762 CALL ccopy( n, work, 1, b, 1 )
763 END IF
764 END IF
765*
766* Undo scaling
767*
768 IF( iascl.EQ.1 ) THEN
769 CALL clascl( 'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb,
770 $ info )
771 CALL slascl( 'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
772 $ info )
773 ELSE IF( iascl.EQ.2 ) THEN
774 CALL clascl( 'G', 0, 0, anrm, bignum, n, nrhs, b, ldb,
775 $ info )
776 CALL slascl( 'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
777 $ info )
778 END IF
779 IF( ibscl.EQ.1 ) THEN
780 CALL clascl( 'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb,
781 $ info )
782 ELSE IF( ibscl.EQ.2 ) THEN
783 CALL clascl( 'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb,
784 $ info )
785 END IF
786 70 CONTINUE
787 work( 1 ) = sroundup_lwork(maxwrk)
788 RETURN
789*
790* End of CGELSS
791*
792 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine cbdsqr(uplo, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, rwork, info)
CBDSQR
Definition cbdsqr.f:233
subroutine ccopy(n, cx, incx, cy, incy)
CCOPY
Definition ccopy.f:81
subroutine cgebrd(m, n, a, lda, d, e, tauq, taup, work, lwork, info)
CGEBRD
Definition cgebrd.f:205
subroutine cgelqf(m, n, a, lda, tau, work, lwork, info)
CGELQF
Definition cgelqf.f:142
subroutine cgelss(m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, rwork, info)
CGELSS solves overdetermined or underdetermined systems for GE matrices
Definition cgelss.f:176
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
Definition cgemm.f:188
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
Definition cgemv.f:160
subroutine cgeqrf(m, n, a, lda, tau, work, lwork, info)
CGEQRF
Definition cgeqrf.f:144
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
Definition clacpy.f:101
subroutine clascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
CLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition clascl.f:142
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
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition claset.f:104
subroutine csrscl(n, sa, sx, incx)
CSRSCL multiplies a vector by the reciprocal of a real scalar.
Definition csrscl.f:82
subroutine cungbr(vect, m, n, k, a, lda, tau, work, lwork, info)
CUNGBR
Definition cungbr.f:156
subroutine cunmbr(vect, side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMBR
Definition cunmbr.f:195
subroutine cunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMLQ
Definition cunmlq.f:166
subroutine cunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
CUNMQR
Definition cunmqr.f:166