177 SUBROUTINE dlalsd( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
178 $ RANK, WORK, IWORK, INFO )
186 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
187 DOUBLE PRECISION RCOND
191 DOUBLE PRECISION B( ldb, * ), D( * ), E( * ), WORK( * )
197 DOUBLE PRECISION ZERO, ONE, TWO
198 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
201 INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
202 $ givptr, i, icmpq1, icmpq2, iwk, j, k, nlvl,
203 $ nm1, nsize, nsub, nwork, perm, poles, s, sizei,
204 $ smlszp, sqre, st, st1, u, vt, z
205 DOUBLE PRECISION CS, EPS, ORGNRM, R, RCND, SN, TOL
209 DOUBLE PRECISION DLAMCH, DLANST
210 EXTERNAL idamax, dlamch, dlanst
217 INTRINSIC abs, dble, int, log, sign
227 ELSE IF( nrhs.LT.1 )
THEN 229 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) )
THEN 233 CALL xerbla(
'DLALSD', -info )
237 eps = dlamch(
'Epsilon' )
241 IF( ( rcond.LE.zero ) .OR. ( rcond.GE.one ) )
THEN 253 ELSE IF( n.EQ.1 )
THEN 254 IF( d( 1 ).EQ.zero )
THEN 255 CALL dlaset(
'A', 1, nrhs, zero, zero, b, ldb )
258 CALL dlascl(
'G', 0, 0, d( 1 ), one, 1, nrhs, b, ldb, info )
259 d( 1 ) = abs( d( 1 ) )
266 IF( uplo.EQ.
'L' )
THEN 268 CALL dlartg( d( i ), e( i ), cs, sn, r )
271 d( i+1 ) = cs*d( i+1 )
273 CALL drot( 1, b( i, 1 ), 1, b( i+1, 1 ), 1, cs, sn )
284 CALL drot( 1, b( j, i ), 1, b( j+1, i ), 1, cs, sn )
293 orgnrm = dlanst(
'M', n, d, e )
294 IF( orgnrm.EQ.zero )
THEN 295 CALL dlaset(
'A', n, nrhs, zero, zero, b, ldb )
299 CALL dlascl(
'G', 0, 0, orgnrm, one, n, 1, d, n, info )
300 CALL dlascl(
'G', 0, 0, orgnrm, one, nm1, 1, e, nm1, info )
305 IF( n.LE.smlsiz )
THEN 307 CALL dlaset(
'A', n, n, zero, one, work, n )
308 CALL dlasdq(
'U', 0, n, n, 0, nrhs, d, e, work, n, work, n, b,
309 $ ldb, work( nwork ), info )
313 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
315 IF( d( i ).LE.tol )
THEN 316 CALL dlaset(
'A', 1, nrhs, zero, zero, b( i, 1 ), ldb )
318 CALL dlascl(
'G', 0, 0, d( i ), one, 1, nrhs, b( i, 1 ),
323 CALL dgemm(
'T',
'N', n, nrhs, n, one, work, n, b, ldb, zero,
325 CALL dlacpy(
'A', n, nrhs, work( nwork ), n, b, ldb )
329 CALL dlascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
330 CALL dlasrt(
'D', n, d, info )
331 CALL dlascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
338 nlvl = int( log( dble( n ) / dble( smlsiz+1 ) ) / log( two ) ) + 1
350 givnum = poles + 2*nlvl*n
351 bx = givnum + 2*nlvl*n
358 givcol = perm + nlvl*n
359 iwk = givcol + nlvl*n*2
368 IF( abs( d( i ) ).LT.eps )
THEN 369 d( i ) = sign( eps, d( i ) )
374 IF( ( abs( e( i ) ).LT.eps ) .OR. ( i.EQ.nm1 ) )
THEN 386 iwork( sizei+nsub-1 ) = nsize
387 ELSE IF( abs( e( i ) ).GE.eps )
THEN 392 iwork( sizei+nsub-1 ) = nsize
400 iwork( sizei+nsub-1 ) = nsize
403 iwork( sizei+nsub-1 ) = 1
404 CALL dcopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
407 IF( nsize.EQ.1 )
THEN 412 CALL dcopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
413 ELSE IF( nsize.LE.smlsiz )
THEN 417 CALL dlaset(
'A', nsize, nsize, zero, one,
418 $ work( vt+st1 ), n )
419 CALL dlasdq(
'U', 0, nsize, nsize, 0, nrhs, d( st ),
420 $ e( st ), work( vt+st1 ), n, work( nwork ),
421 $ n, b( st, 1 ), ldb, work( nwork ), info )
425 CALL dlacpy(
'A', nsize, nrhs, b( st, 1 ), ldb,
426 $ work( bx+st1 ), n )
431 CALL dlasda( icmpq1, smlsiz, nsize, sqre, d( st ),
432 $ e( st ), work( u+st1 ), n, work( vt+st1 ),
433 $ iwork( k+st1 ), work( difl+st1 ),
434 $ work( difr+st1 ), work( z+st1 ),
435 $ work( poles+st1 ), iwork( givptr+st1 ),
436 $ iwork( givcol+st1 ), n, iwork( perm+st1 ),
437 $ work( givnum+st1 ), work( c+st1 ),
438 $ work( s+st1 ), work( nwork ), iwork( iwk ),
444 CALL dlalsa( icmpq2, smlsiz, nsize, nrhs, b( st, 1 ),
445 $ ldb, work( bxst ), n, work( u+st1 ), n,
446 $ work( vt+st1 ), iwork( k+st1 ),
447 $ work( difl+st1 ), work( difr+st1 ),
448 $ work( z+st1 ), work( poles+st1 ),
449 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
450 $ iwork( perm+st1 ), work( givnum+st1 ),
451 $ work( c+st1 ), work( s+st1 ), work( nwork ),
452 $ iwork( iwk ), info )
463 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
470 IF( abs( d( i ) ).LE.tol )
THEN 471 CALL dlaset(
'A', 1, nrhs, zero, zero, work( bx+i-1 ), n )
474 CALL dlascl(
'G', 0, 0, d( i ), one, 1, nrhs,
475 $ work( bx+i-1 ), n, info )
477 d( i ) = abs( d( i ) )
486 nsize = iwork( sizei+i-1 )
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,
495 CALL dlalsa( icmpq2, smlsiz, nsize, nrhs, work( bxst ), n,
496 $ b( st, 1 ), ldb, work( u+st1 ), n,
497 $ work( vt+st1 ), iwork( k+st1 ),
498 $ work( difl+st1 ), work( difr+st1 ),
499 $ work( z+st1 ), work( poles+st1 ),
500 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
501 $ iwork( perm+st1 ), work( givnum+st1 ),
502 $ work( c+st1 ), work( s+st1 ), work( nwork ),
503 $ iwork( iwk ), info )
512 CALL dlascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
513 CALL dlasrt(
'D', n, d, info )
514 CALL dlascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
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 xerbla(SRNAME, INFO)
XERBLA
subroutine dlacpy(UPLO, M, N, A, LDA, B, LDB)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
DGEMM
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 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 drot(N, DX, INCX, DY, INCY, C, S)
DROT
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 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 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 dcopy(N, DX, INCX, DY, INCY)
DCOPY
subroutine dlasrt(ID, N, D, INFO)
DLASRT sorts numbers in increasing or decreasing order.