Source code for mvpure_py.utils.algebra
""" Functions for computing algebraic expressions. """
# Author: Julia Jurkowska
import numpy as np
[docs]
def get_pinv_RN_eigenvals(
R: np.ndarray,
N: np.ndarray
):
eigvals = np.real(
np.sort(np.linalg.eigvals(R @ np.linalg.pinv(N)))
)[::-1]
return eigvals
def _get_S(H: np.ndarray, R: np.ndarray) -> np.ndarray:
"""
Compute the matrix S based on the given transformation.
Using eq. 21.
S is defined as: S := H^t * R^(-1) * H
Where:
- H is a leadfield for given sources
- R is data covariance matrix
Parameters:
-----------
H : array-like
Leadfield matrix
R : array-like
Data covariance matrix
Returns
-------
array-like: Computed matrix S
"""
if H.ndim == 3 and H.shape[2] == 1:
H = np.squeeze(H, axis=-1)
if H.shape[0] == R.shape[0]:
return np.transpose(H) @ np.linalg.pinv(R) @ H
elif H.shape[1] == R.shape[0]:
return H @ np.linalg.pinv(R) @ np.transpose(H)
def _get_G(H: np.ndarray, N: np.ndarray) -> np.ndarray:
"""
Compute the matrix G based on a given transformation.
Using eq. 8.
G is defined as: G := H^t * N^(-1) * H
Where:
- H is a leadfield for given sources
- N is noise covariance matrix
Parameters:
-----------
H : array-like
Leadfield matrix
N : array-like
Noise covariance matrix
Returns
-------
float | array-like : Computed matrix G
"""
if H.ndim == 3 and H.shape[2] == 1:
H = np.squeeze(H, axis=-1)
if H.shape[0] == N.shape[0]:
return np.transpose(H) @ np.linalg.pinv(N) @ H
elif H.shape[1] == N.shape[0]:
return H @ np.linalg.pinv(N) @ np.transpose(H)
def _get_T(H: np.ndarray, R: np.ndarray, N: np.ndarray) -> np.ndarray:
"""
Compute the matrix T based on a given transformation.
Using eq. 22.
T is defined as: T := H^t * R^(-1) * N * R^(-1) * H * S^*(-1)
Where:
S := H^t * R^(-1) * H
G := H^t * N^(-1) * H
- H is a leadfield for given sources
- R is data covariance matrix
- N is noise covariance matrix
Parameters
----------
H : array-like
Leadfield matrix
R : array-like
Data covariance matrix
N : array-like
Noise covariance matrix
Returns
-------
float | array-like: Computed matrix T
"""
R_pinv = np.linalg.pinv(R)
return np.transpose(H) @ R_pinv @ N @ R_pinv @ H
def _get_Q(S: float | np.ndarray, G: float | np.ndarray) -> float | np.ndarray:
"""
Compute the matrix Q for a given transformation.
The matrix Q is defined as:
Q = (H^t * R^(-1) * H^(-1))
- (H^t * N^(-1) * H^(-1))
Note that S = H^t * R^(-1) * H^(-1) [eq. 5]
and G = H^t * N^(-1) * H^(-1) [eq. 8]
Therefore:
Q = S^(-1) - G^(-1)
for 1 ≤ l ≤ l0.
Parameters
----------
S : array-like
Matrix as in eq. 5.
Can be obtained using function _get_S.
G : array-like
Matrix as in eq. 8.
Can be obtained using function _get_G.
Returns
-------
float | array-like: Computed matrix Q.
"""
if isinstance(G, float) and isinstance(S, float):
G = np.array([[G]])
S = np.array([[S]])
Q = np.linalg.pinv(S) - np.linalg.pinv(G)
if Q.size == 1:
return float(Q)
return Q