[SciPy-user] filtering without phase shift
Lance Boyle
lanceboyle at myrealbox.com
Wed Apr 9 05:27:42 EDT 2003
It looks like symiiorder1 does what you did with your filtfilt, but
limited to a first-order filter applied twice, once forward and once
backward. You still have two coefficients to supply.
I can't find info on signal.lfiltic (Python/SciPy newbie).
You don't mention what coefficients you are using on the coefficient
vectors a and b. This can make a difference in the nature of edge
effects.
If you can "fade in" your data, that is, multiply it by a ramp starting
from zero or another small number and increasing to 1 after a few
samples, the edge effect will be reduced. Also, a quarter-cycle of a
raised cosine works nicely. Of course, this would mean messing with
your data.
You can discard the part of your data that is uglified by edge effects.
I guess that's obvious and that you don't have any data to waste.
You might try "making up" some data to put at the beginning and end of
your actual data. I haven't tried this but if the edge effect
("ringing") is pretty much shorter than your data length, you could try
mirror-imaging your data once to the left and once to the right of your
original data, so that then you have a data record that is three times
the length of the original data. Then the first third of the extended
data and the last third are backwards versions of the middle third.
This is so that there are no edges at the beginning and end of the
middle third. Filter as you describe (forward-then-backward) and keep
only the middle third, corresponding to the location of your original
data. Depending on the relative lengths of the edge effect and your
data, a full padding might be unnecessary and only a partial padding
might work, just as long as the edge effects are outside your actual
data.
Which brings up a third possibility, but I mention this only in
principle. I see that lfilter has an option to set the initial
conditions of the filter, zi. In principle, you could come up with a
set of initial conditions that would reduce the edge effects. As it is,
unless you specify otherwise, the filter is starting from the
zero-state and then it is getting hit with the sudden onset of your
data. Finding a suitable set of initial conditions is hard. The best
way would be to pad your data and then record the filter state at the
beginning of the actual data, then start over with the new initial
conditions and at the edge of your actual data, but that is the same as
the previous paragraph.
I'm bored so if you have more questions let me know.
Jerry
On Monday, Apr 7, 2003, at 23:00 America/Phoenix, Andrew Straw wrote:
>
> I trying to lowpass filter my data without introducing a phase shift.
> I'm not a signal analysis whiz, but I know enough to be dangerous. So
> far I've come up with the following, which works except that it has
> some serious edge-effects.
>
> from scipy.signal import lfilter
> from scipy import flipud
>
> def filtfilt(b, a, input_vector):
> """input_vector has shape (n,1)"""
> forward = lfilter(b, a, input_vector, axis=0)
> return flipud(lfilter(b, a, flipud(forward), axis = 0))
>
> Should I attempt to use the signal.lfiltic to minimize edge effects?
> Or should I maybe use symiirorder1? Is there any code anywhere that I
> can look at using these functions?
>
> I think the matlab function filtfilt that does what I want. Is there
> a translation of it to scipy anywhere?
>
> Cheers!
> Andrew
More information about the SciPy-User
mailing list