Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/c_lib/src/ntl_wrap.cpp
4024 views
1
#include <iostream>
2
#include <sstream>
3
using namespace std;
4
5
#include "ntl_wrap.h"
6
#include <NTL/mat_poly_ZZ.h>
7
#include <NTL/LLL.h>
8
#include <NTL/tools.h>
9
10
void del_charstar(char* a) {
11
delete[] a;
12
}
13
14
15
void setup_NTL_error_callback(void (*function)(const char*, void*), void* context)
16
{
17
NTL::SetErrorCallbackFunction(function, context);
18
}
19
20
21
//////// ZZ //////////
22
23
/* Return value is only valid if the result should fit into an int.
24
AUTHOR: David Harvey (2008-06-08) */
25
int ZZ_to_int(const ZZ* x)
26
{
27
return to_int(*x);
28
}
29
30
/* Returns a *new* ZZ object.
31
AUTHOR: David Harvey (2008-06-08) */
32
struct ZZ* int_to_ZZ(int value)
33
{
34
ZZ* output = new ZZ();
35
conv(*output, value);
36
return output;
37
}
38
39
/* Copies the ZZ into the mpz_t
40
Assumes output has been mpz_init'd.
41
AUTHOR: David Harvey
42
Joel B. Mohler moved the ZZX_getitem_as_mpz code out to this function (2007-03-13) */
43
void ZZ_to_mpz(mpz_t* output, const struct ZZ* x)
44
{
45
unsigned char stack_bytes[4096];
46
int use_heap;
47
unsigned long size = NumBytes(*x);
48
use_heap = (size > sizeof(stack_bytes));
49
unsigned char* bytes = use_heap ? (unsigned char*) malloc(size) : stack_bytes;
50
BytesFromZZ(bytes, *x, size);
51
mpz_import(*output, size, -1, 1, 0, 0, bytes);
52
if (sign(*x) < 0)
53
mpz_neg(*output, *output);
54
if (use_heap)
55
free(bytes);
56
}
57
58
// Ok, I know that this is obvious
59
// I just wanted to document the appearance of the magic number 8 in the code below
60
#define bits_in_byte 8
61
62
/* Copies the mpz_t into the ZZ
63
AUTHOR: Joel B. Mohler (2007-03-15) */
64
// This should be changed to an mpz_t not an mpz_t*
65
void mpz_to_ZZ(struct ZZ* output, const mpz_t *x)
66
{
67
unsigned char stack_bytes[4096];
68
int use_heap;
69
size_t size = (mpz_sizeinbase(*x, 2) + bits_in_byte-1) / bits_in_byte;
70
use_heap = (size > sizeof(stack_bytes));
71
void* bytes = use_heap ? malloc(size) : stack_bytes;
72
size_t words_written;
73
mpz_export(bytes, &words_written, -1, 1, 0, 0, *x);
74
clear(*output);
75
ZZFromBytes(*output, (unsigned char *)bytes, words_written);
76
if (mpz_sgn(*x) < 0)
77
NTL::negate(*output, *output);
78
if (use_heap)
79
free(bytes);
80
}
81
82
/* Sets given ZZ to value
83
AUTHOR: David Harvey (2008-06-08) */
84
void ZZ_set_from_int(ZZ* x, int value)
85
{
86
conv(*x, value);
87
}
88
89
long ZZ_remove(struct ZZ &dest, const struct ZZ &src, const struct ZZ &f)
90
{
91
// Based on the code for mpz_remove
92
ZZ fpow[40]; // inexaustible...until year 2020 or so
93
ZZ x, rem;
94
long pwr;
95
int p;
96
97
if (compare(f, 1) <= 0 && compare(f, -1) >= 0)
98
Error("Division by zero");
99
100
if (compare(src, 0) == 0)
101
{
102
if (src != dest)
103
dest = src;
104
return 0;
105
}
106
107
if (compare(f, 2) == 0)
108
{
109
dest = src;
110
return MakeOdd(dest);
111
}
112
113
/* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an
114
upper bound of the result we're seeking. We could also shift down the
115
operands so that they become odd, to make intermediate values smaller. */
116
117
pwr = 0;
118
fpow[0] = ZZ(f);
119
dest = src;
120
rem = ZZ();
121
x = ZZ();
122
123
/* Divide by f, f^2, ..., f^(2^k) until we get a remainder for f^(2^k). */
124
for (p = 0;;p++)
125
{
126
DivRem(x, rem, dest, fpow[p]);
127
if (compare(rem, 0) != 0)
128
break;
129
fpow[p+1] = ZZ();
130
mul(fpow[p+1], fpow[p], fpow[p]);
131
dest = x;
132
}
133
134
pwr = (1 << p) - 1;
135
136
/* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give a
137
zero remainder. */
138
while (--p >= 0)
139
{
140
DivRem(x, rem, dest, fpow[p]);
141
if (compare(rem, 0) == 0)
142
{
143
pwr += 1 << p;
144
dest = x;
145
}
146
}
147
return pwr;
148
}
149
150
//////// ZZ_p //////////
151
152
/* Return value is only valid if the result should fit into an int.
153
AUTHOR: David Harvey (2008-06-08) */
154
int ZZ_p_to_int(const ZZ_p& x )
155
{
156
return ZZ_to_int(&rep(x));
157
}
158
159
/* Returns a *new* ZZ_p object.
160
AUTHOR: David Harvey (2008-06-08) */
161
ZZ_p int_to_ZZ_p(int value)
162
{
163
ZZ_p r;
164
r = value;
165
return r;
166
}
167
168
/* Sets given ZZ_p to value
169
AUTHOR: David Harvey (2008-06-08) */
170
void ZZ_p_set_from_int(ZZ_p* x, int value)
171
{
172
conv(*x, value);
173
}
174
175
void ZZ_p_modulus(struct ZZ* mod, const struct ZZ_p* x)
176
{
177
(*mod) = x->modulus();
178
}
179
180
struct ZZ_p* ZZ_p_pow(const struct ZZ_p* x, long e)
181
{
182
ZZ_p *z = new ZZ_p();
183
power(*z, *x, e);
184
return z;
185
}
186
187
void ntl_ZZ_set_modulus(ZZ* x)
188
{
189
ZZ_p::init(*x);
190
}
191
192
ZZ_p* ZZ_p_inv(ZZ_p* x)
193
{
194
ZZ_p *z = new ZZ_p();
195
inv(*z, *x);
196
return z;
197
}
198
199
ZZ_p* ZZ_p_random(void)
200
{
201
ZZ_p *z = new ZZ_p();
202
random(*z);
203
return z;
204
}
205
206
struct ZZ_p* ZZ_p_neg(struct ZZ_p* x)
207
{
208
return new ZZ_p(-(*x));
209
}
210
211
212
213
///////////////////////////////////////////////
214
//////// ZZX //////////
215
///////////////////////////////////////////////
216
217
char* ZZX_repr(struct ZZX* x)
218
{
219
ostringstream instore;
220
instore << (*x);
221
int n = strlen(instore.str().data());
222
char* buf = new char[n+1];
223
strcpy(buf, instore.str().data());
224
return buf;
225
}
226
227
struct ZZX* ZZX_copy(struct ZZX* x) {
228
return new ZZX(*x);
229
}
230
231
/* Sets ith coefficient of x to value.
232
AUTHOR: David Harvey (2006-06-08) */
233
void ZZX_setitem_from_int(struct ZZX* x, long i, int value)
234
{
235
SetCoeff(*x, i, value);
236
}
237
238
/* Returns ith coefficient of x.
239
Return value is only valid if the result should fit into an int.
240
AUTHOR: David Harvey (2006-06-08) */
241
int ZZX_getitem_as_int(struct ZZX* x, long i)
242
{
243
return ZZ_to_int(&coeff(*x, i));
244
}
245
246
/* Copies ith coefficient of x to output.
247
Assumes output has been mpz_init'd.
248
AUTHOR: David Harvey (2007-02) */
249
void ZZX_getitem_as_mpz(mpz_t* output, struct ZZX* x, long i)
250
{
251
const ZZ& z = coeff(*x, i);
252
ZZ_to_mpz(output, &z);
253
}
254
255
struct ZZX* ZZX_div(struct ZZX* x, struct ZZX* y, int* divisible)
256
{
257
struct ZZX* z = new ZZX();
258
*divisible = divide(*z, *x, *y);
259
return z;
260
}
261
262
263
264
void ZZX_quo_rem(struct ZZX* x, struct ZZX* other, struct ZZX** r, struct ZZX** q)
265
{
266
struct ZZX *qq = new ZZX(), *rr = new ZZX();
267
DivRem(*qq, *rr, *x, *other);
268
*r = rr; *q = qq;
269
}
270
271
272
struct ZZX* ZZX_square(struct ZZX* x)
273
{
274
struct ZZX* s = new ZZX();
275
sqr(*s, *x);
276
return s;
277
}
278
279
280
int ZZX_is_monic(struct ZZX* x)
281
{
282
return IsOne(LeadCoeff(*x));
283
}
284
285
286
struct ZZX* ZZX_neg(struct ZZX* x)
287
{
288
struct ZZX* y = new ZZX();
289
*y = -*x;
290
return y;
291
}
292
293
294
struct ZZX* ZZX_left_shift(struct ZZX* x, long n)
295
{
296
struct ZZX* y = new ZZX();
297
LeftShift(*y, *x, n);
298
return y;
299
}
300
301
302
struct ZZX* ZZX_right_shift(struct ZZX* x, long n)
303
{
304
struct ZZX* y = new ZZX();
305
RightShift(*y, *x, n);
306
return y;
307
}
308
309
struct ZZX* ZZX_primitive_part(struct ZZX* x)
310
{
311
struct ZZX* p = new ZZX();
312
PrimitivePart(*p, *x);
313
return p;
314
}
315
316
317
void ZZX_pseudo_quo_rem(struct ZZX* x, struct ZZX* y, struct ZZX** r, struct ZZX** q)
318
{
319
*r = new ZZX();
320
*q = new ZZX();
321
PseudoDivRem(**q, **r, *x, *y);
322
}
323
324
325
struct ZZX* ZZX_gcd(struct ZZX* x, struct ZZX* y)
326
{
327
struct ZZX* g = new ZZX();
328
GCD(*g, *x, *y);
329
return g;
330
}
331
332
333
void ZZX_xgcd(struct ZZX* x, struct ZZX* y, struct ZZ** r, struct ZZX** s, \
334
struct ZZX** t, int proof)
335
{
336
*r = new ZZ();
337
*s = new ZZX();
338
*t = new ZZX();
339
XGCD(**r, **s, **t, *x, *y, proof);
340
}
341
342
343
long ZZX_degree(struct ZZX* x)
344
{
345
return deg(*x);
346
}
347
348
void ZZX_set_x(struct ZZX* x)
349
{
350
SetX(*x);
351
}
352
353
354
int ZZX_is_x(struct ZZX* x)
355
{
356
return IsX(*x);
357
}
358
359
360
struct ZZX* ZZX_derivative(struct ZZX* x)
361
{
362
ZZX* d = new ZZX();
363
diff(*d, *x);
364
return d;
365
}
366
367
368
struct ZZX* ZZX_reverse(struct ZZX* x)
369
{
370
ZZX* r = new ZZX();
371
reverse(*r, *x);
372
return r;
373
}
374
375
struct ZZX* ZZX_reverse_hi(struct ZZX* x, int hi)
376
{
377
ZZX* r = new ZZX();
378
reverse(*r, *x, hi);
379
return r;
380
}
381
382
383
struct ZZX* ZZX_truncate(struct ZZX* x, long m)
384
{
385
ZZX* t = new ZZX();
386
trunc(*t, *x, m);
387
return t;
388
}
389
390
391
struct ZZX* ZZX_multiply_and_truncate(struct ZZX* x, struct ZZX* y, long m)
392
{
393
ZZX* t = new ZZX();
394
MulTrunc(*t, *x, *y, m);
395
return t;
396
}
397
398
399
struct ZZX* ZZX_square_and_truncate(struct ZZX* x, long m)
400
{
401
ZZX* t = new ZZX();
402
SqrTrunc(*t, *x, m);
403
return t;
404
}
405
406
407
struct ZZX* ZZX_invert_and_truncate(struct ZZX* x, long m)
408
{
409
ZZX* t = new ZZX();
410
InvTrunc(*t, *x, m);
411
return t;
412
}
413
414
415
struct ZZX* ZZX_multiply_mod(struct ZZX* x, struct ZZX* y, struct ZZX* modulus)
416
{
417
ZZX* p = new ZZX();
418
MulMod(*p, *x, *y, *modulus);
419
return p;
420
}
421
422
423
struct ZZ* ZZX_trace_mod(struct ZZX* x, struct ZZX* y)
424
{
425
ZZ* p = new ZZ();
426
TraceMod(*p, *x, *y);
427
return p;
428
}
429
430
431
char* ZZX_trace_list(struct ZZX* x)
432
{
433
vec_ZZ v;
434
TraceVec(v, *x);
435
ostringstream instore;
436
instore << v;
437
int n = strlen(instore.str().data());
438
char* buf = new char[n+1];
439
strcpy(buf, instore.str().data());
440
return buf;
441
}
442
443
444
struct ZZ* ZZX_resultant(struct ZZX* x, struct ZZX* y, int proof)
445
{
446
ZZ* res = new ZZ();
447
resultant(*res, *x, *y, proof);
448
return res;
449
}
450
451
452
struct ZZ* ZZX_norm_mod(struct ZZX* x, struct ZZX* y, int proof)
453
{
454
ZZ* res = new ZZ();
455
NormMod(*res, *x, *y, proof);
456
return res;
457
}
458
459
460
struct ZZ* ZZX_discriminant(struct ZZX* x, int proof)
461
{
462
ZZ* d = new ZZ();
463
discriminant(*d, *x, proof);
464
return d;
465
}
466
467
468
struct ZZX* ZZX_charpoly_mod(struct ZZX* x, struct ZZX* y, int proof)
469
{
470
ZZX* f = new ZZX();
471
CharPolyMod(*f, *x, *y, proof);
472
return f;
473
}
474
475
476
struct ZZX* ZZX_minpoly_mod(struct ZZX* x, struct ZZX* y)
477
{
478
ZZX* f = new ZZX();
479
MinPolyMod(*f, *x, *y);
480
return f;
481
}
482
483
484
void ZZX_clear(struct ZZX* x)
485
{
486
clear(*x);
487
}
488
489
490
void ZZX_preallocate_space(struct ZZX* x, long n)
491
{
492
x->SetMaxLength(n);
493
}
494
495
/*
496
EXTERN struct ZZ* ZZX_polyeval(struct ZZX* f, struct ZZ* a)
497
{
498
ZZ* b = new ZZ();
499
*b = PolyEval(*f, *a);
500
return b;
501
}
502
*/
503
504
void ZZX_squarefree_decomposition(struct ZZX*** v, long** e, long* n, struct ZZX* x)
505
{
506
vec_pair_ZZX_long factors;
507
SquareFreeDecomp(factors, *x);
508
*n = factors.length();
509
*v = (ZZX**) malloc(sizeof(ZZX*) * (*n));
510
*e = (long*) malloc(sizeof(long) * (*n));
511
for (long i = 0; i < (*n); i++) {
512
(*v)[i] = new ZZX(factors[i].a);
513
(*e)[i] = factors[i].b;
514
}
515
}
516
517
///////////////////////////////////////////////
518
//////// ZZ_pX //////////
519
///////////////////////////////////////////////
520
521
// char* ZZ_pX_repr(struct ZZ_pX* x)
522
// {
523
// ostringstream instore;
524
// instore << (*x);
525
// int n = strlen(instore.str().data());
526
// char* buf = new char[n+1];
527
// strcpy(buf, instore.str().data());
528
// return buf;
529
// }
530
531
// void ZZ_pX_dealloc(struct ZZ_pX* x) {
532
// delete x;
533
// }
534
535
// struct ZZ_pX* ZZ_pX_copy(struct ZZ_pX* x) {
536
// return new ZZ_pX(*x);
537
// }
538
539
// /* Sets ith coefficient of x to value.
540
// AUTHOR: David Harvey (2008-06-08) */
541
// void ZZ_pX_setitem_from_int(struct ZZ_pX* x, long i, int value)
542
// {
543
// SetCoeff(*x, i, value);
544
// }
545
546
// /* Returns ith coefficient of x.
547
// Return value is only valid if the result should fit into an int.
548
// AUTHOR: David Harvey (2008-06-08) */
549
// int ZZ_pX_getitem_as_int(struct ZZ_pX* x, long i)
550
// {
551
// return ZZ_to_int(&rep(coeff(*x, i)));
552
// }
553
554
// struct ZZ_pX* ZZ_pX_add(struct ZZ_pX* x, struct ZZ_pX* y)
555
// {
556
// ZZ_pX *z = new ZZ_pX();
557
// add(*z, *x, *y);
558
// return z;
559
// }
560
561
// struct ZZ_pX* ZZ_pX_sub(struct ZZ_pX* x, struct ZZ_pX* y)
562
// {
563
// ZZ_pX *z = new ZZ_pX();
564
// sub(*z, *x, *y);
565
// return z;
566
// }
567
568
// struct ZZ_pX* ZZ_pX_mul(struct ZZ_pX* x, struct ZZ_pX* y)
569
// {
570
// ZZ_pX *z = new ZZ_pX();
571
// mul(*z, *x, *y);
572
// return z;
573
// }
574
575
576
// struct ZZ_pX* ZZ_pX_div(struct ZZ_pX* x, struct ZZ_pX* y, int* divisible)
577
// {
578
// struct ZZ_pX* z = new ZZ_pX();
579
// *divisible = divide(*z, *x, *y);
580
// return z;
581
// }
582
583
584
// struct ZZ_pX* ZZ_pX_mod(struct ZZ_pX* x, struct ZZ_pX* y)
585
// {
586
// struct ZZ_pX* z = new ZZ_pX();
587
// rem(*z, *x, *y);
588
// return z;
589
// }
590
591
592
593
// void ZZ_pX_quo_rem(struct ZZ_pX* x, struct ZZ_pX* y, struct ZZ_pX** r, struct ZZ_pX** q)
594
// {
595
// *r = new ZZ_pX();
596
// *q = new ZZ_pX();
597
// DivRem(**q, **r, *x, *y);
598
// }
599
600
601
// struct ZZ_pX* ZZ_pX_square(struct ZZ_pX* x)
602
// {
603
// struct ZZ_pX* s = new ZZ_pX();
604
// sqr(*s, *x);
605
// return s;
606
// }
607
608
609
610
// int ZZ_pX_is_monic(struct ZZ_pX* x)
611
// {
612
// IsOne(LeadCoeff(*x));
613
// }
614
615
616
// struct ZZ_pX* ZZ_pX_neg(struct ZZ_pX* x)
617
// {
618
// struct ZZ_pX* y = new ZZ_pX();
619
// *y = -*x;
620
// return y;
621
// }
622
623
624
// struct ZZ_pX* ZZ_pX_left_shift(struct ZZ_pX* x, long n)
625
// {
626
// struct ZZ_pX* y = new ZZ_pX();
627
// LeftShift(*y, *x, n);
628
// return y;
629
// }
630
631
632
// struct ZZ_pX* ZZ_pX_right_shift(struct ZZ_pX* x, long n)
633
// {
634
// struct ZZ_pX* y = new ZZ_pX();
635
// RightShift(*y, *x, n);
636
// return y;
637
// }
638
639
640
641
// struct ZZ_pX* ZZ_pX_gcd(struct ZZ_pX* x, struct ZZ_pX* y)
642
// {
643
// struct ZZ_pX* g = new ZZ_pX();
644
// GCD(*g, *x, *y);
645
// return g;
646
// }
647
648
649
// void ZZ_pX_xgcd(struct ZZ_pX** d, struct ZZ_pX** s, struct ZZ_pX** t, struct ZZ_pX* a, struct ZZ_pX* b)
650
// {
651
// *d = new ZZ_pX();
652
// *s = new ZZ_pX();
653
// *t = new ZZ_pX();
654
// XGCD(**d, **s, **t, *a, *b);
655
// }
656
657
// void ZZ_pX_plain_xgcd(struct ZZ_pX** d, struct ZZ_pX** s, struct ZZ_pX** t, struct ZZ_pX* a, struct ZZ_pX* b)
658
// {
659
// *d = new ZZ_pX();
660
// *s = new ZZ_pX();
661
// *t = new ZZ_pX();
662
// PlainXGCD(**d, **s, **t, *a, *b);
663
// }
664
665
// ZZ_p* ZZ_pX_leading_coefficient(struct ZZ_pX* x)
666
// {
667
// return new ZZ_p(LeadCoeff(*x));
668
// }
669
670
671
// void ZZ_pX_set_x(struct ZZ_pX* x)
672
// {
673
// SetX(*x);
674
// }
675
676
677
// int ZZ_pX_is_x(struct ZZ_pX* x)
678
// {
679
// return IsX(*x);
680
// }
681
682
683
// struct ZZ_pX* ZZ_pX_derivative(struct ZZ_pX* x)
684
// {
685
// ZZ_pX* d = new ZZ_pX();
686
// diff(*d, *x);
687
// return d;
688
// }
689
690
691
// struct ZZ_pX* ZZ_pX_reverse(struct ZZ_pX* x)
692
// {
693
// ZZ_pX* r = new ZZ_pX();
694
// reverse(*r, *x);
695
// return r;
696
// }
697
698
// struct ZZ_pX* ZZ_pX_reverse_hi(struct ZZ_pX* x, int hi)
699
// {
700
// ZZ_pX* r = new ZZ_pX();
701
// reverse(*r, *x, hi);
702
// return r;
703
// }
704
705
706
// struct ZZ_pX* ZZ_pX_truncate(struct ZZ_pX* x, long m)
707
// {
708
// ZZ_pX* t = new ZZ_pX();
709
// trunc(*t, *x, m);
710
// return t;
711
// }
712
713
714
// struct ZZ_pX* ZZ_pX_multiply_and_truncate(struct ZZ_pX* x, struct ZZ_pX* y, long m)
715
// {
716
// ZZ_pX* t = new ZZ_pX();
717
// MulTrunc(*t, *x, *y, m);
718
// return t;
719
// }
720
721
722
// struct ZZ_pX* ZZ_pX_square_and_truncate(struct ZZ_pX* x, long m)
723
// {
724
// ZZ_pX* t = new ZZ_pX();
725
// SqrTrunc(*t, *x, m);
726
// return t;
727
// }
728
729
730
// struct ZZ_pX* ZZ_pX_invert_and_truncate(struct ZZ_pX* x, long m)
731
// {
732
// ZZ_pX* t = new ZZ_pX();
733
// InvTrunc(*t, *x, m);
734
// return t;
735
// }
736
737
738
// struct ZZ_pX* ZZ_pX_multiply_mod(struct ZZ_pX* x, struct ZZ_pX* y, struct ZZ_pX* modulus)
739
// {
740
// ZZ_pX* p = new ZZ_pX();
741
// MulMod(*p, *x, *y, *modulus);
742
// return p;
743
// }
744
745
746
// struct ZZ_p* ZZ_pX_trace_mod(struct ZZ_pX* x, struct ZZ_pX* y)
747
// {
748
// ZZ_p* p = new ZZ_p();
749
// TraceMod(*p, *x, *y);
750
// return p;
751
// }
752
753
754
char* ZZ_pX_trace_list(struct ZZ_pX* x)
755
{
756
vec_ZZ_p v;
757
TraceVec(v, *x);
758
ostringstream instore;
759
instore << v;
760
int n = strlen(instore.str().data());
761
char* buf = new char[n+1];
762
strcpy(buf, instore.str().data());
763
return buf;
764
}
765
766
767
// struct ZZ_p* ZZ_pX_resultant(struct ZZ_pX* x, struct ZZ_pX* y)
768
// {
769
// ZZ_p* res = new ZZ_p();
770
// resultant(*res, *x, *y);
771
// return res;
772
// }
773
774
775
// struct ZZ_p* ZZ_pX_norm_mod(struct ZZ_pX* x, struct ZZ_pX* y)
776
// {
777
// ZZ_p* res = new ZZ_p();
778
// NormMod(*res, *x, *y);
779
// return res;
780
// }
781
782
783
784
// struct ZZ_pX* ZZ_pX_charpoly_mod(struct ZZ_pX* x, struct ZZ_pX* y)
785
// {
786
// ZZ_pX* f = new ZZ_pX();
787
// CharPolyMod(*f, *x, *y);
788
// return f;
789
// }
790
791
792
// struct ZZ_pX* ZZ_pX_minpoly_mod(struct ZZ_pX* x, struct ZZ_pX* y)
793
// {
794
// ZZ_pX* f = new ZZ_pX();
795
// MinPolyMod(*f, *x, *y);
796
// return f;
797
// }
798
799
800
// void ZZ_pX_clear(struct ZZ_pX* x)
801
// {
802
// clear(*x);
803
// }
804
805
806
// void ZZ_pX_preallocate_space(struct ZZ_pX* x, long n)
807
// {
808
// x->SetMaxLength(n);
809
// }
810
811
void ZZ_pX_factor(struct ZZ_pX*** v, long** e, long* n, struct ZZ_pX* x, long verbose)
812
{
813
long i;
814
vec_pair_ZZ_pX_long factors;
815
berlekamp(factors, *x, verbose);
816
*n = factors.length();
817
*v = (ZZ_pX**) malloc(sizeof(ZZ_pX*) * (*n));
818
*e = (long*) malloc(sizeof(long)*(*n));
819
for (i=0; i<(*n); i++) {
820
(*v)[i] = new ZZ_pX(factors[i].a);
821
(*e)[i] = factors[i].b;
822
}
823
}
824
825
void ZZ_pX_linear_roots(struct ZZ_p*** v, long* n, struct ZZ_pX* f)
826
{
827
long i;
828
// printf("1\n");
829
vec_ZZ_p w;
830
FindRoots(w, *f);
831
// printf("2\n");
832
*n = w.length();
833
// printf("3 %d\n",*n);
834
(*v) = (ZZ_p**) malloc(sizeof(ZZ_p*)*(*n));
835
for (i=0; i<(*n); i++) {
836
(*v)[i] = new ZZ_p(w[i]);
837
}
838
}
839
840
/////////// ZZ_pE //////////////
841
842
struct ZZ_pX ZZ_pE_to_ZZ_pX(struct ZZ_pE x)
843
{
844
return ZZ_pX(rep(x));
845
}
846
847
848
849
//////// mat_ZZ //////////
850
851
void mat_ZZ_SetDims(struct mat_ZZ* mZZ, long nrows, long ncols){
852
mZZ->SetDims(nrows, ncols);
853
}
854
855
struct mat_ZZ* mat_ZZ_pow(const struct mat_ZZ* x, long e)
856
{
857
mat_ZZ *z = new mat_ZZ();
858
power(*z, *x, e);
859
return z;
860
}
861
862
long mat_ZZ_nrows(const struct mat_ZZ* x)
863
{
864
return x->NumRows();
865
}
866
867
868
long mat_ZZ_ncols(const struct mat_ZZ* x)
869
{
870
return x->NumCols();
871
}
872
873
void mat_ZZ_setitem(struct mat_ZZ* x, int i, int j, const struct ZZ* z)
874
{
875
(*x)[i][j] = *z;
876
877
}
878
879
struct ZZ* mat_ZZ_getitem(const struct mat_ZZ* x, int i, int j)
880
{
881
return new ZZ((*x)(i,j));
882
}
883
884
struct ZZ* mat_ZZ_determinant(const struct mat_ZZ* x, long deterministic)
885
{
886
ZZ* d = new ZZ();
887
determinant(*d, *x, deterministic);
888
return d;
889
}
890
891
struct mat_ZZ* mat_ZZ_HNF(const struct mat_ZZ* A, const struct ZZ* D)
892
{
893
struct mat_ZZ* W = new mat_ZZ();
894
HNF(*W, *A, *D);
895
return W;
896
}
897
898
long mat_ZZ_LLL(struct ZZ **det, struct mat_ZZ *x, long a, long b, long verbose)
899
{
900
*det = new ZZ();
901
return LLL(**det,*x,a,b,verbose);
902
}
903
904
long mat_ZZ_LLL_U(struct ZZ **det, struct mat_ZZ *x, struct mat_ZZ *U, long a, long b, long verbose)
905
{
906
*det = new ZZ();
907
return LLL(**det,*x,*U,a,b,verbose);
908
}
909
910
911
struct ZZX* mat_ZZ_charpoly(const struct mat_ZZ* A)
912
{
913
ZZX* f = new ZZX();
914
CharPoly(*f, *A);
915
return f;
916
}
917
918
/**
919
* GF2EContext
920
*/
921
922
GF2EContext* GF2EContext_construct(void *mem, const GF2X *p)
923
{
924
return new(mem) GF2EContext(*p);
925
}
926
927
928
GF2EContext* GF2EContext_new(const GF2X *p)
929
{
930
return new GF2EContext(*p);
931
}
932
933
934
void mat_GF2E_setitem(struct mat_GF2E* x, int i, int j, const struct GF2E* z)
935
{
936
(*x)[i][j] = *z;
937
}
938
939
void mat_GF2_setitem(struct mat_GF2* x, int i, int j, const struct GF2* z)
940
{
941
(*x)[i][j] = *z;
942
}
943
944
/**
945
* ZZ_pContext
946
*/
947
948
ZZ_pContext* ZZ_pContext_new(ZZ *p)
949
{
950
return new ZZ_pContext(*p);
951
}
952
953
ZZ_pContext* ZZ_pContext_construct(void *mem, ZZ *p)
954
{
955
return new(mem) ZZ_pContext(*p);
956
}
957
958
void ZZ_pContext_restore(ZZ_pContext *ctx)
959
{
960
ctx->restore();
961
}
962
963
// Functions for using ZZ_pX's for p-adic extensions
964
965
void ZZ_pX_conv_modulus(ZZ_pX &fout, const ZZ_pX &fin, const ZZ_pContext &modout)
966
{
967
// Changes the modulus of fin to modout, and puts the result in fout.
968
long i, n;
969
970
n = fin.rep.length();
971
fout.rep.SetLength(n);
972
973
ZZ_p* xp = fout.rep.elts();
974
const ZZ_p* ap = fin.rep.elts();
975
976
// I think it's enough to just restore modout once.
977
// This should be true as long as the function rep taking a ZZ_p as an argument
978
// and returning a ZZ works when the ZZ_p::modulus is incorrect.
979
modout.restore();
980
981
for (i = 0; i < n; i++)
982
{
983
conv(xp[i], rep(ap[i]));
984
}
985
986
// We may have set a leading coefficient to 0, so we have to normalize
987
fout.normalize();
988
}
989
990
void ZZ_pEX_conv_modulus(ZZ_pEX &fout, const ZZ_pEX &fin, const ZZ_pContext &modout)
991
{
992
// Changes the modulus of fin to modout, and puts the result in fout.
993
long i, n, j, m;
994
995
n = fin.rep.length();
996
fout.rep.SetLength(n);
997
998
ZZ_pE* outpe = fout.rep.elts();
999
const ZZ_pE* inpe = fin.rep.elts();
1000
1001
ZZ_p* xp;
1002
const ZZ_p* ap;
1003
// I think it's enough to just restore modout once
1004
// This should be true as long as Loophole() offers access to
1005
// the underlying ZZ_pX representations of ZZ_pEs,
1006
// and rep of a ZZ_p (giving a ZZ) works even if the ZZ_p::modulus is
1007
// incorrect
1008
modout.restore();
1009
1010
for (i = 0; i < n; i++)
1011
{
1012
m = rep(inpe[i]).rep.length();
1013
outpe[i]._ZZ_pE__rep.rep.SetLength(m);
1014
1015
xp = outpe[i]._ZZ_pE__rep.rep.elts();
1016
ap = rep(inpe[i]).rep.elts();
1017
1018
for (j = 0; j < m; j++)
1019
conv(xp[j], rep(ap[j]));
1020
1021
// We may have set a leading coefficient to 0, so we have to normalize
1022
outpe[i]._ZZ_pE__rep.normalize();
1023
}
1024
// We may have set a leading coefficient to 0, so we have to normalize
1025
fout.normalize();
1026
}
1027
1028
void ZZ_pX_min_val_coeff(long & valuation, long &index, const struct ZZ_pX &f, const struct ZZ &p)
1029
{
1030
// Sets index, where the indexth coefficient of f has the minimum p-adic valuation.
1031
// Sets valuation to be this valuation.
1032
// If there are ties, index will be the lowest of the tied indices
1033
// This only makes mathematical sense when p divides the modulus of f.
1034
long i, n, v;
1035
1036
n = f.rep.length();
1037
if (n == 0)
1038
{
1039
index = -1;
1040
return;
1041
}
1042
1043
const ZZ_p* fp = f.rep.elts();
1044
ZZ *u = new ZZ();
1045
1046
valuation = -1;
1047
i = 0;
1048
1049
while (valuation == -1)
1050
{
1051
if (rep(fp[i]) != 0)
1052
{
1053
index = i;
1054
valuation = ZZ_remove(*u, rep(fp[i]), p);
1055
}
1056
i++;
1057
}
1058
for (; i < n; i++)
1059
{
1060
if (rep(fp[i]) != 0)
1061
{
1062
v = ZZ_remove(*u, rep(fp[i]), p);
1063
if (v < valuation)
1064
{
1065
valuation = v;
1066
index = i;
1067
}
1068
}
1069
}
1070
delete u;
1071
}
1072
1073
long ZZ_pX_get_val_coeff(const struct ZZ_pX &f, const struct ZZ &p, long i)
1074
{
1075
// Gets the p-adic valuation of the ith coefficient of f.
1076
ZZ *u = new ZZ();
1077
long ans = ZZ_remove(*u, rep(coeff(f, i)), p);
1078
delete u;
1079
return ans;
1080
}
1081
1082
void ZZ_pX_left_pshift(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ &pn, const struct ZZ_pContext &c)
1083
{
1084
// Multiplies each coefficient by pn, and sets the context of the answer to c.
1085
1086
long i, n;
1087
1088
n = a.rep.length();
1089
x.rep.SetLength(n);
1090
1091
ZZ_p* xp = x.rep.elts();
1092
const ZZ_p* ap = a.rep.elts();
1093
1094
// I think it's enough to just restore modout once.
1095
// This should be true as long as the function rep taking a ZZ_p as an argument
1096
// and returning a ZZ works when the ZZ_p::modulus is incorrect.
1097
c.restore();
1098
1099
for (i = 0; i < n; i++)
1100
{
1101
conv(xp[i], rep(ap[i]) * pn);
1102
}
1103
1104
// We may have set a leading coefficient to 0, so we have to normalize
1105
x.normalize();
1106
}
1107
1108
void ZZ_pX_right_pshift(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ &pn, const struct ZZ_pContext &c)
1109
{
1110
// Divides each coefficient by pn, and sets the context of the answer to c.
1111
1112
long i, n;
1113
1114
n = a.rep.length();
1115
x.rep.SetLength(n);
1116
1117
ZZ_p* xp = x.rep.elts();
1118
const ZZ_p* ap = a.rep.elts();
1119
1120
// I think it's enough to just restore modout once.
1121
// This should be true as long as the function rep taking a ZZ_p as an argument
1122
// and returning a ZZ works when the ZZ_p::modulus is incorrect.
1123
c.restore();
1124
1125
for (i = 0; i < n; i++)
1126
{
1127
conv(xp[i], rep(ap[i]) / pn);
1128
}
1129
1130
// We may have set a leading coefficient to 0, so we have to normalize
1131
x.normalize();
1132
}
1133
1134
void ZZ_pX_InvMod_newton_unram(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ_pXModulus &F, const struct ZZ_pContext &cpn, const struct ZZ_pContext &cp)
1135
{
1136
//int j;
1137
cp.restore();
1138
ZZ_pX *amodp = new ZZ_pX();
1139
ZZ_pX *xmodp = new ZZ_pX();
1140
ZZ_pX *fmodp = new ZZ_pX();
1141
ZZ_pX_conv_modulus(*amodp, a, cp);
1142
ZZ_pX_conv_modulus(*fmodp, F.val(), cp);
1143
InvMod(*xmodp, *amodp, *fmodp);
1144
//cout << "xmodp: " << *xmodp << "\namodp: " << *amodp << "\nfmodp: " << *fmodp << "\n";
1145
cpn.restore();
1146
ZZ_pX *minusa = new ZZ_pX();
1147
ZZ_pX *xn = new ZZ_pX();
1148
ZZ_pX_conv_modulus(*xn, *xmodp, cpn);
1149
NTL::negate(*minusa, a);
1150
while (1 > 0)
1151
{
1152
// x_n = 2*x_{n-1} - a*x_{n-1}^2 = (2 - a*x_{n-1})*x_{n-1}
1153
MulMod(x, *minusa, *xn, F);
1154
SetCoeff(x, 0, ConstTerm(x) + 2);
1155
MulMod(x, x, *xn, F);
1156
if (x == *xn)
1157
break;
1158
*xn = x;
1159
//cout << "x: " << x << "\nxn: " << *xn << "\n";
1160
//cin >> j;
1161
}
1162
delete amodp;
1163
delete xmodp;
1164
delete fmodp;
1165
delete minusa;
1166
delete xn;
1167
}
1168
1169
void ZZ_pX_InvMod_newton_ram(struct ZZ_pX &x, const struct ZZ_pX &a, const struct ZZ_pXModulus &F, const struct ZZ_pContext &cpn)
1170
{
1171
//int j;
1172
cpn.restore();
1173
ZZ_pX *minusa = new ZZ_pX();
1174
ZZ_pX *xn = new ZZ_pX();
1175
SetCoeff(*xn, 0, inv(ConstTerm(a)));
1176
NTL::negate(*minusa, a);
1177
while (1 > 0)
1178
{
1179
// x_n = 2*x_{n-1} - a*x_{n-1}^2 = (2 - a*x_{n-1})*x_{n-1}
1180
MulMod(x, *minusa, *xn, F);
1181
SetCoeff(x, 0, ConstTerm(x) + 2);
1182
MulMod(x, x, *xn, F);
1183
//cout << "x: " << x << "\nxn: " << *xn << "\n";
1184
if (x == *xn)
1185
break;
1186
*xn = x;
1187
//cin >> j;
1188
}
1189
delete minusa;
1190
delete xn;
1191
}
1192
1193
/**
1194
* ZZ_pEContext
1195
*/
1196
1197
ZZ_pEContext* ZZ_pEContext_new(ZZ_pX *f)
1198
{
1199
return new ZZ_pEContext(*f);
1200
}
1201
1202
ZZ_pEContext* ZZ_pEContext_construct(void *mem, ZZ_pX *f)
1203
{
1204
return new(mem) ZZ_pEContext(*f);
1205
}
1206
1207
void ZZ_pEContext_restore(ZZ_pEContext *ctx)
1208
{
1209
ctx->restore();
1210
}
1211
1212
/**
1213
* zz_pContext
1214
*/
1215
1216
zz_pContext* zz_pContext_new(long p)
1217
{
1218
return new zz_pContext(p);
1219
}
1220
1221
zz_pContext* zz_pContext_construct(void *mem, long p)
1222
{
1223
return new(mem) zz_pContext(p);
1224
}
1225
1226
void zz_pContext_restore(zz_pContext *ctx)
1227
{
1228
ctx->restore();
1229
}
1230
1231