@@ -17,10 +17,19 @@ using std::swap;
17
17
18
18
using std::size_t ;
19
19
20
- using c64 = std::complex<double >;
21
- template <typename T>
22
- constexpr T pi () {
23
- return 3.14159265358979323846264338327950288419716 ;
20
+ using complex = std::complex<double >;
21
+ static const double pi = 3.14159265358979323846264338327950288419716 ;
22
+
23
+ template <typename Iter>
24
+ void dft (Iter X, Iter last) {
25
+ const auto N = last - X;
26
+ std::vector<complex> tmp (N);
27
+ for (auto i = 0 ; i < N; ++i) {
28
+ for (auto j = 0 ; j < N; ++j) {
29
+ tmp[i] += X[j] * exp (complex (0 , -2.0 * M_PI * i * j / N));
30
+ }
31
+ }
32
+ std::copy (std::begin (tmp), std::end (tmp), X);
24
33
}
25
34
26
35
// `cooley_tukey` does the cooley-tukey algorithm, recursively
@@ -30,12 +39,12 @@ void cooley_tukey(Iter first, Iter last) {
30
39
if (size >= 2 ) {
31
40
// split the range, with even indices going in the first half,
32
41
// and odd indices going in the last half.
33
- auto temp = std::vector<c64 >(size / 2 );
34
- for (size_t i = 0 ; i < size / 2 ; ++i) {
42
+ auto temp = std::vector<complex >(size / 2 );
43
+ for (int i = 0 ; i < size / 2 ; ++i) {
35
44
temp[i] = first[i * 2 + 1 ];
36
45
first[i] = first[i * 2 ];
37
46
}
38
- for (size_t i = 0 ; i < size / 2 ; ++i) {
47
+ for (int i = 0 ; i < size / 2 ; ++i) {
39
48
first[i + size / 2 ] = temp[i];
40
49
}
41
50
@@ -45,8 +54,8 @@ void cooley_tukey(Iter first, Iter last) {
45
54
cooley_tukey (split, last);
46
55
47
56
// now combine each of those halves with the butterflies
48
- for (size_t k = 0 ; k < size / 2 ; ++k) {
49
- auto w = std::exp (c64 (0 , -2.0 * pi < double >() * k / size));
57
+ for (int k = 0 ; k < size / 2 ; ++k) {
58
+ auto w = std::exp (complex (0 , -2.0 * pi * k / size));
50
59
51
60
auto & bottom = first[k];
52
61
auto & top = first[k + size / 2 ];
@@ -83,11 +92,11 @@ void iterative_cooley_tukey(Iter first, Iter last) {
83
92
84
93
// perform the butterfly on the range
85
94
auto size = last - first;
86
- for (size_t stride = 2 ; stride <= size; stride *= 2 ) {
87
- auto w = exp (c64 (0 , -2.0 * pi < double >() / stride));
88
- for (size_t j = 0 ; j < size; j += stride) {
89
- auto v = c64 (1.0 );
90
- for (size_t k = 0 ; k < stride / 2 ; k++) {
95
+ for (int stride = 2 ; stride <= size; stride *= 2 ) {
96
+ auto w = exp (complex (0 , -2.0 * pi / stride));
97
+ for (int j = 0 ; j < size; j += stride) {
98
+ auto v = complex (1.0 );
99
+ for (int k = 0 ; k < stride / 2 ; k++) {
91
100
first[k + j + stride / 2 ] =
92
101
first[k + j] - v * first[k + j + stride / 2 ];
93
102
first[k + j] -= (first[k + j + stride / 2 ] - first[k + j]);
@@ -103,7 +112,7 @@ int main() {
103
112
std::mt19937 rng (random_device ());
104
113
std::uniform_real_distribution<double > distribution (0.0 , 1.0 );
105
114
106
- std::array<c64 , 64 > initial;
115
+ std::array<complex , 64 > initial;
107
116
std::generate (
108
117
begin (initial), end (initial), [&] { return distribution (rng); });
109
118
@@ -117,7 +126,7 @@ int main() {
117
126
// Check if the arrays are approximately equivalent
118
127
std::cout << std::right << std::setw (16 ) << " idx" << std::setw (16 ) << " rec"
119
128
<< std::setw (16 ) << " it" << std::setw (16 ) << " subtracted" << ' \n ' ;
120
- for (int i = 0 ; i < initial.size (); ++i) {
129
+ for (size_t i = 0 ; i < initial.size (); ++i) {
121
130
auto rec = recursive[i];
122
131
auto it = iterative[i];
123
132
std::cout << std::setw (16 ) << i << std::setw (16 ) << std::abs (rec)
0 commit comments