ฉันจะพล็อตการตอบสนองความถี่ด้วยตนเองของตัวกรองบัตเตอร์เวิร์ ธ บัตเตอร์เวิร์ ธ ใน MATLAB โดยไม่มีฟังก์ชัน freqz ได้อย่างไร


15

ฉันมีรหัสเช่นด้านล่างที่ใช้ตัวกรอง bandpass กับสัญญาณ ฉันเป็น noob ที่ DSP และฉันต้องการที่จะเข้าใจสิ่งที่เกิดขึ้นเบื้องหลังก่อนที่ฉันจะดำเนินการต่อ

freqzการทำเช่นนี้ผมต้องการที่จะทราบวิธีการพล็อตการตอบสนองความถี่ของตัวกรองโดยไม่ต้องใช้

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

ให้ผลลัพธ์ที่[b, a]ฉันจะทำอย่างไร ดูเหมือนว่ามันจะเป็นงานง่าย ๆ แต่ฉันมีเวลาหาสิ่งที่ฉันต้องการในเอกสารหรือออนไลน์

ฉันต้องการที่จะเข้าใจวิธีการทำเช่นนี้โดยเร็วที่สุดเช่นใช้fftอัลกอริทึมเร็วหรืออื่น ๆ

คำตอบ:


25

เรารู้ว่าในฟังก์ชั่นการถ่ายโอนทั่วไปของตัวกรองจะได้รับจาก:

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

ตอนนี้แทนที่z=ejωเพื่อประเมินฟังก์ชั่นการถ่ายโอนในวงกลมหน่วย:

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

ดังนั้นนี้จะกลายเป็นปัญหาของการประเมินผลพหุนามที่ได้รับωωนี่คือขั้นตอน:

  • สร้างเวกเตอร์ของความถี่เชิงมุมω=[0,,π]ในช่วงครึ่งแรกของสเปกตรัม (ไม่จำเป็นต้องไปถึง2π ) wและบันทึกไว้ใน
  • Pre-คำนวณสัญลักษณ์ejωzeที่ทั้งหมดของพวกเขาและเก็บไว้ในตัวแปร
  • ใช้polyvalฟังก์ชั่นในการคำนวณค่าของตัวเศษและส่วนโดยการโทร: polyval(b, ze)หารมันและเก็บHไว้ เพราะเราสนใจแอมพลิจูดจากนั้นจึงเอาค่าสัมบูรณ์ของผลลัพธ์
  • แปลงเป็นสเกล dB โดยใช้: HdB=20เข้าสู่ระบบ10H - ในกรณีนี้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:

ป้อนคำอธิบายรูปภาพที่นี่

และผลลัพธ์ของสคริปต์ของฉัน:

ป้อนคำอธิบายรูปภาพที่นี่

และการเปรียบเทียบอย่างรวดเร็วในระดับเชิงเส้น - ดูดีมาก!

[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'})

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้คุณสามารถเขียนใหม่ลงในฟังก์ชั่นบางอย่างและเพิ่มเงื่อนไขเล็กน้อยเพื่อให้มีประโยชน์มากขึ้น


อีกวิธีหนึ่ง (ที่เสนอก่อนหน้านี้มีความน่าเชื่อถือมากกว่า) ก็คือการใช้คุณสมบัติพื้นฐานการตอบสนองความถี่ของตัวกรองคือการแปลงฟูริเยร์ของการตอบสนองต่อแรงกระตุ้น:

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

δ(t)

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));

ในการเปรียบเทียบนี้จะผลิตต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่


1
คำอธิบายโดยละเอียด
ส่วนที่

ฉันคิดว่าบรรทัด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?
LéoLéopold Hertz 준영

เพื่อชี้แจงให้ผู้อื่นทราบ: "ไม่จำเป็นต้องไปถึง 2 pi" คือเมื่อค่าสัมประสิทธิ์เป็นของจริง มีแอพพลิเคชั่นสำหรับตัวกรองที่มีค่าสัมประสิทธิ์ที่ซับซ้อนและในกรณีนั้นคลื่นความถี่จะไม่สมมาตรอีกต่อไปและในกรณีนั้นต้องการขยายความถี่เป็น 2 pi
Dan Boschen

14

นี่เป็นเพียงแค่ภาคผนวกของคำตอบของโจเจคซึ่งเป็นเรื่องทั่วไปและดีมากเมื่อใช้คณิตศาสตร์ที่มีความแม่นยำสองเท่า เมื่อมีความแม่นยำน้อยกว่าจะมี "ปัญหาโคไซน์" ที่เกิดขึ้นเมื่อความถี่ในการตอบสนองความถี่ต่ำมาก (ต่ำกว่า Nyquist มาก) และเมื่อความถี่เรโซแนนท์ของตัวกรองต่ำมาก

|H(ejω)|2|H(ejω)|=|H(ejω)|

พิจารณารหัสประจำตัวนี้:

cos(ω) = 12sin2(ω2)

บาป2(ω2)ω0

บาป2(ω2)

H(Z)=0+1Z-1+2Z-2a0+a1Z-1+a2Z-2

ซึ่งมีการตอบสนองความถี่ที่ซับซ้อน

H(อีJω)=0+1อี-Jω+2อี-J2ωa0+a1อี-Jω+a2อี-J2ω

ซึ่งมีขนาดกำลังสอง:

|H(อีJω)|2=|0+1อี-Jω+2อี-J2ω|2|a0+a1อี-Jω+a2อี-J2ω|2=(0+1cos(ω)+2cos(2ω))2+(1บาป(ω)+2บาป(2ω))2(a0+a1cos(ω)+a2cos(2ω))2+(a1บาป(ω)+a2บาป(2ω))2=02+12+22+21(0+2)cos(ω)+202cos(2ω)a02+a12+a22+2a1(a0+a2)cos(ω)+2a0a2cos(2ω)

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

เมื่อใช้ตรีโกณมิติด้านบนคุณจะได้ขนาดกำลังสอง:

|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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.