Skip to content

Fix mult_f boundary conventions, window grid, and mg time-domain path - #5

Open
mcdigman wants to merge 1 commit into
workingfrom
mult-f-convention-audit
Open

Fix mult_f boundary conventions, window grid, and mg time-domain path#5
mcdigman wants to merge 1 commit into
workingfrom
mult-f-convention-audit

Conversation

@mcdigman

@mcdigman mcdigman commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes frequency-domain transform boundary conventions, the modified-Gaussian window grid, and the mg time-domain path. Adds a plain-numpy reference specification and a comprehensive convention test suite.

  • Frequency-domain boundaries (both directions): windows crossing the frequency extremes are now handled exactly — forward uses conjugate fold-back for interior bands (instead of zero-truncation); inverse uses mirror-lobe fold-back with 2*Re at self-conjugate bins 0 and ND/2, and drops the stray m=Nf tap the forward never produces. Resolved the center-tap conjugation TODO via the uniform i_midpoint % Nt index.
  • modified_gaussian window: phitilde_vec_norm now sampled on the exact bin grid arange(0, K/2+1)/Nt (the old endpoint=False grid was misscaled and dominated round-trip error); prefactor corrected to sqrt(Nf/2). Fixed phi_vec signature crash (mult_t kwarg / nu shadowing) that broke every time-domain mg call. Expansion coefficients computed lazily and cached.
  • Public API: wavelet family selectable via family='meyer' (default, backward compatible) or family='modified_gaussian'; mult_f must satisfy 1 <= mult_f <= Nf.
  • Performance: both directions now use length-Nt ffts instead of length-K, ~mult_f× less fft work; jitted is 2.9–4.6× faster than the new numpy reference at Nf=2048, Nt=1024, mult_f=8.
  • Consolidation: removed dead code (DX_assign_loop_old, phi_vec_transform, zak/frame-bound diagnostics, _omega_array_loop, _om_dot_helper_old/_convolve, commented-out inverse variants).

New files

  • WDMWaveletTransforms/wavelet_reference.py — plain-numpy executable spec of the conventions
  • tests/wavelet_convention_test.py — 56 tests (jit==reference, closed-form atom cross-checks, round-trip convergence to 6e-15 at mult_f=24, boundary/edge cases, packing/normalization guards)
  • benchmark_transforms.py

Test plan

Modified-Gaussian round trip (Nf=32, Nt=64), previously stuck at ~1e-1 for all mult_f: now 1.7e-3 (mult_f=3), 2.6e-6 (8), 5.5e-12 (16), 6.1e-15 (24).

🤖 Generated with Claude Code

Frequency-domain transforms (both directions) now handle windows that
cross the frequency extremes exactly:
- forward: conjugate fold-back (X[-jj] = conj X[jj], X[ND-jj] = conj X[jj])
  for interior bands instead of zero-truncation
- inverse: mirror-lobe fold-back with 2*Re at the self-conjugate bins
  0 and ND/2; removed the stray m=Nf tap at delta=-K/2 that the forward
  never produces (invisible for Meyer, wrong for Gaussian windows)
- resolved the center-tap conjugation TODO: -conj(F[0]) was an obfuscated
  but exactly correct stand-in for F[Nt/2] at even mult_f / odd m; replaced
  by the uniform index i_midpoint % Nt

modified_gaussian window construction:
- phitilde_vec_norm sampled on the exact bin grid arange(0,K/2+1)/Nt
  (the linspace endpoint=False grid was misscaled by ~2/(mult_f*Nt) and
  dominated round-trip error); prefactor corrected to sqrt(Nf/2) so nrm=1
- phi_vec signature fixed (mult_t kwarg crash broke every time-domain mg
  call); nu parameter no longer shadowed by nu_init
- expansion coefficients now computed lazily and cached instead of at import

Public API: wavelet family is selectable via family='meyer' (default,
backward compatible, legacy stored-data tests unchanged) or
family='modified_gaussian'; mult_f must satisfy 1 <= mult_f <= Nf.

Performance: both directions now use length-Nt ffts (alias-folded taps /
direct packing) instead of length-K, ~mult_f x less fft work; jitted is
2.9-4.6x faster than the new numpy reference at Nf=2048, Nt=1024, mult_f=8.

New: WDMWaveletTransforms/wavelet_reference.py (plain-numpy executable
specification of the conventions), tests/wavelet_convention_test.py
(56 tests: jit==reference, closed-form atom cross-checks, round-trip
convergence to 6e-15 at mult_f=24, boundary/edge cases, packing and
normalization guards), benchmark_transforms.py.

Consolidation: removed DX_assign_loop_old, commented-out inverse variants,
phi_vec_transform, zak_g/zak_g_2filter/frame_bounds diagnostics,
_omega_array_loop, _om_dot_helper_old/_convolve and dead mode branches.

Modified-Gaussian round trip (Nf=32, Nt=64), previously stuck at ~1e-1
for all mult_f: now 1.7e-3 (mult_f=3), 2.6e-6 (8), 5.5e-12 (16), 6.1e-15 (24).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant