Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit d7a757d

Browse files
committed
IterativeFFT.cpp
1 parent 05fc7ea commit d7a757d

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

IterativeFFT.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_IterativeFFT
22+
#endif
23+
24+
#ifndef FUNC_IterativeFFT
25+
#define FUNC_IterativeFFT
26+
27+
#include <cmath>
28+
#include "utils.h"
29+
30+
#include "RecursiveFFT.cpp"
31+
32+
size_t rev(size_t k, size_t n) {
33+
size_t ans = 0;
34+
for (size_t i = 1; i != n; i <<= 1) {
35+
ans <<= 1;
36+
if (k & i)
37+
ans |= 1;
38+
}
39+
return ans;
40+
}
41+
42+
template <typename T>
43+
Matrix<T> BitReverseCopy(Matrix<T>& a) {
44+
const size_t n = a.rows;
45+
Matrix<T> A(n, 1, 0);
46+
for (size_t k = 0; k < n; k++)
47+
A[rev(k, n)] = a[k];
48+
return A;
49+
}
50+
51+
template <typename T>
52+
Matrix<T> IterativeFFT(Matrix<T>& a, bool neg = false) {
53+
const size_t n = a.rows;
54+
Matrix<T> A = BitReverseCopy(a);
55+
for (size_t s = 1; size_t (1 << s) <= n; s++) {
56+
size_t m = 1 << s;
57+
T wm = expi((neg ? -1 : 1) * 2 * M_PI / m);
58+
for (size_t k = 0; k < n; k += m) {
59+
T w = 1;
60+
for (size_t j = 0; j < m / 2; j++) {
61+
T t = w * A[k + j + m / 2][0];
62+
T u = A[k + j][0];
63+
A[k + j][0] = u + t;
64+
A[k + j + m / 2][0] = u - t;
65+
w *= wm;
66+
}
67+
}
68+
}
69+
return A;
70+
}
71+
72+
template <typename T>
73+
Matrix<T> IterativeInverseFFT(Matrix<T>& a) {
74+
const size_t n = a.rows;
75+
Matrix<T> ans = IterativeFFT(a, true);
76+
for (size_t i = 0; i < n; i++)
77+
ans[i][0] /= n;
78+
return ans;
79+
}
80+
81+
template <typename T>
82+
Matrix<T> IterativePolynomialMultiply(Matrix<T>& a, Matrix<T>& b) {
83+
const size_t n = a.rows;
84+
assert(n == b.rows);
85+
Matrix<T> n0(n, 1, 0);
86+
Matrix<T> aa = a.concat_v(n0);
87+
Matrix<T> bb = b.concat_v(n0);
88+
Matrix<T> fa = IterativeFFT(aa);
89+
Matrix<T> fb = IterativeFFT(bb);
90+
Matrix<T> fc(2 * n, 1, 0);
91+
for (size_t i = 0; i < 2 * n; i++)
92+
fc[i][0] = fa[i][0] * fb[i][0];
93+
return IterativeInverseFFT(fc);
94+
}
95+
#endif
96+
97+
#ifdef MAIN_IterativeFFT
98+
int main(int argc, char *argv[]) {
99+
for (size_t i = 0; i < 8; i++) {
100+
std::cout << rev(i, 8) << std::endl;
101+
}
102+
const size_t n = get_argv(argc, argv, 1, 16);
103+
std::vector<int> int_a, int_b;
104+
random_integers(int_a, -n, n, n);
105+
random_integers(int_b, -n, n, n);
106+
using T = Complex<double>;
107+
std::vector<T> buf_a(n), buf_b(n);
108+
for (size_t i = 0; i < int_a.size(); i++)
109+
buf_a[i] = int_a[i];
110+
for (size_t i = 0; i < int_a.size(); i++)
111+
buf_b[i] = int_b[i];
112+
Matrix<T> a(n, 1, buf_a);
113+
std::cout << a << std::endl;
114+
Matrix<T> b(n, 1, buf_b);
115+
std::cout << b << std::endl;
116+
Matrix<T> ans(2 * n, 0);
117+
ans = ans.concat_h(PolynomialMultiply(a, b));
118+
ans = ans.concat_h(IterativePolynomialMultiply(a, b));
119+
std::cout << ans << std::endl;
120+
return 0;
121+
}
122+
#endif
123+

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@
195195
| 30 | RecursiveFFT.cpp | Recursive FFT | 911 |
196196
| 30 | RecursiveFFT.cpp | Inverse FFT | 913 |
197197
| 30 | RecursiveFFT.cpp | Polynomial Multiply | 914 |
198+
| 30 | IterativeFTT.cpp | Iterative FTT | 917 |
199+
| 30 | IterativeFTT.cpp | Bit Reversal Copy | 918 |
198200

199201
# Supplementary Files
200202
* `utils.h`: Utils

0 commit comments

Comments
 (0)