Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

matrix

matrix

Matrix permutation test implementations (Mantel test).

This module provides CPU-parallel implementations of matrix permutation tests for testing correlation between two square matrices, as well as matrix utility functions for distance correlation and matrix centering operations.

Attributes:

NameTypeDescription
MAX_INT

Methods:

NameDescription
distance_correlationCompute the distance correlation between 2 arrays to test for multivariate dependence (linear or non-linear).
double_centerDouble center a 2d array.
matrix_permutation_testMatrix permutation test (Mantel test) for correlating two square matrices.
u_centerU-center a 2d array. U-centering is a bias-corrected form of double-centering.

Methods

distance_correlation

distance_correlation(x: np.ndarray, y: np.ndarray, bias_corrected: bool = True, ttest: bool = False) -> dict

Compute the distance correlation between 2 arrays to test for multivariate dependence (linear or non-linear).

Arrays must match on their first dimension. It’s almost always preferable to compute the bias_corrected version which can also optionally perform a ttest. This ttest operates on a statistic thats ~dcorr^2 and will be also returned.

Explanation: Distance correlation involves computing the normalized covariance of two centered euclidean distance matrices. Each distance matrix is the euclidean distance between rows (if x or y are 2d) or scalars (if x or y are 1d). Each matrix is centered prior to computing the covariance either using double-centering or u-centering, which corrects for bias as the number of dimensions increases. U-centering is almost always preferred in all cases. It also permits inference of the normalized covariance between each distance matrix using a one-tailed directional t-test. (Szekely & Rizzo, 2013). While distance correlation is normally bounded between 0 and 1, u-centering can produce negative estimates, which are never significant.

Validated against the dcor and dcor.ttest functions in the ‘energy’ R package and the dcor.distance_correlation, dcor.udistance_correlation_sqr, and dcor.independence.distance_correlation_t_test functions in the dcor Python package.

Parameters:

NameTypeDescriptionDefault
xndarray1d or 2d numpy array of observations by featuresrequired
yndarray1d or 2d numpy array of observations by featuresrequired
bias_correctedboolif false use double-centering which produces a biased-estimate that converges to 1 as the number of dimensions increase. Otherwise used u-centering to correct this bias. Note this must be True if ttest=True; default TrueTrue
ttestboolperform a ttest using the bias_corrected distance correlation; default FalseFalse

Returns:

NameTypeDescription
resultsdictdictionary of results (correlation, t, p, and df.) Optionally, covariance, x variance, and y variance

Examples:

>>> import numpy as np
>>> x = np.random.randn(20, 3)
>>> y = x + np.random.randn(20, 3) * 0.1  # Strongly correlated
>>> result = distance_correlation(x, y, bias_corrected=True)
>>> 'dcorr' in result
True
>>> 0 <= result['dcorr'] <= 1
True

double_center

double_center(mat: np.ndarray) -> np.ndarray

Double center a 2d array.

Double-centering subtracts row means, column means, and adds the grand mean. This centers both rows and columns around zero.

Parameters:

NameTypeDescriptionDefault
matndarray2d numpy arrayrequired

Returns:

NameTypeDescription
matndarraydouble-centered version of input

Examples:

>>> mat = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=float)
>>> result = double_center(mat)
>>> np.allclose(result.mean(axis=0), 0)
True
>>> np.allclose(result.mean(axis=1), 0)
True

matrix_permutation_test

matrix_permutation_test(data1: np.ndarray, data2: np.ndarray, *, n_permute: int = 5000, metric: str = 'pearson', how: str = 'upper', include_diag: bool = False, tail: int | str = 2, return_null: bool = False, device: str | None = 'cpu', n_jobs: int = -1, random_state: int | None = None, progress_bar: bool = False) -> dict

Matrix permutation test (Mantel test) for correlating two square matrices.

Tests whether the correlation between elements of two matrices is significant by permuting rows and columns of one matrix symmetrically while keeping the other fixed.

Statistical Method: For each permutation, create random permutation perm, then apply: matrix1[perm][:, perm]. This preserves matrix structure while destroying correlation. Count how often permuted correlation is as extreme as observed.

Assumptions:

Parameters:

NameTypeDescriptionDefault
data1ndarrayFirst square matrix (n×n)required
data2ndarraySecond square matrix (n×n)required
n_permuteintNumber of permutations (default: 5000)5000
metricstrCorrelation metric [‘pearson’‘spearman’
howstrWhich elements to compare [‘upper’‘lower’
include_diagboolInclude diagonal elements (only applies if how=‘full’) (default: False)False
tailint | strTest type — 2‘two’ (two-tailed, default) or 1
return_nullboolReturn null distribution (default: False)False
devicestrParallelization method (default: ‘cpu’) - None: Single-threaded NumPy (for debugging/small problems) - ‘cpu’: CPU parallelization via joblib (default, 4-8× speedup)‘cpu’
n_jobsintNumber of parallel workers, -1 = all cores (default: -1) Only used when device=‘cpu’-1
random_stateintRandom seed for reproducibilityNone
progress_barboolShow a progress bar over permutations (default: False)False

Returns:

NameTypeDescription
dictdictDictionary with keys: - ‘correlation’ (float): Observed correlation coefficient - ‘p’ (float): P-value using Phipson-Smyth correction - ‘device’ (str): Parallelization method used (‘cpu’ or None) - ‘null_dist’ (np.ndarray): Null distribution (if return_null=True)
References

Chen, G. et al. (2016). Untangling the relatedness among correlations, part I: nonparametric approaches to inter-subject correlation analysis at the group level. NeuroImage, 142, 248-259.

Mantel, N. (1967). The detection of disease clustering and a generalized regression approach. Cancer Research, 27(2), 209-220.

Examples:

>>> import numpy as np
>>> from nltools.algorithms.inference import matrix_permutation_test
>>>
>>> # Create two correlated similarity matrices
>>> np.random.seed(42)
>>> n = 50
>>> true_pattern = np.random.randn(n)
>>> data1 = np.corrcoef(true_pattern + np.random.randn(n) * 0.1)
>>> data2 = np.corrcoef(true_pattern + np.random.randn(n) * 0.1)
>>>
>>> # Test if matrices are correlated
>>> result = matrix_permutation_test(data1, data2, n_permute=1000)
>>> print(f"Correlation: {result['correlation']:.3f}, p = {result['p']:.4f}")

u_center

u_center(mat: np.ndarray) -> np.ndarray

U-center a 2d array. U-centering is a bias-corrected form of double-centering.

U-centering corrects for bias that occurs with double-centering as the number of dimensions increases. The diagonal is explicitly set to zero.

Parameters:

NameTypeDescriptionDefault
matndarray2d numpy arrayrequired

Returns:

NameTypeDescription
matndarrayu-centered version of input

Examples:

>>> mat = np.random.randn(5, 5)
>>> result = u_center(mat)
>>> np.allclose(np.diag(result), 0)
True