Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Что на выходе алгоритма Герцеля?
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
misyachniy
Для определения амплитуды и фазы сигнала решил поэкспериментировать
с алгоритмом Герцеля,
взял тут: http://www.dsplib.ru/content/goertzel/goertzel.html
Код
int main(){
     // исходные данные    
     int N = 8; //точек ДПФ
     int k = 1; //номер спектрального отсчта

     //исходный сигнал
     double s[8] = {3, 2, 1, -1, 1, -2, -3, -2};

     //массив промежуточных результатов
     double v[8] = {0, 0, 0, 0, 0, 0, 0, 0};

     //параметр альфа
     double a = 2*cos(2*M_PI*k/N);

     //поворотный к-т W_N^-k
     double wr =    cos(2*M_PI*k/N); //реальная часть
     double wi =    sin(2*M_PI*k/N); //мнимая часть

     //учет v[-1] = v[-2] = 0
     v[0] = s[0];    
     v[1] = s[1]+a*v[0];

     // итерационный расчет массива v согласно (14)
     for(int i = 2; i < N; i++)
         v[i] = s[i] + a*v[i-1] - v[i-2];

     //реальная и мнимая части спектрального отсчета S(1) согласно (13)
     double SR = v[N-1]*wr-v[N-2];
     double SI = v[N-1]*wi;

     //печать результата
     printf("S(%d) = %.4f%+.4fj\n",k,SR,SI);

     system("Pause");
     return 0;
}

и алгоритмом FFT для одной частоты
взял тут: http://forum.sources.ru/index.php?showtopi...showall&hl=
Код
function FT(w:Real; N:Integer; a:PReal):Complex;Overload;
var i:Integer;
begin
Result.Re:=0;
Result.Im:=0;
for i:=0 to N-1 do
begin
Result.Re:=Result.Re+A[i]*Cos(-2*Pi*i*w/N);
Result.Im:=Result.Im+A[i]*Sin(-2*Pi*i*w/N);
end;
Result.Re:=Result.Re/N;
Result.Im:=Result.Im/N;
end;


По второй ссылке взял и перевод частей сигнала в реальную амплитуду и фазу.
Код
Faza:=arctan2(С.Im,С.Re);  // Фаза
Amp:=hypot(C.Re, C.Im); // Амплитуда.


Взял 256 отсчетов синусоидального сигнала.
Фазы сошлись - не знаю на сколько реально :-)

Амплитуда после расчета по FFT га 15..20% ниже RMS напряжения который показывает осциллограф.
То есть амплитуда для этого метода корректна.

А по методу Герцеля получается число в ~500 раз больше.

Я читал, что алгоритм Герцеля работает неустойчиво при большой длине выборок. Может в этом вопрос?




Serg76
должно совпадать, ошибка, видимо, в реализации
Xenia
Поделить амплитуду надо на N или на N/2 (в зависимости от алгоритма).
Я при fft делю на N/2, но как у Гершеля не знаю.

Самое простое - запихнуть в массив чистую косинусоиду единичной амплитуды (по формуле вычислить),
а потом проверить, во сколько раз ответ будет больше нормы.
В любом случае это число - двойка в целой степени, зависимой от длины массива.

Обратите внимание! После алгоритма FFT на N делят:
Result.Re:=Result.Re/N;
Result.Im:=Result.Im/N;
а после Гершеля забыли.
Впрочем, эту нормировку обычно в самом алгоритме опускают (для скорости).
Катран
Делал его. Ксения правильно указала.
misyachniy
Прогнал оба алгоритма с реальными данными и нормировкой.
При одинаковой длине выборки результаты идентичны.
Преобразование Фурье выглядит предпочтительнее.
Используя частоту семплирования в 4 раза выше требуемой получаем вырожденое значение sin/cos в три значения -1,0,1.
Умножение уходит и погрешность не накапливается.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.