Why am I getting different frequency responses for the same filter using bode() and fvtool()?

Hello,
I am trying to design a low pass filter with a cutoff frequency of 100 Hz.
I have been given freedom to assume all other parameters accordingly.
Here is my code:
fs = 500; % Sampling frequency
Ts = 1/fs;
fc = 100; % Cutoff frequency
t = 0:(1/fs):0.5;
input = sin(2*pi*50*t) + sin(2*pi*150*t);
noise = randn(size(t));
noisy_input = input + noise;
% Original signal plot and spectrum
p1 = pspectrum(noisy_input, 'power');
N1 = length(p1);
frequencies1 = (0:N1-1)*(fs/N1);
plot((frequencies1/2), p1);
title('Power Spectrum of Original Signal');
xlabel('Frequency (Hz)');
ylabel('Power');
plot(t, noisy_input);
title('Original Signal');
xlabel('Time');
ylabel('Magnitude');
% Designing IIR filter
lpf_iir = designfilt('lowpassiir', 'FilterOrder', 10, 'stopbandFrequency', fc, 'SampleRate', fs, 'StopbandAttenuation', 80);
% Applying filter on noisy input
y5_filtered_iir = filter(lpf_iir, noisy_input);
% Plotting the filtered signal (IIR)
p3 = pspectrum(y5_filtered_iir, 'power');
N3 = length(p3);
frequencies3 = (0:N3-1)*(fs/N3);
plot((frequencies3/2), p3);
title('Power Spectrum of Filtered Signal using IIR Filter');
xlabel('Frequency (Hz)');
ylabel('Power');
plot(t, y5_filtered_iir);
title('Filtered Signal using IIR Filter');
xlabel('Time');
ylabel('Magnitude');
% Bode Plot of the IIR Filter
[num, den] = tf(lpf_iir);
figure;
bode(num, den);
fvtool(lpf_iir);
title('Bode Plot of IIR Filter');
Here is the freq plot using bode():
And here is the freq plot using fvtool():
Now, I do understand that fvtool is used only for digital filters. However I do not know:
  1. Why does the frequency using the bode() command drop at 1 rad/sec (ie., 6.28 Hz) while my cutoff frequency is 100 Hz?
  2. Why are frequency plots itself, both different?
  3. Why is there a spike after 1 rad/sec in the first plot and multiple spikes after 100 Hz in the second plot?
Please tell me if I'm doing or understanding something wrong?

 Accepted Answer

Hi Rinitha,
Here is the design of the low pass filter
fs = 500; % Sampling frequency
Ts = 1/fs;
fc = 100; % Cutoff frequency
% Designing IIR filter
lpf_iir = designfilt('lowpassiir', 'FilterOrder', 10, 'stopbandFrequency', fc, 'SampleRate', fs, 'StopbandAttenuation', 80);
Now pull out the numerator and demoninator of the filter
% Bode Plot of the IIR Filter
[num, den] = tf(lpf_iir);
The problems start here.
The following call to bode is an obosolete usage, though it still works.
which bode(num, den)
/MATLAB/toolbox/control/ctrlobsolete/bode.m
However, in that usage num and den are the numerator and denominator of a continuous time transfer function, whereas here num and den define a discrete time transfer function. I believe there is an old function called dbode that could be used, but I wouldn't recommend it.
Instead, create a tf object as used in the Control System Toolbox. We have to account for the Signal Processing Toolbox convention that num and den define the coefficients in increasing powers of z^-1
h = tf(num,den,Ts,'Variable','z^-1');
Now do the bode plot
figure
bode(h)
It stil doesn't look like fvtool output because of the different frequency units and log scale, etc.. To that end, one option is to use bodeplot, which gives some options for controlling such things. Here's a start. See the relevant doc page for more customizations.
opts = bodeoptions;
opts.FreqUnits = 'Hz';
opts.FreqScale = 'linear';
opts.PhaseUnits = 'rad';
opts.XLim = {[0 250]};
opts.Grid = 'on';
figure
bodeplot(h,opts)
I'm not quite sure how fvtool is handling the phase wrapping, but I'm sure, or at least hope, that could be figured out if needed.

5 Comments

Thank you for answering, Paul!
I understand the usage of bode() and the [num,den] part! Also could I ask why there are many "spikes" or "lobes" after the initial attenuation at 100 Hz? Is there any way i can modify my filter so that it gives a frequency response as close to a basic low pass filter as possible?
The spikes, or nulls, in the magnitude response arise from the locations of transfer function zeros on the unit circle.
fs = 500; % Sampling frequency
Ts = 1/fs;
fc = 100; % Cutoff frequency
% Designing IIR filter
lpf_iir = designfilt('lowpassiir', 'FilterOrder', 10, 'stopbandFrequency', fc, 'SampleRate', fs, 'StopbandAttenuation', 80);
[num, den] = tf(lpf_iir);
[abs(roots(num)) angle(roots(num))/Ts/2/pi] % conver angle to Hz
ans = 10×2
1.0000 216.2471 1.0000 -216.2471 1.0000 161.1117 1.0000 -161.1117 1.0000 127.1575 1.0000 -127.1575 1.0000 100.9393 1.0000 -100.9393 1.0000 108.8734 1.0000 -108.8734
I don't know what you mean by "basic low pass filter." designfilt offers many options, including methods, for designing the filter. Suggest going through that doc page, its examples, and other doc pages for the Signal Processing Toolbox that discuss digital filter design, and play with the tools that are available.
Updated: as my questions have changed.
The spikes, or nulls, in the magnitude response arise from the locations of transfer function zeros on the unit circle.
I have been advised to try removing the zeros out of the bandwidth (here, 250 Hz). However, as far as I know, zeros of a transfer function cannot be moved, correct?
So I was thinking of trying some pole compensation elsewhere to reduce these "nulls" caused by the zeros.. Would that be possible?
I don't know what "removing the zeros" means. Why are the nulls a problem. If you want a low pass filter that doesn't have those deep nulls, consider using another method to design the filter. Here is an approach that uses butter to design a Butterworth filter
fs = 500; % Sampling frequency
Ts = 1/fs;
fc = 100; % Cutoff frequency
% Designing IIR filter
lpf_iir = designfilt('lowpassiir', 'FilterOrder', 10, 'stopbandFrequency', fc, 'SampleRate', fs, 'StopbandAttenuation', 80);
[num, den] = tf(lpf_iir);
freqz(num,den,2048,fs);
[b,a] = butter(6,fc/(fs/2));
freqz(b,a,2048,fs);
We can see that butter interprets the cutoff frequency differently than the default method for designfilt, so you'ld have to play with that parameter to get the result you're looking for. And the Butterworth filter doesn't roll off as steeply. Here, I used the butter function explicitly for illustration, but it's also a 'Method' in designfilt, which is probably what you should really use. Again, I'm sure the Signal Processing Toolbox doc abounds with examples of digital filter design.
I'm assuming that my teacher needs a completely flat frequency response as this:
The Butterworth filter works this way, so thank you for answering!

Sign in to comment.

More Answers (0)

Categories

Asked:

on 14 Jul 2023

Commented:

on 18 Jul 2023

Community Treasure Hunt

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

Start Hunting!