spd_learn.functional.log_cholesky_mean#
- spd_learn.functional.log_cholesky_mean(matrices, weights=None)[source]#
Compute the weighted mean in the Log-Cholesky space.
The Log-Cholesky mean is the arithmetic mean of the Log-Cholesky representations, mapped back to the SPD manifold:
\[\bar{X} = \exp_{\text{chol}}\left(\sum_{i=1}^{N} w_i \log_{\text{chol}}(L_i)\right)\]where \(w_i\) are the weights (summing to 1) and \(X_i = L_i L_i^T\).
- Parameters:
matrices (torch.Tensor) – SPD matrices of shape (N, …, n, n) where N is the number of matrices to average.
weights (torch.Tensor, optional) – Weights of shape (N,) or broadcastable. If None, uniform weights are used. Weights are automatically normalized to sum to 1.
- Returns:
Mean SPD matrix of shape (…, n, n).
- Return type:
Notes
The Log-Cholesky mean has the following properties [Lin, 2019]:
It is the unique minimizer of the sum of squared Log-Cholesky distances.
It can be computed in closed form (no iterative optimization required).
It is computationally more efficient than the Fréchet mean under AIRM.
See also
log_cholesky_distance()Distance under Log-Cholesky metric.
log_cholesky_geodesic()Geodesic interpolation under Log-Cholesky metric.
log_euclidean_mean()Mean under Log-Euclidean metric.
bures_wasserstein_mean()Mean under Bures-Wasserstein metric.
SPDBatchNormMeanVarUses Fréchet mean for batch normalization.
Examples
>>> import torch >>> # Create 4 SPD matrices of size 3x3 >>> matrices = torch.stack([ ... torch.eye(3), ... 2 * torch.eye(3), ... 3 * torch.eye(3), ... 4 * torch.eye(3) ... ]) >>> mean = log_cholesky_mean(matrices) >>> print(f"Mean diagonal: {torch.diag(mean)}") Mean diagonal: tensor([2.2134, 2.2134, 2.2134])