如何在没有freqz函数的MATLAB中手动绘制带通Butterworth滤波器的频率响应?


15

我有如下代码,将带通滤波器应用于信号。我是DSP的新手,我想在继续之前先了解幕后情况。

要做到这一点,我想知道如何绘制滤波器的频率响应不使用freqz

[b, a] = butter(order, [flo fhi]);
filtered_signal = filter(b, a, unfiltered_signal)

鉴于输出,[b, a]我将如何做?这似乎是一个简单的任务,但是我很难在文档或在线中找到所需的内容。

我还想了解如何尽快执行此操作,例如使用fft或其他快速算法。

Answers:


25

我们知道,一般而言,过滤器的传递函数由下式给出:

H(z)=k=0Mbkzkk=0Nakzk

现在替代z=ejω来评价在单位圆上的传递函数:

H(ejω)=k=0Mbkejωkk=0Nakejωk

因此,这仅是在给定ω下进行多项式求值的问题。步骤如下:

  • 创建角频率的矢量ω=[0,,π]对于频谱的第一半部分(没有必要去多达2π)中并保存它w
  • 预计所有它们的指数ejω并将其存储在变量中ze
  • 使用该polyval函数通过调用以下命令来计算分子和分母的值:polyval(b, ze)将其除以并存储在中H。因为我们对振幅感兴趣,所以取结果的绝对值。
  • 使用以下公式转换为dB刻度:HdB=20log10H在这种情况下,1是参考值。

将所有内容放入代码中:

%% Filter definition
a = [1 -0.5 -0.25]; % Some filter with lot's of static gain
b = [1 3 2];

%% My freqz calculation
N = 1024; % Number of points to evaluate at
upp = pi; % Evaluate only up to fs/2
% Create the vector of angular frequencies at one more point.
% After that remove the last element (Nyquist frequency)
w = linspace(0, pi, N+1); 
w(end) = [];
ze = exp(-1j*w); % Pre-compute exponent
H = polyval(b, ze)./polyval(a, ze); % Evaluate transfer function and take the amplitude
Ha = abs(H);
Hdb  = 20*log10(Ha); % Convert to dB scale
wn   = w/pi;
% Plot and set axis limits
xlim = ([0 1]);
plot(wn, Hdb)
grid on

%% MATLAB freqz
figure
freqz(b,a)

原始输出freqz

enter image description here

和我的脚本的输出:

enter image description here

快速线性比例比较-看起来很棒!

[h_f, w_f] = freqz(b,a);
figure
xlim = ([0 1]);
plot(w, Ha) % mine
grid on
hold on
plot(w_f, abs(h_f), '--r') % MATLAB
legend({'my freqz','MATLAB freqz'})

enter image description here

现在,您可以将其重写为某些函数,并添加一些条件以使其更有用。


另一种方法(以前提出的方法更可靠)是使用基本属性,即滤波器的频率响应是其脉冲响应的傅立叶变换:

H(ω)=F{h(t)}

因此,您必须输入系统的δ(t)信号,计算滤波器的响应,并对其进行FFT:

d = [zeros(1,length(w_f)) 1 zeros(1,length(w_f)-1)];
h = filter(b, a, d);
HH = abs(fft(h));
HH = HH(1:length(w_f));

相比之下,这将产生以下结果:

enter image description here


1
详细说明
partida 2014年

我在想这条线a = [1 -0.5 -0.25]; % Some filter with lot's of static gain。您能在这里解释一下这些参数的选择吗?我正在阅读我的Matlab手册,它[h,w] = freqz(hfilt,n)在突触的一部分中说。您要在中指定两个过滤器(a,b)freqz。两个过滤器都在hfilt吗?还是一个n
莱奥列奥波尔德·赫兹준 영

只是要为其他人澄清一下:“不需要增加2 pi”是指系数是实数。对于具有复杂系数的滤波器,存在一些应用,在这种情况下,频谱将不再对称,并且在这种情况下,希望将频率扩展到2 pi。
Dan Boschen's

14

这只是jojek答案的附录,使用双精度数学时,它更通用,也非常好。当精度较低时,当频率响应中的频率非常低(远低于Nyquist)并且滤波器的谐振频率非常低时,就会出现“余弦问题”。

当你计算幅度(平方)频率响应这些复杂的指数将被转换为正弦和余弦,但是当数学运算开始时,只有余弦可以生存。这应该很清楚,因为幅度是一个偶函数| ^ h é - Ĵ ω| = | ^ h Ë Ĵ ω| wrt频率和仅余弦是偶函数。|H(ejω)|2|H(ejω)|=|H(ejω)|

考虑以下触发身份:

