-
Notifications
You must be signed in to change notification settings - Fork 0
/
fourier_transform.cpp
67 lines (62 loc) · 1.91 KB
/
fourier_transform.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
struct fft
{
int len, id;
int sp[maxn];
pair<double, double> p[3][maxn], tmp[maxn];
void init(int l, int * s)
{
this->len = l;
for(int i = 0; i < len; ++i)
sp[i] = s[i];
}
void fill(int m, int d, int c)
{
if(m == len) p[c][d] = tmp[id++];
else
{
fill(m << 1, d, c);
fill(m << 1, d + m, c);
}
}
void calc(double oper, int c)
{
for(int d = 0; (1 << d) < len; ++d)
{
int m = (1 << d);
double x = pi / m * oper;
double i0 = sin(x), r0 = cos(x);
for(int k = 0; k < len; k += (m << 1))
{
double i = 0, r = 1;
for(int j = 0; j < m; ++j)
{
double tr = r * p[c][k + j + m].first - i * p[c][k + j + m].second;
double ti = r * p[c][k + j + m].second + i * p[c][k + j + m].first;
p[c][k + j + m].first = p[c][k + j].first - tr;
p[c][k + j + m].second = p[c][k + j].second - ti;
p[c][k + j].first += tr;
p[c][k + j].second += ti;
double tmpi = i;
i = i * r0 + r * i0; r = r * r0 - tmpi * i0;
}
}
}
}
void multi()
{
for(int i = 0; i < len; ++i)
{
tmp[i].first = sp[i];
tmp[i].second = 0.0;
}
id = 0; fill(1, 0, 0); calc(1.0, 0);
id = 0; fill(1, 0, 1); calc(1.0, 1);
for(int i = 0; i < len; ++i)
{
tmp[i].first = p[0][i].first * p[1][i].first - p[0][i].second * p[1][i].second;
tmp[i].second = p[0][i].first * p[1][i].second + p[0][i].second * p[1][i].first;
}
id = 0; fill(1, 0, 2); calc(-1.0, 2);
for(int i = 0; i < len; ++i) p[2][i].first /= len;
}
}f;