Як я вручну побудую частотну характеристику смугового фільтра Баттерворта в MATLAB без функції freqz?


15

У мене є код, як нижче, який застосовує смуговий фільтр до сигналу. Я зовсім ноб у DSP і хочу зрозуміти, що відбувається за лаштунками, перш ніж продовжувати.

Для цього я хочу знати, як побудувати частотну характеристику фільтра без використання freqz.

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

З урахуванням результатів, [b, a]як би я це зробив? Здається, це було б простим завданням, але мені важко знайти те, що мені потрібно в документації або в Інтернеті.

Я також хотів би зрозуміти, як це зробити якомога швидше, наприклад, використовуючи fftінший швидкий алгоритм.

Відповіді:


25

Ми знаємо, що загалом функція передачі фільтра задається:

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

Тепер замінимо 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 :

enter image description here

І вихід мого сценарію:

enter image description here

І швидке порівняння в лінійному масштабі - виглядає чудово!

[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'})

enter image description here

Тепер ви можете переписати його на якусь функцію та додати кілька умов, щоб зробити її кориснішою.


Іншим способом (раніше запропонованим є більш надійним) було б використання основної властивості: частотна характеристика фільтра - це перетворення Фур'є в його імпульсному відгуку:

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));

Для порівняння це призведе до наступного:

enter image description here


1
Детальне пояснення
партида

Я думаю про цю лінію a = [1 -0.5 -0.25]; % Some filter with lot's of static gain. Чи можете ви пояснити мені вибір цих параметрів тут, будь ласка. Я читаю посібник з Матлаба, і він говорить [h,w] = freqz(hfilt,n)в одній частині конспекту. Ви даєте два фільтри (a, b) у freqz. Чи є два фільтри hfilt? Або один в n?
Лео Леопольд Герц 준영

Просто для уточнення для інших: "Не потрібно підніматися до 2 пі" - це коли коефіцієнти реальні. Існують програми для фільтрів зі складними коефіцієнтами, і в такому випадку спектр більше не буде симетричним і в такому випадку хочеться збільшити частоту до 2 пі.
Дан Бошен

14

це лише доповнення до відповіді джоджека, яка є більш загальною та ідеально хорошою, коли використовується математика з двома точністю. коли є менша точність, виникає "косинусна проблема", яка виникає, коли або частота в частотній характеристиці дуже низька (набагато нижче, ніж у Найквіста), а також коли резонансні частоти фільтра дуже низькі.

|H(ejω)|2|H(ejω)|=|H(ejω)|частота wrt і лише косинуси - це навіть функції.

врахуйте цю ідентичність тригена:

cos(ω) = 12sin2(ω2)

sin2(ω2)ω0 . настільки малі, що термін і інформація про частоту в цьому терміні втрачаються, коли додається термін (або це негатив) до 1. Це відбувається навіть з плаваючою точкою, але менша проблема з плаваючими з подвійною точністю. але деякі з нас, які передають цю функцію частотної характеристики у передачу, можуть не мати ресурсу плаваючої точки з подвійною точністю або будь-якої плаваючої точки.

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ω)

|H(ejω)|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 та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.