Skip to content

Commit 02e9270

Browse files
committed
Reorganized functions
1 parent f277725 commit 02e9270

File tree

7 files changed

+162
-145
lines changed

7 files changed

+162
-145
lines changed

content/numerical/FFTPolynomial.h

Lines changed: 0 additions & 144 deletions
This file was deleted.

content/numerical/PolynomialBase.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Author: chilli, Andrew He, Adamant
3+
* Date: 2019-04-27
4+
* Description: A FFT based Polynomial class.
5+
*/
6+
#pragma once
7+
8+
#include "../number-theory/ModularArithmetic.h"
9+
#include "FastFourierTransform.h"
10+
#include "FastFourierTransformMod.h"
11+
// #include "NumberTheoreticTransform.h"
12+
13+
typedef Mod num;
14+
typedef vector<num> poly;
15+
vector<Mod> conv(vector<Mod> a, vector<Mod> b) {
16+
auto res = convMod<mod>(vl(all(a)), vl(all(b)));
17+
// auto res = conv(vl(all(a)), vl(all(b)));
18+
return vector<Mod>(all(res));
19+
}
20+
poly &operator+=(poly &a, const poly &b) {
21+
a.resize(max(sz(a), sz(b)));
22+
rep(i, 0, sz(b)) a[i] = a[i] + b[i];
23+
return a;
24+
}
25+
poly &operator-=(poly &a, const poly &b) {
26+
a.resize(max(sz(a), sz(b)));
27+
rep(i, 0, sz(b)) a[i] = a[i] - b[i];
28+
return a;
29+
}
30+
31+
poly &operator*=(poly &a, const poly &b) {
32+
if (sz(a) + sz(b) < 100){
33+
poly res(sz(a) + sz(b) - 1);
34+
rep(i,0,sz(a)) rep(j,0,sz(b))
35+
res[i + j] = (res[i + j] + a[i] * b[j]);
36+
return (a = res);
37+
}
38+
return a = conv(a, b);
39+
}
40+
poly operator*(poly a, const num b) {
41+
poly c = a;
42+
trav(i, c) i = i * b;
43+
return c;
44+
}
45+
#define OP(o, oe) \
46+
poly operator o(poly a, poly b) { \
47+
poly c = a; \
48+
return c oe b; \
49+
}
50+
OP(*, *=) OP(+, +=) OP(-, -=);
51+
poly modK(poly a, int k) { return {a.begin(), a.begin() + min(k, sz(a))}; }
52+
poly inverse(poly A) {
53+
poly B = poly({num(1) / A[0]});
54+
while (sz(B) < sz(A))
55+
B = modK(B * (poly({num(2)}) - modK(A, 2*sz(B)) * B), 2 * sz(B));
56+
return modK(B, sz(A));
57+
}

content/numerical/PolynomialEval.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#pragma once
2+
3+
#include "PolynomialMod.h"
4+
5+
vector<num> eval(const poly &a, const vector<num> &x) {
6+
int n = sz(x);
7+
if (!n) return {};
8+
vector<poly> up(2 * n);
9+
rep(i, 0, n) up[i + n] = poly({num(0) - x[i], 1});
10+
for (int i = n - 1; i > 0; i--)
11+
up[i] = up[2 * i] * up[2 * i + 1];
12+
vector<poly> down(2 * n);
13+
down[1] = a % up[1];
14+
rep(i, 2, 2 * n) down[i] = down[i / 2] % up[i];
15+
vector<num> y(n);
16+
rep(i, 0, n) y[i] = down[i + n][0];
17+
return y;
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include "PolynomialMod.h"
4+
#include "PolynomialPow.h"
5+
#include "PolynomialEval.h"
6+
7+
poly interp(vector<num> x, vector<num> y) {
8+
int n=sz(x);
9+
vector<poly> up(n*2);
10+
rep(i,0,n) up[i+n] = poly({num(0)-x[i], num(1)});
11+
for(int i=n-1; i>0;i--) up[i] = up[2*i]*up[2*i+1];
12+
vector<num> a = eval(deriv(up[1]), x);
13+
vector<poly> down(2*n);
14+
rep(i,0,n) down[i+n] = poly({y[i]*(num(1)/a[i])});
15+
for(int i=n-1;i>0;i--) down[i] = down[i*2] * up[i*2+1] + down[i*2+1] * up[i*2];
16+
return down[1];
17+
}

content/numerical/PolynomialMod.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
3+
#include "PolynomialBase.h"
4+
5+
poly &operator/=(poly &a, poly b) {
6+
if (sz(a) < sz(b))
7+
return a = {};
8+
int s = sz(a) - sz(b) + 1;
9+
reverse(all(a)), reverse(all(b));
10+
a.resize(s), b.resize(s);
11+
a = a * inverse(b);
12+
a.resize(s), reverse(all(a));
13+
return a;
14+
}
15+
OP(/, /=)
16+
poly &operator%=(poly &a, poly &b) {
17+
if (sz(a) < sz(b))
18+
return a;
19+
poly c = (a / b) * b;
20+
a.resize(sz(b) - 1);
21+
rep(i, 0, sz(a)) a[i] = a[i] - c[i];
22+
return a;
23+
}
24+
OP(%, %=)

content/numerical/PolynomialPow.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include "PolynomialBase.h"
4+
poly deriv(poly a) {
5+
if (a.empty())
6+
return {};
7+
poly b(sz(a) - 1);
8+
rep(i, 1, sz(a)) b[i - 1] = a[i] * num(i);
9+
return b;
10+
}
11+
poly integr(poly a) {
12+
if (a.empty()) return {0};
13+
poly b(sz(a) + 1);
14+
b[1] = num(1);
15+
rep(i, 2, sz(b)) b[i] = b[mod%i]*Mod(-mod/i+mod);
16+
rep(i, 1 ,sz(b)) b[i] = a[i-1] * b[i];
17+
return b;
18+
}
19+
poly log(poly a) {
20+
return modK(integr(deriv(a) * inverse(a)), sz(a));
21+
}
22+
poly exp(poly a) {
23+
poly b(1, num(1));
24+
if (a.empty())
25+
return b;
26+
while (sz(b) < sz(a)) {
27+
b.resize(sz(b) * 2);
28+
b *= (poly({num(1)}) + modK(a, sz(b)) - log(b));
29+
b.resize(sz(b) / 2 + 1);
30+
}
31+
return modK(b, sz(a));
32+
}
33+
poly pow(poly a, ll m) {
34+
int p = 0, n = sz(a);
35+
while (p < sz(a) && a[p].x == 0)
36+
++p;
37+
if (ll(m)*p >= sz(a)) return poly(sz(a));
38+
num j = a[p];
39+
a = {a.begin() + p, a.end()};
40+
a = a * (num(1) / j);
41+
a.resize(n);
42+
auto res = exp(log(a) * num(m)) * (j ^ m);
43+
res.insert(res.begin(), p*m, 0);
44+
return modK(res, n);
45+
}

content/numerical/chapter.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
\chapter{Numerical}
22

33
\kactlimport{GoldenSectionSearch.h}
4-
\kactlimport{FFTPolynomial.h}
4+
\kactlimport{PolynomialBase.h}
55
\kactlimport{PolyRoots.h}
66
\kactlimport{BerlekampMassey.h}
77
\kactlimport{LinearRecurrence.h}

0 commit comments

Comments
 (0)