# What is the relationship between scales and frequency in a Morlet wavelet transform?

I'm using PyWavelets, with a complex Morlet wavelet. Its complex wavelet transform function requires scales as one of its parameters, rather than frequencies. However, I don't understand the relationship between the two. I'm generating my scales like this:

base_scale = CENTER_FREQ * quality / base_freq
far_scale = base_scale / 2**num_octaves
scales = numpy.geomspace(base_scale, far_scale, num=num_octaves*voices_per_octave+1, endpoint=True)


That is, if I expect my signal to be at about 20 kHz, I want to set the scales to be such that the frequencies returned are between 10 kHz and 40 kHz. In this case, the num_octaves variable might be 2, base_freq would be 10000, and voices_per_octave might be 50. Then scales would be an array of length 101, ranging logarithmically from the scale corresponding to 10 kHz up to the scale corresponding to 40 kHz.

However, this only works if CENTER_FREQ (the wavelet's central frequency) is a small number. If I increase it beyond 31, the frequencies returned by:

coeffs, freqs = pywt.cwt(data, scales, wavelet, 1/quality)


(where quality is the sampling rate of the data) are dead wrong. Is there any easier way to determine the needed scales that correspond to the frequencies I want?

• Most wavelets don't have a frequency. Which wavelet are you using? Morlet wavelet has a frequency similar to a STFT kernel. – endolith Jun 20 '17 at 21:50
• Thank you. I just edited the question to indicate that I'm using the complex Morlet wavelet. (I'd been so deep in Morlets, that I had begun to forget that there are other wavelets.) – Adam Smith Jun 20 '17 at 22:18

There is an internal function in the PyWavelets library called scale2frequency() that takes 2 arguments plus an optional 3rd: wavelet, scale, and then precision. By its name, I assume that it's made to take a scale and return the associated frequency. However it's an involutory function: $f(f(x)) = x$. So it can also be used to calculate scale from frequency. (This might be undocumented behavior, and I have no idea if it'll still work this way in future versions.)
The problem I was running into involved the optional precision argument. It would appear that as the wavelet's central frequency increases, the required precision became very high. I was able to mitigate the problem somewhat by increasing precision beyond the default value of 8. But as it gets higher and higher, the amount of memory and processing power increases drastically, to the point where I burned through all my system's virtual memory long before it was high enough to return valid answers.