coco_pipe.dim_reduction.reducers.spatiotemporal =============================================== .. py:module:: coco_pipe.dim_reduction.reducers.spatiotemporal .. autoapi-nested-parse:: Spatiotemporal dimensionality reduction reducers. This module provides reducers for structured signals where time, trials, or snapshots are part of the data layout. These reducers follow the shared `BaseReducer` contract while declaring nonstandard input layouts through the `capabilities` mapping. Classes ------- DMDReducer Dynamic Mode Decomposition wrapper based on `pydmd.DMD`. TRCAReducer Task-Related Component Analysis wrapper based on `meegkit.trca.TRCA`. .. rubric:: References .. [1] Schmid, P. J. (2010). "Dynamic mode decomposition of numerical and experimental data". Journal of Fluid Mechanics, 656, 5-28. .. [2] PyDMD documentation: https://github.com/mathLab/PyDMD .. [3] Nakanishi, M., Wang, Y., Chen, X., Wang, Y.-T., Gao, X., and Jung, T.-P. (2018). "Enhancing detection of SSVEPs for a high-speed brain speller using task-related component analysis". IEEE Transactions on Biomedical Engineering, 65(1), 104-112. .. [4] MEEGkit documentation: https://github.com/nbara/python-meegkit Author: Hamza Abdelhedi (hamza.abdelhedi@umontreal.ca) Classes ------- .. autoapisummary:: coco_pipe.dim_reduction.reducers.spatiotemporal.DMDReducer coco_pipe.dim_reduction.reducers.spatiotemporal.TRCAReducer Module Contents --------------- .. py:class:: DMDReducer(n_components: int = 0, force_transpose: bool = False, **kwargs) Bases: :py:obj:`coco_pipe.dim_reduction.reducers.base.BaseReducer` Dynamic Mode Decomposition reducer. DMD decomposes a snapshot matrix into dynamic modes that capture coherent spatial patterns and their temporal evolution. It is useful for spatiotemporal systems such as fluid flows, simulation outputs, and structured neural trajectories when data are arranged as `(n_features, n_snapshots)`. :param n_components: Number of modes to keep. This is forwarded to PyDMD as `svd_rank`. A value of `0` keeps all modes. :type n_components: int, default=0 :param force_transpose: If ``True``, transpose incoming arrays from `(n_snapshots, n_features)` to `(n_features, n_snapshots)` before fitting and transforming. :type force_transpose: bool, default=False :param \*\*kwargs: Additional keyword arguments forwarded to `pydmd.DMD` after signature filtering. Common options include `tlsq_rank`, `exact`, and `opt`. :type \*\*kwargs: dict .. attribute:: model Fitted DMD estimator after `fit`. :type: pydmd.DMD or None .. rubric:: Notes Unlike most reducers in this package, DMD expects columns to represent time snapshots. This is declared through `capabilities["input_layout"] = "features_snapshots"`. .. seealso:: :obj:`TRCAReducer` Trial-structured spatiotemporal reducer for labeled repeated signals. :obj:`PHATEReducer` Nonlinear embedding often useful for smooth trajectories. :obj:`UMAPReducer` Nonlinear neighborhood-preserving reducer for tabular inputs. :obj:`PCAReducer` Linear baseline for sample-feature matrices. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.dim_reduction import DMDReducer >>> x = np.linspace(0, 2 * np.pi, 20) >>> t = np.linspace(0, 4 * np.pi, 40) >>> X = np.sin(x)[:, None] * np.cos(t)[None, :] >>> reducer = DMDReducer(n_components=2) >>> _ = reducer.fit(X) >>> reducer.eigs_.shape (2,) >>> reducer.transform(X).shape (40, 2) .. py:property:: capabilities :type: dict Return capability metadata for DMD. :returns: Capability mapping describing DMD as a linear reducer operating on `(n_features, n_snapshots)` inputs. :rtype: dict .. py:attribute:: force_transpose :value: False .. py:method:: fit(X: coco_pipe.dim_reduction.reducers.base.ArrayLike, y: Optional[coco_pipe.dim_reduction.reducers.base.ArrayLike] = None) -> DMDReducer Fit DMD on the input snapshot matrix. :param X: Training data. If `force_transpose=True`, input may instead be provided as `(n_snapshots, n_features)`. :type X: ArrayLike of shape (n_features, n_snapshots) :param y: Ignored. Present for API compatibility. :type y: ArrayLike, optional :returns: Fitted reducer instance. :rtype: DMDReducer .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.dim_reduction import DMDReducer >>> X = np.random.rand(5, 20) >>> reducer = DMDReducer(n_components=2) >>> _ = reducer.fit(X) >>> reducer.model is not None True .. py:method:: transform(X: coco_pipe.dim_reduction.reducers.base.ArrayLike) -> numpy.ndarray Project snapshots onto the fitted DMD modes. :param X: Data to project. If `force_transpose=True`, input may instead be provided as `(n_snapshots, n_features)`. :type X: ArrayLike of shape (n_features, n_snapshots) :returns: Time-evolution amplitudes projected onto the fitted modes. :rtype: np.ndarray of shape (n_snapshots, n_components) .. py:property:: svd_rank :type: int Return the SVD rank used for the DMD decomposition. :returns: SVD rank. :rtype: int .. py:property:: n_modes_ :type: Optional[int] Return the number of fitted DMD modes. :returns: Mode count or None if not fitted. :rtype: int or None .. py:property:: eigs_ :type: numpy.ndarray Return the DMD eigenvalues. :returns: Eigenvalues associated with the fitted modes. :rtype: np.ndarray :raises RuntimeError: If the reducer has not been fitted. .. py:property:: modes_ :type: numpy.ndarray Return the DMD spatial modes. :returns: Spatial mode matrix exposed by the fitted DMD model. :rtype: np.ndarray :raises RuntimeError: If the reducer has not been fitted. .. py:method:: get_components() -> numpy.ndarray Return DMD modes in component-major layout. :returns: Mode matrix transposed to `(n_components, n_features)`. :rtype: np.ndarray .. py:property:: reconstructed_data_ :type: numpy.ndarray Return the reconstructed snapshot matrix from the fitted DMD model. :returns: Reconstructed data exposed by the fitted DMD backend. :rtype: np.ndarray :raises RuntimeError: If the reducer has not been fitted. .. py:class:: TRCAReducer(n_components: int = 1, sfreq: float = 250.0, filterbank: Optional[list] = None, **kwargs) Bases: :py:obj:`coco_pipe.dim_reduction.reducers.base.BaseReducer` Task-Related Component Analysis reducer. TRCA learns spatial filters that maximize reproducibility across repeated labeled trials. It is primarily useful for trial-based biosignal data such as SSVEP or ERP analyses, but the reducer contract is expressed in terms of generic `(n_trials, n_channels, n_times)` arrays rather than any specific domain object. :param n_components: Number of output components to keep after projection. The underlying TRCA backend may produce more `(band, class)` filters; this wrapper truncates the projected output to the requested count. :type n_components: int, default=1 :param sfreq: Sampling frequency in Hertz. :type sfreq: float, default=250.0 :param filterbank: Filterbank definition passed to `meegkit.trca.TRCA`. If omitted, a single broad band `[(8, 30), (7, 35)]` is used. :type filterbank: list, optional :param \*\*kwargs: Additional keyword arguments forwarded to `meegkit.trca.TRCA` after signature filtering. :type \*\*kwargs: dict .. attribute:: model Fitted TRCA estimator after `fit`. :type: meegkit.trca.TRCA or None .. rubric:: Notes TRCA requires class labels during fitting. The `y` argument is not optional in practice even though it remains optional in the shared reducer interface. .. seealso:: :obj:`DMDReducer` Snapshot-based spatiotemporal decomposition. :obj:`PCAReducer` Linear reducer for standard sample-feature matrices. :obj:`UMAPReducer` Nonlinear reducer for standard sample-feature matrices. :obj:`PHATEReducer` Nonlinear reducer often used for continuous trajectories. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.dim_reduction import TRCAReducer >>> X = np.random.rand(8, 4, 50) >>> y = np.array([0, 0, 0, 0, 1, 1, 1, 1]) >>> reducer = TRCAReducer(n_components=1, sfreq=100.0) >>> _ = reducer.fit(X, y=y) >>> reducer.transform(X).shape (8, 1, 50) >>> reducer.get_diagnostics()["coef_"].shape[0] >= 1 True .. py:property:: capabilities :type: dict Return capability metadata for TRCA. :returns: Capability mapping describing TRCA as a linear reducer operating on `(n_trials, n_channels, n_times)` inputs. :rtype: dict .. py:attribute:: sfreq :value: 250.0 .. py:attribute:: filterbank :value: [[(8, 30), (7, 35)]] .. py:property:: n_bands :type: int Return the number of filter bands. :returns: Band count. :rtype: int .. py:property:: n_classes :type: Optional[int] Return the number of classes identified by TRCA. :returns: Class count or None if not fitted. :rtype: int or None .. py:method:: fit(X: coco_pipe.dim_reduction.reducers.base.ArrayLike, y: Optional[coco_pipe.dim_reduction.reducers.base.ArrayLike] = None) -> TRCAReducer Fit TRCA on labeled trial data. :param X: Training data. :type X: ArrayLike of shape (n_trials, n_channels, n_times) :param y: Class labels aligned with trials. This argument is required. :type y: ArrayLike of shape (n_trials,) :returns: Fitted reducer instance. :rtype: TRCAReducer :raises ValueError: If the input is not 3-dimensional, if `y` is missing, or if label length does not match the number of trials. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.dim_reduction import TRCAReducer >>> X = np.random.rand(6, 3, 40) >>> y = np.array([0, 0, 0, 1, 1, 1]) >>> reducer = TRCAReducer(n_components=1, sfreq=100.0) >>> _ = reducer.fit(X, y=y) >>> reducer.model is not None True .. py:method:: transform(X: coco_pipe.dim_reduction.reducers.base.ArrayLike) -> numpy.ndarray Project trial data using the fitted TRCA spatial filters. :param X: New data to project. :type X: ArrayLike of shape (n_trials, n_channels, n_times) :returns: Projected trial signals, truncated to `n_components`. :rtype: np.ndarray of shape (n_trials, n_components, n_times) :raises ValueError: If the input is not 3-dimensional. .. py:method:: get_components() -> numpy.ndarray Return the learned TRCA spatial filters. :returns: Spatial filter tensor with shape determined by the TRCA backend. :rtype: np.ndarray