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 slasrt(ID, N, D, INFO)
SLASRT sorts numbers in increasing or decreasing order.
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 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 xerbla(SRNAME, INFO)
XERBLA
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
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 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 scopy(N, SX, INCX, SY, INCY)
SCOPY
subroutine srot(N, SX, INCX, SY, INCY, C, S)
SROT
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
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...