Dynamic Mode Decomposition for EEG signal analysis
Project description
pydmdeeg
Dynamic Mode Decomposition for EEG Signal Analysis
A Python library for extracting spatio-temporal coherent patterns from EEG data using Dynamic Mode Decomposition (DMD). This method enables data-driven decomposition of neural recordings into interpretable oscillatory modes.
Features
- Two DMD algorithms: Exact and standard implementations based on Tu et al. (2014)
- Sliding window analysis: Configurable window size and overlap for time-resolved decomposition
- Delay embedding: Shift-stacking technique for enhanced temporal dynamics capture
- SVD truncation: Optional hard thresholding (optht) or fixed-rank truncation for noise reduction
- Data scaling: Multiple preprocessing options (centering, normalization, z-scoring)
- Rich visualization: Built-in plotting for DMD spectra, channel statistics, and reconstruction errors
- Multi-trial support: Handle epoched EEG data with trial labels for condition comparisons
Installation
From PyPI (recommended)
pip install pydmdeeg
From source
git clone https://github.com/christiangoelz/pydmdeeg.git
cd pydmdeeg
pip install -e ".[dev]"
Quick Start
import numpy as np
from pydmdeeg import DMD
# Generate synthetic EEG-like data
# Shape: (n_trials, n_channels, n_timepoints)
n_trials, n_channels, n_times = 10, 64, 1000
sampling_rate = 256 # Hz
# Create data with oscillatory components
t = np.linspace(0, n_times/sampling_rate, n_times)
X = np.zeros((n_trials, n_channels, n_times))
for trial in range(n_trials):
for ch in range(n_channels):
# Alpha (10 Hz) and beta (20 Hz) oscillations with noise
X[trial, ch, :] = (
np.sin(2 * np.pi * 10 * t) +
0.5 * np.sin(2 * np.pi * 20 * t) +
0.3 * np.random.randn(n_times)
)
# Trial labels (e.g., 0 = rest, 1 = task)
y = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
# Channel names
channels = [f'Ch{i+1}' for i in range(n_channels)]
# Initialize DMD
dmd = DMD(
X=X,
y=y,
channels=channels,
dt=1/sampling_rate,
win_size=128,
overlap=64,
algorithm='exact',
datascale='norm'
)
# Run decomposition
dmd.DMD_win()
# Extract alpha band (8-12 Hz) mode statistics
alpha_stats = dmd.mode_stats(fbands=[[8, 12]], labels=[0, 1])
print(alpha_stats)
# Get mode magnitudes for specific frequency band
psi = dmd.get_PSI(fband=[8, 12], labels=[1])
API Reference
DMD Class
DMD(
X, # EEG data: (n_trials, n_channels, n_times) or (n_channels, n_times)
y, # Trial labels: (n_trials,)
channels, # Channel names: list of strings
dt, # Sampling interval: 1/sampling_rate
stacking_factor=0, # Delay embedding factor (0 = no stacking)
win_size=100, # Window size in samples
overlap=0, # Window overlap in samples
datascale='norm', # Scaling: 'none', 'centre', 'norm', 'centre_norm'
algorithm='exact', # DMD algorithm: 'exact' or 'standard'
truncation={'method': None, 'keep': None} # SVD truncation settings
)
Key Methods
| Method | Description |
|---|---|
DMD_win() |
Run DMD decomposition across sliding windows |
mode_stats(fbands, labels) |
Compute statistics for modes in frequency bands |
get_PSI(fband, labels) |
Extract mode magnitudes for frequency band |
get_AMP(fband, labels) |
Extract mode amplitudes for frequency band |
select_trials(selector) |
Select subset of trials |
plot_frRPsi(labels) |
Plot DMD power spectrum |
plot_frRLam(labels) |
Plot eigenvalue spectrum |
plot_statsCH() |
Plot channel statistics heatmap |
plot_ChAmpErr(labels) |
Plot reconstruction error |
Mathematical Background
Dynamic Mode Decomposition approximates the linear operator A that best maps consecutive time snapshots:
X' ≈ AX
where X and X' are time-shifted data matrices. The eigenvalues of A (λ) encode oscillation frequencies and growth/decay rates, while eigenvectors (Φ) represent spatial patterns.
For EEG analysis:
- Frequencies: μ = Im(log(λ)) / (2πΔt)
- Spatial modes: Φ shows channel contributions to each oscillatory pattern
- Amplitudes: |Φ| weighted by initial conditions
Publications Using This Method
This implementation has been validated in peer-reviewed neuroscience research:
-
Goelz C et al. (2021). Classification of visuomotor tasks based on electroencephalographic data depends on age-related differences in brain activity patterns. Neural Networks. DOI
-
Goelz C et al. (2021). Electrophysiological signatures of dedifferentiation differ between fit and less fit older adults. Cognitive Neurodynamics. DOI
-
Goelz C et al. (2018). Improved Neural Control of Movements Manifests in Expertise-Related Differences in Force Output and Brain Network Dynamics. Frontiers in Physiology. DOI
-
Vieluf S et al. (2018). Age- and Expertise-Related Differences of Sensorimotor Network Dynamics during Force Control. Neuroscience. DOI
References
- Brunton BW et al. (2016). Extracting spatial-temporal coherent patterns in large-scale neural recordings using dynamic mode decomposition. J Neurosci Methods. DOI
- Tu JH et al. (2014). On dynamic mode decomposition: Theory and applications. J Computational Dynamics. DOI
- Donoho D & Gavish M (2014). The Optimal Hard Threshold for Singular Values is 4/√3. IEEE Trans Information Theory. DOI
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linting
ruff check .
# Run type checking
mypy pydmdeeg
License
MIT License - see LICENSE for details.
Citation
If you use this software in your research, please cite:
@software{pydmdeeg,
author = {Goelz, Christian},
title = {pydmdeeg: Dynamic Mode Decomposition for EEG Analysis},
url = {https://github.com/christiangoelz/pydmdeeg},
version = {0.2.0},
year = {2024}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydmdeeg-0.2.0.tar.gz.
File metadata
- Download URL: pydmdeeg-0.2.0.tar.gz
- Upload date:
- Size: 21.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e194cf1954be152b14b06cf008ef7158f88e1cd4bcfc91494158df9a1afd3435
|
|
| MD5 |
dd6b1d03480abf5d7af36cf87cb55ac3
|
|
| BLAKE2b-256 |
794f38f0e9c4a7066b07e71cd123b4e1b68c11a5883379a3eb81461d1662362e
|
File details
Details for the file pydmdeeg-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pydmdeeg-0.2.0-py3-none-any.whl
- Upload date:
- Size: 13.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c051ecb0bac5c1e79f7f103944b7a2bf5a13eaa2deaf7d22c57d4c6f6bffe0c
|
|
| MD5 |
29a42139214d45dd1b77a1302581e524
|
|
| BLAKE2b-256 |
8648adb6e794a04cda1f574b92618f538212d48fdf37b8e18ac13467f302651e
|