LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches

◆ dlalsd()

subroutine dlalsd ( character uplo,
integer smlsiz,
integer n,
integer nrhs,
double precision, dimension( * ) d,
double precision, dimension( * ) e,
double precision, dimension( ldb, * ) b,
integer ldb,
double precision rcond,
integer rank,
double precision, dimension( * ) work,
integer, dimension( * ) iwork,
integer info )

DLALSD uses the singular value decomposition of A to solve the least squares problem.

Download DLALSD + dependencies [TGZ] [ZIP] [TXT]

Purpose:
!>
!> DLALSD uses the singular value decomposition of A to solve the least
!> squares problem of finding X to minimize the Euclidean norm of each
!> column of A*X-B, where A is N-by-N upper bidiagonal, and X and B
!> are N-by-NRHS. The solution X overwrites B.
!>
!> The singular values of A smaller than RCOND times the largest
!> singular value are treated as zero in solving the least squares
!> problem; in this case a minimum norm solution is returned.
!> The actual singular values are returned in D in ascending order.
!>
!> 
Parameters
[in]UPLO
!>          UPLO is CHARACTER*1
!>         = 'U': D and E define an upper bidiagonal matrix.
!>         = 'L': D and E define a  lower bidiagonal matrix.
!> 
[in]SMLSIZ
!>          SMLSIZ is INTEGER
!>         The maximum size of the subproblems at the bottom of the
!>         computation tree.
!> 
[in]N
!>          N is INTEGER
!>         The dimension of the  bidiagonal matrix.  N >= 0.
!> 
[in]NRHS
!>          NRHS is INTEGER
!>         The number of columns of B. NRHS must be at least 1.
!> 
[in,out]D
!>          D is DOUBLE PRECISION array, dimension (N)
!>         On entry D contains the main diagonal of the bidiagonal
!>         matrix. On exit, if INFO = 0, D contains its singular values.
!> 
[in,out]E
!>          E is DOUBLE PRECISION array, dimension (N-1)
!>         Contains the super-diagonal entries of the bidiagonal matrix.
!>         On exit, E has been destroyed.
!> 
[in,out]B
!>          B is DOUBLE PRECISION array, dimension (LDB,NRHS)
!>         On input, B contains the right hand sides of the least
!>         squares problem. On output, B contains the solution X.
!> 
[in]LDB
!>          LDB is INTEGER
!>         The leading dimension of B in the calling subprogram.
!>         LDB must be at least max(1,N).
!> 
[in]RCOND
!>          RCOND is DOUBLE PRECISION
!>         The singular values of A less than or equal to RCOND times
!>         the largest singular value are treated as zero in solving
!>         the least squares problem. If RCOND is negative,
!>         machine precision is used instead.
!>         For example, if diag(S)*X=B were the least squares problem,
!>         where diag(S) is a diagonal matrix of singular values, the
!>         solution would be X(i) = B(i) / S(i) if S(i) is greater than
!>         RCOND*max(S), and X(i) = 0 if S(i) is less than or equal to
!>         RCOND*max(S).
!> 
[out]RANK
!>          RANK is INTEGER
!>         The number of singular values of A greater than RCOND times
!>         the largest singular value.
!> 
[out]WORK
!>          WORK is DOUBLE PRECISION array, dimension at least
!>         (9*N + 2*N*SMLSIZ + 8*N*NLVL + N*NRHS + (SMLSIZ+1)**2),
!>         where NLVL = max(0, INT(log_2 (N/(SMLSIZ+1))) + 1).
!> 
[out]IWORK
!>          IWORK is INTEGER array, dimension at least
!>         (3*N*NLVL + 11*N)
!> 
[out]INFO
!>          INFO is INTEGER
!>         = 0:  successful exit.
!>         < 0:  if INFO = -i, the i-th argument had an illegal value.
!>         > 0:  The algorithm failed to compute a singular value while
!>               working on the submatrix lying in rows and columns
!>               INFO/(N+1) through MOD(INFO,N+1).
!> 
Author
Univ. of Tennessee
Univ. of California Berkeley
Univ. of Colorado Denver
NAG Ltd.
Contributors:
Ming Gu and Ren-Cang Li, Computer Science Division, University of California at Berkeley, USA
Osni Marques, LBNL/NERSC, USA

Definition at line 169 of file dlalsd.f.

