Класс Dmatrix - операции с
матрицами на C++
Динамическая модель вибрации
двигателя
Класс HHT - метод EMD (эмпирическая модовая декомпозиция) на C++
Теория и практика программирования БПФ от
М.В.
Класс FFT
Калюжный О.Н.
Внимание! В данной версии класса используется прореживание по
времени. Сигнал на входе БПФ формируется следующим образом:
четные отсчеты подаются на действительную часть входа, нечетные – на мнимую,
что позволяет значительно ускорить вычисления без потери качества. Если
Вы используете класс, полученный с этого сайта до 23.04.2018, имейте в виду,
что текст этой страницы скорректирован в соответствии с изменениями класса.
См. также примечание внизу, связанное с обновлением от 07.08.2017.
Класс FFT предназначен для
встраивания в исходный код задач, реализованных на языке C++, в которых необходимо проводить расчет
спектра (АЧХ) сигнала по методу БПФ (быстрого преобразования Фурье).
Класс
содержит следующие основные переменные и функции, используемые программистом
при встраивании кода:
Переменные
на входе БПФ:
N –
количество точек спектра (спектр строится на основе 2*N измерений сигнала).
T – степень
числа 2, определяющая количество точек спектра N (то
есть N = 2 ^ T).
Xre[T][], Xim[T][] – массивы измерений сигнала на входе
(действительная и мнимая части; в действительную часть подаются четные отсчеты,
в мнимую - нечетные).
tm[] –
массив значений моментов времени измерений сигнала.
No – номер крайней пары значений (чет./нечет.) в накопленном массиве измерений сигнала.
Изменяется от 0 до N
–
1; после появления N-й пары
значений сигнала сохраняется значение No = N –
1.
CFreq –
минимальная частота регистрации сигнала на входе, при которой производится
расчет спектра. В некоторых случаях, из-за сбоев или задержек в каналах
измерений, частота регистрации падает. Проводить расчет спектра в этих случаях
не имеет смысла.
Otsechka –
признак отказа от расчета спектра при частоте регистрации, меньшей CFreq.
Flt –
простейший сглаживающий фильтр, предназначенный для сглаживания значений
моментов времени. Такое сглаживание имеет смысл применять в том случае, если
известно, что регистрация сигнала производится с постоянной частотой, но, по
причине задержек в канале, частота регистрации «гуляет». Фильтр имеет
передаточную функцию 1 / (Tp + 1). Чтобы отключить фильтр,
достаточно при расчете переменной dT вместо dT
= Flt.Go(tm[N - 1] - tm[0] + dt); написать dT = tm[N - 1] - tm[0] + dt;
fH, fT – параметры сглаживающего фильтра.
Переменные
на выходе БПФ:
A[] –
набор амплитуд спектра.
freq[] –
набор частот спектра.
Все
остальные переменные не используются программистом при работе с классом.
Функции
класса FFT:
Prepare() –
функция расчета поворачивающих множителей; выполняется один раз перед началом
работы с поступающим сигналом. Набор поворачивающих множителей зависит только
от заданного числа T,
поэтому данная функция запускается один раз перед расчетами спектра по
поступающему сигналу.
PutVal() –
функция подготовки данных в массивах tm
и
Xre и в
других переменных перед очередным расчетом спектра.
Spectrum() –
расчет спектра.
Встраивание класса FFT на конкретном примере
Проект testfft создан в среде Borland Builder 6 и предназначен для
опробования класса FFT:
пользователь может задавать амплитуды и частоты 3-х гармоник и наблюдать на
экране спектр получившегося сигнала при разных количествах точек спектра и
разных частотах регистрации. Параметр T,
задаваемый с формы, определяет количество точек сигнала, используемых для
построения спектра, то есть T
спектра
будет на 1 меньше, чем T
сигнала.
Исходный
код проекта состоит из 4-х unit’ов:
umain –
пользовательский интерфейс; здесь производится ввод параметров, создание нити (thread), объекта fft класса FFT, их инициализация и запуск, прием и вывод
на форму поступающей от этих объектов информации;
thr –
нить, формирующая и передающая информацию объекту fft;
fft –
здесь находится класс FFT;
flt
–
здесь находится сглаживающий фильтр.
umain:
В
обработчике нажатия кнопки «СТАРТ» производится создание и инициализация
объектов Thr (нити)
и fft
(БПФ),
запуск функции Prepare() (расчет поворачивающих
множителей) и запуск нити функцией Resume().
Обработчик
закрытия формы останавливает нить и удаляет созданные объекты.
Таймер
перерисовывает график, отображая на нем текущие результаты расчета спектра.
thr:
Функция
Look() выполняется с частотой, зависящей от частоты
вашего процессора. В ней выполняется расчет гармоник и значений времени (по
заданной частоте дискретизации samplingFR) и передача
этих данных алгоритму БПФ для очередного расчета спектра.
Примечание (обновление класса)
В
практических приложениях часто возникает необходимость рассчитывать АЧХ, изменяющуюся
в режиме онлайн. Расчет можно проводить с разным шагом. Если, например, получив
данные сигнала X0, …, XN–1, мы
получаем на выходе первый набор амплитуд и частот, а получив следующее
наблюдение XN, мы
рассчитываем по X1, …, XN следующий набор – то, в таком
случае, мы считаем АЧХ с шагом 1.
В
случае достаточно большой частоты регистрации считать АЧХ на каждом шаге
нерационально, т.к. это занимает слишком много времени. Поэтому функция класса FFT PutVal(void) заменена на PutVal(bool
c). Если c = true, функция сообщает алгоритму БПФ вновь поступившие данные и рассчитывает АЧХ. Если же c = false, происходит передача данных,
но расчет не производится.
В класс
TThr
нашего
примера добавлена переменная step,
получающая значение с формы (поле Шаг расчета). Как можно увидеть в
исходниках примера, функция PutVal(c) запускается с
переменной c = true с
частотой, заданной step, что
ускоряет расчет и позволяет выводить на экран изменяющийся спектр сигнала в
реальном времени или еще быстрее, в зависимости от задачи.
Интересные книжки:
Г. Дженкинс, Д. Ваттс, «Спектральный анализ и его приложения -
Выпуск I»
Г. Дженкинс, Д. Ваттс, «Спектральный анализ и его приложения -
Выпуск II»