Мы знаем, что в целом передаточная функция фильтра определяется как:
H(z)=∑Mk=0bkz−k∑Nk=0akz−k
Теперь подставим z=ejω чтобы оценить передаточную функцию на единичном круге:
ЧАС( еJ ω) = ∑Mк = 0бКе- J ω KΣNк = 0aКе- J ω K
Таким образом, это становится только проблемой полиномиальной оценки при заданном ω . Вот шаги:
- Создайте вектор угловых частот ω = [ 0 , … , π] для первой половины спектра (не нужно подниматься до 2 π ) и сохраните его в
w
.
- Предварительно вычислите показатель степени е- J ω для всех из них и сохраните его в переменной
ze
.
- Используйте
polyval
функцию для вычисления значений числителя и знаменателя, вызывая:, polyval(b, ze)
разделите их и сохраните в H
. Поскольку нас интересует амплитуда, то берем абсолютное значение результата.
- Преобразовать в шкалу дБ с помощью: ЧАСdВ= 20 log10ЧАС - в этом случае 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'})
Теперь вы можете переписать его в некоторую функцию и добавить несколько условий, чтобы сделать его более полезным.
Другой способ (ранее предложенный является более надежным) заключается в использовании фундаментального свойства, заключающегося в том, что частотная характеристика фильтра является преобразованием Фурье его импульсной характеристики:
ЧАС( ω ) = 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));
Для сравнения это даст следующее:
a = [1 -0.5 -0.25]; % Some filter with lot's of static gain
. Можете ли вы объяснить мне выбор этих параметров здесь, пожалуйста. Я читаю руководство по моему Matlab, и оно написано[h,w] = freqz(hfilt,n)
в одной части синапса. Вы даете два фильтра (а, б) вfreqz
. Оба фильтра вhfilt
? Или один вn
?это всего лишь дополнение к ответу Джохека, которое является более общим и совершенно хорошим, когда используется математика двойной точности. когда точность меньше, возникает «проблема косинуса», которая возникает, когда либо частота в частотной характеристике очень низкая (намного ниже, чем Найквист), а также когда резонансные частоты фильтра очень низкие.
рассмотрим этот триг личности:
который имеет сложную частотную характеристику
который имеет величину в квадрате:
используя приведенную выше идентичность триггера, вы получаете для квадрата величины:
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.
источник