เรารู้ว่าในฟังก์ชั่นการถ่ายโอนทั่วไปของตัวกรองจะได้รับจาก:
H(z)=∑Mk=0bkz−k∑Nk=0akz−k
ตอนนี้แทนที่z=ejωเพื่อประเมินฟังก์ชั่นการถ่ายโอนในวงกลมหน่วย:
H(ejω)=∑Mk=0bke−jωk∑Nk=0ake−jωk
ดังนั้นนี้จะกลายเป็นปัญหาของการประเมินผลพหุนามที่ได้รับωωนี่คือขั้นตอน:
- สร้างเวกเตอร์ของความถี่เชิงมุมω=[0,…,π]ในช่วงครึ่งแรกของสเปกตรัม (ไม่จำเป็นต้องไปถึง2π )
w
และบันทึกไว้ใน
- Pre-คำนวณสัญลักษณ์e−jω
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));
ในการเปรียบเทียบนี้จะผลิตต่อไปนี้: