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