LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
cgelsd.f
Go to the documentation of this file.
1*> \brief <b> CGELSD computes the minimum-norm solution to a linear least squares problem 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 CGELSD + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgelsd.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgelsd.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgelsd.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE CGELSD( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
20* WORK, LWORK, RWORK, IWORK, INFO )
21*
22* .. Scalar Arguments ..
23* INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
24* REAL RCOND
25* ..
26* .. Array Arguments ..
27* INTEGER IWORK( * )
28* REAL RWORK( * ), S( * )
29* COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
30* ..
31*
32*
33*> \par Purpose:
34* =============
35*>
36*> \verbatim
37*>
38*> CGELSD computes the minimum-norm solution to a real linear least
39*> squares problem:
40*> minimize 2-norm(| b - A*x |)
41*> using the singular value decomposition (SVD) of A. A is an M-by-N
42*> matrix which may be rank-deficient.
43*>
44*> Several right hand side vectors b and solution vectors x can be
45*> handled in a single call; they are stored as the columns of the
46*> M-by-NRHS right hand side matrix B and the N-by-NRHS solution
47*> matrix X.
48*>
49*> The problem is solved in three steps:
50*> (1) Reduce the coefficient matrix A to bidiagonal form with
51*> Householder transformations, reducing the original problem
52*> into a "bidiagonal least squares problem" (BLS)
53*> (2) Solve the BLS using a divide and conquer approach.
54*> (3) Apply back all the Householder transformations to solve
55*> the original least squares problem.
56*>
57*> The effective rank of A is determined by treating as zero those
58*> singular values which are less than RCOND times the largest singular
59*> value.
60*>
61*> \endverbatim
62*
63* Arguments:
64* ==========
65*
66*> \param[in] M
67*> \verbatim
68*> M is INTEGER
69*> The number of rows of the matrix A. M >= 0.
70*> \endverbatim
71*>
72*> \param[in] N
73*> \verbatim
74*> N is INTEGER
75*> The number of columns of the matrix A. N >= 0.
76*> \endverbatim
77*>
78*> \param[in] NRHS
79*> \verbatim
80*> NRHS is INTEGER
81*> The number of right hand sides, i.e., the number of columns
82*> of the matrices B and X. NRHS >= 0.
83*> \endverbatim
84*>
85*> \param[in,out] A
86*> \verbatim
87*> A is COMPLEX array, dimension (LDA,N)
88*> On entry, the M-by-N matrix A.
89*> On exit, A has been destroyed.
90*> \endverbatim
91*>
92*> \param[in] LDA
93*> \verbatim
94*> LDA is INTEGER
95*> The leading dimension of the array A. LDA >= max(1,M).
96*> \endverbatim
97*>
98*> \param[in,out] B
99*> \verbatim
100*> B is COMPLEX array, dimension (LDB,NRHS)
101*> On entry, the M-by-NRHS right hand side matrix B.
102*> On exit, B is overwritten by the N-by-NRHS solution matrix X.
103*> If m >= n and RANK = n, the residual sum-of-squares for
104*> the solution in the i-th column is given by the sum of
105*> squares of the modulus of elements n+1:m in that column.
106*> \endverbatim
107*>
108*> \param[in] LDB
109*> \verbatim
110*> LDB is INTEGER
111*> The leading dimension of the array B. LDB >= max(1,M,N).
112*> \endverbatim
113*>
114*> \param[out] S
115*> \verbatim
116*> S is REAL array, dimension (min(M,N))
117*> The singular values of A in decreasing order.
118*> The condition number of A in the 2-norm = S(1)/S(min(m,n)).
119*> \endverbatim
120*>
121*> \param[in] RCOND
122*> \verbatim
123*> RCOND is REAL
124*> RCOND is used to determine the effective rank of A.
125*> Singular values S(i) <= RCOND*S(1) are treated as zero.
126*> If RCOND < 0, machine precision is used instead.
127*> \endverbatim
128*>
129*> \param[out] RANK
130*> \verbatim
131*> RANK is INTEGER
132*> The effective rank of A, i.e., the number of singular values
133*> which are greater than RCOND*S(1).
134*> \endverbatim
135*>
136*> \param[out] WORK
137*> \verbatim
138*> WORK is COMPLEX array, dimension (MAX(1,LWORK))
139*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
140*> \endverbatim
141*>
142*> \param[in] LWORK
143*> \verbatim
144*> LWORK is INTEGER
145*> The dimension of the array WORK. LWORK must be at least 1.
146*> The exact minimum amount of workspace needed depends on M,
147*> N and NRHS. As long as LWORK is at least
148*> 2 * N + N * NRHS
149*> if M is greater than or equal to N or
150*> 2 * M + M * NRHS
151*> if M is less than N, the code will execute correctly.
152*> For good performance, LWORK should generally be larger.
153*>
154*> If LWORK = -1, then a workspace query is assumed; the routine
155*> only calculates the optimal size of the array WORK and the
156*> minimum sizes of the arrays RWORK and IWORK, and returns
157*> these values as the first entries of the WORK, RWORK and
158*> IWORK arrays, and no error message related to LWORK is issued
159*> by XERBLA.
160*> \endverbatim
161*>
162*> \param[out] RWORK
163*> \verbatim
164*> RWORK is REAL array, dimension (MAX(1,LRWORK))
165*> LRWORK >=
166*> 10*N + 2*N*SMLSIZ + 8*N*NLVL + 3*SMLSIZ*NRHS +
167*> MAX( (SMLSIZ+1)**2, N*(1+NRHS) + 2*NRHS )
168*> if M is greater than or equal to N or
169*> 10*M + 2*M*SMLSIZ + 8*M*NLVL + 3*SMLSIZ*NRHS +
170*> MAX( (SMLSIZ+1)**2, N*(1+NRHS) + 2*NRHS )
171*> if M is less than N, the code will execute correctly.
172*> SMLSIZ is returned by ILAENV and is equal to the maximum
173*> size of the subproblems at the bottom of the computation
174*> tree (usually about 25), and
175*> NLVL = MAX( 0, INT( LOG_2( MIN( M,N )/(SMLSIZ+1) ) ) + 1 )
176*> On exit, if INFO = 0, RWORK(1) returns the minimum LRWORK.
177*> \endverbatim
178*>
179*> \param[out] IWORK
180*> \verbatim
181*> IWORK is INTEGER array, dimension (MAX(1,LIWORK))
182*> LIWORK >= max(1, 3*MINMN*NLVL + 11*MINMN),
183*> where MINMN = MIN( M,N ).
184*> On exit, if INFO = 0, IWORK(1) returns the minimum LIWORK.
185*> \endverbatim
186*>
187*> \param[out] INFO
188*> \verbatim
189*> INFO is INTEGER
190*> = 0: successful exit
191*> < 0: if INFO = -i, the i-th argument had an illegal value.
192*> > 0: the algorithm for computing the SVD failed to converge;
193*> if INFO = i, i off-diagonal elements of an intermediate
194*> bidiagonal form did not converge to zero.
195*> \endverbatim
196*
197* Authors:
198* ========
199*
200*> \author Univ. of Tennessee
201*> \author Univ. of California Berkeley
202*> \author Univ. of Colorado Denver
203*> \author NAG Ltd.
204*
205*> \ingroup gelsd
206*
207*> \par Contributors:
208* ==================
209*>
210*> Ming Gu and Ren-Cang Li, Computer Science Division, University of
211*> California at Berkeley, USA \n
212*> Osni Marques, LBNL/NERSC, USA \n
213*
214* =====================================================================
215 SUBROUTINE cgelsd( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK,
216 $ WORK, LWORK, RWORK, IWORK, INFO )
217*
218* -- LAPACK driver routine --
219* -- LAPACK is a software package provided by Univ. of Tennessee, --
220* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
221*
222* .. Scalar Arguments ..
223 INTEGER INFO, LDA, LDB, LWORK, M, N, NRHS, RANK
224 REAL RCOND
225* ..
226* .. Array Arguments ..
227 INTEGER IWORK( * )
228 REAL RWORK( * ), S( * )
229 COMPLEX A( LDA, * ), B( LDB, * ), WORK( * )
230* ..
231*
232* =====================================================================
233*
234* .. Parameters ..
235 REAL ZERO, ONE, TWO
236 parameter( zero = 0.0e+0, one = 1.0e+0, two = 2.0e+0 )
237 COMPLEX CZERO
238 parameter( czero = ( 0.0e+0, 0.0e+0 ) )
239* ..
240* .. Local Scalars ..
241 LOGICAL LQUERY
242 INTEGER IASCL, IBSCL, IE, IL, ITAU, ITAUP, ITAUQ,
243 $ ldwork, liwork, lrwork, maxmn, maxwrk, minmn,
244 $ minwrk, mm, mnthr, nlvl, nrwork, nwork, smlsiz
245 REAL ANRM, BIGNUM, BNRM, EPS, SFMIN, SMLNUM
246* ..
247* .. External Subroutines ..
248 EXTERNAL cgebrd, cgelqf, cgeqrf, clacpy,
250 $ cunmlq, cunmqr, slascl,
251 $ slaset, xerbla
252* ..
253* .. External Functions ..
254 INTEGER ILAENV
255 REAL CLANGE, SLAMCH, SROUNDUP_LWORK
256 EXTERNAL clange, slamch, ilaenv,
257 $ sroundup_lwork
258* ..
259* .. Intrinsic Functions ..
260 INTRINSIC int, log, max, min, real
261* ..
262* .. Executable Statements ..
263*
264* Test the input arguments.
265*
266 info = 0
267 minmn = min( m, n )
268 maxmn = max( m, n )
269 lquery = ( lwork.EQ.-1 )
270 IF( m.LT.0 ) THEN
271 info = -1
272 ELSE IF( n.LT.0 ) THEN
273 info = -2
274 ELSE IF( nrhs.LT.0 ) THEN
275 info = -3
276 ELSE IF( lda.LT.max( 1, m ) ) THEN
277 info = -5
278 ELSE IF( ldb.LT.max( 1, maxmn ) ) THEN
279 info = -7
280 END IF
281*
282* Compute workspace.
283* (Note: Comments in the code beginning "Workspace:" describe the
284* minimal amount of workspace needed at that point in the code,
285* as well as the preferred amount for good performance.
286* NB refers to the optimal block size for the immediately
287* following subroutine, as returned by ILAENV.)
288*
289 IF( info.EQ.0 ) THEN
290 minwrk = 1
291 maxwrk = 1
292 liwork = 1
293 lrwork = 1
294 IF( minmn.GT.0 ) THEN
295 smlsiz = ilaenv( 9, 'CGELSD', ' ', 0, 0, 0, 0 )
296 mnthr = ilaenv( 6, 'CGELSD', ' ', m, n, nrhs, -1 )
297 nlvl = max( int( log( real( minmn ) / real( smlsiz + 1 ) ) /
298 $ log( two ) ) + 1, 0 )
299 liwork = 3*minmn*nlvl + 11*minmn
300 mm = m
301 IF( m.GE.n .AND. m.GE.mnthr ) THEN
302*
303* Path 1a - overdetermined, with many more rows than
304* columns.
305*
306 mm = n
307 maxwrk = max( maxwrk, n*ilaenv( 1, 'CGEQRF', ' ', m,
308 $ n,
309 $ -1, -1 ) )
310 maxwrk = max( maxwrk, nrhs*ilaenv( 1, 'CUNMQR', 'LC',
311 $ m,
312 $ nrhs, n, -1 ) )
313 END IF
314 IF( m.GE.n ) THEN
315*
316* Path 1 - overdetermined or exactly determined.
317*
318 lrwork = 10*n + 2*n*smlsiz + 8*n*nlvl + 3*smlsiz*nrhs +
319 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
320 maxwrk = max( maxwrk, 2*n + ( mm + n )*ilaenv( 1,
321 $ 'CGEBRD', ' ', mm, n, -1, -1 ) )
322 maxwrk = max( maxwrk, 2*n + nrhs*ilaenv( 1, 'CUNMBR',
323 $ 'QLC', mm, nrhs, n, -1 ) )
324 maxwrk = max( maxwrk, 2*n + ( n - 1 )*ilaenv( 1,
325 $ 'CUNMBR', 'PLN', n, nrhs, n, -1 ) )
326 maxwrk = max( maxwrk, 2*n + n*nrhs )
327 minwrk = max( 2*n + mm, 2*n + n*nrhs )
328 END IF
329 IF( n.GT.m ) THEN
330 lrwork = 10*m + 2*m*smlsiz + 8*m*nlvl + 3*smlsiz*nrhs +
331 $ max( (smlsiz+1)**2, n*(1+nrhs) + 2*nrhs )
332 IF( n.GE.mnthr ) THEN
333*
334* Path 2a - underdetermined, with many more columns
335* than rows.
336*
337 maxwrk = m + m*ilaenv( 1, 'CGELQF', ' ', m, n, -1,
338 $ -1 )
339 maxwrk = max( maxwrk, m*m + 4*m + 2*m*ilaenv( 1,
340 $ 'CGEBRD', ' ', m, m, -1, -1 ) )
341 maxwrk = max( maxwrk, m*m + 4*m + nrhs*ilaenv( 1,
342 $ 'CUNMBR', 'QLC', m, nrhs, m, -1 ) )
343 maxwrk = max( maxwrk,
344 $ m*m + 4*m + ( m - 1 )*ilaenv( 1,
345 $ 'CUNMLQ', 'LC', n, nrhs, m, -1 ) )
346 IF( nrhs.GT.1 ) THEN
347 maxwrk = max( maxwrk, m*m + m + m*nrhs )
348 ELSE
349 maxwrk = max( maxwrk, m*m + 2*m )
350 END IF
351 maxwrk = max( maxwrk, m*m + 4*m + m*nrhs )
352! XXX: Ensure the Path 2a case below is triggered. The workspace
353! calculation should use queries for all routines eventually.
354 maxwrk = max( maxwrk,
355 $ 4*m+m*m+max( m, 2*m-4, nrhs, n-3*m ) )
356 ELSE
357*
358* Path 2 - underdetermined.
359*
360 maxwrk = 2*m + ( n + m )*ilaenv( 1, 'CGEBRD', ' ',
361 $ m,
362 $ n, -1, -1 )
363 maxwrk = max( maxwrk, 2*m + nrhs*ilaenv( 1,
364 $ 'CUNMBR',
365 $ 'QLC', m, nrhs, m, -1 ) )
366 maxwrk = max( maxwrk, 2*m + m*ilaenv( 1, 'CUNMBR',
367 $ 'PLN', n, nrhs, m, -1 ) )
368 maxwrk = max( maxwrk, 2*m + m*nrhs )
369 END IF
370 minwrk = max( 2*m + n, 2*m + m*nrhs )
371 END IF
372 END IF
373 minwrk = min( minwrk, maxwrk )
374 work( 1 ) = sroundup_lwork(maxwrk)
375 iwork( 1 ) = liwork
376 rwork( 1 ) = real( lrwork )
377*
378 IF( lwork.LT.minwrk .AND. .NOT.lquery ) THEN
379 info = -12
380 END IF
381 END IF
382*
383 IF( info.NE.0 ) THEN
384 CALL xerbla( 'CGELSD', -info )
385 RETURN
386 ELSE IF( lquery ) THEN
387 RETURN
388 END IF
389*
390* Quick return if possible.
391*
392 IF( m.EQ.0 .OR. n.EQ.0 ) THEN
393 rank = 0
394 RETURN
395 END IF
396*
397* Get machine parameters.
398*
399 eps = slamch( 'P' )
400 sfmin = slamch( 'S' )
401 smlnum = sfmin / eps
402 bignum = one / smlnum
403*
404* Scale A if max entry outside range [SMLNUM,BIGNUM].
405*
406 anrm = clange( 'M', m, n, a, lda, rwork )
407 iascl = 0
408 IF( anrm.GT.zero .AND. anrm.LT.smlnum ) THEN
409*
410* Scale matrix norm up to SMLNUM
411*
412 CALL clascl( 'G', 0, 0, anrm, smlnum, m, n, a, lda, info )
413 iascl = 1
414 ELSE IF( anrm.GT.bignum ) THEN
415*
416* Scale matrix norm down to BIGNUM.
417*
418 CALL clascl( 'G', 0, 0, anrm, bignum, m, n, a, lda, info )
419 iascl = 2
420 ELSE IF( anrm.EQ.zero ) THEN
421*
422* Matrix all zero. Return zero solution.
423*
424 CALL claset( 'F', max( m, n ), nrhs, czero, czero, b, ldb )
425 CALL slaset( 'F', minmn, 1, zero, zero, s, 1 )
426 rank = 0
427 GO TO 10
428 END IF
429*
430* Scale B if max entry outside range [SMLNUM,BIGNUM].
431*
432 bnrm = clange( 'M', m, nrhs, b, ldb, rwork )
433 ibscl = 0
434 IF( bnrm.GT.zero .AND. bnrm.LT.smlnum ) THEN
435*
436* Scale matrix norm up to SMLNUM.
437*
438 CALL clascl( 'G', 0, 0, bnrm, smlnum, m, nrhs, b, ldb,
439 $ info )
440 ibscl = 1
441 ELSE IF( bnrm.GT.bignum ) THEN
442*
443* Scale matrix norm down to BIGNUM.
444*
445 CALL clascl( 'G', 0, 0, bnrm, bignum, m, nrhs, b, ldb,
446 $ info )
447 ibscl = 2
448 END IF
449*
450* If M < N make sure B(M+1:N,:) = 0
451*
452 IF( m.LT.n )
453 $ CALL claset( 'F', n-m, nrhs, czero, czero, b( m+1, 1 ),
454 $ ldb )
455*
456* Overdetermined case.
457*
458 IF( m.GE.n ) THEN
459*
460* Path 1 - overdetermined or exactly determined.
461*
462 mm = m
463 IF( m.GE.mnthr ) THEN
464*
465* Path 1a - overdetermined, with many more rows than columns
466*
467 mm = n
468 itau = 1
469 nwork = itau + n
470*
471* Compute A=Q*R.
472* (RWorkspace: need N)
473* (CWorkspace: need N, prefer N*NB)
474*
475 CALL cgeqrf( m, n, a, lda, work( itau ), work( nwork ),
476 $ lwork-nwork+1, info )
477*
478* Multiply B by transpose(Q).
479* (RWorkspace: need N)
480* (CWorkspace: need NRHS, prefer NRHS*NB)
481*
482 CALL cunmqr( 'L', 'C', m, nrhs, n, a, lda, work( itau ),
483 $ b,
484 $ ldb, work( nwork ), lwork-nwork+1, info )
485*
486* Zero out below R.
487*
488 IF( n.GT.1 ) THEN
489 CALL claset( 'L', n-1, n-1, czero, czero, a( 2, 1 ),
490 $ lda )
491 END IF
492 END IF
493*
494 itauq = 1
495 itaup = itauq + n
496 nwork = itaup + n
497 ie = 1
498 nrwork = ie + n
499*
500* Bidiagonalize R in A.
501* (RWorkspace: need N)
502* (CWorkspace: need 2*N+MM, prefer 2*N+(MM+N)*NB)
503*
504 CALL cgebrd( mm, n, a, lda, s, rwork( ie ), work( itauq ),
505 $ work( itaup ), work( nwork ), lwork-nwork+1,
506 $ info )
507*
508* Multiply B by transpose of left bidiagonalizing vectors of R.
509* (CWorkspace: need 2*N+NRHS, prefer 2*N+NRHS*NB)
510*
511 CALL cunmbr( 'Q', 'L', 'C', mm, nrhs, n, a, lda,
512 $ work( itauq ),
513 $ b, ldb, work( nwork ), lwork-nwork+1, info )
514*
515* Solve the bidiagonal least squares problem.
516*
517 CALL clalsd( 'U', smlsiz, n, nrhs, s, rwork( ie ), b, ldb,
518 $ rcond, rank, work( nwork ), rwork( nrwork ),
519 $ iwork, info )
520 IF( info.NE.0 ) THEN
521 GO TO 10
522 END IF
523*
524* Multiply B by right bidiagonalizing vectors of R.
525*
526 CALL cunmbr( 'P', 'L', 'N', n, nrhs, n, a, lda,
527 $ work( itaup ),
528 $ b, ldb, work( nwork ), lwork-nwork+1, info )
529*
530 ELSE IF( n.GE.mnthr .AND. lwork.GE.4*m+m*m+
531 $ max( m, 2*m-4, nrhs, n-3*m ) ) THEN
532*
533* Path 2a - underdetermined, with many more columns than rows
534* and sufficient workspace for an efficient algorithm.
535*
536 ldwork = m
537 IF( lwork.GE.max( 4*m+m*lda+max( m, 2*m-4, nrhs, n-3*m ),
538 $ m*lda+m+m*nrhs ) )ldwork = lda
539 itau = 1
540 nwork = m + 1
541*
542* Compute A=L*Q.
543* (CWorkspace: need 2*M, prefer M+M*NB)
544*
545 CALL cgelqf( m, n, a, lda, work( itau ), work( nwork ),
546 $ lwork-nwork+1, info )
547 il = nwork
548*
549* Copy L to WORK(IL), zeroing out above its diagonal.
550*
551 CALL clacpy( 'L', m, m, a, lda, work( il ), ldwork )
552 CALL claset( 'U', m-1, m-1, czero, czero, work( il+ldwork ),
553 $ ldwork )
554 itauq = il + ldwork*m
555 itaup = itauq + m
556 nwork = itaup + m
557 ie = 1
558 nrwork = ie + m
559*
560* Bidiagonalize L in WORK(IL).
561* (RWorkspace: need M)
562* (CWorkspace: need M*M+4*M, prefer M*M+4*M+2*M*NB)
563*
564 CALL cgebrd( m, m, work( il ), ldwork, s, rwork( ie ),
565 $ work( itauq ), work( itaup ), work( nwork ),
566 $ lwork-nwork+1, info )
567*
568* Multiply B by transpose of left bidiagonalizing vectors of L.
569* (CWorkspace: need M*M+4*M+NRHS, prefer M*M+4*M+NRHS*NB)
570*
571 CALL cunmbr( 'Q', 'L', 'C', m, nrhs, m, work( il ), ldwork,
572 $ work( itauq ), b, ldb, work( nwork ),
573 $ lwork-nwork+1, info )
574*
575* Solve the bidiagonal least squares problem.
576*
577 CALL clalsd( 'U', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
578 $ rcond, rank, work( nwork ), rwork( nrwork ),
579 $ iwork, info )
580 IF( info.NE.0 ) THEN
581 GO TO 10
582 END IF
583*
584* Multiply B by right bidiagonalizing vectors of L.
585*
586 CALL cunmbr( 'P', 'L', 'N', m, nrhs, m, work( il ), ldwork,
587 $ work( itaup ), b, ldb, work( nwork ),
588 $ lwork-nwork+1, info )
589*
590* Zero out below first M rows of B.
591*
592 CALL claset( 'F', n-m, nrhs, czero, czero, b( m+1, 1 ),
593 $ ldb )
594 nwork = itau + m
595*
596* Multiply transpose(Q) by B.
597* (CWorkspace: need NRHS, prefer NRHS*NB)
598*
599 CALL cunmlq( 'L', 'C', n, nrhs, m, a, lda, work( itau ), b,
600 $ ldb, work( nwork ), lwork-nwork+1, info )
601*
602 ELSE
603*
604* Path 2 - remaining underdetermined cases.
605*
606 itauq = 1
607 itaup = itauq + m
608 nwork = itaup + m
609 ie = 1
610 nrwork = ie + m
611*
612* Bidiagonalize A.
613* (RWorkspace: need M)
614* (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
615*
616 CALL cgebrd( m, n, a, lda, s, rwork( ie ), work( itauq ),
617 $ work( itaup ), work( nwork ), lwork-nwork+1,
618 $ info )
619*
620* Multiply B by transpose of left bidiagonalizing vectors.
621* (CWorkspace: need 2*M+NRHS, prefer 2*M+NRHS*NB)
622*
623 CALL cunmbr( 'Q', 'L', 'C', m, nrhs, n, a, lda,
624 $ work( itauq ),
625 $ b, ldb, work( nwork ), lwork-nwork+1, info )
626*
627* Solve the bidiagonal least squares problem.
628*
629 CALL clalsd( 'L', smlsiz, m, nrhs, s, rwork( ie ), b, ldb,
630 $ rcond, rank, work( nwork ), rwork( nrwork ),
631 $ iwork, info )
632 IF( info.NE.0 ) THEN
633 GO TO 10
634 END IF
635*
636* Multiply B by right bidiagonalizing vectors of A.
637*
638 CALL cunmbr( 'P', 'L', 'N', n, nrhs, m, a, lda,
639 $ work( itaup ),
640 $ b, ldb, work( nwork ), lwork-nwork+1, info )
641*
642 END IF
643*
644* Undo scaling.
645*
646 IF( iascl.EQ.1 ) THEN
647 CALL clascl( 'G', 0, 0, anrm, smlnum, n, nrhs, b, ldb,
648 $ info )
649 CALL slascl( 'G', 0, 0, smlnum, anrm, minmn, 1, s, minmn,
650 $ info )
651 ELSE IF( iascl.EQ.2 ) THEN
652 CALL clascl( 'G', 0, 0, anrm, bignum, n, nrhs, b, ldb,
653 $ info )
654 CALL slascl( 'G', 0, 0, bignum, anrm, minmn, 1, s, minmn,
655 $ info )
656 END IF
657 IF( ibscl.EQ.1 ) THEN
658 CALL clascl( 'G', 0, 0, smlnum, bnrm, n, nrhs, b, ldb,
659 $ info )
660 ELSE IF( ibscl.EQ.2 ) THEN
661 CALL clascl( 'G', 0, 0, bignum, bnrm, n, nrhs, b, ldb,
662 $ info )
663 END IF
664*
665 10 CONTINUE
666 work( 1 ) = sroundup_lwork(maxwrk)
667 iwork( 1 ) = liwork
668 rwork( 1 ) = real( lrwork )
669 RETURN
670*
671* End of CGELSD
672*
673 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
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 cgelsd(m, n, nrhs, a, lda, b, ldb, s, rcond, rank, work, lwork, rwork, iwork, info)
CGELSD computes the minimum-norm solution to a linear least squares problem for GE matrices
Definition cgelsd.f:217
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 clalsd(uplo, smlsiz, n, nrhs, d, e, b, ldb, rcond, rank, work, rwork, iwork, info)
CLALSD uses the singular value decomposition of A to solve the least squares problem.
Definition clalsd.f:178
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 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