The manifold hypothesis
Record N neurons and each moment gives an N-dimensional activity vector. Empirically, the cloud of points does not fill N-space; it clusters near a low-dimensional manifold of dimension d \ll N. Shared inputs and recurrent connectivity make neurons co-vary, so the effective degrees of freedom are few. The neural trajectory is the path the state traces on that manifold during a movement — and it, not the individual spike trains, is what we want to decode.
Linear reduction: PCA and factor analysis
PCA finds orthogonal directions of maximal variance and keeps the top d. But PCA lumps shared signal together with private, single-neuron noise, so noisy channels can hijack the top components. Factor analysis fixes this by modeling each neuron as shared latent factors (through a loading matrix \Lambda) plus independent private noise.
\mathbf{x} = \Lambda\mathbf{z} + \boldsymbol{\epsilon}, \quad \boldsymbol{\epsilon}\sim\mathcal{N}(0,\Psi)\ \text{diagonal} \;\Rightarrow\; \operatorname{Cov}(\mathbf{x}) = \Lambda\Lambda^{\top} + \PsiFactor analysis splits the covariance into shared structure \Lambda\Lambda^{\top} and diagonal private variance \Psi — the right split for independently noisy spikes.
Factor analysis explains the correlations among many neurons with a few shared hidden factors, and lets each neuron keep its own private noise. It splits total covariance into a shared part and a diagonal private part — the right model when each spike train is independently noisy.
- \mathbf{z}
- The few shared latent factors.
- \Lambda
- The loading matrix mapping factors to neurons.
- \Lambda\Lambda^{\top}
- The shared covariance structure — the low-dimensional part.
- \Psi
- Diagonal matrix of each neuron's private variance.
Two neurons driven by a common factor co-vary through \Lambda\Lambda^{\top}; their leftover jitter lives in \Psi — the shared structure is the neural manifold.
How many dimensions?
Given the covariance eigenvalues \lambda_i, the participation ratio gives a single number for effective dimensionality: it is large when variance is spread evenly across many modes and small when a few modes dominate.
d_{\mathrm{PR}} = \frac{\left(\sum_i \lambda_i\right)^{2}}{\sum_i \lambda_i^{2}}Participation ratio: effective dimensionality from the covariance eigenvalues.
The participation ratio turns a spread of variance across dimensions into a single effective number of dimensions. If variance is spread evenly over many dimensions it is high; if one dimension dominates it is near 1.
- \lambda_i
- The eigenvalues of the covariance — variance along each principal axis.
- \frac{\left(\sum_i \lambda_i\right)^{2}}{\sum_i \lambda_i^{2}}
- The effective dimension count.
Ten equal eigenvalues give d_{\mathrm{PR}} = 10; one huge plus nine tiny gives d_{\mathrm{PR}}\approx 1 — a measure of neural dimensionality.
# X: (T, N) trial-concatenated, mean-centered activity cov = np.cov(X, rowvar=False) # (N, N) lam = np.linalg.eigvalsh(cov) # eigenvalues d_pr = lam.sum()**2 / (lam**2).sum() # participation ratio
For simple reaching, effective dimensionality is often small — on the order of ten — even with hundreds of neurons, and it grows with task complexity. The caveat matters: measured dimensionality depends on the task, the number of neurons, and the trial count. It is a property of the experiment as much as of the brain.
GPFA: smooth single-trial latents
Trial-averaging is the cheap way to see structure, but it hides single-trial dynamics — exactly what a real-time BCI must decode. Gaussian-process factor analysis extracts smooth latent trajectories from single trials by placing a temporal Gaussian-process smoothness prior on each latent, jointly with the factor-analysis observation model. The result is denoised single-trial latent states you can decode from.
Shared variability, and why it matters
The on-manifold versus off-manifold split is not just tidy math. Shared variability and noise correlations set how decodable information scales with neuron count and constrain what a decoder can achieve. Structured covariance is why the OLE beat the population vector in the last guide, and it is the same covariance a Kalman or Riemannian decoder exploits — the manifold view and the estimator view are two sides of one coin.