[DSP.jl] What resampling parameters should I use to get the same output as the decimate function in MATLAB?

Hello everyone, I am a cognitive neuroscience researcher, have little knowledge about the detail of signal processing, We are trying to resampling our signal with DSP.jl, and expect to get identical(or similar) result as decimate in MATLAB did, based on the document it’s possible, but how to implement confused us a lot.
I’m very appreciated for your help. :smiley:

Hi @Losses, Can you clarify what you’ve tried and the way that it’s not doing what you expect? The best thing would be a code chunk that folks could copy-paste to see what you’re doing, and then provide suggestions as to what you should change.

I’m guessing that the main places where DSP.jl’s resample might differ have to do with delays introduced by filtering and also with edge effects, but it’s not clear to me how MATLAB’s decimate is implemented, so an example of what you’re seeing would be helpful.

1 Like

@ssfrr Thank you for the reply, What we are trying to down sampling waveform brain activity data (very similar to sound wave) from 55.5Hz to 1Hz, and trying to avoid the impact of high frequency signal, we used to use decimate function in MATLAB to achieve this, what they did is:

  • a lowpass Chebyshev Type I infinite impulse response (IIR) filter of order 8

But what DSP.jl provided is a FIR based method, I don’t know whether using DSP.resample will cause some additional effects…

Both DSP.resample and MATLAB’s decimate apply a lowpass filter and then throw away samples to get to the new sample rate (fn1). From what I can tell from the decimate documentation it does some other fancy things to improve how well the signal lines up at the very beginning and end, and also to detect some possible numerical issues when designing the IIR filter (TBH I don’t really understand what they’re doing there).

There shouldn’t be much practical difference whether you use an IIR or FIR filter. Probably the bigger question is whether the edge effects mess you up (they show up as “ringing” or “ripple”). This is mostly a problem if the beginning or end of your signal is far from zero, which also crops up if your signal has a substantial DC component (constant offset). (fn2).

For instance, here’s a modified version of one of the examples on the decimate doc:

using Plots
using DSP

N = 200
t = 0:N-1
x = sin.(0.04t) + sin.(0.08t);
plt = sticks(t, x)
rs = resample(x, 1//4)
scatter!(plt, 0:4:N-1, rs, marker=true)

Which gives:

Note the lowpass filtering isn’t actually having much effect here because there isn’t any high-frequency content in the signal.

To illustrate the possible edge effects, heres a version with a DC offset (x = sin.(0.04t) + sin.(0.08t) + 5). You can see the ripple at the beginning and the end.

Hope this is helpful. In some ways the short answer is "DSP.jl’s resample has some small differences from MATLAB’s decimate, but for many use-cases those differences won’t matter. If your goal is to reproduce exactly some previous data then you might be in a little trouble, but if your goal is just to lowpass and downsample your data then this should be what you’re looking for.

Footnotes

fn1: This is a little more complicated if the original samplerate isn’t an integer multiple of the new one, but is a reasonable mental model of what’s going on.

fn2: This would actually be a good place where DSP.jl could improve, it would be nice for users not to have to worry about this. There’s an issue for it.

4 Likes

Thank you for your in-depth explanation! I think my question is solved!