Skip to content

Commit 0f971dc

Browse files
committed
.
1 parent f6bf619 commit 0f971dc

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/MagicPoly.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
2+
#include <NTL/lzz_pX.h>
3+
#include "NumbTh.h"
4+
5+
NTL_CLIENT
6+
7+
void compute_a_vals(Vec<long>& a, long p, long e)
8+
// computes a[m] = a(m)/m! for m = p..(e-1)(p-1)+1,
9+
// as defined by Chen and Han.
10+
// a.length() is set to (e-1)(p-1)+2
11+
12+
{
13+
long p_to_e = power_long(p, e);
14+
long p_to_2e = power_long(p, 2*e);
15+
16+
long len = (e-1)*(p-1)+2;
17+
18+
zz_pPush push(p_to_2e);
19+
20+
zz_pX x_plus_1_to_p = power(zz_pX(INIT_MONO, 1) + 1, p);
21+
zz_pX denom = InvTrunc(x_plus_1_to_p - zz_pX(INIT_MONO, p), len);
22+
zz_pX poly = MulTrunc(x_plus_1_to_p, denom, len);
23+
poly *= p;
24+
25+
a.SetLength(len);
26+
27+
long m_fac = 1;
28+
for (long m = 2; m < p; m++) {
29+
m_fac = MulMod(m_fac, m, p_to_2e);
30+
}
31+
32+
for (long m = p; m < len; m++) {
33+
m_fac = MulMod(m_fac, m, p_to_2e);
34+
long c = rep(coeff(poly, m));
35+
long d = GCD(m_fac, p_to_2e);
36+
if (d == 0 || d > p_to_e || c % d != 0) Error("cannot divide");
37+
long m_fac_deflated = (m_fac / d) % p_to_e;
38+
long c_deflated = (c / d) % p_to_e;
39+
a[m] = MulMod(c_deflated, InvMod(m_fac_deflated, p_to_e), p_to_e);
40+
}
41+
42+
}
43+
44+
int main(int argc, char **argv)
45+
{
46+
ArgMapping amap;
47+
48+
long p = 2;
49+
amap.arg("p", p);
50+
51+
long e = 2;
52+
amap.arg("e", e);
53+
54+
amap.parse(argc, argv);
55+
56+
Vec<long> a;
57+
58+
compute_a_vals(a, p, e);
59+
60+
long p_to_e = power_long(p, e);
61+
long len = (e-1)*(p-1)+2;
62+
63+
zz_pPush push(p_to_e);
64+
65+
zz_pX poly(0);
66+
zz_pX term(1);
67+
zz_pX X(INIT_MONO, 1);
68+
69+
poly = 0;
70+
term = 1;
71+
72+
for (long m = 0; m < p; m++) {
73+
term *= (X-m);
74+
}
75+
76+
for (long m = p; m < len; m++) {
77+
poly += term * a[m];
78+
term *= (X-m);
79+
}
80+
81+
cout << poly << "\n";
82+
83+
for (long i = 0; i < 1000; i++) {
84+
zz_p x;
85+
random(x);
86+
zz_p fx = eval(poly, x);
87+
if (fx + (rep(x) % p) != x) Error("bad eval");
88+
}
89+
}

0 commit comments

Comments
 (0)