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 )