Skip to content

Repository files navigation

Morvex

Fast constant-Q Morlet filter banks in PyTorch: scalable time-frequency analysis on CPU and GPU

Python 3.12+ PyTorch uv Ruff ty prek CI License: MIT

Note

This project is under active development and may undergo significant changes.

Overview

This Python library provides an implementation of the Morlet wavelet transform for time-frequency analysis. The implementation follows the original, physically intuitive formulation by Jean Morlet (French geophysicist and pioneer of wavelet theory), which defines wavelet shape through a parameter called shape ratio, $\kappa$. This parameter determines the Gaussian time width at half-maximum expressed as a multiple of the wavelet's dominant period. This approach ensures that the wavelet's shape is preserved across frequencies and makes the constant-Q property explicit.

Built entirely on PyTorch, Morvex runs on both GPU and CPU with no code changes required.

Installation

Prerequisite

Install the uv Python package manager.

Core installation (without PyTorch)

If you already have PyTorch installed and need only the core functionality of Morvex, run the following command:

uv add git+https://github.com/nimanzik/Morvex

Full installation with PyTorch

Morvex provides optional extras for different PyTorch configurations (CUDA versions and CPU-only). If you do not already have PyTorch installed, choose the build that matches your hardware and CUDA version, and pass the corresponding name from the table below to uv's --extra option.

Extra name PyTorch build
torch-cpu CPU
torch-cu126 CUDA 12.6
torch-cu130 CUDA 13.0
torch-cu132 CUDA 13.2

Replace <extra-name> with an extra name from the table:

uv add git+https://github.com/nimanzik/Morvex \
    --extra <extra-name>

For example, to install with CPU-only PyTorch:

uv add git+https://github.com/nimanzik/Morvex --extra torch-cpu

and to install with CUDA 13.0 enabled PyTorch:

uv add git+https://github.com/nimanzik/Morvex --extra torch-cu130

Quick start

Important

The units of time_duration and sampling_freq must be compatible (e.g., seconds and Hz, milliseconds and kHz etc). Morvex does not enforce unit consistency in the input parameters, and it is assumed that users will provide compatible values.

Filter bank and CWT

import torch

from morvex import MorletFilterBank

# Build a constant-Q filter bank
fbank = MorletFilterBank(
    n_octaves=4,           # Number of octaves
    resolution=8,          # Number of filters per octave
    shape_ratio=5.0,       # Shape ratio (kappa)
    time_duration=2.0,     # Wavelet time duration (here in seconds)
    sampling_freq=1000.0,  # Sampling frequency (here in Hz)
)

# Compute the wavelet transform (scalogram) of an 8-second signal
signal = torch.randn(8000)
scalogram = fbank(signal, coeff_type="power")

scalogram.shape
# torch.Size([n_wavelets, 8000])

Batch processing

The forward pass supports arbitrary leading dimensions for batch processing. For example, to compute the CWT of a batch of 16 stereo signals (3 channels, 8 seconds each):

signals = torch.randn(16, 3, 8000)
scalogram = fbank(signals, coeff_type="magnitude")

scalogram.shape
# torch.Size([16, 3, n_wavelets, 8000])

GPU acceleration

Since Morvex is a standard torch.nn.Module, moving the filter bank and input data to GPU is straightforward:

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

fbank = fbank.to(device)
signal = signal.to(device)
scalogram = fbank(signal, coeff_type="power")  # Computed on GPU if available

Visualisation

To display the frequency responses of the filter bank:

import matplotlib.pyplot as plt

from morvex.plotting import plot_freq_resps

fig, ax = plt.subplots()
plot_freq_resps(fbank, plot_obj=ax, color="skyblue")
plt.show()

To display the scalogram in the time-frequency plane:

import numpy as np

from morvex.plotting import plot_time_freq_plane

scalogram = scalogram.cpu().numpy()  # Move to CPU for plotting
freqs = fbank.center_freqs.cpu().numpy()
times = np.arange(scalogram.shape[-1]) / fbank.sampling_freq

fig, ax = plt.subplots()
plot_time_freq_plane(ax, freqs, times, scalogram, log_scale=True)
plt.show()

Troubleshooting

Report issues or bugs on GitHub Issues.

About

Fast constant-Q Morlet filter banks in PyTorch: scalable time-frequency analysis on CPU and GPU

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages