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, , C, DIFL, DIFR, GIVCOL, GIVNUM,
202 $ givptr, i, icmpq1, icmpq2, iwk, j, k, nlvl,
204 $ smlszp, sqre, st, st1, u, vt, z
205 DOUBLE PRECISION CS, EPS, ORGNRM, R, RCND, SN, TOL
209 DOUBLE PRECISION DLAMCH,
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
233CALL 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 )