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