# Question about low pass filter in DSP.jl

**URL:** <https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214>\
**Category:** Signal and Image Processing\
**Tags:** dsp\
**Created:** [April 8, 2022, 8:15am UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214 "2022-04-08T08:15:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![henry2004y](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henry2004y/32/9284_2.png) [@henry2004y](https://discourse.julialang.org/u/henry2004y)\
**Post date:** [April 8, 2022, 8:15am UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214/1 "2022-04-08T08:15:17Z")

</div>

Hi,

I’m new to the domain of signal processing. Recently I have encountered some phase related issues with the low pass filter in DSP.jl.

In MATLAB,

```matlab
fs = 1e3;
t = 0:1/fs:1;
% comment out random noise for testing
x = [1 2]*sin(2*pi*[50 250]'.*t) % + randn(size(t))/10;

lowpass(x,150,fs)

```

gave me exactly what I expected

 ![matlab_lowpassfilter](https://global.discourse-cdn.com/julialang/original/3X/c/a/ca539e70759b88896f26ae9cd216bcc4193203fb.jpeg)

However, using DSP.jl

```julia
using DSP, PyPlot

fs = 1e3
t = 0:1/fs:1
# comment out random noise for testing
x = @. sin(2*pi*50*t) + 2*sin(2*pi*250*t)# + randn() / 10

responsetype = Lowpass(150; fs)
designmethod = FIRWindow(hanning(128; zerophase=false))
#designmethod = FIRWindow(hanning(64; padding=30, zerophase=false))
#designmethod = FIRWindow(rect(128; zerophase=false))
#designmethod = Butterworth(4)
x_low = filt(digitalfilter(responsetype, designmethod), x)

figure()
plot(t, x)
plot(t, x_low)

```

I got

 ![julia_DSP_lowpassfilter](https://global.discourse-cdn.com/julialang/original/3X/1/a/1a2144e0c6db5209bc7e1b01a3aa9a66d32369fa.png)  
with `FIRWindow` as shown above and  
 ![julia_DSP_lowpassfilter_butterworth](https://global.discourse-cdn.com/julialang/original/3X/c/f/cfb3c9b4bddb621aff8244eda07b2aa9775154f4.png)  
with `Butterworth(5)`.

I also tried some other design methods, but I always saw a shift in phase. My question is, how can MATLAB guarantee no phase shift with `lowpass`, and how can I reproduce that using DSP.jl?

---

<div class="post-metadata">

**Author:** ![henry2004y](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henry2004y/32/9284_2.png) [@henry2004y](https://discourse.julialang.org/u/henry2004y)\
**Post date:** [April 8, 2022, 8:27am UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214/2 "2022-04-08T08:27:00Z")

</div>

I found that there is another function `filtfilt`. If I use `filtfilt` instead of `filt`, it seems to have zero phase distortion. Then when should I use `filt` if it always creates a shift? In the options of FIRWindows, there is often a `zerophase` optional argument that confuses me.

---

<div class="post-metadata">

**Author:** ![RGerzaguet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rgerzaguet/32/45492_2.png) [@RGerzaguet](https://discourse.julialang.org/u/RGerzaguet)\
**Post date:** [April 8, 2022, 8:36am UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214/3 "2022-04-08T08:36:18Z")

</div>

Hello  
The phase shift is absolutely normal, you may juste have a look on the frequency response of you Butterworth filter at the frequency of your signal.  
When you use `filtfiltt` you apply the filtering two times, the first in the classic way and a second time in a reverse way, which cancel the phase. Note that in practical systems (like real time filtering on a temporal series), you cannot do a `filtfilt`.

---

<div class="post-metadata">

**Author:** ![mgkuhn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgkuhn/32/6276_2.png) [@mgkuhn](https://discourse.julialang.org/u/mgkuhn)\
**Post date:** [April 8, 2022, 12:20pm UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214/4 "2022-04-08T12:20:54Z")

</div>

The `filt` function applies a _causal_ filter, i.e. one that cannot look into the future (a prerequisite for real-time processing). Therefore it can only react to its input with some delay. However there is a simple trick: applying such a filter twice on a signal that is already completely available in memory, once in forward direction, and once in backward direction, causes these delays to cancel each other out. The `filtfilt` function does exactly that for you. But keep in mind that it does apply the filter twice, i.e. it will double the filter order (make its transition steeper). The result is a _non-causal_ filter (output samples will be affected by “future” input samples).

Other methods to obtain non-causal filters exist, for example filtering in the frequency domain, i.e. pad the signal, apply the FFT, attenuate some frequencies as desired, and then apply the inverse FFT and remove the padding (and boundary effects). (If you use that method, never forget that the discrete Fourier transform operates always on a single period of a periodic signal, i.e. its last and first sample are neighbours. Hence the need for padding to separate them. The padding width should be at least the length of the impulse response of your filter.)

---

<div class="post-metadata">

**Author:** ![Jake](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jake/32/46007_2.png) [@Jake](https://discourse.julialang.org/u/Jake)\
**Post date:** [August 2, 2022, 9:23pm UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214/5 "2022-08-02T21:23:36Z")

</div>

> [@mgkuhn](#):
>
> The padding width should be at least the length of the impulse response of your filter.

Would you use zero padding or a more sophisticated form of padding like mirroring the signal and applying a window to the padded signal?

---

<div class="post-metadata">

**Author:** ![mgkuhn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mgkuhn/32/6276_2.png) [@mgkuhn](https://discourse.julialang.org/u/mgkuhn)\
**Post date:** [August 3, 2022, 10:00am UTC](https://discourse.julialang.org/t/question-about-low-pass-filter-in-dsp-jl/79214/6 "2022-08-03T10:00:16Z")

</div>

Depends entirely on the application. Most common is zero padding, in particular if what you are filtering with the FFT is just one block out of a sequence of blocks, that you are then afterwards going stitch back together, with whatever overflowed into the padding region being added to the corresponding samples in the next block, so nothing gets lost, as shown on slide 86 in [DSP lecture recording 21: FFT based convolution](https://www.cl.cam.ac.uk/teaching/2021/DSP/video/#h21).
