https://github.com/deepcharles/convmmp
https://github.com/deepcharles/convmmp
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/deepcharles/convmmp
- Owner: deepcharles
- License: bsd-2-clause
- Created: 2024-11-22T16:57:46.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-12-17T14:23:38.000Z (over 1 year ago)
- Last Synced: 2025-03-20T19:38:47.602Z (over 1 year ago)
- Language: Jupyter Notebook
- Size: 645 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Convolutional Sparse Coding with Multipath Orthogonal Matching Pursuit
Python implementation of the algorithm described in (Gomes et al., 2024):
- Gomes, Y., Truong, C., Saut, J.-P., Hafid, F., Prieur, P., & Oudre, L. (2025). Convolutional Sparse Coding with Multipath Orthogonal Matching Pursuit. Proceedings of the IEEE International Conference on Acoustics, Speech, and Signal Processing (ICASSP).
A **codeless graphical interface** is available here: [https://convmmp.streamlit.app/](https://convmmp.streamlit.app/)
## Install
To install the Python package, run in a terminal:
```bash
python -m pip install git+https://github.com/deepcharles/convmmp
```
## Usage
Here is a code snippet to illustrate our algorithm on sample data (see the `example` folder).
```python
import numpy as np
import matplotlib.pyplot as plt
from mpcsc import multipathcsc # our library
```
#### Load data
```python
data = np.load("example_data.npz")
signal = data["signal"]
dictionary = data["dictionary"]
print(f"{signal.shape = } (n_samples, n_dims)")
print(f"{dictionary.shape = } (n_atoms, n_samples_atom, n_dims)")
```
signal.shape = (2000, 1) (n_samples, n_dims)
dictionary.shape = (143, 512, 1) (n_atoms, n_samples_atom, n_dims)
#### Convolution sparse coding with multipath
```python
# This line is long to execute the first time, because code is compiled.
approx, time_idxs, atom_idxs, vals, path = multipathcsc(signal=signal, dictionary=dictionary, n_atoms_to_find=3, n_paths=5)
print(f"The best solution was obtained with path {path}.")
```
The best solution was obtained with path [1 0 0].
- `approx` contains the best approximation of `signal`.
- `time_idxs` contains the time indexes of the selected atoms.
- `atom_idxs` contains the indexes of the selected atoms.
- `vals` contains the multiplicative factors to scale the atoms (which
have unit norm).
- `path` is the path of the best solution.
```python
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(signal, label="Original")
ax.plot(approx, label="Smoothed")
plt.legend()
ax.set_xmargin(0)
```

#### Decomposition
```python
fig, ax = plt.subplots(figsize=(10, 4))
# ax.plot(signal, label="Original")
ax.set_xmargin(0)
n_samples_atom = dictionary.shape[1]
for k_atom in range(time_idxs.size):
approx_single_atom = np.zeros_like(signal)
start = time_idxs[k_atom]
end = start + n_samples_atom
atom = dictionary[atom_idxs[k_atom]]
val = vals[k_atom]
approx_single_atom[start:end] = val * atom
ax.plot(approx_single_atom, label=f"Atom {k_atom+1}")
plt.legend()
```
