-
Notifications
You must be signed in to change notification settings - Fork 0
/
myCA.R
61 lines (49 loc) · 1.32 KB
/
myCA.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#' @author
#' Nicolas Hervé - http://herve.name
library(irlba)
library(Matrix)
myCA <- function (Y, lessMemory = TRUE, nv = 5) {
myCA_log("Data preparation ...")
s = sum(Y)
P = Y/s
r = P %*% data.matrix(rep(1, ncol(Y)))
c = t(P) %*% data.matrix(rep(1, nrow(Y)))
rp = r^-0.5
cp = c^-0.5
if (lessMemory) {
d_r = Diagonal(,rp[,1])
d_c = Diagonal(,cp[,1])
} else {
d_r = diag(rp[,1])
d_c = diag(cp[,1])
}
myCA_log("Matrix multiplication ...")
S = P - r %*% t(c)
S = d_r %*% S %*% d_c
if (lessMemory) {
myCA_log("Launching IRLBA ...")
svd = irlba(S, nv = nv, verbose = TRUE)
} else {
myCA_log("Launching SVD ...")
svd = svd(S)
}
myCA_log("... done")
rowProj = d_r %*% svd$u
colProj = d_c %*% svd$v
output <- list(rowProj = rowProj, colProj = colProj, c = c, d = svd$d)
class(output) <- "myCA"
return(output)
}
myCA_log <- function(msg) {
message(paste(as.POSIXlt(Sys.time()), "[myCA]", msg))
}
myCA_project <- function (myCA, Y2) {
r2 = Y2 %*% data.matrix(rep(1, ncol(Y2)))
s2 = r2 %*% t(data.matrix(rep(1, ncol(Y2))))
P2 = Y2/s2
S2 = P2 - data.matrix(rep(1, nrow(P2))) %*% t(myCA$c)
rowProj2 = S2 %*% myCA$colProj / (data.matrix(rep(1, nrow(P2))) %*% myCA$d)
output <- list(rowProj = rowProj2)
class(output) <- "myCA"
return(output)
}