When scale = FALSE and scale_block = TRUE, each block x is normalized by ||x||_F / sqrt(N) where N is either the number of rows of x or the number of rows minus one. This PR modifies the code to apply this transform in a more straightforward fashion. Here is a small benchmark to show that it does not only simplify the code but also speeds up the computation:
library(rbenchmark)
custom_frob = function(x, N, bias = T) {
if(NROW(x) > NCOL(x))
{
covarMat <- cov2(x, bias = bias)
}
else
{
covarMat <- 1/N*(x%*%t(x))
}
variance_block <- sum(diag(covarMat))
}
x = matrix(rnorm(10000), 500, 1000); bias = T; N = nrow(x) + bias - 1
benchmark("new" = {
res = 1/sqrt(N) * norm(x, type = "F")
},
"old" = {
res = sqrt(custom_frob(x, N, bias))
},
replications = 1000)
> test replications elapsed relative user.self sys.self user.child sys.child
> 1 new 1000 1.193 1.000 1.194 0.000 0.000 0.000
> 2 old 1000 136.393 114.328 135.085 1.129 0.022 0.173
When
scale = FALSE
andscale_block = TRUE
, each blockx
is normalized by||x||_F / sqrt(N)
whereN
is either the number of rows ofx
or the number of rows minus one. This PR modifies the code to apply this transform in a more straightforward fashion. Here is a small benchmark to show that it does not only simplify the code but also speeds up the computation: