179 SUBROUTINE slalsd( UPLO, SMLSIZ, N, NRHS, D, E, B, LDB, RCOND,
180 $ RANK, WORK, IWORK, INFO )
189 INTEGER INFO, LDB, N, NRHS, RANK, SMLSIZ
194 REAL B( ldb, * ), D( * ), E( * ), WORK( * )
201 parameter( zero = 0.0e0, one = 1.0e0, two = 2.0e0 )
204 INTEGER BX, BXST, C, DIFL, DIFR, GIVCOL, GIVNUM,
205 $ givptr, i, icmpq1, icmpq2, iwk, j, k, nlvl,
206 $ nm1, nsize, nsub, nwork, perm, poles, s, sizei,
207 $ smlszp, sqre, st, st1, u, vt, z
208 REAL CS, EPS, ORGNRM, R, RCND, SN, TOL
213 EXTERNAL isamax, slamch, slanst
220 INTRINSIC abs, int, log,
REAL, SIGN
230 ELSE IF( nrhs.LT.1 )
THEN 232 ELSE IF( ( ldb.LT.1 ) .OR. ( ldb.LT.n ) )
THEN 236 CALL xerbla(
'SLALSD', -info )
240 eps = slamch(
'Epsilon' )
244 IF( ( rcond.LE.zero ) .OR. ( rcond.GE.one ) )
THEN 256 ELSE IF( n.EQ.1 )
THEN 257 IF( d( 1 ).EQ.zero )
THEN 258 CALL slaset(
'A', 1, nrhs, zero, zero, b, ldb )
261 CALL slascl(
'G', 0, 0, d( 1 ), one, 1, nrhs, b, ldb, info )
262 d( 1 ) = abs( d( 1 ) )
269 IF( uplo.EQ.
'L' )
THEN 271 CALL slartg( d( i ), e( i ), cs, sn, r )
274 d( i+1 ) = cs*d( i+1 )
276 CALL srot( 1, b( i, 1 ), 1, b( i+1, 1 ), 1, cs, sn )
287 CALL srot( 1, b( j, i ), 1, b( j+1, i ), 1, cs, sn )
296 orgnrm = slanst(
'M', n, d, e )
297 IF( orgnrm.EQ.zero )
THEN 298 CALL slaset(
'A', n, nrhs, zero, zero, b, ldb )
302 CALL slascl(
'G', 0, 0, orgnrm, one, n, 1, d, n, info )
303 CALL slascl(
'G', 0, 0, orgnrm, one, nm1, 1, e, nm1, info )
308 IF( n.LE.smlsiz )
THEN 310 CALL slaset(
'A', n, n, zero, one, work, n )
311 CALL slasdq(
'U', 0, n, n, 0, nrhs, d, e, work, n, work, n, b,
312 $ ldb, work( nwork ), info )
316 tol = rcnd*abs( d( isamax( n, d, 1 ) ) )
318 IF( d( i ).LE.tol )
THEN 319 CALL slaset(
'A', 1, nrhs, zero, zero, b( i, 1 ), ldb )
321 CALL slascl(
'G', 0, 0, d( i ), one, 1, nrhs, b( i, 1 ),
326 CALL sgemm(
'T',
'N', n, nrhs, n, one, work, n, b, ldb, zero,
328 CALL slacpy(
'A', n, nrhs, work( nwork ), n, b, ldb )
332 CALL slascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
333 CALL slasrt(
'D', n, d, info )
334 CALL slascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
341 nlvl = int( log(
REAL( N ) /
REAL( SMLSIZ+1 ) ) / log( TWO ) ) + 1
353 givnum = poles + 2*nlvl*n
354 bx = givnum + 2*nlvl*n
361 givcol = perm + nlvl*n
362 iwk = givcol + nlvl*n*2
371 IF( abs( d( i ) ).LT.eps )
THEN 372 d( i ) = sign( eps, d( i ) )
377 IF( ( abs( e( i ) ).LT.eps ) .OR. ( i.EQ.nm1 ) )
THEN 389 iwork( sizei+nsub-1 ) = nsize
390 ELSE IF( abs( e( i ) ).GE.eps )
THEN 395 iwork( sizei+nsub-1 ) = nsize
403 iwork( sizei+nsub-1 ) = nsize
406 iwork( sizei+nsub-1 ) = 1
407 CALL scopy( nrhs, b( n, 1 ), ldb, work( bx+nm1 ), n )
410 IF( nsize.EQ.1 )
THEN 415 CALL scopy( nrhs, b( st, 1 ), ldb, work( bx+st1 ), n )
416 ELSE IF( nsize.LE.smlsiz )
THEN 420 CALL slaset(
'A', nsize, nsize, zero, one,
421 $ work( vt+st1 ), n )
422 CALL slasdq(
'U', 0, nsize, nsize, 0, nrhs, d( st ),
423 $ e( st ), work( vt+st1 ), n, work( nwork ),
424 $ n, b( st, 1 ), ldb, work( nwork ), info )
428 CALL slacpy(
'A', nsize, nrhs, b( st, 1 ), ldb,
429 $ work( bx+st1 ), n )
434 CALL slasda( icmpq1, smlsiz, nsize, sqre, d( st ),
435 $ e( st ), work( u+st1 ), n, work( vt+st1 ),
436 $ iwork( k+st1 ), work( difl+st1 ),
437 $ work( difr+st1 ), work( z+st1 ),
438 $ work( poles+st1 ), iwork( givptr+st1 ),
439 $ iwork( givcol+st1 ), n, iwork( perm+st1 ),
440 $ work( givnum+st1 ), work( c+st1 ),
441 $ work( s+st1 ), work( nwork ), iwork( iwk ),
447 CALL slalsa( icmpq2, smlsiz, nsize, nrhs, b( st, 1 ),
448 $ ldb, work( bxst ), n, work( u+st1 ), n,
449 $ work( vt+st1 ), iwork( k+st1 ),
450 $ work( difl+st1 ), work( difr+st1 ),
451 $ work( z+st1 ), work( poles+st1 ),
452 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
453 $ iwork( perm+st1 ), work( givnum+st1 ),
454 $ work( c+st1 ), work( s+st1 ), work( nwork ),
455 $ iwork( iwk ), info )
466 tol = rcnd*abs( d( isamax( n, d, 1 ) ) )
473 IF( abs( d( i ) ).LE.tol )
THEN 474 CALL slaset(
'A', 1, nrhs, zero, zero, work( bx+i-1 ), n )
477 CALL slascl(
'G', 0, 0, d( i ), one, 1, nrhs,
478 $ work( bx+i-1 ), n, info )
480 d( i ) = abs( d( i ) )
489 nsize = iwork( sizei+i-1 )
491 IF( nsize.EQ.1 )
THEN 492 CALL scopy( nrhs, work( bxst ), n, b( st, 1 ), ldb )
493 ELSE IF( nsize.LE.smlsiz )
THEN 494 CALL sgemm(
'T',
'N', nsize, nrhs, nsize, one,
495 $ work( vt+st1 ), n, work( bxst ), n, zero,
498 CALL slalsa( icmpq2, smlsiz, nsize, nrhs, work( bxst ), n,
499 $ b( st, 1 ), ldb, work( u+st1 ), n,
500 $ work( vt+st1 ), iwork( k+st1 ),
501 $ work( difl+st1 ), work( difr+st1 ),
502 $ work( z+st1 ), work( poles+st1 ),
503 $ iwork( givptr+st1 ), iwork( givcol+st1 ), n,
504 $ iwork( perm+st1 ), work( givnum+st1 ),
505 $ work( c+st1 ), work( s+st1 ), work( nwork ),
506 $ iwork( iwk ), info )
515 CALL slascl(
'G', 0, 0, one, orgnrm, n, 1, d, n, info )
516 CALL slasrt(
'D', n, d, info )
517 CALL slascl(
'G', 0, 0, orgnrm, one, n, nrhs, b, ldb, info )
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 slasrt(ID, N, D, INFO)
SLASRT sorts numbers in increasing or decreasing order.
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 slartg(F, G, CS, SN, R)
SLARTG generates a plane rotation with real cosine and real sine.
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
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 srot(N, SX, INCX, SY, INCY, C, S)
SROT
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 xerbla(SRNAME, INFO)
XERBLA
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 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 slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
subroutine scopy(N, SX, INCX, SY, INCY)
SCOPY