Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241782 views
1
/*********************************************************************
2
3
(c) Copyright 2006-2010 Salman Baig and Chris Hall
4
5
This file is part of ELLFF
6
7
ELLFF is free software: you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation, either version 3 of the License, or
10
(at your option) any later version.
11
12
ELLFF is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
16
17
You should have received a copy of the GNU General Public License
18
along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
*********************************************************************/
21
22
//
23
// helper routines for L-function computations
24
//
25
// - induced ordering on elements of: F_p[x], F_q, F_q[x]
26
// - converting elements to unsigned longs: F_p[x], F_q(, F_q[x])
27
// - enumerating elements: F_p[x], F_q(, F_q[x])
28
// - evaluating elements of F_q[x] at elements of F_q
29
// - exponentiation in F_q^*
30
31
#include <assert.h>
32
#include <stdio.h>
33
#include <stdlib.h>
34
#include <math.h>
35
#include <NTL/ZZX.h>
36
#include <NTL/lzz_p.h>
37
#include <NTL/lzz_pE.h>
38
#include <NTL/lzz_pX.h>
39
#include <NTL/lzz_pEX.h>
40
#include <NTL/lzz_pXFactoring.h>
41
#include <NTL/lzz_pEXFactoring.h>
42
#include <NTL/lzz_pX.h>
43
44
#include "helper.h"
45
#include "lzz_pEExtra.h"
46
47
NTL_CLIENT
48
49
#define NO_CARRY 0
50
#define CARRY 1
51
52
///////////////////////////////////////////////////////////////////////////
53
54
// return a modulus appropriate for F_q=F_{p^d}
55
56
void get_modulus(zz_pX& pi, int p, int d)
57
{
58
zz_p::init(p);
59
SetX(pi);
60
pi <<= d-1;
61
while (IterIrredTest(pi) == 0 && inc(pi,d-1) == 0)
62
;
63
assert(IterIrredTest(pi) == 1 && deg(pi) == d);
64
}
65
66
// return moduli pi_1 for F_{p^d1}/F_p and pi_2 for F_{p^{d1*d2}}/F_p and
67
// identify a zero of pi_1 in F_{p^{d1*d2}}
68
69
void get_modulus(zz_pX& pi_1, zz_pX& pi_2, zz_pX& a, int p, int d1, int d2)
70
{
71
get_modulus(pi_1, p, d1);
72
get_modulus(pi_2, p, d1*d2);
73
74
// find alpha
75
zz_pE::init(pi_2);
76
77
zz_pEX pi;
78
conv(pi, pi_1);
79
80
zz_pE zero;
81
82
FindRoot(zero, pi);
83
84
a = rep(zero);
85
}
86
87
// initialize F_{p^d} with canonical irreducible in F_p[x]
88
89
void init_NTL_ff(int p, int d, int precompute_inverses,
90
int precompute_square_roots, int precompute_legendre_char,
91
int precompute_pth_frobenius_map)
92
{
93
zz_pX pi;
94
get_modulus(pi, p, d);
95
zz_pE::init(pi);
96
97
// make sure size of finite field fits in a long
98
assert(zz_pE::cardinality().WideSinglePrecision());
99
100
zz_pEExtraContext c(precompute_inverses,
101
precompute_square_roots,
102
precompute_legendre_char,
103
precompute_pth_frobenius_map);
104
c.restore();
105
}
106
107
///////////////////////////////////////////////////////////////////////////
108
109
// compare elements in F_p[x] ordered by degree then leading coefficient
110
111
long operator<(zz_pX& f, zz_pX& g)
112
{
113
int i;
114
115
if (deg(f) < deg(g)) return 1;
116
if (deg(f) > deg(g)) return 0;
117
for (i = deg(f); i >= 0; i--) {
118
if (coeff(f,i).LoopHole() < coeff(g,i).LoopHole()) return 1;
119
if (coeff(f,i).LoopHole() > coeff(g,i).LoopHole()) return 0;
120
}
121
122
return 0;
123
}
124
inline long operator<=(zz_pX& f, zz_pX& g)
125
{ return (f < g) || (f == g); }
126
inline long operator>( zz_pX& f, zz_pX& g)
127
{ return (g <= f); }
128
inline long operator>=(zz_pX& f, zz_pX& g)
129
{ return (g < f); }
130
131
// compare elements of F_q
132
133
long operator<(zz_pE& x, zz_pE& y)
134
{
135
return x.LoopHole() < y.LoopHole();
136
}
137
inline long operator<=(zz_pE& f, zz_pE& g)
138
{ return (f < g) || (f == g); }
139
inline long operator>(zz_pE& f, zz_pE& g)
140
{ return (g <= f); }
141
inline long operator>=(zz_pE& f, zz_pE& g)
142
{ return (g < f); }
143
144
// compare elements in F_q[x] ordered by degree then leading coefficient
145
146
long operator<(zz_pEX& f, zz_pEX& g)
147
{
148
int i;
149
150
if (deg(f) < deg(g)) return 1;
151
if (deg(f) > deg(g)) return 0;
152
for (i = deg(f); i >= 0; i--) {
153
zz_pE cf = coeff(f,i), cg = coeff(g,i);
154
if (cf < cg) return 1;
155
if (cf > cg) return 0;
156
}
157
158
return 0;
159
}
160
inline long operator<=(zz_pEX& f, zz_pEX& g)
161
{ return (f < g) || (f == g); }
162
inline long operator>( zz_pEX& f, zz_pEX& g)
163
{ return (g <= f); }
164
inline long operator>=(zz_pEX& f, zz_pEX& g)
165
{ return (g < f); }
166
167
///////////////////////////////////////////////////////////////////////////
168
169
// convert elt of F_p[x] to int using coefficients as base-p digits
170
// used to determine index of elt in table
171
172
unsigned long to_ulong(const zz_pX& x)
173
{
174
unsigned long u;
175
int i;
176
static zz_p c;
177
178
c = LeadCoeff(x);
179
static long p;
180
p = c.modulus();
181
for (u = 0, i = deg(x); i >= 0; i--) {
182
GetCoeff(c, x,i);
183
u = u * p + rep(c);
184
}
185
186
return u;
187
}
188
189
void from_ulong(unsigned long ul, zz_pX& x)
190
{
191
static zz_pX t_to_i;
192
static long p;
193
static zz_p c;
194
195
// get current field characteristic
196
t_to_i = 1;
197
c = ConstTerm(t_to_i);
198
p = c.modulus();
199
200
// convert base-p number ul to polynomial
201
x = 0;
202
while (ul != 0) {
203
x += (ul%p)*t_to_i;
204
t_to_i <<= 1;
205
ul /= p;
206
}
207
}
208
209
void from_ulong(unsigned long ul, zz_pE& x)
210
{
211
static zz_pX rep;
212
from_ulong(ul, rep);
213
x = to_zz_pE(rep);
214
}
215
216
unsigned long to_ulong(zz_pE& x)
217
{
218
static zz_pX y;
219
y = x.LoopHole();
220
return to_ulong(y);
221
}
222
223
// increment polynomial as if coefficients were base-p digits of an
224
// integer. corresponding sequence of polynomials is a so-called lexical
225
// ordering.
226
227
int inc(zz_pX& x, long max_deg)
228
{
229
zz_pX tee_to_i(0,1);
230
int i;
231
232
i = 0;
233
do {
234
x += tee_to_i;
235
tee_to_i <<= 1;
236
} while (coeff(x,i) == 0 && ++i <= max_deg);
237
238
return (i > max_deg) ? CARRY : NO_CARRY;
239
}
240
241
int inc(zz_pEX& x, long max_deg)
242
{
243
zz_pEX tee_to_i(0,1);
244
int i, r;
245
zz_pE c;
246
247
i = 0;
248
do {
249
c = coeff(x, i);
250
r = inc(c);
251
SetCoeff(x, i, c);
252
} while (r == 1 && ++i <= max_deg);
253
254
return (i > max_deg) ? CARRY : NO_CARRY;
255
}
256
257
// replaces x with next element in 'lexical ordering' of F_q
258
259
int inc(zz_pE& x)
260
{
261
long d = deg(x.modulus()), i;
262
zz_pE tee = to_zz_pE(zz_pX(1,1)), tee_to_i = to_zz_pE(zz_pX(0,1));
263
264
i = 0;
265
do {
266
x += tee_to_i;
267
tee_to_i *= tee;
268
} while (coeff(x.LoopHole(),i) == 0 && ++i < d);
269
270
return (i >= d) ? 1 : 0;
271
}
272
273
// evaluate polynomial f at x
274
275
zz_pE eval(const zz_pX& f, const zz_pE& x)
276
{
277
static zz_pE y,z;
278
static zz_p t;
279
long i;
280
281
GetCoeff(t, f,deg(f));
282
y=t;
283
for (i = deg(f)-1; i >= 0; i--) {
284
GetCoeff(t, f, i);
285
mul(z, y, x);
286
add(y, z, t);
287
}
288
289
return y;
290
}
291
292
ZZ eval(const ZZX& f, const ZZ& x)
293
{
294
static ZZ y,z;
295
static ZZ t;
296
long i;
297
298
GetCoeff(t, f, deg(f));
299
y=t;
300
for (i = deg(f)-1; i >= 0; i--) {
301
GetCoeff(t, f, i);
302
mul(z, y, x);
303
add(y, z, t);
304
}
305
return y;
306
}
307
308
// convert a long to a string
309
310
char *ltoa(long i)
311
{
312
static char result[20], *str;
313
314
str = result + 19;
315
*str-- = 0;
316
do {
317
*str-- = (i%10) + '0';
318
i /= 10;
319
} while (i != 0);
320
321
return str+1;
322
}
323
324
// compute x^e
325
326
zz_pE operator^(const zz_pE& x, const int e)
327
{
328
zz_pE result, l;
329
long i;
330
331
result = 1;
332
if (e == 0) return result;
333
if (e < 0) return 1/(x^(-e));
334
335
// I = 2^i
336
for (i = 0, l = x; (1<<i) <= e; i++) {
337
if (e & (1<<i))
338
result *= l;
339
l = sqr(l);
340
}
341
342
return result;
343
}
344
345
// compute x^e
346
347
zz_pEX operator^(const zz_pEX& x, const int e)
348
{
349
zz_pEX result, l;
350
long i;
351
352
assert(e >= 0);
353
354
result = 1;
355
if (e == 0) return result;
356
357
// I = 2^i
358
for (i = 0, l = x; (1<<i) <= e; i++) {
359
if (e & (1<<i))
360
result *= l;
361
l = sqr(l);
362
}
363
364
return result;
365
}
366
367
#ifdef MAIN
368
int main(int argc, char **argv)
369
{
370
zz_pX pi_1, pi_2, a;
371
372
get_modulus(pi_1, pi_2, a, 5, 2, 2);
373
374
long q = to_long(zz_pE::cardinality());
375
cout << "q = " << q << endl;
376
377
cout << "pi_1 = " << pi_1 << endl;
378
cout << "pi_2 = " << pi_2 << endl;
379
cout << "a = " << a << endl;
380
}
381
#endif // MAIN
382
383