Wir wissen, dass die Übertragungsfunktion eines Filters im Allgemeinen gegeben ist durch:
H( z) = ∑Mk = 0bkz- k∑Nk = 0einkz- k
Setzen Sie nun z= ej ω , um die Übertragungsfunktion auf dem Einheitskreis zu bewerten:
H( ej ω) = ∑Mk = 0bke- j ωk∑Nk =0einke- j ω k
Somit wird dies nur ein Problem der Polynomauswertung bei einem gegebenen ω . Hier sind die Schritte:
- Erstellen Sie einen Vektor der Winkelfrequenzen ω = [ 0 , … , π] für die erste Hälfte des Spektrums (Sie müssen nicht auf 2 π ) und speichern Sie ihn in
w
.
- Berechnen Sie den Exponenten e- j ω und speichern Sie ihn in einer Variablen
ze
.
- Verwenden Sie die
polyval
Funktion, um die Werte von Zähler und Nenner durch Aufrufen von: zu berechnen polyval(b, ze)
, zu teilen und in zu speichern H
. Da wir an der Amplitude interessiert sind, nehmen wir den absoluten Wert des Ergebnisses.
- In dB-Skala umwandeln mit: HdB= 20 log10H - in diesem Fall ist 1 der Referenzwert.
All das in Code einfügen:
%% 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)
Ursprüngliche Ausgabe von freqz
:
Und die Ausgabe meines Skripts:
Und schneller Vergleich im linearen Maßstab - sieht gut aus!
[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'})
Jetzt können Sie es in eine Funktion umschreiben und einige Bedingungen hinzufügen, um es nützlicher zu machen.
Ein anderer Weg (der zuvor vorgeschlagen wurde, ist zuverlässiger) wäre die Verwendung der fundamentalen Eigenschaft, dass der Frequenzgang eines Filters eine Fourier-Transformation seines Impulsgangs ist:
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));
Im Vergleich ergibt sich folgendes:
a = [1 -0.5 -0.25]; % Some filter with lot's of static gain
. Können Sie mir die Auswahl dieser Parameter hier erläutern? Ich lese das Handbuch meines Matlab und es steht[h,w] = freqz(hfilt,n)
in einem Teil der Synapse. Sie geben zwei Filter (a, b) infreqz
. Sind beide Filter inhfilt
? Oder einer inn
?Dies ist nur ein Nachtrag zu Jojeks Antwort, die allgemeiner gehalten ist und bei Verwendung von Mathematik mit doppelter Genauigkeit perfekt funktioniert. Wenn die Genauigkeit geringer ist, tritt ein "Kosinusproblem" auf, das auftritt, wenn entweder die Frequenz im Frequenzgang sehr niedrig ist (viel niedriger als in Nyquist), oder wenn die Resonanzfrequenzen des Filters sehr niedrig sind.
Betrachten Sie diese Trigger-Identität:
Also, was ich getan habe, ist, die oben angegebene Triggeridentität zu verwenden und alle Cosinus-Terme zu entfernen und sie im Wesentlichen durch Terme zu ersetzen, die wie aussehenSünde2( ω2)
das hat einen komplexen Frequenzgang
welches die quadratische Größe hat:
Mit der obigen Triggeridentität erhalten Sie das Quadrat der Größe:
whereϕ≜sin2(ω2)
if your gear is intending to plot this as dB, it comes out as
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.
quelle