mixle.stats.matrix.matrix_normal module

Matrix normal distribution MN(M, U, V) – a distribution over n-by-p real matrices.

The matrix normal is the Gaussian on matrices with a separable (Kronecker) covariance: a draw X has mean matrix M (n, p), an among-row covariance U (n, n) and an among-column covariance V (p, p), and vec(X) ~ N(vec(M), V (x) U) (column-stacking vec). Equivalently X = M + A Z B^T with U = A A^T, V = B B^T and Z standard normal. Its density is

log p(X) = -np/2 log(2pi) - n/2 log|V| - p/2 log|U| - 1/2 tr(U^{-1} (X-M) V^{-1} (X-M)^T).

U and V are identifiable only through their Kronecker product U (x) V (scaling U by c and V by 1/c is the same law), so the estimator anchors V[0,0] = 1. It is fit by the standard flip-flop MLE: alternate the closed-form updates of U given V and V given U to convergence – here from a fixed sufficient statistic (the row-blocked second moment), so it converges inside a single estimate call.

Reference: Dawid, ‘Some matrix-variate distribution theory’, Biometrika (1981).

class MatrixNormalDistribution(mean, row_covar, col_covar, name=None, keys=None)[source]

Bases: SequenceEncodableProbabilityDistribution

Matrix normal distribution over (n, p) matrices with row covariance U and column covariance V.

Parameters:
density(x)[source]

Return the matrix-normal density at a single (n, p) matrix.

Parameters:

x (ndarray)

Return type:

float

log_density(x)[source]

Return the log-density at a single (n, p) matrix.

Parameters:

x (ndarray)

Return type:

float

seq_log_density(x)[source]

Vectorized log-density for a stack of matrices, shape (N, n, p).

Parameters:

x (ndarray)

Return type:

ndarray

sampler(seed=None)[source]

Return a sampler for drawing matrices from this distribution.

Parameters:

seed (int | None)

Return type:

MatrixNormalSampler

estimator(pseudo_count=None)[source]

Return a flip-flop MLE estimator for the mean and the two covariance factors.

Parameters:

pseudo_count (float | None)

Return type:

MatrixNormalEstimator

dist_to_encoder()[source]

Return the data encoder used by this distribution for vectorized methods.

Return type:

MatrixNormalDataEncoder

class MatrixNormalSampler(dist, seed=None)[source]

Bases: DistributionSampler

Draw matrices by X = M + chol(U) Z chol(V)^T with Z standard normal.

Parameters:
  • dist (MatrixNormalDistribution)

  • seed (int | None)

sample(size=None)[source]

Draw one matrix or a batch of independent matrix-normal samples.

Parameters:

size (int | None)

Return type:

ndarray

class MatrixNormalAccumulator(n, p, name=None, keys=None)[source]

Bases: SequenceEncodableStatisticAccumulator

Accumulate the mean and the row-blocked second moment T[a,b,c,d] = sum_i X_i[a,c] X_i[b,d].

Parameters:
update(x, weight, estimate)[source]

Accumulate weighted mean and row-blocked second moments for one matrix.

Parameters:
  • x (ndarray)

  • weight (float)

  • estimate (MatrixNormalDistribution | None)

Return type:

None

initialize(x, weight, rng)[source]

Initialize the sufficient statistics with one weighted matrix.

Parameters:
Return type:

None

seq_update(x, weights, estimate)[source]

Accumulate weighted mean and block moments for encoded matrices.

Parameters:
  • x (ndarray)

  • weights (ndarray)

  • estimate (MatrixNormalDistribution | None)

Return type:

None

seq_initialize(x, weights, rng)[source]

Initialize the sufficient statistics from encoded matrices.

Parameters:
Return type:

None

combine(suff_stat)[source]

Merge serialized matrix-normal sufficient statistics into this accumulator.

Parameters:

suff_stat (tuple[ndarray, ndarray, float])

Return type:

MatrixNormalAccumulator

value()[source]

Return the weighted sum, block second moment, and total weight.

Return type:

tuple[ndarray, ndarray, float]

from_value(x)[source]

Restore the accumulator from serialized matrix-normal statistics.

Parameters:

x (tuple[ndarray, ndarray, float])

Return type:

MatrixNormalAccumulator

key_merge(stats_dict)[source]

Merge this accumulator into a keyed statistics dictionary.

Parameters:

stats_dict (dict[str, Any])

Return type:

None

key_replace(stats_dict)[source]

Replace this accumulator from a keyed statistics dictionary.

Parameters:

stats_dict (dict[str, Any])

Return type:

None

acc_to_encoder()[source]

Return an encoder compatible with matrix-normal vectorized updates.

Return type:

MatrixNormalDataEncoder

class MatrixNormalAccumulatorFactory(n, p, name=None, keys=None)[source]

Bases: StatisticAccumulatorFactory

Factory for MatrixNormalAccumulator.

Parameters:
make()[source]

Create an empty matrix-normal accumulator.

Return type:

MatrixNormalAccumulator

class MatrixNormalEstimator(n, p, max_iter=100, tol=1.0e-9, name=None, keys=None)[source]

Bases: ParameterEstimator

Flip-flop maximum-likelihood estimator for the matrix-normal parameters.

Parameters:
accumulator_factory()[source]

Return a factory for matrix-normal sufficient-statistic accumulators.

Return type:

MatrixNormalAccumulatorFactory

estimate(nobs, suff_stat)[source]

Estimate the mean and covariance factors using flip-flop updates.

Parameters:
Return type:

MatrixNormalDistribution

class MatrixNormalDataEncoder[source]

Bases: DataSequenceEncoder

Encode a sequence of (n, p) matrices as an (N, n, p) float array.

seq_encode(x)[source]

Encode matrices as a floating-point stack for vectorized evaluation.

Parameters:

x (Sequence[ndarray])

Return type:

ndarray