spectral_connectivity.minimum_phase_decomposition.minimum_phase_decomposition#
- minimum_phase_decomposition(cross_spectral_matrix: ndarray[tuple[int, ...], dtype[complexfloating]], tolerance: float = 1e-08, max_iterations: int = 500, *, _warn_on_failure: bool = True) ndarray[tuple[int, ...], dtype[complexfloating]][source]#
Compute minimum phase decomposition using Wilson algorithm.
Finds a minimum phase matrix square root G of the cross-spectral density matrix S such that S = G G^H, where all poles of G are inside the unit circle. This decomposition is essential for computing directed connectivity measures like spectral Granger causality.
- Parameters:
cross_spectral_matrix (NDArray[complexfloating],) – shape (n_time_samples, …, n_fft_samples, n_signals, n_signals) Cross-spectral density matrix to be decomposed. Must be Hermitian positive semidefinite for each frequency.
tolerance (float, default=1e-8) – Relative convergence tolerance for Wilson algorithm iterations.
max_iterations (int, default=500) – Maximum number of iterations before stopping algorithm. Near-singular cross-spectral matrices (highly correlated channels) can need several hundred iterations to reach the relative tolerance; the loop returns early as soon as every sub-spectrum has converged.
- Returns:
minimum_phase_factor – shape (n_time_samples, …, n_fft_samples, n_signals, n_signals) Minimum phase square root of cross_spectral_matrix. All eigenvalues have negative real parts (minimum phase property).
- Return type:
NDArray[complexfloating],
Examples
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> n_times, n_freqs, n_signals = 1, 32, 2 >>> # A valid cross-spectral matrix (Hermitian positive definite). Here it is >>> # constant across frequency (a white process), which factors exactly. >>> a = rng.standard_normal((n_signals, n_signals)) >>> spd = a @ a.T + n_signals * np.eye(n_signals) >>> cross_spec = np.tile(spd, (n_times, n_freqs, 1, 1)) >>> min_phase = minimum_phase_decomposition(cross_spec) >>> # The factor reconstructs the input: G @ G^H == S. >>> reconstructed = np.matmul(min_phase, min_phase.conj().swapaxes(-1, -2)) >>> error = np.abs(reconstructed - cross_spec).max() >>> bool(error < 1e-6) True
Notes
The Wilson algorithm iteratively refines an initial guess using the “plus” operator (causal projection) until convergence. The algorithm may not converge for all time points; warnings are issued when the maximum iteration count is reached.
When the spectrum is exactly conjugate-symmetric,
S(-f) == conj(S(f))bit for bit (as SciPy’s FFT gives for real-valued signals), every iterate keeps that symmetry, so the iteration runs on the non-negative frequencies with real FFTs and mirrors the rest. Spectra symmetric only up to rounding (possible with other FFT backends such as CuPy’s), or not at all (complex-valued signals), take the two-sided iteration, which does about twice the arithmetic per iteration.Each update is built from a square root
LofS(S = L Lᴴ), computed once, which lets sub-spectra with near-collinear channels converge. An indefinite or non-finiteShas no such square root and is returned as NaN with the non-convergence warning.Convergence of the iterate does not by itself guarantee
G Gᴴ ≈ S. The factorization assumes the cross-spectrum is resolved finely enough in frequency that the corresponding autocovariance decays within the analysis window; an under-resolved (aliased) spectrum can satisfy the successive- iterate convergence test yet reconstructSpoorly, silently biasing the directed-connectivity measures built on it. Useminimum_phase_reconstruction_error()to check factorization quality explicitly, and a longer FFT (largern_fft_samples/n_time_samples_per_window) if the error is large.References
[1]Wilson, G. T. (1972). The factorization of matricial spectral densities. SIAM Journal on Applied Mathematics, 23(4), 420-426.
[2]Dhamala, M., Rangarajan, G., & Ding, M. (2008). Analyzing information flow in brain networks with nonparametric Granger causality. NeuroImage, 41(2), 354-362.