# Downsample a signal by a non-integer factor

I have a signal with a sample rate of 8.9286 MHz and I want to downsample it to 500 kHz.

Since 8.9286 is not an integer multiple of 0.5 I can't simply decimate. Which downsample techniques are recommended to be used?

If I use this solution then I there will be a step to decimate by a factor of 647 $$(89286=2\times3\times23\times647),$$ which is prime, and would alias my signal in frequencies that are useful, so I can't filter them.

I could apply DFT to the original signal, then reconstruct in the time domain with the sample rate of 500 kHz, but that would take too much computational effort.

Is there a faster or simpler way to downsample it?

If python is OK, you can just resample using an appropriate (approximate) interpolator:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
from scipy.signal import butter, lfilter

T = 10000
t = np.linspace(0,1,T, endpoint=True)
x = np.sin(2*np.pi*t*10)
ratio = 8.9286/0.5
t2 = np.linspace(0,1,int(T/ratio))

b, a = butter(6, 2*np.pi/ratio, btype='low', analog=False)
x_lpf = lfilter(b,a,x)

interpolated = interp1d(t, x_lpf, kind='cubic')

plt.plot(t,x)
plt.plot(t2,interpolated(t2),'.')


• Too bad cubic interpolation doesn't exist in any language except Python... -Seriously: I'd say this is a good suggestion that might work just as well for the OP as any complicated polyphase filtering. But it might not... it depends on what signal properties are important. A bit of discussion would be good. At any rate, an example with a single sine isn't going to show much of the up- or downsides! Jul 4 at 11:16
• That should work, and fortunately I'm using Python. It's for my Msc Dissertation so, do you know if is there are paper that use it for upsample/downsample? Jul 4 at 14:38
• @IvoTebexreni My guess is: yes, but I am on mobile now so finding them will be harder. I’ll be at my desk a little later and will check then.
– Peter K.
Jul 4 at 14:41
• @IvoTebexreni that would not be "paper" material, that's just textbook material (which is good, that's faster and easier to read). The classic would be harris' multirate processing book. But that would already be a bit over the top: Jul 4 at 14:41
• What you'd need is chapter 4 of (at least in the second edition that I got for very very cheap used online) Oppenheim and Schafer: Discrete-Time Signal Processing. That chapter is called Sampling of Continuous-Time Signals, and the section you'd need to understand 4.6 Changing the Sampling Rate Using Discrete-Time Processing. Jul 4 at 14:43

You need a resampler. There's different resamplers!

I'm not sure you're correctly interpreting the answer you cite: you don't just decimate by 647; you'd first (at least mathematically) upsample by some other factor. I'm not even quite where you got the 647 from, but an exact rational resampler would have to interpolate by 2500 and decimate by 44643. That's indeed a very unattractive resampler. 2500 and 44643 are coprime (or relatively prime), not prime in themselves; this is only important because if they weren't, you could cancel out factors.

Generally, you'd avoid resamplers where the interpolation or decimation sizes are so extreme, because you'll need to designa a $$\frac1{44643}$$-band filter, and that will lead to a very long filter.

Instead, you first try to bring the input rate "closer" to the output rate, e.g. by decimation-by-4, then apply an arbitrary resampler. Such arbitrary resamplers approximate the signal shape between samples at more or less arbitrary points. There's again many arbitrary resampler architectures, but the one I most commonly use is the polyphase filter bank arbitrary resampler, as e.g. implemented by the GNU Radio PFB arbitrary resampler block.

However, it's worth noting that in you fixed-input/output-rate scenario, it might be worth considering whether you actually need your output rate to be exactly 500 kHz. For example, assuming you use this for wireless communications with packets with a preamble. Then, using an upsampling by 20 and a downsampling by 357 will give you a rate that's only 4·10⁻⁴ larger than 500 kHz. If your packet is, say, only 256 samples long after the preamble, when you properly aligned timing in the preamble, the timing of your last payload sample will be 10% too early. You could even incorporate that knowledge, and retard your timing synchronization at the preamble by 5% of a symbol period, so that the maximum absolute timing error over the whole packet is but 5%, if 10% timing error increases your error vector magnitude too much. 20 up, 357 down is still not an easy rational resampling, but on my slightly older CPU core it runs, at an output rate of 5.1 MHz/s around 20% faster than the exact arbitrary resample, and about twice as fast as the exact rational resampler (2500/44643).

Notice that

1. even the exact arbitrary resampler is about five times as fast running on a single x86_64 CPU core than it needs to be to achieve 500 kHz, so if that's your platform, being "smarter" than just using an existing rational resampler implementation doesn't help (aside from maybe saving energy).
2. if you plan to implement this in hardware, check whether it would be faster / easier to hold a whole set of filter coefficient vectors in memory and evaluate a different filter for every output sample, or to have one very long filter. Use the polyphase arbitrary, or the rational resampling approach, accordingly.
• Note also that any sane resampling scheme is going to use some sort of polyphase filtering -- if you're not just grabbing code from somewhere and pasting it in, looking up polyphase filtering and understanding it is probably a good idea. Jul 3 at 23:44
• Here's one paper which compares different polynomial interpolators for resampling purpose : yehar.com/blog/wp-content/uploads/2009/08/deip.pdf , (source code: yehar.com/blog/?p=197 ) Jul 4 at 17:00
• … should also (maybe even moreso) say that to @OlliNiemitalo, I guess! Jul 4 at 17:22
• @MarcusMüller: I'm pretty sure that splines can go through the original points, if you choose the flavor of the spline correctly. And I do know from working it out that interpolation using splines works out to polyphase filtering with an implied low-pass filter in the middle. It may not be the best low-pass filter, but it always works out to a low-pass filter. Actually choosing a better one is probably, well, better, but I do find it interesting that it gets you to a similar end point using an entirely different conceptual starting point. Jul 5 at 20:28
• @TimWescott that's true, you can constrain your splines to be proper interpolators. But: I've had a student insist they do their radar target distance (through time-difference of arrival) estimation through spline interpolation with "default" parameters, and not too surprisingly, sinc-interpolation through zero-padding the FFT of the correlation does a lot better. Jul 5 at 21:26