OverLordGoldDragon / ssqueezepy

Synchrosqueezing, wavelet transforms, and time-frequency analysis in Python
MIT License
636 stars 96 forks source link

`center_frequency` yields negative frequency for extreme scale #41

Open scottfleming opened 3 years ago

scottfleming commented 3 years ago

The following example returns wc = -3.1354 but according to the specs it should be nonnegative, unless I'm misunderstanding something.

from ssqueezepy import wavelets, Wavelet
wavelet = Wavelet(("morlet", {"mu":14.0}))
_ = wavelets.center_frequency(
    wavelet,  
    scale=np.array([1.0]),  
    kind='peak',
    N=1024,
    viz=1
)
OverLordGoldDragon commented 3 years ago

Thanks for the report.

Current imlpementations of center_frequency, time_resolution, and freq_resolution are discretized approximations of underlying continuous-time parameters. This is a flawed approach (I didn't know better at the time), and I may improve it eventually to base on discrete logic.

The problem here specifically is that the wavelet isn't "well-behaved" at this scale - meaning, its lowest frequency goes either to left of FFT bin 1, or its highest frequency to right of Nyquist. The most generous well-behaved range can be found as:

from ssqueezepy import Wavelet
from ssqueezepy.utils import cwt_scalebounds

wavelet = Wavelet(("morlet", {"mu":14.0}))
cwt_scalebounds(wavelet, N=1024, preset='maximal')
# (4.081687670534748, 4545.465174704532)

Granted it still shouldn't return a negative, so it's an unhandled edge case.