169 SUBROUTINE dlalsd( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
170 $ RANK, WORK, IWORK, INFO )
178 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
179 DOUBLE PRECISION RCOND
183 DOUBLE PRECISION B( LDB, * ), D( * ), E( * ), WORK( * )
189 DOUBLE PRECISION ZERO, ONE, TWO
190 parameter( zero = 0.0d0, one = 1.0d0, two = 2.0d0 )
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
201 DOUBLE PRECISION DLAMCH, DLANST
202 EXTERNAL idamax, dlamch, dlanst
210 INTRINSIC abs, dble, int, log, sign
220 ELSE IF( nrhs.LT.1 )
THEN
222 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) )
THEN
226 CALL xerbla(
'DLALSD', -info )
230 eps = dlamch(
'Epsilon' )
234 IF( ( rcond.LE.zero ) .OR. ( rcond.GE.one ) )
THEN
246 ELSE IF( n.EQ.1 )
THEN
247 IF( d( 1 ).EQ.zero )
THEN
248 CALL dlaset(
'A', 1, nrhs, zero, zero, b, ldb )
251 CALL dlascl(
'G', 0, 0, d( 1 ), one, 1, nrhs, b, ldb,
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,
288 orgnrm = dlanst(
'M', n, d, e )
289 IF( orgnrm.EQ.zero )
THEN
290 CALL dlaset(
'A', n, nrhs, zero, zero, b, ldb )
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 )
300 IF( n.LE.smlsiz )
THEN
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,
305 $ ldb, work( nwork ), info )
309 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
311 IF( d( i ).LE.tol )
THEN
312 CALL dlaset(
'A', 1, nrhs, zero, zero, b( i, 1 ),
315 CALL dlascl(
'G', 0, 0, d( i ), one, 1, nrhs, b( i,
321 CALL dgemm(
'T',
'N', n, nrhs, n, one, work, n, b, ldb,
324 CALL dlacpy(
'A', n, nrhs, work( nwork ), n, b, ldb )
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 )
337 nlvl = int( log( dble( n ) / dble( smlsiz+1 ) ) / log( two ) ) + 1
349 givnum = poles + 2*nlvl*n
350 bx = givnum + 2*nlvl*n
357 givcol = perm + nlvl*n
358 iwk = givcol + nlvl*n*2
367 IF( abs( d( i ) ).LT.eps )
THEN
368 d( i ) = sign( eps, d( i ) )
373 IF( ( abs( e( i ) ).LT.eps ) .OR. ( i.EQ.nm1 ) )
THEN
385 iwork( sizei+nsub-1 ) = nsize
386 ELSE IF( abs( e( i ) ).GE.eps )
THEN
391 iwork( sizei+nsub-1 ) = nsize
399 iwork( sizei+nsub-1 ) = nsize
402 iwork( sizei+nsub-1 ) = 1
403 CALL dcopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
406 IF( nsize.EQ.1 )
THEN
411 CALL dcopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
412 ELSE IF( nsize.LE.smlsiz )
THEN
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 )
424 CALL dlacpy(
'A', nsize, nrhs, b( st, 1 ), ldb,
425 $ work( bx+st1 ), n )
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 ),
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 )
462 tol = rcnd*abs( d( idamax( n, d, 1 ) ) )
469 IF( abs( d( i ) ).LE.tol )
THEN
470 CALL dlaset(
'A', 1, nrhs, zero, zero, work( bx+i-1 ),
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 ),
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 )
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 )