Skip to content

Commit 8a1a6d7

Browse files
committed
WIP: ...
1 parent d70beaa commit 8a1a6d7

2 files changed

Lines changed: 43 additions & 61 deletions

File tree

R/simlr.R

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ simlrU <- function(
11831183
if (mixAlg == "avg") {
11841184
avgU <- projectionsU[[1]] * 0.0
11851185
for (j in wtobind) {
1186-
avgU <- avgU + projectionsU[[j]] / (nmodalities - 1)
1186+
avgU <- avgU + projectionsU[[j]] / length(wtobind)
11871187
}
11881188
basis <- avgU
11891189
} else if (mixAlg == "stochastic") { # FIXME
@@ -1218,77 +1218,57 @@ simlrU <- function(
12181218
}
12191219
} else if (mixAlg == "newton-schulz") {
12201220
# This is a fast way to get an orthogonal basis from the averaged projections
1221-
n_mod_minus_1 <- length(wtobind)
1221+
n_mod <- length(wtobind)
12221222
M <- matrix(0, nrow(avgU), nc)
1223-
for (idx in seq_len(n_mod_minus_1)) {
1223+
for (idx in seq_len(n_mod)) {
12241224
start_col <- (idx - 1) * nc + 1
12251225
end_col <- idx * nc
12261226
M <- M + avgU[, start_col:end_col]
12271227
}
1228-
M <- M / n_mod_minus_1
1229-
1230-
if (expBeta > 0 && !is.null(previousU)) {
1231-
# Exponential moving average blending
1232-
M <- (1 - expBeta) * M + expBeta * previousU
1233-
# Single Newton-Schulz iteration step for symmetric decorrelation
1234-
MtM <- t(M) %*% M
1235-
# We use a single NS step logic: W_{k+1} = 0.5 * W_k * (3I - W_k^T W_k)
1236-
# But we must ensure it's still a valid approximation.
1237-
# Alternatively, use inv_sqrt_sym_newton with max_iter=1
1238-
inv_sqrt_MtM <- inv_sqrt_sym_newton(MtM, max_iter = 1L)
1239-
basis <- M %*% inv_sqrt_MtM
1240-
} else {
1241-
# Standard full convergence
1242-
MtM <- t(M) %*% M
1243-
inv_sqrt_MtM <- inv_sqrt_sym_newton(MtM)
1244-
basis <- M %*% inv_sqrt_MtM
1245-
}
1228+
M <- M / n_mod
1229+
MtM <- t(M) %*% M
1230+
inv_sqrt_MtM <- inv_sqrt_sym_newton(MtM)
1231+
basis <- M %*% inv_sqrt_MtM
12461232
} else if (mixAlg == "ica-newton") {
12471233
# FastICA-style update with Newton-Schulz symmetric decorrelation
1248-
n_mod_minus_1 <- length(wtobind)
1234+
n_mod <- length(wtobind)
12491235
M <- matrix(0, nrow(avgU), nc)
1250-
for (idx in seq_len(n_mod_minus_1)) {
1236+
for (idx in seq_len(n_mod)) {
12511237
start_col <- (idx - 1) * nc + 1
12521238
end_col <- idx * nc
12531239
M <- M + avgU[, start_col:end_col]
12541240
}
1255-
M <- M / n_mod_minus_1
1256-
1257-
if (expBeta > 0 && !is.null(previousU)) {
1258-
# 1. Blend current average with previous state
1259-
M_blended <- (1 - expBeta) * M + expBeta * previousU
1260-
# 2. Whiten blended (single step)
1261-
MtM <- t(M_blended) %*% M_blended
1262-
M_whitened <- M_blended %*% inv_sqrt_sym_newton(MtM, max_iter = 1L)
1263-
# 3. Single FastICA fixed-point step
1264-
tanhM <- tanh(M_whitened)
1265-
E1 <- t(M_whitened) %*% tanhM / nrow(M_whitened)
1266-
E2 <- colMeans(1 - tanhM^2)
1267-
basis <- M_whitened %*% (E1 - diag(E2))
1268-
# 4. Single NS decorrelation step
1269-
BtB <- t(basis) %*% basis
1270-
basis <- basis %*% inv_sqrt_sym_newton(BtB, max_iter = 1L)
1271-
} else {
1272-
# Standard full convergence (initial step or no EMA)
1273-
MtM <- t(M) %*% M
1274-
M <- M %*% inv_sqrt_sym_newton(MtM)
1275-
tanhM <- tanh(M)
1276-
E1 <- t(M) %*% tanhM / nrow(M)
1277-
E2 <- colMeans(1 - tanhM^2)
1278-
basis <- M %*% (E1 - diag(E2))
1279-
BtB <- t(basis) %*% basis
1280-
basis <- basis %*% inv_sqrt_sym_newton(BtB)
1281-
}
1241+
M <- M / n_mod
1242+
# Standard full convergence (initial step or no EMA)
1243+
MtM <- t(M) %*% M
1244+
M <- M %*% inv_sqrt_sym_newton(MtM)
1245+
tanhM <- tanh(M)
1246+
E1 <- t(M) %*% tanhM / nrow(M)
1247+
E2 <- colMeans(1 - tanhM^2)
1248+
basis <- M %*% (E1 - diag(E2))
1249+
BtB <- t(basis) %*% basis
1250+
basis <- basis %*% inv_sqrt_sym_newton(BtB)
12821251
} else {
12831252
basis <- (ba_svd(scale(avgU,T,T), nu = nc, nv = 0)$u)
12841253
}
12851254
}
12861255

1287-
if (expBeta > 0 && !is.null(previousU) && !(mixAlg %in% c("newton-schulz", "ica-newton"))) {
1288-
basis <- (1 - expBeta) * basis + expBeta * previousU
1256+
if (ncol(basis) < nc) {
1257+
needed <- nc - ncol(basis)
1258+
if (!is.null(previousU) && ncol(previousU) == nc) {
1259+
pad <- previousU[, (ncol(basis) + 1):nc, drop = FALSE]
1260+
} else {
1261+
pad <- matrix(rnorm(nrow(basis) * needed), nrow = nrow(basis), ncol = needed)
1262+
}
1263+
basis <- cbind(basis, pad)
1264+
}
1265+
1266+
if (expBeta > 0 && !is.null(previousU) ) {
1267+
basis <- nsa_flow( Y0 = basis, X0 = previousU, w = expBeta, retraction = "soft_polar",
1268+
max_iter=10, apply_nonneg=FALSE )$Y
12891269
# Single Newton-Schulz iteration step for symmetric decorrelation
1290-
BtB <- t(basis) %*% basis
1291-
basis <- basis %*% inv_sqrt_sym_newton(BtB, max_iter = 1L)
1270+
# BtB <- t(basis) %*% basis
1271+
# basis <- basis %*% inv_sqrt_sym_newton(BtB, max_iter = 1L)
12921272
}
12931273
colnames(basis)=paste0("PC",1:nc)
12941274
if (!orthogonalize) {

tests/testthat/bench_simlr_versions.R

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ source("R/simlr.R")
2525
cat("Running SIMLR Recent Version (simlrZZ)...\n")
2626
start_time <- Sys.time()
2727
mix='newton-schulz'
28-
# mix='ica'
28+
mix='ica'
2929
# mix='ica-newton'
30-
mix='pca'
31-
oppter='armijo_gradient'
30+
# mix='svd'
31+
ebber=0.9
32+
oppter='adam'
33+
mye='regression'
3234
res_recent <- simlr( matlist, initialUMatrix = 3, iterations = 100,
33-
sparse_gradient = TRUE, energyType = "acc", mixAlg=mix,
34-
expBeta=0,
35+
sparse_gradient = TRUE, energyType = mye, mixAlg=mix,
36+
expBeta=ebber,
3537
optimizationStyle = oppter, verbose=2)
3638
end_time <- Sys.time()
3739
time_recent <- as.numeric(difftime(end_time, start_time, units = "secs"))
@@ -40,8 +42,8 @@ time_recent <- as.numeric(difftime(end_time, start_time, units = "secs"))
4042
cat("\nRunning SIMLR Reference Version (simlr)...\n")
4143
start_time <- Sys.time()
4244
res_ref <- backup_simlr(matlist, initialUMatrix = 3, iterations = 100,
43-
energyType = "acc", mixAlg=mix,
44-
expBeta=0,
45+
energyType = mye, mixAlg=mix,
46+
expBeta=ebber,
4547
optimizationStyle = oppter, verbose=2 )
4648
end_time <- Sys.time()
4749
time_ref <- as.numeric(difftime(end_time, start_time, units = "secs"))

0 commit comments

Comments
 (0)