मैं फ्रीक्ज़ फ़ंक्शन के बिना MATLAB में एक बैंडपास बटरवर्थ फ़िल्टर की आवृत्ति प्रतिक्रिया को मैन्युअल रूप से कैसे करूं?


15

मेरे पास नीचे जैसा कोड है जो एक सिग्नल पर एक बैंडपास फ़िल्टर लागू करता है। मैं डीएसपी पर काफी नोबॉल हूं और आगे बढ़ने से पहले मैं समझना चाहता हूं कि पर्दे के पीछे क्या चल रहा है।

ऐसा करने के लिए, मैं यह जानना चाहता हूं कि कैसे उपयोग किए बिना फ़िल्टर की आवृत्ति प्रतिक्रिया को प्लॉट किया जाए freqz

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

आउटपुट [b, a]को देखते हुए मैं यह कैसे करूंगा? ऐसा लगता है कि यह एक सरल कार्य होगा, लेकिन मुझे एक मुश्किल समय मिल रहा है कि मुझे दस्तावेज या ऑनलाइन में क्या चाहिए।

मैं यह भी समझना चाहता हूं कि यह कैसे जल्दी से जल्दी करना है, जैसे कि एक fftया अन्य तेज एल्गोरिथ्म का उपयोग करना ।

जवाबों:


25

हम जानते हैं कि एक फिल्टर के सामान्य हस्तांतरण समारोह द्वारा दिया जाता है:

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

अब स्थानापन्न 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:

यहाँ छवि विवरण दर्ज करें

और मेरी स्क्रिप्ट का आउटपुट:

यहाँ छवि विवरण दर्ज करें

और रेखीय पैमाने में त्वरित तुलना - बहुत अच्छी लगती है!

[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) सिग्नल में फीड करना चाहिए , अपने फ़िल्टर की प्रतिक्रिया की गणना करें और इसका 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));

इसकी तुलना में यह निम्नलिखित उत्पादन करेगा:

यहाँ छवि विवरण दर्ज करें


1
विस्तृत विवरण
भाग

मैं यह लाइन सोच रहा हूं a = [1 -0.5 -0.25]; % Some filter with lot's of static gain। क्या आप मुझे इन मापदंडों के चयन की व्याख्या कर सकते हैं, कृपया। मैं अपने मटलब के मैनुअल को पढ़ रहा हूं और यह [h,w] = freqz(hfilt,n)सिंकैप्स के एक हिस्से में कहता है। आप दो फिल्टर (ए, बी) में दे रहे हैं freqz। क्या दोनों फ़िल्टर में हैं hfilt? या एक में n?
लेओ लेपोल्ड हर्ट्ज़ o

बस दूसरों के लिए स्पष्ट करने के लिए: "2 पी तक जाने की कोई आवश्यकता नहीं है" जब गुणांक वास्तविक होते हैं। जटिल गुणांक वाले फिल्टर के लिए अनुप्रयोग हैं और उस स्थिति में स्पेक्ट्रम सममित नहीं होगा और उस स्थिति में आवृत्ति को 2 पीआई तक बढ़ाना चाहते हैं।
डैन बॉशेन

14

यह सिर्फ जोजेक के जवाब का एक परिशिष्ट है जो अधिक सामान्य है और पूरी तरह से अच्छा है जब डबल-सटीक गणित का उपयोग किया जाता है। जब कम सटीकता होती है, तो एक "कोसाइन समस्या" होती है, जो तब होती है जब फ़्रीक्वेंसी रिस्पॉन्स में फ़्रीक्वेंसी बहुत कम (Nyquist की तुलना में बहुत कम) होती है और यह भी कि जब फ़िल्टर के गुंजयमान आवृत्तियाँ बहुत कम होती हैं।

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

इस ट्रिगर पहचान पर विचार करें:

cos(ω) = 12sin2(ω2)

sin2(ω2)ω0

इसलिए, मैंने जो किया है वह ऊपर दी गई ट्रिगर पहचान का उपयोग करता है और सभी कोसिन शर्तों को समाप्त कर देता है, अनिवार्य रूप से उन्हें जैसे दिखने वाले शब्दों के साथ बदल रहा है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ω)

so, one can see that the magnitude frequency response |H(ejω)| is an even symmetry function and depends only on the cosines cos(ω) and cos(2ω). for very low ω, the values of those cosines are so close to 1 that, with single-precision fixed or floating point, there are few bits remaining that differentiate those values from 1. that is the "cosine problem".

using the trig identity above, you get for magnitude squared:

|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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.