если резулатат вашего алгоритма Герцеля отличается от fft то значит где-то ошибка. Результат должен совпадать. Теперь по существу. Вот матлаб код для проверки. Берем 500 отсчетов синусоиды s = sin(2*pi*50*t/Fs) на частоте 50 Гц и рассчитываем 50-ый отсчет FFT используя алгоритм герцеля. Получаем фазу -90 градусов, поскольку фаза 0 будет если взять s = сos(2*pi*50*t/Fs). Если посмотрите спектр FFT, то нет эффекта растекания поскольку я взял 500 отсчетов. Если вы берете 512 отсчетов то эффект растекания будет и фаза изменится. При этом если посмотрите из примера разница между отсчетом FFT и герцелем ничтожно мала (1E-12). Так и должно быть поскольку алгоритм Герцеля и рассчитывает один отсчет FFT.
Код
clear all;
close all;
clc;
%% input data
N = 500;
t = 0:N-1;
Fs = 500;
k = 50;
s = sin(2*pi*50*t/Fs);
%% Goertzel algorithm
W = exp(2i*pi*k/N);
v = zeros(1,N);
a = 2*cos(2*pi*k/N);
v(1) = s(1);
v(2) = s(2) + a*v(1);
for n = 3:N
v(n) = s(n) + a*v(n-1) - v(n-2);
end
G = W*v(n) - v(n-1);
%% fft
S = fft(s);
figure; plot(abs(S))
%%
fprintf('разница между fft и Герцелем: %e\n', G - S(k+1));
fprintf('фаза: %.4f\n', angle(G)*180/pi);
PS по поводу накопления ошибок поставьте в исходных данных
Код
%% input data
N = 500000;
t = 0:N-1;
Fs = 500;
k = 50000;
и все равно ошибка будет на уровне 1E-6 при абсолютном значении спектра 1E6 (т.е. на 12 порядков ниже)
Сообщение отредактировал bahurin - Nov 5 2012, 13:47