On sait qu'en général la fonction de transfert d'un filtre est donnée par:
H(z)=∑Mk=0bkz−k∑Nk=0akz−k
Remplacez maintenant z=ejω pour évaluer la fonction de transfert sur le cercle unitaire:
H(ejω)=∑Mk=0bke−jωk∑Nk=0ake−jωk
Cela devient donc seulement un problème d'évaluation polynôme à une donnée ω . Voici les étapes:
- Créez un vecteur de fréquences angulaires ω=[0,…,π] pour la première moitié du spectre (pas besoin de monter jusqu'à 2π ) et enregistrez-le
w
.
- Pré-calculer l'exposant e−jω sur chacun d'eux et le stocker dans une variable
ze
.
- Utilisez la
polyval
fonction pour calculer les valeurs du numérateur et du dénominateur en appelant polyval(b, ze)
:, divisez-les et enregistrez-les H
. Parce que nous nous intéressons à l'amplitude, prenons alors la valeur absolue du résultat.
- Convertir en échelle dB en utilisant: HdB=20log10H - dans ce cas, 1 est la valeur de référence.
Mettre tout cela dans le code:
%% 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)
Sortie originale de freqz
:
Et la sortie de mon script:
Et une comparaison rapide à l'échelle linéaire - a fière allure!
[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'})
Vous pouvez maintenant le réécrire dans une fonction et ajouter quelques conditions pour le rendre plus utile.
Une autre façon (précédemment proposée est plus fiable) serait d'utiliser la propriété fondamentale, que la réponse en fréquence d'un filtre est une transformée de Fourier de sa réponse impulsionnelle:
H(ω)=F{h(t)}
Par conséquent, vous devez alimenter le signal δ(t) votre système , calculer la réponse de votre filtre et en prendre la 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));
En comparaison, cela produira ce qui suit:
a = [1 -0.5 -0.25]; % Some filter with lot's of static gain
. Pouvez-vous m'expliquer ici la sélection de ces paramètres. Je lis le manuel de mon Matlab et il est écrit[h,w] = freqz(hfilt,n)
dans une partie de la synapse. Vous donnez deux filtres (a, b) àfreqz
. Les deux filtres sont-ils en placehfilt
? Ou un enn
?ce n'est qu'un addendum à la réponse de jojek qui est plus générale et parfaitement bonne lorsque les mathématiques en double précision sont utilisées. quand il y a moins de précision, il y a un "problème de cosinus" qui surgit lorsque la fréquence dans la réponse en fréquence est très basse (beaucoup plus basse que Nyquist) et aussi quand les fréquences de résonance du filtre sont très basses.
considérez cette identité trig:
qui a une réponse en fréquence complexe
qui a une magnitude au carré:
en utilisant l'identité trig ci-dessus, vous obtenez pour la grandeur au carré:
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.
la source