/*******************************************************************************
* Данная программа производит расчет данных для построения графика функции
*
* s(t) = sin(1/sin(t))
*
* Расчет функции производится в диапазоне t от -pi до pi и от -0.2 до 0.2.
*
* Сохраненные данные:
*
* dat/fourier_series_signal0.txt - данные функции при t от -2*pi до 2*pi;
* dat/fourier_series_signal1.txt - данные функции при t от -0.2 до 0.2.
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
/* размер массивов */
#define N 10000
int main(int argc, char* argv[])
{
double t[N]; /* массив аргументов функции */
double s[N]; /* массив значений функции s(t) = sin(1/sin(t)) */
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
int k;
/* Загружаем libdspl.dll */
hdspl = dspl_load();
if(!hdspl)
{
printf("Cannot to load libdspl!\n");
return 0;
}
/* заполняем массив t от -2*pi до 2*pi */
linspace(-M_2PI, M_2PI, N, DSPL_PERIODIC, t);
/* рассчитываем функцию s(t) = sin(1/sin(t))
* для каждого значения переменной t[k] */
for(k = 0; k < N; k++)
s[k] = sin(1.0/sin(t[k]));
/* Сохраняем данные в файл dat/fourier_series_signal0.txt */
writetxt(t, s, N, "dat/fourier_series_signal0.txt");
/* заполняем массив t от -0.2 до 0.2 */
linspace(-0.2, 0.2, N, DSPL_PERIODIC, t);
/* рассчитываем функцию s(t) = sin(1/sin(t))
* для каждого значения переменной t[k] */
for(k = 0; k < N; k++)
s[k] = sin(1.0/sin(t[k]));
/* Сохраняем данные в файл dat/fourier_series_signal1.txt */
writetxt(t, s, N, "dat/fourier_series_signal1.txt");
/* plotting by GNUPLOT */
gnuplot_create(argc, argv, 560, 380, "img/dirichlet_ex.png", &hplot);
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set xlabel 'x'");
gnuplot_cmd(hplot, "set ylabel 'sin(1/sin(x))'");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_signal1.txt' with lines");
gnuplot_close(hplot);
/* Выгружаем libdspl.dll из памяти */
dspl_free(hdspl);
return 0;
}
Представление периодических сигналов рядом Фурье
![]() DSPL-2.0 — свободная библиотека алгоритмов цифровой обработки сигналов Распространяется под лицензией LGPL v3
Страница проекта на SourceForge
|

1768–1830
Мы рассмотрим выражения ряда Фурье в тригонометрической и комплексной форме, а также уделим внимание условиям Дирихле сходимости ряда Фурье. Кроме того, мы подробно остановимся на пояснении такого понятия как отрицательная частота спектра сигнала, которое часто вызывает сложность при знакомстве с теорией спектрального анализа.
Пусть имеется периодический сигнал непрерывного времени
, который повторяется с периодом
с, т.е.
, где
— произвольное целое число.
В качестве примера на рисунке 1 показана последовательность прямоугольных импульсов длительности c, повторяющиеся с периодом
с.

прямоугольных импульсов
Из курса математического анализа известно [1, стр. 158], что система тригонометрических функций






1805–1859

![\left[ -\frac{T}{2}, \frac{T}{2} \right]](img/eqlin-09.png)
- Сигнал
не должен иметь бесконечных значений.
- Сигнал
должен быть кусочно-непрерывным, т.е. иметь конечное число точек разрыва первого рода (скачки и устранимые разрывы).
- Сигнал
должен быть кусочно-монотонным и иметь конечное число экстремумов.
Например, периодическая функция не удовлетворяет условиям Дирихле, потому что функция
имеет разрывы второго рода и принимает бесконечные значения при
, где
— произвольное целое. Таким образом, функция
не может быть представлена рядом Фурье. Также можно привести пример функции
, которая является ограниченной, но также не удовлетворяет условиям Дирихле, поскольку имеет бесконечное число точек экстремума при приближении к нулю. График функции
показан на рисунке 2.


а — два периода повторения; б — в окрестности

На рисунке 2а показано два периода повторения функции , а на рисунке 2б — область в окрестности
. Можно видеть, что при приближении
к нулю, частота колебаний бесконечно возрастает, и такая функция не может быть представлена рядом Фурье, потому что она не является кусочно-монотонной.
Необходимо заметить, что на практике не бывает сигналов с бесконечными значениями тока или напряжения. Функции с бесконечным числом экстремумов типа
также в прикладных задачах не встречаются.
Все реальные периодические сигналы удовлетворяют условиям Дирихле и могут быть представлены бесконечным тригонометрическим рядом Фурье вида:



Во всех точках, где сигнал
непрерывен, ряд Фурье (2) сходится к значениям данного сигнала, а в точках разрыва первого рода — к среднему значению , где
и
— пределы слева и справа от точки разрыва соответственно.
Также из курса математического анализа известно [2, стр. 500], что использование усеченного ряда Фурье, содержащего только первых членов вместо бесконечной суммы, приводит к приближенному представлению сигнала
:



а — прямоугольных импульсов; б — пилообразного сигнала
В предыдущем параграфе мы рассмотрели тригонометрический ряд Фурье для разложения произвольного периодического сигнала , удовлетворяющего условиям Дирихле.
Применив формулу Эйлера, можно показать:









Рассмотрим коэффициенты для комплексных экспонент, вращающихся с положительными частотами :








1707–1783







Из выражения (2) следует, что для вещественного сигнала коэффициенты
и
ряда (2) также являются вещественными. Однако (9) ставит в соответствие вещественному сигналу
, набор комплексно-сопряженных коэффициентов
, относящихся как положительным, так и к отрицательным частотам
.
В предыдущем параграфе мы осуществили переход от тригонометрического ряда Фурье (2) к ряду Фурье в комплексной форме (9). В результате, вместо разложения периодических сигналов в базисе вещественных тригонометрических функций, мы получили разложение в базисе комплексных экспонент, с комплексными коэффициентами , да еще и появились отрицательные частоты в разложении! Поскольку данный вопрос часто встречает непонимание, то необходимо дать некоторые пояснения.
Во-первых, работать с комплексными экспонентами в большинстве случаев проще, чем с тригонометрическими функциями. Например, при умножении и делении комплексных экспонент достаточно лишь сложить (вычесть) показатели, в то время как формулы умножения и деления тригонометрических функций более громоздкие.
Дифференцировать и интегрировать экспоненты, пусть даже комплексные, также проще, чем тригонометрические функции, которые постоянно меняются при дифференцировании и интегрировании (синус превращается в косинус и наоборот).
Если сигнал периодический и вещественный, то тригонометрический ряд Фурье (2) кажется более наглядным, потому что все коэффициенты разложения ,
и
остаются вещественными.
Однако, часто приходится иметь дело с комплексными периодическими сигналами (например, при модуляции и демодуляции используют квадратурное представление комплексной огибающей). В этом случае при использовании тригонометрического ряда Фурье все коэффициенты
,
и
разложения (2) станут комплексными, в то время как при использовании ряда Фурье в комплексной форме (9) будет использованы одни и те же коэффициенты разложения
как для вещественных, так и для комплексных входных сигналов.
Ну и наконец, необходимо остановиться на пояснении отрицательных частот, которые появились в (9). Этот вопрос часто вызывает непонимание.
В повседневной жизни мы не сталкиваемся с отрицательными частотами. Например, мы никогда не настраиваем свой радиоприемник на отрицательную частоту. Давайте рассмотрим следующую аналогию из механики. Пусть имеется механический пружинный маятник, который совершает свободные колебания с некоторой частотой . Может ли маятник колебаться с отрицательной частотой
? Конечно нет. Как не бывает радиостанций, выходящих в эфир на отрицательных частотах, так и частота колебаний маятника не может быть отрицательной.
Но пружинный маятник — одномерный объект (маятник совершает колебания вдоль одной прямой).
Мы можем также привести еще одну аналогию из механики: колесо, вращающееся с частотой . Колесо, в отличие от маятника вращается, т.е. точка на поверхности колеса перемещается в плоскости, а не просто совершает колебания вдоль одной прямой. Поэтому для однозначного задания вращения колеса, задать частоту вращения недостаточно, потому что необходимо задать также направление вращения. Вот именно для этого мы и можем использовать знак частоты.
Так, если колесо вращается с угловой частотой рад/с против часовой стрелки, то считаем, что колесо вращается с положительной частотой, а если по направлению часовой стрелки, то частота вращения будет отрицательной. Таким образом, для задания вращения отрицательная частота перестает быть бессмыслицей и указывает направление вращения.
А теперь самое главное, что мы должны понять. Колебание одномерного объекта (например, пружинного маятника) может быть представлено как сумма вращений двух векторов, показанных на рисунке 4.

как сумма вращений двух векторов
на комплексной плоскости
Маятник совершает колебания вдоль вещественной оси комплексной плоскости с частотой по гармоническому закону
. Движение маятника показано горизонтальным вектором. Верхний вектор совершает вращения на комплексной плоскости с положительной частотой
(против часовой стрелки), а нижний вектор вращается с отрицательной частотой
(по направлению часовой стрелки). Рисунок 4 наглядно иллюстрирует хорошо известное из курса тригонометрии соотношение:







Ряд Фурье в комплексной форме представляет собой разложение периодического сигнала в сумму комплексных экспонент, вращающихся с положительными и отрицательными частотами кратными
рад/c с соответствующими комплексными коэффициентами
, которые определяют спектр сигнала
. Комплексные коэффициенты
могут быть представлены по формуле Эйлера как
, где
— амплитудный спектр, a
— фазовый спектр.
Поскольку периодические сигналы раскладываются в ряд только на фиксированной сетке частот , то спектр
периодических сигналов является линейчатым (дискретным).

прямоугольных импульсов:
а — амплитудный спектр; б — фазовый спектр
На рисунке 5 приведен пример амплитудного и фазового
спектра периодической последовательности прямоугольных импульсов (см. рисунок 1) при
с, длительности импульса
c и амплитуде импульсов
В.
Амплитудный спектр исходного вещественного сигнала является симметричным относительно нулевой частоты, а фазовый спектр — антисимметричным. При этом заметим, что значения фазового спектра и
соответствуют одной и той же точке комплексной плоскости
.
Можно сделать вывод, что все коэффициенты разложения приведенного сигнала являются чисто вещественными, и фазовый спектр соответствует отрицательным коэффициентам
.
Обратим внимание, что размерность амплитудного спектра
совпадает с размерностью сигнала
.
Если
описывает изменение напряжения во времени, измеряемое в вольт,
то амплитуды гармоник спектра
также будут иметь размерность вольт.
В данном разделе рассмотрено представление периодических сигналов при помощи ряда Фурье. Приведены выражения для ряда Фурье в тригонометрической и комплексной формах. Мы уделили особое внимание условиям Дирихле сходимости ряда Фурье и были приведены примеры функций, для которых ряд Фурье расходится.
Мы подробно остановились на выражении ряда Фурье в комплексной форме и показали, что периодические сигналы как вещественные, так и комплексные представляются рядом комплексных экспонент с положительными и отрицательными частотами. При этом коэффициенты разложения являются также комплексными и характеризуют амплитудный и фазовый спектр периодического сигнала.
В следующем разделе мы более детально рассмотрим свойства спектров периодических сигналов.
Данные для построения рисунков данного раздела были просчитаны при использовании библиотеки DSPL-2.0
Ниже приведён исходный код программы расчета данных для построения рисунка 2:
Исходный код программы расчета данных для построения
графиков приближения периодической последовательности прямоугольных импульсов и
пилообразного сигнала усеченным рядом Фурье (рисунок 3):
/*******************************************************************************
* Данная программа производит расчет приближенного представления
* периодической последовательности прямоугольных импульсов и
* пилообразного сигнала усеченным рядом Фурье.
*
* Сохраненные данные:
*
* dat/fourier_series_pimp0.txt - Последовательность прямоугольных импульсов
*
* dat/fourier_series_pimp_rec_5.txt - восстановленная последовательность
* прямоугольных импульсов при
* использовании 2 гармоник
*
* dat/fourier_series_pimp_rec_9.txt - восстановленная последовательность
* прямоугольных импульсов при
* использовании 4 гармоник
*
* dat/fourier_series_pimp_rec_21.txt - восстановленная последовательность
* прямоугольных импульсов при
* использовании 10 гармоник
*
* dat/fourier_series_pimp_rec_61.txt - восстановленная последовательность
* прямоугольных импульсов при
* использовании 10 гармоник
*
* dat/fourier_series_saw0.txt - Исходный пилообразный сигнал
*
* dat/fourier_series_saw_rec_5.txt - восстановленная пилообразный сигнал
* при использовании 2 гармоник
*
* dat/fourier_series_saw_rec_9.txt - восстановленная пилообразный сигнал
* при использовании 4 гармоник
*
* dat/fourier_series_saw_rec_21.txt - восстановленная пилообразный сигнал
* при использовании 10 гармоник
*
* dat/fourier_series_saw_rec_61.txt - восстановленная пилообразный сигнал
* при использовании 30 гармоник
*
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
/* размер массивов исходных и восстановленных сигналов */
#define N 1000
/* Период */
#define T 2
/* Длительность импульса */
#define TAU 1
/* Максимальное количество коэффициентов ряда Фурье */
#define MAX_M 61
/* Количество периодов */
#define P 3.0
int main(int argc, char* argv[])
{
double t[N]; /* время */
double s[N]; /* исходный сигнал */
double x[N]; /* восстановленный сигнал */
double w[MAX_M]; /* массив частоты */
complex_t S[MAX_M]; /* Спектр */
complex_t xc[N]; /* восстановленный по спектру */
/* комплексный сигнал */
/*
* Количество спектральных гармоник усеченного ряда
* Заметим, что 5 гармоник усеченного ряда содержат
* две пары комплексно-сопряженных спектральных компонент
* и одну постоянную составляющую.
* Это означает, что ряд из 5 гармоник в комплексной форме соответствует
* двум значениям a_n и b_n ряда в тригонометрической форме.
* Аналогично M = 21 соответствует 10 значениям a_n и b_n ряда
* в тригонометрической форме.
*/
int M[4] = {5, 9, 21, MAX_M};
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
int k, n;
char fname[64]; /* имя файла для сохранения рассчитанных данных */
/* Загружаем libdspl.dll */
hdspl = dspl_load();
if(!hdspl)
{
printf("Cannot to load libdspl!\n");
return 0;
}
/* Заполняю вектор времени для P периодов повторения
* периодических сигналов
*/
linspace(-T*0.5*P, T*0.5*P, N, DSPL_PERIODIC, t);
/*--------------------------------------------------------------------------*/
/* последовательность прямоугольных импульсов */
signal_pimp(t, N, 1.0, TAU, 0.0, T, s);
/* сохраняем в файл dat/fourier_series_pimp0.txt */
writetxt(t, s, N, "dat/fourier_series_pimp0.txt");
/* цикл по разному количеству гармоник усеченного ряда */
for(k = 0; k < 4; k++)
{
/* расчет спектра для текущего усеченного ряда */
fourier_series_dec(t, s, N, T, M[k], w, S);
/* нормировка потому что P периодов в исходном сигнале */
for(n = 0; n < M[k]; n++)
{
RE(S[n]) /= P;
IM(S[n]) /= P;
}
/* восстанавливаю сигнал по усеченному ряду */
fourier_series_rec(w, S, M[k], t, N, xc);
/* Комплексный восстановленный сигнал имеет
* мнимую часть на уровне машинной точности */
cmplx2re(xc, N, x, NULL);
/* сохраняю в файл для последующего построения графика */
sprintf(fname, "dat/fourier_series_pimp_rec_%d.txt", M[k]);
writetxt(t, x, N, fname);
}
/*--------------------------------------------------------------------------*/
/* Пилообразный сигнал */
signal_saw(t, N, 0.5, 0.0, T, s);
for(n = 0; n < N; n++)
s[n] += 0.5;
/* сохраняем в файл dat/fourier_series_saw0.txt */
writetxt(t, s, N, "dat/fourier_series_saw0.txt");
/* цикл по разному количеству гармоник усеченного ряда */
for(k = 0; k < 4; k++)
{
/* расчет спектра для текущего усеченного ряда */
fourier_series_dec(t, s, N, T, M[k], w, S);
/* нормировка потому что P периодов в исходном сигнале */
for(n = 0; n < M[k]; n++)
{
RE(S[n]) /= P;
IM(S[n]) /= P;
}
/* восстанавливаю сигнал по усеченному ряду */
fourier_series_rec(w, S, M[k], t, N, xc);
/* Комплексный восстановленный сигнал имеет
* мнимую часть на уровне машинной точности */
cmplx2re(xc, N, x, NULL);
/* сохраняю в файл для последующего построения графика */
sprintf(fname, "dat/fourier_series_saw_rec_%d.txt", M[k]);
writetxt(t, x, N, fname);
}
/* Построение графиков пакетом GNUPLOT */
gnuplot_create(argc, argv, 800, 640, "img/fourier_series_rec.png", &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set multiplot layout 4,2 rowsfirst");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_pimp0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_pimp_rec_5.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_saw0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_saw_rec_5.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_pimp0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_pimp_rec_9.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_saw0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_saw_rec_9.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_pimp0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_pimp_rec_21.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_saw0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_saw_rec_21.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_pimp0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_pimp_rec_61.txt' with lines");
gnuplot_cmd(hplot, "plot 'dat/fourier_series_saw0.txt' with lines,\\");
gnuplot_cmd(hplot, " 'dat/fourier_series_saw_rec_61.txt' with lines");
gnuplot_cmd(hplot, "unset multiplot");
gnuplot_close(hplot);
/* Выгружаем libdspl.dll из памяти */
dspl_free(hdspl);
return 0;
}
Исходный код программы расчета амплитудного и фазового спектра (рисунок 5):
/*******************************************************************************
* Данная программа производит расчет амплитудного и фазвого спектра
* последовательности прямоугольных импульсов
*
* Сохраненные данные:
*
* dat/fourier_series_pimp_mag.txt - амплитудный спектр
* dat/fourier_series_pimp_phi.txt - фазовый спектр
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "dspl.h"
/* количество точек прямоугольного
* импульса на одном периоде повторения */
#define N 1000
/* Период повторения сигнала */
#define T 4
/* Длительность импульса */
#define TAU 2
/* Количество гармоник спектра */
#define K 41
int main(int argc, char* argv[])
{
double t[N]; /* время */
double s[N]; /* исходный сигнал */
double w[K]; /* массив частоты */
complex_t S[K]; /* спектр */
double mag[K]; /* амплитудный спектр */
double phi[K]; /* фазовый спектр */
void* hdspl; /* DSPL handle */
void* hplot; /* GNUPLOT handle */
int n;
/* Загружаем libdspl.dll */
hdspl = dspl_load();
if(!hdspl)
{
printf("cannot to load libdspl!\n");
return 0;
}
/* заполняем массив времени для одного периода сигнала */
linspace(-T*0.5, T*0.5, N, DSPL_SYMMETRIC, t);
/* сигнал */
signal_pimp(t, N, 2.0, TAU, 0.0, T, s);
/* расчет комплексного спектра */
fourier_series_dec(t, s, N, T, K, w, S);
/* Амплитудный и фазовый спектры */
for(n = 0; n < K; n++)
{
mag[n] = ABS(S[n]);
phi[n] = atan2(IM(S[n]), RE(S[n]));
}
/* Сохранение амплитудного спектра в файл */
writetxt(w, mag, K, "dat/fourier_series_pimp_mag.txt");
/* Сохранение фазового спектра в файл */
writetxt(w, phi, K, "dat/fourier_series_pimp_phi.txt");
/* Построение графиков пакетом GNUPLOT */
gnuplot_create(argc, argv, 560, 380, "img/spectrum.png", &hplot);
gnuplot_cmd(hplot, "unset key");
gnuplot_cmd(hplot, "set grid");
gnuplot_cmd(hplot, "set lmargin 8");
gnuplot_cmd(hplot, "set multiplot layout 2,1 rowsfirst");
gnuplot_cmd(hplot, "set xlabel 'Частота, рад/с'");
gnuplot_cmd(hplot, "set ylabel 'Амплитудный спектр'");
gnuplot_cmd(hplot, "plot[-10*pi:10*pi] 'dat/fourier_series_pimp_mag.txt' with impulses lt 1 ,\\");
gnuplot_cmd(hplot, "'dat/fourier_series_pimp_mag.txt' with points pt 7 ps 0.5 lt 1");
gnuplot_cmd(hplot, "set ylabel 'Фазовый спектр'");
gnuplot_cmd(hplot, "plot[-10*pi:10*pi] 'dat/fourier_series_pimp_phi.txt' with impulses lt 1 ,\\");
gnuplot_cmd(hplot, "'dat/fourier_series_pimp_phi.txt' with points pt 7 ps 0.5 lt 1");
gnuplot_cmd(hplot, "unset multiplot");
gnuplot_close(hplot);
/* Выгружаем libdspl.dll из памяти */
dspl_free(hdspl);
return 0;
}
Некоторые свойства разложения периодических сигналов в ряд Фурье
Спектр периодической последовательности прямоугольных импульсов
Преобразование Фурье непериодических сигналов