tensor_predictors/tensorPredictors/R/gmlm_mlm.R

45 lines
1.3 KiB
R

#' A multi-linear model
#'
#' @export
gmlm_mlm <- function(X, F, sample.axis) {
# get (set) problem (observation) dimensions
modes <- seq_along(dim(X))[-sample.axis]
dimX <- dim(X)[modes]
sample.size <- dim(X)[sample.axis]
if (!is.array(F)) {
dim(F) <- c(1L, sample.size)[(seq_along(dim(X)) == sample.axis) + 1L]
}
dimF <- dim(F)[modes]
# vectorize the tensor valued data (columns are the vectorized samples)
matX <- mat(X, modes)
matF <- mat(F, modes)
# center
matX <- matX - (meanX <- rowMeans(matX))
matF <- matF - rowMeans(matF)
# solve vectorized linear model
B <- tcrossprod(matX, matF) %*% pinv(tcrossprod(matF))
# decompose linear model solution as Kronecker product
betas <- approx.kron(B, dimX, dimF)
# reshape centered vectorized `X` and `F` into tensors (now, sample axis
# is last axis)
X <- `dim<-`(matX, c(dimX, sample.size))
F <- `dim<-`(matF, c(dimF, sample.size))
# and estimate covariances (sample axis is last axis)
Sigmas <- mcov(X - mlm(F, betas), sample.axis = length(dim(X)))
# finaly, invert covariances to get the scatter matrices `Omegas`
Omegas <- Map(solve, Sigmas)
list(
eta1 = array(meanX, dim = dim(X)[-sample.axis]),
betas = betas,
Omegas = Omegas
)
}