Skip to content

Commit

Permalink
✨ adds fft convolution
Browse files Browse the repository at this point in the history
  • Loading branch information
iagorrr committed Feb 1, 2024
1 parent 2233efc commit 80f9e72
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
82 changes: 82 additions & 0 deletions algorithms/math/fft-convolution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const ld PI = acos(-1);

/* change the ld to doulbe may increase performance =D */
struct num {
ld a{0.0}, b{0.0};
num() {}
num(ld na) : a{na} {}
num(ld na, ld nb) : a{na}, b{nb} {}

const num operator+(const num& c) const {
return num(a + c.a, b + c.b);
}
const num operator-(const num& c) const {
return num(a - c.a, b - c.b);
}
const num operator*(const num& c) const {
return num(a * c.a - b * c.b, a * c.b + b * c.a);
}
const num operator/(const ll& c) const {
return num(a / c, b / c);
}
};

void fft(vector<num>& a, bool invert) {
int n = len(a);
for (int i = 1, j = 0; i < n; i++) {
int bit = n >> 1;
for (; j & bit; bit >>= 1) j ^= bit;
j ^= bit;
if (i < j) swap(a[i], a[j]);
}
for (int sz = 2; sz <= n; sz <<= 1) {
ld ang = 2 * PI / sz * (invert ? -1 : 1);
num wsz(cos(ang), sin(ang));
for (int i = 0; i < n; i += sz) {
num w(1);
rep(j, 0, sz / 2) {
num u = a[i + j], v = a[i + j + sz / 2] * w;
a[i + j] = u + v;
a[i + j + sz / 2] = u - v;
w = w * wsz;
}
}
}
if (invert)
for (num& x : a) x = x / n;
}

vi conv(vi const a, vi const b) {
vector<num> fa(all(a));
vector<num> fb(all(b));
int n = 1;
while (n < len(a) + len(b)) n <<= 1;
fa.resize(n);
fb.resize(n);
fft(fa, false);
fft(fb, false);
rep(i, 0, n) fa[i] = fa[i] * fb[i];
fft(fa, true);
vi result(n);
rep(i, 0, n) result[i] = round(fa[i].a);
while (len(result) and result.back() == 0)
result.pop_back();

/* Unconment this line if you want a boolean convolution*/
for (auto& xi : result) xi = min(xi, 1ll);

return result;
}
vll poly_exp(vll& ps, int k) {
vll ret(len(ps));
auto base = ps;
ret[0] = 1;

while (k) {
if (k & 1) ret = conv(ret, base);
k >>= 1;
base = conv(base, base);
}

return ret;
}
3 changes: 3 additions & 0 deletions algorithms/math/fft-convolution.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
\subsection{FFT Convolution}

Performs convolution in a vector duh !

0 comments on commit 80f9e72

Please sign in to comment.