fmrilatent

Memory-efficient latent space representations for fMRI data in R.

Overview

fmrilatent provides S4 classes and methods for representing neuroimaging data using matrix factorization. The LatentNeuroVec class stores 4D fMRI data as:

X[v,t] = Σ basis[t,k] × loadings[v,k] + offset[v]

This enables compact storage and efficient computation for dimensionality-reduced fMRI data (PCA, ICA, wavelet decompositions, etc.).

The package also provides operator-backed latent representations for transport-aware workflows. In that role, fmrilatent owns:

It does not own first-level GLM fitting, contrast handling, temporal autocorrelation models, or inference. Downstream modeling packages should consume coef_time(x, "analysis") together with the decoder and projection generics.

Installation

# Install from GitHub
# remotes::install_github("bbuchsbaum/fmrilatent")
install.packages("fmrilatent", repos = c('https://bbuchsbaum.r-universe.dev', 'https://cloud.r-project.org'))

Dependencies

The package requires neuroim2 for neuroimaging data structures:

remotes::install_github("bbuchsbaum/neuroim2")

Quick Start

Basic Usage

library(fmrilatent)
library(neuroim2)
library(Matrix)

# Create example data
n_time <- 100
n_components <- 10
n_voxels <- 1000

# Temporal basis (time x components)
basis <- Matrix(rnorm(n_time * n_components), nrow = n_time)

# Spatial loadings (voxels x components)
loadings <- Matrix(rnorm(n_voxels * n_components), nrow = n_voxels, sparse = TRUE)

# Create 4D space and mask
space <- NeuroSpace(c(10, 10, 10, n_time))
mask <- LogicalNeuroVol(array(TRUE, c(10, 10, 10)), NeuroSpace(c(10, 10, 10)))

# Construct LatentNeuroVec
lvec <- LatentNeuroVec(
  basis = basis,
  loadings = loadings,
  space = space,
  mask = mask
)

# Access components
basis(lvec)      # Get temporal basis
loadings(lvec)   # Get spatial loadings
lvec[[1]]        # Extract first volume

Using the Encoding API

The encode() function provides a high-level interface for creating latent representations:

# Create data matrix (time x voxels)
X <- matrix(rnorm(n_time * n_voxels), nrow = n_time)

# Encode with temporal Slepian basis
lvec <- encode(X, spec_time_slepian(tr = 2, bandwidth = 0.1), mask = mask)

# Encode with DCT basis
lvec_dct <- encode(X, spec_time_dct(k = 15), mask = mask)

# Spatiotemporal encoding (separable)
lvec_st <- encode(X, 
  spec_st(
    time = spec_time_bspline(k = 10),
    space = spec_space_slepian(k = 3)
  ),
  mask = mask
)

Transport-Backed Encoding

Transport-backed encoding uses a shared basis asset together with a subject-specific field operator. The target mask must describe the field operator target domain. Pass it explicitly, or attach it to field_operator$provenance$target_mask.

Downstream Handoff

The stable handoff to downstream model-fitting code is:

In v1, analysis coordinates are Euclidean by contract. Raw-coordinate metrics are only exposed when the raw-to-analysis transform has an explicit linear matrix representation.

Available Basis Families

Temporal bases:

Spatial bases:

Combined:

Lazy Evaluation with Handles

For memory efficiency, bases can be computed lazily:

# Create with handle (lazy evaluation)
lvec <- encode(X, spec_time_slepian(tr = 2), mask = mask, materialize = "handle")

# Basis is computed on first access
b <- basis(lvec)  # Materializes and caches the basis

Key Features

Documentation

License

GPL (>= 3)

Albers theme

This package uses the albersdown theme. Existing vignette theme hooks are replaced so albers.css and local albers.js render consistently on CRAN and GitHub Pages. The defaults are configured via params$family and params$preset (family = 'red', preset = 'homage'). The pkgdown site uses template: { package: albersdown } together with generated pkgdown/extra.css and pkgdown/extra.js so the theme is linked and activated on site pages.