annotate main/signal/filtfilt.m @ 0:6b33357c7561 octave-forge

Initial revision
author pkienzle
date Wed, 10 Oct 2001 19:54:49 +0000
parents
children 76fe0d9e2cf8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
1 ## Copyright (C) 1999 Paul Kienzle
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
2 ##
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
3 ## This program is free software; you can redistribute it and/or modify
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
4 ## it under the terms of the GNU General Public License as published by
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
5 ## the Free Software Foundation; either version 2 of the License, or
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
6 ## (at your option) any later version.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
7 ##
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
8 ## This program is distributed in the hope that it will be useful,
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
11 ## GNU General Public License for more details.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
12 ##
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
13 ## You should have received a copy of the GNU General Public License
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
14 ## along with this program; if not, write to the Free Software
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
15 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
16
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
17 ## usage: y = filtfilt(b, a, x)
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
18 ##
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
19 ## Forward and reverse filter the signal. This corrects for phase
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
20 ## distortion introduced by a one-pass filter, though it does square the
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
21 ## magnitude response in the process. That's the theory at least. In
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
22 ## practice the phase correction is not perfect, and magnitude response
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
23 ## is distorted, particularly in the stop band.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
24 ##
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
25 ## In this version, I zero-pad the end of the signal to give the reverse
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
26 ## filter time to ramp up to the level at the end of the signal.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
27 ## Unfortunately, the degree of padding required is dependent on the
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
28 ## nature of the filter and not just its order, so this function needs
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
29 ## some work yet.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
30 ##
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
31 ## Example
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
32 ## [b, a]=butter(3, 0.1); % 10 Hz low-pass filter
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
33 ## t = 0:0.01:1.0; % 1 second sample
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
34 ## x=sin(2*pi*t*2.3)+0.25*randn(size(t)); % 2.3 Hz sinusoid+noise
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
35 ## y = filtfilt(b,a,x); z = filter(b,a,x); % apply filter
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
36 ## plot(t,x,';data;',t,y,';filtfilt;',t,z,';filter;')
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
37
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
38 ## Changelog:
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
39 ## 2000 02 pkienzle@kienzle.powernet.co.uk
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
40 ## - pad with zeros to load up the state vector on filter reverse.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
41 ## - add example
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
42
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
43 ## TODO: In Matlab filtfilt `reduces filter startup transients by carefully
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
44 ## TODO: choosing initial conditions, and by prepending onto the input
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
45 ## TODO: sequence a short, reflected piece of the input sequence'.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
46 ## TODO: Once filtic is written, use that here.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
47 ## TODO: My version seems to have similar quality to matlab, but both are
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
48 ## TODO: pretty bad. They do remove gross lag errors, though.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
49 ## TODO: Note that if x is really long, it might be worth doing
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
50 ## TODO: the zero padding as a separate call to filter so that the
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
51 ## TODO: vector never has to be copied. E.g.,
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
52 ## TODO: [y, state] = filter(b,a,x);
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
53 ## TODO: tail = filter(b,a,zeros(1,max(length(b),length(a))),state);
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
54 ## TODO: [tail, state] = filter(b,a,flipXX(tail));
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
55 ## TODO: y = flipXX(filter(b,a,flipXX(y), state));
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
56 ## TODO: Don't know for what n this would be faster, if any, but the
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
57 ## TODO: memory saving might be nice.
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
58
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
59 function y = filtfilt(b, a, x)
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
60 if (nargin != 3)
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
61 usage("y=filtfilt(b,a,x)");
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
62 end
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
63
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
64 if (rows(x) == 1)
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
65 y = filter(b,a,[x, zeros(1,2*max(length(a),length(b)))]);
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
66 y = fliplr(filter(b,a,fliplr(y)));
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
67 else
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
68 y = filter(b,a,[x ; zeros(2*max(length(a),length(b)), 1)]);
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
69 y = flipud(filter(b,a,flipud(y)));
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
70 endif
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
71 y = y(1:length(x));
6b33357c7561 Initial revision
pkienzle
parents:
diff changeset
72 endfunction