blob: fa5fa846da7e7ba6b525d02c00642e44ddf4d8ab [file] [log] [blame]
# standard SSVD
ssvd.svd <- function(x, k, p=25, qiter=0 ) {
a <- as.matrix(x)
m <- nrow(a)
n <- ncol(a)
p <- min( min(m,n)-k,p)
r <- k+p
omega <- matrix ( rnorm(r*n), nrow=n, ncol=r)
y <- a %*% omega
q <- qr.Q(qr(y))
b<- t(q) %*% a
#power iterations
for ( i in 1:qiter ) {
y <- a %*% t(b)
q <- qr.Q(qr(y))
b <- t(q) %*% a
}
bbt <- b %*% t(b)
e <- eigen(bbt, symmetric=T)
res <- list()
res$svalues <- sqrt(e$values)[1:k]
uhat=e$vectors[1:k,1:k]
res$u <- (q %*% e$vectors)[,1:k]
res$v <- (t(b) %*% e$vectors %*% diag(1/e$values))[,1:k]
return(res)
}
#SSVD with Q=YR^-1 substitute.
# this is just a simulation, because it is suboptimal to verify the actual result
ssvd.svd1 <- function(x, k, p=25, qiter=0 ) {
a <- as.matrix(x)
m <- nrow(a)
n <- ncol(a)
p <- min( min(m,n)-k,p)
r <- k+p
omega <- matrix ( rnorm(r*n), nrow=n, ncol=r)
# in reality we of course don't need to form and persist y
# but this is just verification
y <- a %*% omega
yty <- t(y) %*% y
R <- chol(yty, pivot = T)
q <- y %*% solve(R)
b<- t( q ) %*% a
#power iterations
for ( i in 1:qiter ) {
y <- a %*% t(b)
yty <- t(y) %*% y
R <- chol(yty, pivot = T)
q <- y %*% solve(R)
b <- t(q) %*% a
}
bbt <- b %*% t(b)
e <- eigen(bbt, symmetric=T)
res <- list()
res$svalues <- sqrt(e$values)[1:k]
uhat=e$vectors[1:k,1:k]
res$u <- (q %*% e$vectors)[,1:k]
res$v <- (t(b) %*% e$vectors %*% diag(1/e$values))[,1:k]
return(res)
}
#############
## ssvd with pci options
ssvd.cpca <- function ( x, k, p=25, qiter=0, fixY=T ) {
a <- as.matrix(x)
m <- nrow(a)
n <- ncol(a)
p <- min( min(m,n)-k,p)
r <- k+p
# compute median xi
xi<-colMeans(a)
omega <- matrix ( rnorm(r*n), nrow=n, ncol=r)
y <- a %*% omega
#fix y
if ( fixY ) {
#debug
cat ("fixing Y...\n");
s_o = t(omega) %*% cbind(xi)
for (i in 1:r ) y[,i]<- y[,i]-s_o[i]
}
q <- qr.Q(qr(y))
b<- t(q) %*% a
# compute sum of q rows
s_q <- cbind(colSums(q))
# compute B*xi
# of course in MR implementation
# it will be collected as sums of ( B[,i] * xi[i] ) and reduced after.
s_b <- b %*% cbind(xi)
#power iterations
for ( i in 1:qiter ) {
# fix b
b <- b - s_q %*% rbind(xi)
y <- a %*% t(b)
# fix y
if ( fixY )
for (i in 1:r ) y[,i]<- y[,i]-s_b[i]
q <- qr.Q(qr(y))
b <- t(q) %*% a
# recompute s_{q}
s_q <- cbind(colSums(q))
#recompute s_{b}
s_b <- b %*% cbind(xi)
}
#C is the outer product of S_q and S_b per doc
C <- s_q %*% t(s_b)
# fixing BB'
bbt <- b %*% t(b) -C -t(C) + sum(xi * xi)* (s_q %*% t(s_q))
e <- eigen(bbt, symmetric=T)
res <- list()
res$svalues <- sqrt(e$values)[1:k]
uhat=e$vectors[1:k,1:k]
res$u <- (q %*% e$vectors)[,1:k]
res$v <- (t(b- s_q %*% rbind(xi) ) %*% e$vectors %*% diag(1/e$values))[,1:k]
return(res)
}