Linear Algebra Utilities
- causationentropy.core.linalg.correlation_log_determinant(A, epsilon=1e-10)[source]
Compute the logarithm of the determinant of a correlation matrix.
This function calculates the signed log-determinant of the correlation matrix derived from the input data matrix A. The correlation matrix is defined as:
\[\mathbf{R}_{ij} = \frac{\text{Cov}(X_i, X_j)}{\sqrt{\text{Var}(X_i) \text{Var}(X_j)}}\]The log-determinant is computed using:
\[\log |\mathbf{R}| = \text{sign}(|\mathbf{R}|) \cdot \log(||\mathbf{R}||)\]This approach provides numerical stability for matrices that may be close to singular.
- Parameters:
A (array-like of shape (n_samples, n_features)) – Input data matrix where rows are samples and columns are features.
epsilon (float, default=1e-10) – Small regularization parameter (currently unused but reserved for potential numerical stabilization).
- Returns:
log_det – Logarithm of the determinant of the correlation matrix. Returns 0.0 for degenerate cases (empty matrix or scalar).
- Return type:
Notes
Special Cases: - Empty matrix (n_features = 0): Returns 0.0 - Scalar correlation (1x1 matrix): Returns 0.0 - Singular matrix: May return -inf or raise warnings
Numerical Considerations: - Uses numpy.linalg.slogdet for stable computation of log-determinant - Handles edge cases gracefully without exceptions - More stable than computing log(det(R)) directly
Applications: - Gaussian mutual information calculation - Model selection criteria (AIC, BIC) - Multivariate normality testing - Information-theoretic measures
Interpretation: - Large positive values: High linear dependence among variables - Values near zero: Near-independence of variables - Large negative values: Multicollinearity, near-singular correlation matrix
Examples
>>> import numpy as np >>> from causationentropy.core.linalg import correlation_log_determinant >>> >>> # Independent variables >>> A_indep = np.random.randn(100, 3) >>> log_det_indep = correlation_log_determinant(A_indep) >>> print(f"Independent variables log-det: {log_det_indep:.3f}") >>> >>> # Correlated variables >>> A_corr = np.random.randn(100, 1) >>> A_corr = np.hstack([A_corr, A_corr + 0.1*np.random.randn(100, 1)]) >>> log_det_corr = correlation_log_determinant(A_corr) >>> print(f"Correlated variables log-det: {log_det_corr:.3f}") >>> >>> # Expected: log_det_corr < log_det_indep due to correlation
See also
numpy.corrcoefCompute correlation coefficients
numpy.linalg.slogdetCompute sign and log-determinant
- causationentropy.core.linalg.subnetwork(G, lag)[source]
Extract a subgraph containing only edges at a specific lag.
The general return value from discover_network is a NetworkX MultiDiGraph with lag, p-value, and cmi encoded as edge attributes. This method returns a DiGraph containing only edges at the specified lag value.
Since the input is a MultiDiGraph, bidirectional connections at the same lag are represented as two separate directed edges: one from i to j and one from j to i.
- Parameters:
G (nx.MultiDiGraph) – The causal network graph from discover_network with edge attributes ‘lag’, ‘cmi’, and ‘p_value’.
lag (int) – The time lag to extract. Only edges with this lag value will be included.
- Returns:
H – A directed graph containing only the edges at the specified lag. Edge attributes ‘cmi’ and ‘p_value’ are preserved.
- Return type:
nx.DiGraph
Examples
>>> import networkx as nx >>> from causationentropy.core.linalg import subnetwork >>> >>> G = nx.MultiDiGraph() >>> G.add_edge(0, 1, lag=1, cmi=0.5, p_value=0.01) >>> G.add_edge(1, 2, lag=2, cmi=0.3, p_value=0.05) >>> >>> H1 = subnetwork(G, lag=1) >>> H1.number_of_edges() 1
- causationentropy.core.linalg.companion_matrix(G)[source]
Construct the block companion matrix for a causal network.
The purpose of this method is to store the causal graph in a structure that this library prefers and is not necessarily the graph theoretical construction.
The companion matrix is a block-structured matrix used in vector autoregression (VAR) and dynamical systems analysis:
\[\begin{split}C = \begin{bmatrix} A^{(1)} & A^{(2)} & \cdots & A^{(K-1)} & A^{(K)} \\ I & 0 & \cdots & 0 & 0 \\ 0 & I & \cdots & 0 & 0 \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & \cdots & I & 0 \end{bmatrix}\end{split}\]Each \(A^{(k)}\) is the adjacency matrix of edges with lag = k, and I represents an identity matrix of size n x n.
- Parameters:
G (nx.MultiDiGraph) – The causal network graph from discover_network. Must contain edge attribute ‘lag’.
- Returns:
C – The block companion matrix. Returns empty (0, 0) array if max_lag = 0.
- Return type:
np.ndarray of shape (n_nodes * max_lag, n_nodes * max_lag)
Notes
Nodes are ordered according to NetworkX’s default ordering (sorted)
Edges with lag=0 are ignored (contemporaneous effects not included)
The matrix enables analysis of temporal dynamics via eigenvalue analysis
Examples
>>> import networkx as nx >>> import numpy as np >>> from causationentropy.core.linalg import companion_matrix >>> >>> G = nx.MultiDiGraph() >>> G.add_nodes_from([0, 1, 2]) >>> G.add_edge(0, 1, lag=1, cmi=0.5, p_value=0.01) >>> G.add_edge(1, 2, lag=2, cmi=0.3, p_value=0.05) >>> >>> C = companion_matrix(G) >>> print(C.shape) (6, 6)