0

We have two lowpass filters with a different cutoff value:

b, a = signal.butter(2, 0.125)
b2, a2 = signal.butter(2, 0.140) 

When applying the first filter to x[0:10000] and the second to x[10000:20000] with lfilter, we have to use initial conditions for the output to be "continuous", as seen here in the answer of Continuity issue when applying an IIR filter on successive time-frames:

zi = lfilter_zi(b, a)
x[0:10000], zi = lfilter(b, a, x[0:10000], zi=zi)
x[10000:20000], zi = lfilter(b2, a2, x[10000:20000], zi=zi)

Question: how to do the same when applying filtfilt (forward and backwards filtering), to ensure continuity when using filters on consecutive blocks, as there is no zi initial conditions parameter?

sobek
  • 1,386
  • 10
  • 28
Basj
  • 41,386
  • 99
  • 383
  • 673
  • I don't think that the implementation of `filtfilt` lends itself to block-processing, unfortunately. You may have to search for a specialized implementation or implement something yourself. – sobek Sep 26 '18 at 13:13
  • 1
    Could you elaborate why you need acausal filtering? Maybe there's another solution for your problem... – sobek Sep 26 '18 at 13:19
  • @sobek When using `lfilter` (that has the `zi` initial condition parameter, so this one works well for block-processing) there is a delay `delta` for a step function (Heavyside) to reach, say, 95% of the final value. I noticed `filtfilt` compensates this delay (to the price of a pre-ringing), that's why I was using it. I could also use `lfilter` and shift the time-axis by `delta/2` to avoid the too-big latency caused by `lfilter`. How is called this `delta` for a filter? Is there a way to compute it? – Basj Sep 26 '18 at 13:21
  • Yes, that's what an acausal filter does, it takes input values "from the future" to calculate the current output value. But why is it important to you? You can achieve the same by shifting the timestamps of the output signal relative to the input signal. What you call `delta` is usually called the *time constant of the step response* and is denoted by the greek letter **tau**. – sobek Sep 26 '18 at 13:24
  • @sobek It's important because my input signal `x` is separated into several signals `x = x1 + x2 + x3`. Then I'm applying modifications (filtering, etc.) on `x1`, this gives `x1_modified`. Then I'm resumming `x_modified = x1_modified + x2 + x3`. If there is some delay in `x1`'s modification, it will be weird when resumming with `x2` and `x3` which are not delayed. That's why I was looking for delay compensation, and that's why I was using `filtfilt` instead of `lfilter`. – Basj Sep 26 '18 at 13:27
  • @sobek Moreover as `x1` has to be modified with a cutoff *that varies along time* (thus this [question](https://stackoverflow.com/questions/52403589/lowpass-filter-with-a-time-varying-cutoff-frequency-with-python)), I have to do it "by blocks". Thus this problem `filtfilt` + continuity when doing block processing! This is the full picture :) – Basj Sep 26 '18 at 13:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/180804/discussion-between-sobek-and-basj). – sobek Sep 26 '18 at 13:32

0 Answers0