0

After performing SVD on a matrix, I would like to create a function (I'm not good with functions in R yet) that creates a reduced matrix per my specified n-value.

For instance, here is the R code for what I have now.

scores = c(3,1,1,-1,3,1)
Mat = matrix(scores, nrow=2)
svd = svd(Mat)

Now, to go from the matrix factorization to the original matrix, via brute force and ignorance, the following works.

score1 = svd$u[,1] %*% t(svd$v[,1]) * svd$d[1]
    score2 = svd$u[,2] %*% t(svd$v[,2]) * svd$d[2]

z = score1 + score2
z

    [,1] [,2] [,3]
[1,]    3    1    3
[2,]    1   -1    1

Going forward, I want to be able to do this on a large matrix and would like to be able to specify the number of factors. So, instead of summing scores 1:n, I want a function to do that for me.

MAJ Les
  • 13
  • 1
  • 1
  • 4
  • This sounds like more of a programming question than a statistics question. – Adrian May 27 '15 at 14:47
  • This is one for Stackoverflow. Nevertheless, here's the function: `reconstruct <- function(m, f=1){ s <- svd(m); s$u[,1:f] %*% diag(s$d[1:f], f, f) %*% t(s$v[,1:f]) }` – conjugateprior May 27 '15 at 15:57
  • Usage: `reconstruct(Mat, 1)` for a rank 1 reconstruction. `reconstruct(Mat, 2)` for a complete recovery. – conjugateprior May 27 '15 at 15:59

1 Answers1

2

Cannot you just wrap your matrix arithmetic in a small function of your own?

recover_matrix_from_svd <- function(svd) {
    score <- 0
    for(i in 1:ncol(svd$u)) {
    score <- score + svd$u[,i] %*% t(svd$v[,i]) * svd$d[i]
    }
    score
}

alternatively, the diag function is very useful for this. Using it results in a much clearer computation:

recover_matrix_from_svd <- function(svd) {
    svd$u %*% diag(svd$d) %*% t(svd$v)
}
Matthew Drury
  • 845
  • 8
  • 17
  • 1
    and the second approach is shown in the examples section of `help("svd")`. – Roland May 27 '15 at 15:48
  • Many thanks, this worked perfectly. I also tweaked it to do for(i in 1:n), where I can specify whatever n moves me. – MAJ Les May 27 '15 at 17:00