dwt_multilevel

Function dwt_multilevel 

pub fn dwt_multilevel<T: SignalType + 'static>(
    signal: &Signal<T>,
    wavelet: &dyn Wavelet,
    levels: usize,
    boundary: BoundaryMode,
) -> Result<MultilevelDWTResult<T>>
Expand description

Perform multi-level 1D Discrete Wavelet Transform.

§Output length convention

  • BoundaryMode::Periodic: per-band M = ceil(N/2) at each level, matching the output shape of PyWavelets mode='periodization'. For odd N the signal is padded to the next even length with the last sample repeated before the circular convolution wraps, so the forward/inverse pair round-trips exactly for any filter length (the pre-2.0.0 wrap-into-head broke this for filter_len ≥ 4). ferro-wave’s Periodic convolution offset differs from PyWavelets’ so the numerical cA/cD values will not match PyWavelets bit for bit, only the output shape and round-trip semantics.
  • BoundaryMode::Symmetric / BoundaryMode::Zero / BoundaryMode::Constant: per-band M = (N + L − 1) / 2 at each level (where L is the filter length), matching PyWavelets’ default mode='symmetric' and friends bit for bit.

In both cases the original per-level input length is recorded on MultilevelDWTResult::per_level_lengths so that idwt_multilevel can recover the input exactly. Biorthogonal wavelets (CDF 5/3, CDF 9/7) route through the lifting scheme, which is length-preserving and boundary-mode independent.

§Energy conservation

Parseval’s identity ‖signal‖² = ‖approx‖² + ‖detail‖² holds for the combinations where the forward map is an isometry on the input:

  • Periodic with N even: 2·M = N, exact to 1e-12.
  • Zero with any orthogonal wavelet: the literal-zero extension contributes no energy, exact to 1e-12.

Periodic at odd N and Symmetric/Constant at any N are over-complete (2·M > N, or boundary samples added by the extension), so ‖approx‖² + ‖detail‖² > ‖signal‖². Round-trip reconstruction via idwt_multilevel is still exact (the inverse truncates back to original_length via per_level_lengths); only the forward-stage Parseval identity is affected. Worst-case inflations are pinned by tests/transforms/dwt.rs::test_dwt_haar_energy_conservation_bounds and test_dwt_non_haar_non_periodic_energy_error_bound.