171 SUBROUTINE dlalsd( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
172 $ RANK, WORK, IWORK, INFO )
180 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
181 DOUBLE PRECISION RCOND
185 DOUBLE PRECISION B( LDB, * ), D( * ), E( * ), WORK( * )
191 DOUBLE PRECISION ZERO, ONE, TWO
192 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
195 INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
196 $ givptr, i, icmpq1, icmpq2, iwk, j, k, nlvl,
197 $ nm1, nsize, nsub, nwork, perm, poles, s, sizei,
198 $ smlszp, sqre, st, st1, u, vt, z
199 DOUBLE PRECISION CS, EPS, ORGNRM, R, RCND, SN, TOL
203 DOUBLE PRECISION DLAMCH, DLANST
204 EXTERNAL idamax, dlamch, dlanst
211 INTRINSIC abs, dble, int, log, sign
221 ELSE IF( nrhs.LT.1 )
THEN
223 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) )
THEN
227 CALL xerbla(
'DLALSD', -info )
231 eps = dlamch(
'Epsilon' )
235 IF( ( rcond.LE.zero ) .OR. ( rcond.GE.one ) )
THEN
247 ELSE IF( n.EQ.1 )
THEN
248 IF( d( 1 ).EQ.zero )
THEN
249 CALL dlaset(
'A', 1, nrhs, zero, zero, b, ldb )
252 CALL dlascl(
'G', 0, 0, d( 1 ), one, 1, nrhs, b, ldb, info )
253 d( 1 ) = abs( d( 1 ) )
260 IF( uplo.EQ.
'L' )
THEN
262 CALL dlartg( d( i ), e( i ), cs, sn, r )
265 d( i+1 ) = cs*d( i+1 )
267 CALL drot( 1, b( i, 1 ), 1, b( i+1, 1 ), 1, cs, sn )
278 CALL drot( 1, b( j, i ), 1, b( j+1, i ), 1, cs, sn )
287 orgnrm = dlanst(
'M', n, d, e )
288 IF( orgnrm.EQ.zero )
THEN
289 CALL dlaset(
'A', n, nrhs, zero, zero, b, ldb )
293 CALL dlascl(
'G', 0, 0, orgnrm, one, n, 1, d, n, info )
294 CALL dlascl(
'G', 0, 0, orgnrm, one, nm1, 1, e, nm1, info )
299 IF( n.LE.smlsiz )
THEN
301 CALL dlaset(
'A', n, n, zero, one, work, n )
302 CALL dlasdq(
'U', 0, n, n, 0, nrhs, d, e, work, n, work, n, b,
303 $ ldb, work( nwork ), info )
307 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
309 IF( d( i ).LE.tol )
THEN
310 CALL dlaset(
'A', 1, nrhs, zero, zero, b( i, 1 ), ldb )
312 CALL dlascl(
'G', 0, 0, d( i ), one, 1, nrhs, b( i, 1 ),
317 CALL dgemm(
'T',
'N', n, nrhs, n, one, work, n, b, ldb, zero,
319 CALL dlacpy(
'A', n, nrhs, work( nwork ), n, b, ldb )
323 CALL dlascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
324 CALL dlasrt(
'D', n, d, info )
325 CALL dlascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
332 nlvl = int( log( dble( n ) / dble( smlsiz+1 ) ) / log( two ) ) + 1
344 givnum = poles + 2*nlvl*n
345 bx = givnum + 2*nlvl*n
352 givcol = perm + nlvl*n
353 iwk = givcol + nlvl*n*2
362 IF( abs( d( i ) ).LT.eps )
THEN
363 d( i ) = sign( eps, d( i ) )
368 IF( ( abs( e( i ) ).LT.eps ) .OR. ( i.EQ.nm1 ) )
THEN
380 iwork( sizei+nsub-1 ) = nsize
381 ELSE IF( abs( e( i ) ).GE.eps )
THEN
386 iwork( sizei+nsub-1 ) = nsize
394 iwork( sizei+nsub-1 ) = nsize
397 iwork( sizei+nsub-1 ) = 1
398 CALL dcopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
401 IF( nsize.EQ.1 )
THEN
406 CALL dcopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
407 ELSE IF( nsize.LE.smlsiz )
THEN
411 CALL dlaset(
'A', nsize, nsize, zero, one,
412 $ work( vt+st1 ), n )
413 CALL dlasdq(
'U', 0, nsize, nsize, 0, nrhs, d( st ),
414 $ e( st ), work( vt+st1 ), n, work( nwork ),
415 $ n, b( st, 1 ), ldb, work( nwork ), info )
419 CALL dlacpy(
'A', nsize, nrhs, b( st, 1 ), ldb,
420 $ work( bx+st1 ), n )
425 CALL dlasda( icmpq1, smlsiz, nsize, sqre, d( st ),
426 $ e( st ), work( u+st1 ), n, work( vt+st1 ),
427 $ iwork( k+st1 ), work( difl+st1 ),
428 $ work( difr+st1 ), work( z+st1 ),
429 $ work( poles+st1 ), iwork( givptr+st1 ),
430 $ iwork( givcol+st1 ), n, iwork( perm+st1 ),
431 $ work( givnum+st1 ), work( c+st1 ),
432 $ work( s+st1 ), work( nwork ), iwork( iwk ),
438 CALL dlalsa( icmpq2, smlsiz, nsize, nrhs, b( st, 1 ),
439 $ ldb, work( bxst ), n, work( u+st1 ), n,
440 $ work( vt+st1 ), iwork( k+st1 ),
441 $ work( difl+st1 ), work( difr+st1 ),
442 $ work( z+st1 ), work( poles+st1 ),
443 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
444 $ iwork( perm+st1 ), work( givnum+st1 ),
445 $ work( c+st1 ), work( s+st1 ), work( nwork ),
446 $ iwork( iwk ), info )
457 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
464 IF( abs( d( i ) ).LE.tol )
THEN
465 CALL dlaset(
'A', 1, nrhs, zero, zero, work( bx+i-1 ), n )
468 CALL dlascl(
'G', 0, 0, d( i ), one, 1, nrhs,
469 $ work( bx+i-1 ), n, info )
471 d( i ) = abs( d( i ) )
480 nsize = iwork( sizei+i-1 )
482 IF( nsize.EQ.1 )
THEN
483 CALL dcopy( nrhs, work( bxst ), n, b( st, 1 ), ldb )
484 ELSE IF( nsize.LE.smlsiz )
THEN
485 CALL dgemm(
'T',
'N', nsize, nrhs, nsize, one,
486 $ work( vt+st1 ), n, work( bxst ), n, zero,
489 CALL dlalsa( icmpq2, smlsiz, nsize, nrhs, work( bxst ), n,
490 $ b( st, 1 ), ldb, work( u+st1 ), n,
491 $ work( vt+st1 ), iwork( k+st1 ),
492 $ work( difl+st1 ), work( difr+st1 ),
493 $ work( z+st1 ), work( poles+st1 ),
494 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
495 $ iwork( perm+st1 ), work( givnum+st1 ),
496 $ work( c+st1 ), work( s+st1 ), work( nwork ),
497 $ iwork( iwk ), info )
506 CALL dlascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
507 CALL dlasrt(
'D', n, d, info )
508 CALL dlascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
subroutine xerbla(srname, info)
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
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.
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.
subroutine dlartg(f, g, c, s, r)
DLARTG generates a plane rotation with real cosine and real sine.
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.
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...
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....
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.
subroutine dlasrt(id, n, d, info)
DLASRT sorts numbers in increasing or decreasing order.
subroutine drot(n, dx, incx, dy, incy, c, s)
DROT