177 SUBROUTINE slalsd( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
178 $ RANK, WORK, IWORK, INFO )
186 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
191 REAL B( LDB, * ), D( * ), E( * ), WORK( * )
198 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0 )
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 REAL CS, EPS, ORGNRM, R, RCND, SN, TOL
210 EXTERNAL isamax, slamch, slanst
217 INTRINSIC abs, int, log, real, sign
227 ELSE IF( nrhs.LT.1 )
THEN
229 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) )
THEN
233 CALL xerbla(
'SLALSD', -info )
237 eps = slamch(
'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 slaset(
'A', 1, nrhs, zero, zero, b, ldb )
258 CALL slascl(
'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 slartg( d( i ), e( i ), cs, sn, r )
271 d( i+1 ) = cs*d( i+1 )
273 CALL srot( 1, b( i, 1 ), 1, b( i+1, 1 ), 1, cs, sn )
284 CALL srot( 1, b( j, i ), 1, b( j+1, i ), 1, cs, sn )
293 orgnrm = slanst(
'M', n, d, e )
294 IF( orgnrm.EQ.zero )
THEN
295 CALL slaset(
'A', n, nrhs, zero, zero, b, ldb )
299 CALL slascl(
'G', 0, 0, orgnrm, one, n, 1, d, n, info )
300 CALL slascl(
'G', 0, 0, orgnrm, one, nm1, 1, e, nm1, info )
305 IF( n.LE.smlsiz )
THEN
307 CALL slaset(
'A', n, n, zero, one, work, n )
308 CALL slasdq(
'U', 0, n, n, 0, nrhs, d, e, work, n, work, n, b,
309 $ ldb, work( nwork ), info )
313 tol = rcnd*abs( d( isamax( n, d, 1 ) ) )
315 IF( d( i ).LE.tol )
THEN
316 CALL slaset(
'A', 1, nrhs, zero, zero, b( i, 1 ), ldb )
318 CALL slascl(
'G', 0, 0, d( i ), one, 1, nrhs, b( i, 1 ),
323 CALL sgemm(
'T',
'N', n, nrhs, n, one, work, n, b, ldb, zero,
325 CALL slacpy(
'A', n, nrhs, work( nwork ), n, b, ldb )
329 CALL slascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
330 CALL slasrt(
'D', n, d, info )
331 CALL slascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
338 nlvl = int( log( real( n ) / real( 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 scopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
407 IF( nsize.EQ.1 )
THEN
412 CALL scopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
413 ELSE IF( nsize.LE.smlsiz )
THEN
417 CALL slaset(
'A', nsize, nsize, zero, one,
418 $ work( vt+st1 ), n )
419 CALL slasdq(
'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 slacpy(
'A', nsize, nrhs, b( st, 1 ), ldb,
426 $ work( bx+st1 ), n )
431 CALL slasda( 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 slalsa( 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( isamax( n, d, 1 ) ) )
470 IF( abs( d( i ) ).LE.tol )
THEN
471 CALL slaset(
'A', 1, nrhs, zero, zero, work( bx+i-1 ), n )
474 CALL slascl(
'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 scopy( nrhs, work( bxst ), n, b( st, 1 ), ldb )
490 ELSE IF( nsize.LE.smlsiz )
THEN
491 CALL sgemm(
'T',
'N', nsize, nrhs, nsize, one,
492 $ work( vt+st1 ), n, work( bxst ), n, zero,
495 CALL slalsa( 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 slascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
513 CALL slasrt(
'D', n, d, info )
514 CALL slascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
subroutine slascl(TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO)
SLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine slartg(f, g, c, s, r)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine slasdq(UPLO, SQRE, N, NCVT, NRU, NCC, D, E, VT, LDVT, U, LDU, C, LDC, WORK, INFO)
SLASDQ computes the SVD of a real bidiagonal matrix with diagonal d and off-diagonal e....
subroutine slasda(ICOMPQ, SMLSIZ, N, SQRE, D, E, U, LDU, VT, K, DIFL, DIFR, Z, POLES, GIVPTR, GIVCOL, LDGCOL, PERM, GIVNUM, C, S, WORK, IWORK, INFO)
SLASDA computes the singular value decomposition (SVD) of a real upper bidiagonal matrix with diagona...
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine slasrt(ID, N, D, INFO)
SLASRT sorts numbers in increasing or decreasing order.
subroutine slalsd(UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND, RANK, WORK, IWORK, INFO)
SLALSD uses the singular value decomposition of A to solve the least squares problem.
subroutine slalsa(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)
SLALSA computes the SVD of the coefficient matrix in compact form. Used by sgelsd.
subroutine srot(N, SX, INCX, SY, INCY, C, S)
SROT
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM