JuliaDSP / Wavelets.jl

A Julia package for fast discrete wavelet transforms and utilities
Other
185 stars 30 forks source link

Normalization of Battle-Lemarie filters and symlets #34

Open jpjones76 opened 7 years ago

jpjones76 commented 7 years ago

Wavelet filters are typically scaled to have unit energy and sum to sqrt(2.0); this simplifies a number of equations and transforms. So why are these wavelet families different?

Battle-Lemarie filters

sumabs2(FILTERS["batt2"]) = 0.5; sum(FILTERS["batt2"]) = 1.0 sumabs2(FILTERS["batt4"]) = 0.5; sum(FILTERS["batt4"]) = 1.0 sumabs2(FILTERS["batt6"]) = 0.5; sum(FILTERS["batt6"]) = 1.0

symlets

sumabs2(FILTERS["sym4"]) = 2.0; sum(FILTERS["sym4"]) = 2.0 sumabs2(FILTERS["sym5"]) = 2.0; sum(FILTERS["sym5"]) = 2.0 sumabs2(FILTERS["sym6"]) = 2.0; sum(FILTERS["sym6"]) = 2.0 sumabs2(FILTERS["sym7"]) = 2.0; sum(FILTERS["sym7"]) = 2.0 sumabs2(FILTERS["sym8"]) = 2.0; sum(FILTERS["sym8"]) = 2.0 sumabs2(FILTERS["sym9"]) = 2.0; sum(FILTERS["sym9"]) = 2.0 sumabs2(FILTERS["sym10"]) = 2.0; sum(FILTERS["sym10"]) = 2.0

I realize that Matlab's wavelet toolbox scales symlets to have energy ~0.5, so this isn't the only wavelet toolbox that uses unusual scaling for symlets; but why this particular choice?

gummif commented 7 years ago

I see you are accessing FILTERS which is actually meant to be private. If you construct the wavelets with the wavelet function the filters will all be normalized to unit energy

sum(abs2, WT.qmf(wavelet(WT.batt4))) == 1.0
jpjones76 commented 7 years ago

I do see that your code renormalizes the filters, i.e., in OrthoFilter:

# make sure it is normalized in l2-norm
    return OrthoFilter{T}(qmf./norm(qmf), name)

What I don't understand is why it's preferable to normalize a declared constant in a return statement rather than declare the normalized filters as the constant. Naively, I'd expect most users to want normalized wavelet filters for their applications, in which case this order of operations reduces speed.

gummif commented 7 years ago

You are correct, the constants should be normalized. I will definitely take a look at precomputing and saving the constants in normalized form.