1#include "include/fourier.h"
2#define _USE_MATH_DEFINES
7#include "include/numerical_methods.h"
10# define M_PI 3.14159265358979323846
18std::vector<ComplexNumber> FourierTransform::DFT(
const std::vector<ComplexNumber>& signal) {
19 int N = signal.size();
20 std::vector<ComplexNumber> spectrum(N);
22 for (
int k = 0; k < N; ++k) {
24 for (
int n = 0; n < N; ++n) {
25 double angle = -2.0 * M_PI * k * n / N;
27 sum = sum + signal[n] * twiddle;
35std::vector<ComplexNumber> FourierTransform::IDFT(
const std::vector<ComplexNumber>& spectrum) {
36 int N = spectrum.size();
37 std::vector<ComplexNumber> signal(N);
39 for (
int n = 0; n < N; ++n) {
41 for (
int k = 0; k < N; ++k) {
42 double angle = 2.0 * M_PI * k * n / N;
44 sum = sum + spectrum[k] * twiddle;
53static int reverseBits(
int num,
int bits) {
55 for (
int i = 0; i < bits; ++i) {
56 result = (result << 1) | (num & 1);
63std::vector<ComplexNumber> FourierTransform::FFT(
const std::vector<ComplexNumber>& signal) {
64 int N = signal.size();
67 if (N == 0 || (N & (N - 1)) != 0) {
79 std::vector<ComplexNumber> result(signal);
82 for (
int i = 0; i < N; ++i) {
83 int j = reverseBits(i, bits);
85 std::swap(result[i], result[j]);
90 for (
int len = 2; len <= N; len <<= 1) {
91 double angle = -2.0 * M_PI / len;
94 for (
int i = 0; i < N; i += len) {
96 for (
int j = 0; j < len / 2; ++j) {
99 result[i + j] = u + v;
100 result[i + j + len / 2] = u - v;
109std::vector<ComplexNumber> FourierTransform::IFFT(
const std::vector<ComplexNumber>& spectrum) {
110 int N = spectrum.size();
113 std::vector<ComplexNumber> conjugated(N);
114 for (
int i = 0; i < N; ++i) {
116 -spectrum[i].getValue().imag());
120 std::vector<ComplexNumber> result = FFT(conjugated);
123 for (
int i = 0; i < N; ++i) {
125 -result[i].getValue().imag() / N);
132ComplexNumber FourierTransform::continuousFT(std::function<
double(
double)> f,
double omega,
double T) {
133 const int samples = 1000;
134 double dt = 2 * T / samples;
137 for (
int n = 0; n < samples; ++n) {
138 double t = -T + n * dt;
139 double angle = -omega * t;
147std::function<double(
double)> FourierTransform::inverseFT(std::function<
ComplexNumber(
double)> F,
double t_max) {
148 return [F, t_max](
double t) ->
double {
149 const int samples = 1000;
150 double domega = 2 * t_max / samples;
153 for (
int n = 0; n < samples; ++n) {
154 double omega = -t_max + n * domega;
156 double angle = omega * t;
159 result += integrand.getValue().real() * domega;
162 return result / (2 * M_PI);
167std::vector<ComplexNumber> FourierTransform::fourierSeries(std::function<
double(
double)> f,
double period,
int harmonics) {
168 std::vector<ComplexNumber> coefficients(2 * harmonics + 1);
169 double omega0 = 2 * M_PI / period;
171 for (
int n = -harmonics; n <= harmonics; ++n) {
172 const int samples = 1000;
173 double dt = period / samples;
176 for (
int k = 0; k < samples; ++k) {
178 double angle = -n * omega0 * t;
183 coefficients[n + harmonics] = sum / period;
190std::vector<double> FourierTransform::powerSpectrum(
const std::vector<double>& signal) {
192 std::vector<ComplexNumber> complexSignal;
193 for (
double val : signal) {
198 std::vector<ComplexNumber> spectrum = FFT(complexSignal);
201 std::vector<double> power(spectrum.size());
202 for (
size_t i = 0; i < spectrum.size(); ++i) {
203 power[i] = spectrum[i].getValue().real() * spectrum[i].getValue().real()
205 spectrum[i].getValue().imag() * spectrum[i].getValue().imag();
211std::vector<double> FourierTransform::magnitude(
const std::vector<ComplexNumber>& spectrum) {
212 std::vector<double> mag(spectrum.size());
213 for (
size_t i = 0; i < spectrum.size(); ++i) {
215 sqrt(spectrum[i].getValue().real() * spectrum[i].getValue().real()
217 spectrum[i].getValue().imag() * spectrum[i].getValue().imag());
222std::vector<double> FourierTransform::phase(
const std::vector<ComplexNumber>& spectrum) {
223 std::vector<double> ph(spectrum.size());
224 for (
size_t i = 0; i < spectrum.size(); ++i) {
226 atan2(spectrum[i].getValue().imag(), spectrum[i].getValue().real());
232std::vector<double> FourierTransform::hammingWindow(
int N) {
233 std::vector<double> window(N);
234 for (
int n = 0; n < N; ++n) {
235 window[n] = 0.54 - 0.46 * cos(2 * M_PI * n / (N - 1));
240std::vector<double> FourierTransform::hanningWindow(
int N) {
241 std::vector<double> window(N);
242 for (
int n = 0; n < N; ++n) {
243 window[n] = 0.5 * (1 - cos(2 * M_PI * n / (N - 1)));
248std::vector<double> FourierTransform::blackmanWindow(
int N) {
249 std::vector<double> window(N);
250 for (
int n = 0; n < N; ++n) {
251 double factor = 2 * M_PI * n / (N - 1);
252 window[n] = 0.42 - 0.5 * cos(factor) + 0.08 * cos(2 * factor);