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