cos(ω) = 12sin2(ω2)

sin2(ω2)ω0。如此之小,以至于当将项(或它是负数)加到1时,该项和该项中的频率信息都会丢失。即使是浮点运算,情况也是如此,但双精度浮点运算的问题较少。但是我们当中有些将这个频率响应函数付诸实践的人可能没有双精度浮点或任何浮点的资源。

sin2(ω2)

H(z)=b0+b1z1+b2z2a0+a1z1+a2z2

频率响应复杂

H(ejω)=b0+b1ejω+b2ej2ωa0+a1ejω+a2ej2ω

幅度平方:

|H(ejω)|2=|b0+b1ejω+b2ej2ω|2|a0+a1ejω+a2ej2ω|2=(b0+b1cos(ω)+b2cos(2ω))2+(b1sin(ω)+b2sin(2ω))2(a0+a1cos(ω)+a2cos(2ω))2+(a1sin(ω)+a2sin(2ω))2=b02+b12+b22+2b1(b0+b2)cos(ω)+2b0b2cos(2ω)a02+a12+a22+2a1(a0+a2)cos(ω)+2a0a2cos(2ω)

|H(ejω)|cos(ω)cos(2ω)ω11

使用上面的trig身份,您将得到幅度平方:

|H(ejω)|2=b02+b12+b22+2b1(b0+b2)cos(ω)+2b0b2cos(2ω)a02+a12+a22+2a1(a0+a2)cos(ω)+2a0a2cos(2ω)=b02+b12+b22+2b1(b0+b2)(12sin2(ω2))+2b0b2(12sin2(ω))a02+a12+a22+2a1(a0+a2)(12sin2(ω2))+2a0a2(12sin2(ω))=b02+b12+b22+2b1(b0+b2)(12sin2(ω2))+2b0b2(2cos2(ω)1)a02+a12+a22+2a1(a0+a2)(12sin2(ω2))+2a0a2(2cos2(ω)1)=b02+b12+b22+2b1(b0+b2)(12sin2(ω2))+2b0b2(2(12sin2(ω2))21)a02+a12+a22+2a1(a0+a2)(12sin2(ω2))+2a0a2(2(12sin2(ω2))21)=b02+b12+b22+2b1(b0+b2)(12ϕ)+2b0b2(2(12ϕ)21)a02+a12+a22+2a1(a0+a2)(12ϕ)+2a0a2(2(12ϕ)21)=b02+b12+b22+2b1(b0+b2)(12ϕ)+2b0b2(18ϕ+8ϕ2)a02+a12+a22+2a1(a0+a2)(12ϕ)+2a0a2(18ϕ+8ϕ2)=b02+b12+b22+2b1b0+2b1b24(b1b0+b1b2)ϕ+2b0b216b0b2ϕ+16b0b2ϕ2a02+a12+a22+2a1a0+2a1a24(a1a0+a1a2)ϕ+2a0a216a0a2ϕ+16a0a2ϕ2=(b02+b12+b22+2b1b0+2b1b2+2b0b2)4(b1b0+b1b24b0b2)ϕ+16b0b2ϕ2(a02+a12+a22+2a1a0+2a1a2+2a0a2)4(a1a0+a1a24a0a2)ϕ+16a0a2ϕ2=14(b02+b12+b22+2b1b0+2b1b2+2b0b2)(b1b0+b1b24b0b2)ϕ+4b0b2ϕ214(a02+a12+a22+2a1a0+2a1a2+2a0a2)(a1a0+a1a24a0a2)ϕ+4a0a2ϕ2=(b0+b1+b22)2ϕ(4b0b2(1ϕ)+b1(b0+b2))(a0+a1+a22)2ϕ(4a0a2(1ϕ)+a1(a0+a2))

where ϕsin2(ω2)

if your gear is intending to plot this as dB, it comes out as

20log10|H(ejω)| = 10log10((b0+b1+b22)2ϕ(4b0b2(1ϕ)+b1(b0+b2)))10log10((a0+a1+a22)2ϕ(4a0a2(1ϕ)+a1(a0+a2)))

so your division turns into subtraction, but you have to be able to compute logarithms to some base or another. numerically, you will have much less trouble with this for low frequencies than doing it the apparent way.


2
That's really cool, thank you Robert! +1
jojek

@Robert I "believe" similar to my comment for Jojek above that this only applies as well when the coefficients are real (and therefore the spectrum is symmetric and thus the magnitude converts to cosines as you show)... Am I correct?
Dan Boschen

yes. that commitment is made when you go from the first line of |H(ejω)|2=... to the second line. no going back after that.
robert bristow-johnson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.