171*
172* -- LAPACK computational routine --
173* -- LAPACK is a software package provided by Univ. of Tennessee, --
174* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
175*
176* .. Scalar Arguments ..
177 CHARACTER UPLO
178 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
179 DOUBLE PRECISION RCOND
180* ..
181* .. Array Arguments ..
182 INTEGER IWORK( * )
183 DOUBLE PRECISION B( LDB, * ), D( * ), E( * ), WORK( * )
184* ..
185*
186* =====================================================================
187*
188* .. Parameters ..
189 DOUBLE PRECISION ZERO, ONE, TWO
190 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
191* ..
192* .. Local Scalars ..
193 INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
194 $ GIVPTR, I, ICMPQ1, ICMPQ2, IWK, J, K, NLVL,
195 $ NM1, NSIZE, NSUB, NWORK, PERM, POLES, S, SIZEI,
196 $ SMLSZP, SQRE, ST, ST1, U, VT, Z
197 DOUBLE PRECISION CS, EPS, ORGNRM, R, RCND, SN, TOL
198* ..
199* .. External Functions ..
200 INTEGER IDAMAX
201 DOUBLE PRECISION DLAMCH, DLANST
202 EXTERNAL idamax, dlamch, dlanst
203* ..
204* .. External Subroutines ..
205 EXTERNAL dcopy, dgemm, dlacpy, dlalsa, dlartg,
206 $ dlascl,
208* ..
209* .. Intrinsic Functions ..
210 INTRINSIC abs, dble, int, log, sign
211* ..
212* .. Executable Statements ..
213*
214* Test the input parameters.
215*
216 info = 0
217*
218 IF( n.LT.0 ) THEN
219 info = -3
220 ELSE IF( nrhs.LT.1 ) THEN
221 info = -4
222 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) ) THEN
223 info = -8
224 END IF
225 IF( info.NE.0 ) THEN
226 CALL xerbla( 'DLALSD', -info )
227 RETURN
228 END IF
229*
230 eps = dlamch( 'Epsilon' )
231*
232* Set up the tolerance.
233*
234 IF( ( rcond.LE.zero ) .OR. ( rcond.GE.one ) ) THEN
235 rcnd = eps
236 ELSE
237 rcnd = rcond
238 END IF
239*
240 rank = 0
241*
242* Quick return if possible.
243*
244 IF( n.EQ.0 ) THEN
245 RETURN
246 ELSE IF( n.EQ.1 ) THEN
247 IF( d( 1 ).EQ.zero ) THEN
248 CALL dlaset( 'A', 1, nrhs, zero, zero, b, ldb )
249 ELSE
250 rank = 1
251 CALL dlascl( 'G', 0, 0, d( 1 ), one, 1, nrhs, b, ldb,
252 $ info )
253 d( 1 ) = abs( d( 1 ) )
254 END IF
255 RETURN
256 END IF
257*
258* Rotate the matrix if it is lower bidiagonal.
259*
260 IF( uplo.EQ.'L' ) THEN
261 DO 10 i = 1, n - 1
262 CALL dlartg( d( i ), e( i ), cs, sn, r )
263 d( i ) = r
264 e( i ) = sn*d( i+1 )
265 d( i+1 ) = cs*d( i+1 )
266 IF( nrhs.EQ.1 ) THEN
267 CALL drot( 1, b( i, 1 ), 1, b( i+1, 1 ), 1, cs, sn )
268 ELSE
269 work( i*2-1 ) = cs
270 work( i*2 ) = sn
271 END IF
272 10 CONTINUE
273 IF( nrhs.GT.1 ) THEN
274 DO 30 i = 1, nrhs
275 DO 20 j = 1, n - 1
276 cs = work( j*2-1 )
277 sn = work( j*2 )
278 CALL drot( 1, b( j, i ), 1, b( j+1, i ), 1, cs,
279 $ sn )
280 20 CONTINUE
281 30 CONTINUE
282 END IF
283 END IF
284*
285* Scale.
286*
287 nm1 = n - 1
288 orgnrm = dlanst( 'M', n, d, e )
289 IF( orgnrm.EQ.zero ) THEN
290 CALL dlaset( 'A', n, nrhs, zero, zero, b, ldb )
291 RETURN
292 END IF
293*
294 CALL dlascl( 'G', 0, 0, orgnrm, one, n, 1, d, n, info )
295 CALL dlascl( 'G', 0, 0, orgnrm, one, nm1, 1, e, nm1, info )
296*
297* If N is smaller than the minimum divide size SMLSIZ, then solve
298* the problem with another solver.
299*
300 IF( n.LE.smlsiz ) THEN
301 nwork = 1 + n*n
302 CALL dlaset( 'A', n, n, zero, one, work, n )
303 CALL dlasdq( 'U', 0, n, n, 0, nrhs, d, e, work, n, work, n,
304 $ b,
305 $ ldb, work( nwork ), info )
306 IF( info.NE.0 ) THEN
307 RETURN
308 END IF
309 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
310 DO 40 i = 1, n
311 IF( d( i ).LE.tol ) THEN
312 CALL dlaset( 'A', 1, nrhs, zero, zero, b( i, 1 ),
313 $ ldb )
314 ELSE
315 CALL dlascl( 'G', 0, 0, d( i ), one, 1, nrhs, b( i,
316 $ 1 ),
317 $ ldb, info )
318 rank = rank + 1
319 END IF
320 40 CONTINUE
321 CALL dgemm( 'T', 'N', n, nrhs, n, one, work, n, b, ldb,
322 $ zero,
323 $ work( nwork ), n )
324 CALL dlacpy( 'A', n, nrhs, work( nwork ), n, b, ldb )
325*
326* Unscale.
327*
328 CALL dlascl( 'G', 0, 0, one, orgnrm, n, 1, d, n, info )
329 CALL dlasrt( 'D', n, d, info )
330 CALL dlascl( 'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
331*
332 RETURN
333 END IF
334*
335* Book-keeping and setting up some constants.
336*
337 nlvl = int( log( dble( n ) / dble( smlsiz+1 ) ) / log( two ) ) + 1
338*
339 smlszp = smlsiz + 1
340*
341 u = 1
342 vt = 1 + smlsiz*n
343 difl = vt + smlszp*n
344 difr = difl + nlvl*n
345 z = difr + nlvl*n*2
346 c = z + nlvl*n
347 s = c + n
348 poles = s + n
349 givnum = poles + 2*nlvl*n
350 bx = givnum + 2*nlvl*n
351 nwork = bx + n*nrhs
352*
353 sizei = 1 + n
354 k = sizei + n
355 givptr = k + n
356 perm = givptr + n
357 givcol = perm + nlvl*n
358 iwk = givcol + nlvl*n*2
359*
360 st = 1
361 sqre = 0
362 icmpq1 = 1
363 icmpq2 = 0
364 nsub = 0
365*
366 DO 50 i = 1, n
367 IF( abs( d( i ) ).LT.eps ) THEN
368 d( i ) = sign( eps, d( i ) )
369 END IF
370 50 CONTINUE
371*
372 DO 60 i = 1, nm1
373 IF( ( abs( e( i ) ).LT.eps ) .OR. ( i.EQ.nm1 ) ) THEN
374 nsub = nsub + 1
375 iwork( nsub ) = st
376*
377* Subproblem found. First determine its size and then
378* apply divide and conquer on it.
379*
380 IF( i.LT.nm1 ) THEN
381*
382* A subproblem with E(I) small for I < NM1.
383*
384 nsize = i - st + 1
385 iwork( sizei+nsub-1 ) = nsize
386 ELSE IF( abs( e( i ) ).GE.eps ) THEN
387*
388* A subproblem with E(NM1) not too small but I = NM1.
389*
390 nsize = n - st + 1
391 iwork( sizei+nsub-1 ) = nsize
392 ELSE
393*
394* A subproblem with E(NM1) small. This implies an
395* 1-by-1 subproblem at D(N), which is not solved
396* explicitly.
397*
398 nsize = i - st + 1
399 iwork( sizei+nsub-1 ) = nsize
400 nsub = nsub + 1
401 iwork( nsub ) = n
402 iwork( sizei+nsub-1 ) = 1
403 CALL dcopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
404 END IF
405 st1 = st - 1
406 IF( nsize.EQ.1 ) THEN
407*
408* This is a 1-by-1 subproblem and is not solved
409* explicitly.
410*
411 CALL dcopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
412 ELSE IF( nsize.LE.smlsiz ) THEN
413*
414* This is a small subproblem and is solved by DLASDQ.
415*
416 CALL dlaset( 'A', nsize, nsize, zero, one,
417 $ work( vt+st1 ), n )
418 CALL dlasdq( 'U', 0, nsize, nsize, 0, nrhs, d( st ),
419 $ e( st ), work( vt+st1 ), n, work( nwork ),
420 $ n, b( st, 1 ), ldb, work( nwork ), info )
421 IF( info.NE.0 ) THEN
422 RETURN
423 END IF
424 CALL dlacpy( 'A', nsize, nrhs, b( st, 1 ), ldb,
425 $ work( bx+st1 ), n )
426 ELSE
427*
428* A large problem. Solve it using divide and conquer.
429*
430 CALL dlasda( icmpq1, smlsiz, nsize, sqre, d( st ),
431 $ e( st ), work( u+st1 ), n, work( vt+st1 ),
432 $ iwork( k+st1 ), work( difl+st1 ),
433 $ work( difr+st1 ), work( z+st1 ),
434 $ work( poles+st1 ), iwork( givptr+st1 ),
435 $ iwork( givcol+st1 ), n, iwork( perm+st1 ),
436 $ work( givnum+st1 ), work( c+st1 ),
437 $ work( s+st1 ), work( nwork ), iwork( iwk ),
438 $ info )
439 IF( info.NE.0 ) THEN
440 RETURN
441 END IF
442 bxst = bx + st1
443 CALL dlalsa( icmpq2, smlsiz, nsize, nrhs, b( st, 1 ),
444 $ ldb, work( bxst ), n, work( u+st1 ), n,
445 $ work( vt+st1 ), iwork( k+st1 ),
446 $ work( difl+st1 ), work( difr+st1 ),
447 $ work( z+st1 ), work( poles+st1 ),
448 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
449 $ iwork( perm+st1 ), work( givnum+st1 ),
450 $ work( c+st1 ), work( s+st1 ), work( nwork ),
451 $ iwork( iwk ), info )
452 IF( info.NE.0 ) THEN
453 RETURN
454 END IF
455 END IF
456 st = i + 1
457 END IF
458 60 CONTINUE
459*
460* Apply the singular values and treat the tiny ones as zero.
461*
462 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
463*
464 DO 70 i = 1, n
465*
466* Some of the elements in D can be negative because 1-by-1
467* subproblems were not solved explicitly.
468*
469 IF( abs( d( i ) ).LE.tol ) THEN
470 CALL dlaset( 'A', 1, nrhs, zero, zero, work( bx+i-1 ),
471 $ n )
472 ELSE
473 rank = rank + 1
474 CALL dlascl( 'G', 0, 0, d( i ), one, 1, nrhs,
475 $ work( bx+i-1 ), n, info )
476 END IF
477 d( i ) = abs( d( i ) )
478 70 CONTINUE
479*
480* Now apply back the right singular vectors.
481*
482 icmpq2 = 1
483 DO 80 i = 1, nsub
484 st = iwork( i )
485 st1 = st - 1
486 nsize = iwork( sizei+i-1 )
487 bxst = bx + st1
488 IF( nsize.EQ.1 ) THEN
489 CALL dcopy( nrhs, work( bxst ), n, b( st, 1 ), ldb )
490 ELSE IF( nsize.LE.smlsiz ) THEN
491 CALL dgemm( 'T', 'N', nsize, nrhs, nsize, one,
492 $ work( vt+st1 ), n, work( bxst ), n, zero,
493 $ b( st, 1 ), ldb )
494 ELSE
495 CALL dlalsa( icmpq2, smlsiz, nsize, nrhs, work( bxst ),
496 $ n,
497 $ b( st, 1 ), ldb, work( u+st1 ), n,
498 $ work( vt+st1 ), iwork( k+st1 ),
499 $ work( difl+st1 ), work( difr+st1 ),
500 $ work( z+st1 ), work( poles+st1 ),
501 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
502 $ iwork( perm+st1 ), work( givnum+st1 ),
503 $ work( c+st1 ), work( s+st1 ), work( nwork ),
504 $ iwork( iwk ), info )
505 IF( info.NE.0 ) THEN
506 RETURN
507 END IF
508 END IF
509 80 CONTINUE
510*
511* Unscale and sort the singular values.
512*
513 CALL dlascl( 'G', 0, 0, one, orgnrm, n, 1, d, n, info )
514 CALL dlasrt( 'D', n, d, info )
515 CALL dlascl( 'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
516*
517 RETURN
518*
519* End of DLALSD
520*
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
Definition dcopy.f:82
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
Definition dgemm.f:188
integer function idamax(n, dx, incx)
IDAMAX
Definition idamax.f:71
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 dlalsa(icompq, smlsiz, n, nrhs, b, ldb, bx, ldbx, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, work, iwork, info)
DLALSA computes the SVD of the coefficient matrix in compact form. Used by sgelsd.
Definition dlalsa.f:266
double precision function dlamch(cmach)
DLAMCH
Definition dlamch.f:69
double precision function dlanst(norm, n, d, e)
DLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
Definition dlanst.f:98
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
Definition dlartg.f90:111
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 dlasda(icompq, smlsiz, n, sqre, d, e, u, ldu, vt, k, difl, difr, z, poles, givptr, givcol, ldgcol, perm, givnum, c, s, work, iwork, info)
DLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagona...
Definition dlasda.f:272
subroutine dlasdq(uplo, sqre, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work, info)
DLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e....
Definition dlasdq.f:210
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 dlasrt(id, n, d, info)
DLASRT sorts numbers in increasing or decreasing order.
Definition dlasrt.f:86
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT
Definition drot.f:92
Here is the call graph for this function:
Here is the caller graph for this function: