TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
fast_fourier_transform.cpp
Go to the documentation of this file.
1
22#include <cassert>
23#include <cmath>
24#include <complex>
25#include <cstdint>
26#include <iostream>
27#include <vector>
28
33namespace numerical_methods {
42std::complex<double> *FastFourierTransform(std::complex<double> *p, uint8_t n) {
43 if (n == 1) {
44 return p;
45 }
46
47 double pi = 2 * asin(1.0);
48
49 std::complex<double> om = std::complex<double>(
50 cos(2 * pi / n), sin(2 * pi / n));
51
52 auto *pe = new std::complex<double>[n / 2];
53
54 auto *po = new std::complex<double>[n / 2];
55
56 int k1 = 0, k2 = 0;
57 for (int j = 0; j < n; j++) {
58 if (j % 2 == 0) {
59 pe[k1++] = p[j];
60
61 } else {
62 po[k2++] = p[j];
63 }
64 }
65
66 std::complex<double> *ye =
67 FastFourierTransform(pe, n / 2);
68
69 std::complex<double> *yo =
70 FastFourierTransform(po, n / 2);
71
72 auto *y = new std::complex<double>[n];
73
74 k1 = 0, k2 = 0;
75
76 for (int i = 0; i < n / 2; i++) {
77 y[i] =
78 ye[k1] + pow(om, i) * yo[k2];
79 y[i + n / 2] =
80 ye[k1] - pow(om, i) * yo[k2];
81
82 k1++;
83 k2++;
84 }
85
86 if (n != 2) {
87 delete[] pe;
88 delete[] po;
89 }
90
91 delete[] ye;
92 delete[] yo;
93 return y;
94}
95
96} // namespace numerical_methods
97
105static void test() {
106 /* descriptions of the following test */
107
108 auto *t1 = new std::complex<double>[2];
109 auto *t2 = new std::complex<double>[4];
110
111 t1[0] = {1, 0};
112 t1[1] = {2, 0};
113 t2[0] = {1, 0};
114 t2[1] = {2, 0};
115 t2[2] = {3, 0};
116 t2[3] = {4, 0};
117
118 uint8_t n1 = 2;
119 uint8_t n2 = 4;
120 std::vector<std::complex<double>> r1 = {
121 {3, 0}, {-1, 0}};
122
123 std::vector<std::complex<double>> r2 = {
124 {10, 0}, {-2, -2}, {-2, 0}, {-2, 2}};
125
126 std::complex<double> *o1 = numerical_methods::FastFourierTransform(t1, n1);
127 std::complex<double> *t3 =
128 o1;
129 std::complex<double> *o2 = numerical_methods::FastFourierTransform(t2, n2);
130 std::complex<double> *t4 =
131 o2;
132 for (uint8_t i = 0; i < n1; i++) {
133 assert((r1[i].real() - o1->real() < 0.000000000001) &&
134 (r1[i].imag() - o1->imag() <
135 0.000000000001));
137 o1++;
138 }
139
140 for (uint8_t i = 0; i < n2; i++) {
141 assert((r2[i].real() - o2->real() < 0.000000000001) &&
142 (r2[i].imag() - o2->imag() <
143 0.000000000001));
145 o2++;
146 }
147
148 delete[] t1;
149 delete[] t2;
150 delete[] t3;
151 delete[] t4;
152 std::cout << "All tests have successfully passed!\n";
153}
154
163int main(int argc, char const *argv[]) {
164 test(); // run self-test implementations
165 // with 2 defined test cases
166 return 0;
167}
static void test()
Self-test implementations.
int main()
Main function.
std::complex< double > * FastFourierTransform(std::complex< double > *p, uint8_t n)
FastFourierTransform is a recursive function which returns list of complex numbers.