freqz() magnitude plot behavior for estimated filter coefficients
3 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I am working on a project involving estimating a digital filter representation of an experimentally-determined frequency response.
The system in question has a frequency response that, interestingly, has a slight increase in magnitude as frequency increases, like the following plot:

I've estimated FIR filter coefficients using the invfreqz() function with denominator n = 0, and numerator m = 200. This results in a set of coefficients, a and b, respectively.
Given a set of frequencies used in the initial experiment in which we obtained the frequency response, stored and normalized in the vector w -> [0,pi], validating these coefficients using the function freqz() in the following manner results in the following plot. It appears to be pretty consistent with the initial frequency response data.
h = freqz(b,a,w);
subplot(2,1,1); plot(w,abs(h)); grid on; ylabel('Magnitude'); xlabel('Frequency (Hz)');
subplot(2,1,2); plot(w,angle(h)); grid on; ylabel('Phase (rad)'); xlabel('Frequency (Hz)');

However, when I don't input the frequency vector, and instead let freqz() output the frequency bins, the resulting plot is quite different:
[h,w] = freqz(b,a);
subplot(2,1,1); plot(w,abs(h)); grid on; ylabel('Magnitude'); xlabel('Frequency (Hz)');
subplot(2,1,2); plot(w,angle(h)); grid on; ylabel('Phase (rad)'); xlabel('Frequency (Hz)');

The frequency vector from the experiment consists of only 101 points between 60 and 10060 Hz, so I suspect the freqz() function is interpolating to fill out the default size-512 frequency output vector in the latter case. But I'm not sure why that results in such a strong sinusoidal pattern, or why the phase appears to tend around 0 radians for the entire spectrum, rather than a slight linear decrease.
What could be going on here?
3 Commenti
Paul
il 4 Gen 2024
Except I thought the w vector was in rad from 0->pi, not rad/s?
In any case, I suggest uploading your b, a, and w vectors in .mat file using the paper clip icon on the Insert menu.
Risposte (1)
Star Strider
il 3 Gen 2024
The third argument to freqz (when the first two are the transfer function coefficients, different with a second-order-section matrix or a digital filter object) is the number of points at which to evalate the transfer function (in this instance). Ideally, that should be a scalar.
Experimenting with that idea —
b = fir1(200, 0.9, 'high'); % Prototype filter
a = 1;
w = linspace(60, 1E+4, 101)/(2*pi) % Radian Frequency Vector (Guess)
figure
h = freqz(b,a,w);
subplot(2,1,1); plot(w,abs(h)); grid on; ylabel('Magnitude'); xlabel('Frequency (Hz)');
subplot(2,1,2); plot(w,angle(h)); grid on; ylabel('Phase (rad)'); xlabel('Frequency (Hz)');
figure
[h,w] = freqz(b,a);
subplot(2,1,1); plot(w,abs(h)); grid on; ylabel('Magnitude'); xlabel('Frequency (Hz)');
subplot(2,1,2); plot(w,angle(h)); grid on; ylabel('Phase (rad)'); xlabel('Frequency (Hz)');
figure
freqz(b, 1, 2^16, 10000) % High-Resolution Version
What you are seeing may be a very low resolution version of the actual transfer function in the first instance, although I have no idea how freqz interprets a vector input for the third argument, since it expects a scalar, and apparently doesn’t check to be sure that it is, or that the value is an integer. When you leave freqz to its own devices, it produces a higher resolution version.
Without your code (or your ‘b’ vector), this is only a guess on my part, however it could explain the discrepancy.
The problem is likely not with freqz, and is instead what you are giving it.
.
0 Commenti
Vedere anche
Categorie
Scopri di più su Digital Filter Analysis in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!