Why do I receive different results when comparing a digital filter designed using the BUTTER and BILINEAR functions in the Signal Processing Toolbox?

7 views (last 30 days)
Using the following specifications:
Fs = 172800;
Fc = 70000;
where "Fs" represents the sampling frequency and "Fc" represents the cutoff frequency, I created a digital filter in two different ways:
1. Using the BUTTER function.
[B ,A] = butter(4,Fc/(Fs/2));
2. Using the BILINEAR function to convert the analog filter designed using the BUTTER function into a digital filter through a bilinear transformation.
[Bs,As] = butter(4,Fc*2*pi,'s');
[Bz,Az] = bilinear(Bs,As,Fs);
I then used the FVTOOL function to compute the magnitude response and compared the two results:
fvtool(B,A,Bz,Az);
Notice that the results of the two magnitude responses are not the same even though I am using the same specifications.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 16 Nov 2009
This is the expected behavior for filter discretization in the Signal Processing Toolbox. The example above illustrates the nonlinear nature of the bilinear transformation. To counteract this nonlinearity, it is necessary to create analog domain filters with "prewarped" band edges, which map to the correct locations upon bilinear transformation.
If you want to design the analog filter that will be equivalent to the design using the ‘s’ option in the BUTTER function, you need to prewarp the frequency as follows:
Wc = tan(pi/2*Fc/(Fs/2)); % Analog prewarped freq. rad/second
Note that this frequency is already in rad/second so the analog design is:
[Bs,As] = butter(4,Wc,'s');
Now the issue is what sampling frequency (Fs) to use with BILINEAR. In the prewarping method used to compute "Wc", we implicitly used the bilinear transformation that is most commonly seen in the literature:
s=(1-z^(-1))/(1+z^(-1)).
In the BILINEAR function documentation, the following transformation is used:
s = 2*Fs*(z-1)/(z+1)
which is equivalent to
s = 2*Fs*(1-z^(-1))/(1+z^(-1)).
To make this compatible to the one we have used for "Fc", we need to set the sampling frequency "Fs" to 0.5. Note that this "Fs" is used solely for the purpose
of the bilinear transformation, i.e. it is set to 0.5 such that s=(1-z^(-1))/(1+z^(-1)).
By using Fs=0.5 for the BILINEAR function as follows:
[Bz,Az] = bilinear(Bs,As,.5);
using FVTOOL as follows will show two identical filters:
fvtool(B,A,Bz,Az);
Note that if you are uncomfortable with using a different "Fs" for the bilinear transformation, you could use the same "Fs" throughout if you take that into account when prewarping as follows:
Wc = 2*Fs*tan(pi/2*Fc/(Fs/2));
[Bs,As] = butter(4,Wc,'s');
[Bz,Az] = bilinear(Bs,As,Fs);
[B ,A] = butter(4,Fc/(Fs/2));
fvtool(B,A,Bz,Az);
A similar discussion can be found in the documentation by typing the following command in MATLAB 7.0.4 (R14SP2):
web([docroot,'/toolbox/signal/filter15.html'])
  1 Comment
Harry
Harry on 18 Feb 2021
@MathWorks Support Team What about when designing a Butterworth filter using fdesign.design? I see a third type of behavior and I can't figure out what is different in this case.
I can't see any way of controlling prewarping with fdesign.design. When I try designopts(D, 'butter'), these are the only available options:
FilterStructure
SOSScaleNorm
SOSScaleOpts
MatchExactly
SystemObject

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!