o
odinpkg.dev
packages / library / Odin_Wavelet_Library

Odin_Wavelet_Library

5742f08library

A fast, comprehensive wavelet transform library for the Odin programming language, inspired by PyWavelets.

No license · updated 5 months ago

Odin Wavelet Library

A fast, comprehensive wavelet transform library for the Odin programming language, inspired by PyWavelets.

Features

Wavelet Families

  • Haar - Simplest wavelet, fast computation
  • Daubechies (db1-db10) - Widely used orthogonal wavelets
  • Symlets (sym2-sym8) - Near-symmetric wavelets
  • Coiflets (coif1-coif4) - Wavelets with vanishing moments

Transform Types

  • 1D DWT/IDWT - Discrete Wavelet Transform for f32 and complex64
  • 2D DWT/IDWT - 2D transform for image processing
  • Multi-level decomposition - wavedec/waverec for full decomposition
  • SWT - Stationary (Undecimated) Wavelet Transform
  • CWT - Continuous Wavelet Transform with Morlet and Mexican Hat wavelets

Signal Processing

  • Denoising - Wavelet-based signal denoising with hard/soft thresholding
  • Thresholding - Hard, soft, and garrote thresholding
  • Noise estimation - MAD-based noise level estimation

Boundary Modes

  • Zero, Constant, Symmetric, Reflect, Periodic, Smooth, Antisymmetric

Quick Start

import wv "wavelets"

main :: proc() {
    // Create a wavelet
    wavelet, ok := wv.get_wavelet("db4")
    if !ok do return
    defer wv.destroy_wavelet(&wavelet)
    
    // Your signal
    signal := []f32{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}
    
    // Single-level DWT
    coeffs := wv.dwt(signal, wavelet)
    defer delete(coeffs.approx)
    defer delete(coeffs.detail)
    
    // Reconstruct
    reconstructed := wv.idwt(coeffs, wavelet, len(signal))
    defer delete(reconstructed)
}

Multi-level Decomposition

import wv "wavelets"

// Full decomposition
result := wv.wavedec(signal, wavelet, 4)  // 4 levels
defer wv.destroy_wavedec_result(&result)

// result.coeffs[0] = approximation coefficients (cA)
// result.coeffs[1..] = detail coefficients (cD) from coarse to fine

// Reconstruction
reconstructed := wv.waverec(result, wavelet)
defer delete(reconstructed)

2D Transform (Images)

import wv "wavelets"

// image is [][]f32
coeffs := wv.dwt2(image, wavelet)
defer wv.destroy_coeffs_2d(&coeffs)

// coeffs.approx = LL (approximation)
// coeffs.horiz  = LH (horizontal detail)
// coeffs.vert   = HL (vertical detail)
// coeffs.diag   = HH (diagonal detail)

// Reconstruct
reconstructed := wv.idwt2(coeffs, wavelet, {rows, cols})

Complex Signal Processing

import wv "wavelets"

// Works with complex64 (real: f32, imag: f32)
complex_signal := make([]wv.Complex64, n)
for i in 0..<n {
    complex_signal[i] = complex(real_part, imag_part)
}

coeffs := wv.dwt_complex(complex_signal, wavelet)
reconstructed := wv.idwt_complex(coeffs, wavelet, len(complex_signal))

Denoising

import wv "wavelets"

// Automatic wavelet denoising
denoised := wv.denoise(noisy_signal, wavelet, 4, .Symmetric, .Soft)
defer delete(denoised)

// Manual thresholding
wv.threshold(coefficients, threshold_value, .Soft)

Continuous Wavelet Transform

import wv "wavelets"

// Generate scales
scales := wv.log_scales(1, 64, 32)  // 32 scales from 1 to 64
defer delete(scales)

// Morlet CWT
result := wv.cwt_morlet(signal, scales)
defer wv.destroy_cwt_result(&result)

// result.coefficients[scale][time] contains complex coefficients

Stationary Wavelet Transform

import wv "wavelets"

// SWT (signal length must be power of 2)
result := wv.swt(signal, wavelet, 3)  // 3 levels
defer wv.destroy_swt_result(&result)

