"""Reproducer: MatrixWavedec silently fails with biorthogonal wavelets.
MatrixWavedec/MatrixWaverec apply orthogonalize() to boundary filter rows,
which assumes A = S^T (true for orthogonal wavelets only). For biorthogonal
wavelets like bior4.4, this breaks the A@S = I relationship, causing large
reconstruction errors — with no warning or error raised.
"""
import torch
import ptwt
from ptwt import MatrixWavedec, MatrixWaverec
torch.manual_seed(0)
x = torch.randn(128, dtype=torch.float64)
# --- Orthogonal wavelet (db4): works perfectly ---
coeffs = MatrixWavedec("db4", level=3)(x)
rec = MatrixWaverec("db4")(coeffs)
print(f"db4 reconstruction error: {(rec - x).abs().max():.2e}") # 2.66e-15
# --- Biorthogonal wavelet (bior4.4): silently wrong ---
coeffs = MatrixWavedec("bior4.4", level=3)(x)
rec = MatrixWaverec("bior4.4")(coeffs)
print(f"bior4.4 reconstruction error: {(rec - x).abs().max():.2e}") # 3.77e-01
# --- Conv-based bior4.4: works fine ---
coeffs = ptwt.wavedec(x.reshape(1, 1, -1), "bior4.4", level=3)
rec = ptwt.waverec(coeffs, "bior4.4")
print(f"bior4.4 conv reconstruction: {(rec.squeeze()[:128] - x).abs().max():.2e}") # 5.45e-12
Claude's reproducer: