Есть несколько комментариев о преобразовании Фурье, и я надеюсь, что смогу объяснить все для вас. Кроме того, я не знаю, что вы подразумеваете под «математическим преобразованием Фурье», так как ни одно из выражений в вашем коде не похоже на ряд Фурье пилообразной волны .
Чтобы точно понятьчто делает fft функция , мы можем делать шаг за шагом. Сначала, следуя вашему коду, мы создаем и строим один период пилообразной волны.
n = 1024;
fs = 1024;
dt = 1/fs;
t = (0:(n-1))*dt;
x = 0.5*sawtooth(2*pi*t);
figure; plot(t,x); xlabel('t [s]'); ylabel('x');
Теперь мы можем вычислить несколько вещей. Во-первых, частота Найквиста , максимальная обнаруживаемая частота из выборок.
f_max = 0.5*fs
f_max =
512
Также минимальная обнаруживаемая частота
f_min = 1/t(end)
f_min =
1.000977517106549
Рассчитайте теперь дискретное преобразование Фурье с функцией MATLAB:
X = fft(x)/n;
Эта функция получает комплексные коэффициенты каждого члена дискретного преобразования Фурье . Обратите внимание, что он рассчитывает коэффициенты, используя выражение exp, а не в виде синусов и косинусов. Деление на n
должно гарантировать, что первый коэффициент равен среднему арифметическому для выборок
. Если вы хотите построить амплитуду / фазу преобразованного сигнала, вы можете набрать:
f = linspace(f_min,f_max,n/2); % frequency vector
a0 = X(1); % constant amplitude
X(1)=[]; % we don't have to plot the first component, as it is the constant amplitude term
XP = X(1:n/2); % we get only the first half of the array, as the second half is the reflection along the y-axis
figure
subplot(2,1,1)
plot(f,abs(XP)); ylabel('Amplitude');
subplot(2,1,2)
plot(f,angle(XP)); ylabel('Phase');
xlabel('Frequency [Hz]')
Что означает этот график? На рисунке показаны амплитуда и фаза комплексных коэффициентов членов в ряду Фурье, которые представляют исходный сигнал (пилообразная волна). Вы можете использовать эти коэффициенты для получения аппроксимации сигнала в терминах (усеченного) ряда Фурье. Конечно, для этого нам понадобится целое преобразование (а не только первая половина, как это обычно делается для построения графика).
X = fft(x)/n;
amplitude = abs(X);
phase = angle(X);
f = fs*[(0:(n/2)-1)/n (-n/2:-1)/n]; % frequency vector with all components
% we calculate the value of x for each time step
for j=1:n
x_approx(j) = 0;
for k=1:n % summation done using a for
x_approx(j) = x_approx(j)+X(k)*exp(2*pi*1i/n*(j-1)*(k-1));
end
x_approx(j) = x_approx(j);
end
Примечание: приведенный выше код для пояснения и делаетне намерены быть хорошо закодированы. Суммирование может быть выполнено в MATLAB гораздо лучше, чем использование цикла for, и в коде появятся некоторые предупреждения, предупреждающие пользователя о предварительном выделении каждой переменной для скорости.
Приведенный выше кодвычисляет x(ti)
для каждого времени ti
, используя условия усеченного ряда Фурье. Если мы построим и исходный сигнал, и аппроксимированный, мы получим:
figure
plot(t,x,t,x_approx)
legend('original signal','signal from fft','location','best')
Исходный сигнал и приблизительный сигнал почти равны. На самом деле,
norm(x-x_approx)
ans =
1.997566360514140e-12
Почти ноль, но не совсем ноль. Кроме того, на графике выше будет выдано предупреждение из-за использования комплексных коэффициентов при расчете приближенного сигнала:
Предупреждение: мнимые части комплексных аргументов X и / или Y игнорируются
Но вы можете проверить, что мнимый член очень близок к нулю. Это не совсем ноль из-за ошибок округления в вычислениях.
norm(imag(x_approx))
ans =
1.402648396024229e-12
Обратите внимание на приведенные выше коды, как интерпретировать и использовать результаты функции fft и как онипредставлены в виде опыта, а не в виде синусов и косинусов, как вы кодировали.