// result.levels[i].approx and result.levels[i].detail
// All have same length as original signal

Building

# Build everything
make all

# Run tests
make run-test

# Run benchmarks
make run-bench

# Run comparison with PyWavelets
make run-comp

# Build with debug symbols
make debug

# Clean
make clean

API Reference

Wavelet Functions

  • get_wavelet(name) -> (Wavelet, bool) - Create wavelet by name
  • destroy_wavelet(wavelet) - Free wavelet resources
  • list_wavelets() -> []string - List available wavelets

1D Transform

  • dwt(signal, wavelet, mode) -> Coeffs_1D - Single-level DWT
  • idwt(coeffs, wavelet, length) -> []f32 - Single-level IDWT
  • wavedec(signal, wavelet, level, mode) -> Wavedec_Result - Multi-level decomposition
  • waverec(result, wavelet) -> []f32 - Multi-level reconstruction
  • dwt_max_level(data_len, filter_len) -> int - Maximum decomposition level

2D Transform

  • dwt2(image, wavelet, mode) -> Coeffs_2D - 2D DWT
  • idwt2(coeffs, wavelet, shape) -> [][]f32 - 2D IDWT

Stationary Transform

  • swt(signal, wavelet, level) -> SWT_Result - Stationary DWT
  • iswt(result, wavelet) -> []f32 - Inverse SWT

Continuous Transform

  • cwt_morlet(signal, scales, omega0) -> CWT_Result - Morlet CWT
  • cwt_mexican_hat(signal, scales) -> [][]f32 - Mexican Hat CWT
  • log_scales(min, max, num) -> []f32 - Generate logarithmic scales
  • linear_scales(min, max, num) -> []f32 - Generate linear scales

Signal Processing

  • denoise(signal, wavelet, level, mode, thresh_type) -> []f32 - Wavelet denoising
  • threshold(data, thresh, type) - Apply thresholding
  • estimate_noise_std(coeffs) -> f32 - Estimate noise level

Utilities

  • energy(signal) -> f32 - Signal energy
  • rms(signal) -> f32 - Root mean square
  • snr_db(original, noisy) -> f32 - Signal-to-noise ratio
  • pad_to_power2(signal) -> ([]f32, original_len) - Pad to power of 2

Performance

The library achieves perfect reconstruction (errors at floating-point precision limit ~1e-7) for all wavelet transforms.

Comparison with PyWavelets

Both libraries achieve identical reconstruction accuracy:

Test Odin Library PyWavelets Status
DWT/IDWT Reconstruction 2.38e-07 to 5.96e-07 1.19e-07 to 4.77e-07 ✓ Match
Multi-level (5 levels) 5.96e-07 to 8.34e-07 5.36e-07 to 7.15e-07 ✓ Match
2D DWT/IDWT 1.79e-07 to 4.17e-07 ~3e-07 ✓ Match
Complex DWT 1.33e-07 to 2.40e-07 ~2e-07 ✓ Match
Energy Conservation <2% deviation <2% deviation ✓ Match
Linearity 4.77e-07 to 9.54e-07 ~5e-07 ✓ Match

Performance Benchmarks (n=65536 samples, optimized build)

Wavelet Odin (MS/s) PyWavelets (MS/s) Ratio
Haar 583 1304 2.2x
Db4 385 630 1.6x
Sym4 387 630 1.6x

MS/s = Million Samples per second

With optimized build flags (-o:speed -disable-assert -no-bounds-check), the Odin library achieves 60-65% of PyWavelets performance. PyWavelets uses a highly optimized C backend with SIMD vectorization.

Running the Comparison

# Run comprehensive comparison test
make run-comp

# This runs:
# 1. Odin library validation (49 tests, 100% pass rate)
# 2. PyWavelets benchmark (requires Python + pywavelets)

Supported Wavelets

Family Names Filter Lengths
Haar haar, db1 2
Daubechies db2-db10 4-20
Symlets sym2-sym8 4-16
Coiflets coif1-coif4 6-24

License

MIT License