brainda.algorithms.manifold package

Submodules

brainda.algorithms.manifold.riemann module

Riemannian Geometry for BCI.

class brainda.algorithms.manifold.riemann.Alignment(align_method: str = 'euclid', cov_method: str = 'lwf', n_jobs: Optional[int] = None)

Bases: BaseEstimator, TransformerMixin

Riemannian/Euclidean Alignment.

fit(X: ndarray, y: Optional[ndarray] = None)
transform(X)
class brainda.algorithms.manifold.riemann.FGDA(n_jobs=1)

Bases: BaseEstimator, TransformerMixin

Fisher Geodesic Discriminat Analysis.

fit(X, y)
transform(X)
class brainda.algorithms.manifold.riemann.FgMDRM(n_jobs: Optional[int] = None)

Bases: BaseEstimator, TransformerMixin, ClassifierMixin

fit(X: ndarray, y: ndarray, sample_weight: Optional[ndarray] = None)
predict(X: ndarray)
transform(X: ndarray)
class brainda.algorithms.manifold.riemann.MDRM(n_jobs: int = 1)

Bases: BaseEstimator, TransformerMixin, ClassifierMixin

fit(X: ndarray, y: ndarray, sample_weight: Optional[ndarray] = None)
predict(X: ndarray)
predict_proba(X: ndarray)
transform(X: ndarray)
class brainda.algorithms.manifold.riemann.RecursiveAlignment(align_method: str = 'euclid', cov_method: str = 'lwf', n_jobs: Optional[int] = None)

Bases: BaseEstimator, TransformerMixin

Recursive Riemannian/Euclidean Alignment.

fit(X, y=None)
transform(X)
class brainda.algorithms.manifold.riemann.TSClassifier(clf=LogisticRegression(), n_jobs=None)

Bases: BaseEstimator, ClassifierMixin

fit(X: ndarray, y: ndarray)
predict(X: ndarray)
predict_proba(X: ndarray)
brainda.algorithms.manifold.riemann.distance_riemann(A: ndarray, B: ndarray, n_jobs: Optional[int] = None)

Riemannian distance between two covariance matrices A and B.

Parameters:
  • A (ndarray) – First positive-definite matrix, shape (n_trials, n_channels, n_channels) or (n_channels, n_channels).

  • B (ndarray) – Second positive-definite matrix.

Returns:

Riemannian distance between A and B.

Return type:

ndarray | float

Notes

\[d = {\left( \sum_i \log(\lambda_i)^2 \right)}^{-1/2}\]

where \(\lambda_i\) are the joint eigenvalues of A and B.

brainda.algorithms.manifold.riemann.expmap(Si: ndarray, P: ndarray, n_jobs: Optional[int] = None)

Exponential map from the tangent space to the positive-definite space.

Exponential map projects \(\mathbf{S}_i \in \mathcal{T}_{\mathbf{P}} \mathcal{M}\) bach to the manifold \(\mathcal{M}\).

Parameters:
  • Si (ndarray) – Tangent space point (in matrix form).

  • P (ndarray) – Reference point.

  • n_jobs (int, optional) – the number of jobs to use.

Returns:

Pi – SPD matrix.

Return type:

ndarray

brainda.algorithms.manifold.riemann.geodesic(P1: ndarray, P2: ndarray, t: float, n_jobs: Optional[int] = None)

Geodesic.

The geodesic curve between any two SPD matrices \(\mathbf{P}_1,\mathbf{P}_2 \in \mathcal{M}\).

Parameters:
  • P1 (ndarray) – SPD matrix.

  • P2 (ndarray) – SPD matrix, the same shape of P1.

  • t (float) – \(0 \leq t \leq 1\).

  • n_jobs (int, optional) – the number of jobs to use.

Returns:

phi – SPD matrix on the geodesic curve between P1 and P2.

Return type:

ndarray

brainda.algorithms.manifold.riemann.logmap(Pi: ndarray, P: ndarray, n_jobs: Optional[int] = None)

Logarithm map from the positive-definite space to the tangent space.

Logarithm map projects \(\mathbf{P}_i \in \mathcal{M}\) to the tangent space point \(\mathbf{S}_i \in \mathcal{T}_{\mathbf{P}} \mathcal{M}\) at \(\mathbf{P} \in \mathcal{M}\).

Parameters:
  • Pi (ndarray) – SPD matrix.

  • P (ndarray) – Reference point.

  • n_jobs (int, optional) – the number of jobs to use.

Returns:

Si – Tangent space point (in matrix form).

Return type:

ndarray

brainda.algorithms.manifold.riemann.mdrm_kernel(X: ndarray, y: ndarray, sample_weight: Optional[ndarray] = None, n_jobs: int = 1)

Minimum Distance to Riemannian Mean.

Parameters:
  • X (ndarray) – eeg data, shape (n_trials, n_channels, n_samples)

  • y (ndarray) – labels, shape (n_trials)

  • sample_weight (Optional[ndarray], optional) – sample weights, by default None

  • n_jobs (int) – the number of jobs to use, by default 1

Returns:

centroids of each class, shape (n_class, n_channels, n_channels).

Return type:

ndarray

brainda.algorithms.manifold.riemann.mean_riemann(covmats, tol=1e-11, maxiter=300, init=None, sample_weight=None, n_jobs=None)

Return the mean covariance matrix according to the Riemannian metric.

Parameters:
  • covmats (ndarray) – Covariance matrices set, shape (n_trials, n_channels, n_channels).

  • tol (float, optional) – The tolerance to stop the gradient descent (default 1e-8).

  • maxiter (int, optional) – The maximum number of iteration (default 50).

  • init (None|ndarray, optional) – A covariance matrix used to initialize the gradient descent (default None), if None the arithmetic mean is used.

  • sample_weight (None|ndarray, optional) – The weight of each sample (efault None), if None weights are 1 otherwise weights are normalized.

Returns:

C – The Riemannian mean covariance matrix.

Return type:

ndarray

Notes

The procedure is similar to a gradient descent minimizing the sum of riemannian distance to the mean.

\[\mathbf{C} = \arg \min{(\sum_i \delta_R ( \mathbf{C} , \mathbf{C}_i)^2)}\]

where :math:delta_R is riemann distance.

brainda.algorithms.manifold.riemann.tangent_space(Pi: ndarray, P: ndarray, n_jobs: Optional[int] = None)

Logarithm map projects SPD matrices to the tangent vectors.

Parameters:
  • Pi (ndarray) – SPD matrices, shape (n_trials, n_channels, n_channels).

  • P (ndarray) – Reference point.

Returns:

vSi – Tangent vectors, shape (n_trials, n_channels*(n_channels+1)/2).

Return type:

ndarray

brainda.algorithms.manifold.riemann.untangent_space(vSi: ndarray, P: ndarray, n_jobs: Optional[int] = None)

Logarithm map projects SPD matrices to the tangent vectors.

Parameters:
  • vSi (ndarray) – Tangent vectors, shape (n_trials, n_channels*(n_channels+1)/2).

  • P (ndarray) – Reference point.

Returns:

Pi – SPD matrices, shape (n_trials, n_channels, n_channels).

Return type:

ndarray

brainda.algorithms.manifold.riemann.unvectorize(vSi: ndarray)

unvectorize tangent space points.

Parameters:

vSi (ndarray) – vectorized version of Si, shape (n_trials, n_channels*(n_channels+1)/2)

Returns:

points in the tangent space, shape (n_trials, n_channels, n_channels)

Return type:

ndarray

brainda.algorithms.manifold.riemann.vectorize(Si: ndarray)

vectorize tangent space points.

Parameters:

Si (ndarray) – points in the tangent space, shape (n_trials, n_channels, n_channels)

Returns:

vectorized version of Si, shape (n_trials, n_channels*(n_channels+1)/2)

Return type:

ndarray

brainda.algorithms.manifold.rpa module

Riemannian Procrustes Analysis. Modified from https://github.com/plcrodrigues/RPA

brainda.algorithms.manifold.rpa.get_recenter(X: ndarray, cov_method: str = 'cov', mean_method: str = 'riemann', n_jobs: int = 1)
brainda.algorithms.manifold.rpa.get_rescale(X: ndarray, cov_method: str = 'cov', n_jobs: int = 1)
brainda.algorithms.manifold.rpa.get_rotate(Xs: ndarray, ys: ndarray, Xt: ndarray, yt: ndarray, cov_method: str = 'cov', metric: str = 'euclid', n_jobs: int = 1)
brainda.algorithms.manifold.rpa.recenter(X: ndarray, iM12: ndarray)
brainda.algorithms.manifold.rpa.rescale(X: ndarray, M: ndarray, scale: float, cov_method: str = 'cov', n_jobs: int = 1)
brainda.algorithms.manifold.rpa.rotate(Xt: ndarray, Ropt: ndarray)

Module contents