source: git/ntl/doc/lzz_pX.txt @ 26e030

spielwiese
Last change on this file since 26e030 was 2cfffe, checked in by Hans Schönemann <hannes@…>, 21 years ago
This commit was generated by cvs2svn to compensate for changes in r6316, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6317 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 24.7 KB
Line 
1
2/**************************************************************************\
3
4MODULE: zz_pX
5
6SUMMARY:
7
8The class zz_pX implements polynomial arithmetic modulo p.
9
10Polynomial arithmetic is implemented using a combination of classical
11routines, Karatsuba, and FFT.
12
13\**************************************************************************/
14
15#include "zz_p.h"
16#include "vec_zz_p.h"
17
18class zz_pX {
19public:
20
21   zz_pX(); // initial value 0
22
23   zz_pX(const zz_pX& a); // copy
24
25   zz_pX& operator=(const zz_pX& a); // assignment
26   zz_pX& operator=(zz_p a);
27   zz_pX& operator=(long a);
28
29   ~zz_pX(); // destructor
30
31   zz_pX(long i, zz_p c); // initialize to X^i*c
32   zz_pX(long i, long c);
33   
34};
35
36
37
38
39
40/**************************************************************************\
41
42                                  Comparison
43
44\**************************************************************************/
45
46
47long operator==(const zz_pX& a, const zz_pX& b);
48long operator!=(const zz_pX& a, const zz_pX& b);
49
50long IsZero(const zz_pX& a); // test for 0
51long IsOne(const zz_pX& a); // test for 1
52
53// PROMOTIONS: operators ==, != promote {long, zz_p} to zz_pX on (a, b)
54
55
56/**************************************************************************\
57
58                                   Addition
59
60\**************************************************************************/
61
62// operator notation:
63
64zz_pX operator+(const zz_pX& a, const zz_pX& b);
65zz_pX operator-(const zz_pX& a, const zz_pX& b);
66
67zz_pX operator-(const zz_pX& a); // unary -
68
69zz_pX& operator+=(zz_pX& x, const zz_pX& a);
70zz_pX& operator+=(zz_pX& x, zz_p a);
71zz_pX& operator+=(zz_pX& x, long a);
72
73zz_pX& operator-=(zz_pX& x, const zz_pX& a);
74zz_pX& operator-=(zz_pX& x, zz_p a);
75zz_pX& operator-=(zz_pX& x, long a);
76
77zz_pX& operator++(zz_pX& x);  // prefix
78void operator++(zz_pX& x, int);  // postfix
79
80zz_pX& operator--(zz_pX& x);  // prefix
81void operator--(zz_pX& x, int);  // postfix
82
83// procedural versions:
84
85
86void add(zz_pX& x, const zz_pX& a, const zz_pX& b); // x = a + b
87void sub(zz_pX& x, const zz_pX& a, const zz_pX& b); // x = a - b
88void negate(zz_pX& x, const zz_pX& a); // x = -a
89
90// PROMOTIONS: binary +, - and procedures add, sub promote {long, zz_p}
91// to zz_pX on (a, b).
92
93
94/**************************************************************************\
95
96                               Multiplication
97
98\**************************************************************************/
99
100// operator notation:
101
102zz_pX operator*(const zz_pX& a, const zz_pX& b);
103
104zz_pX& operator*=(zz_pX& x, const zz_pX& a);
105zz_pX& operator*=(zz_pX& x, zz_p a);
106zz_pX& operator*=(zz_pX& x, long a);
107
108// procedural versions:
109
110
111void mul(zz_pX& x, const zz_pX& a, const zz_pX& b); // x = a * b
112
113void sqr(zz_pX& x, const zz_pX& a); // x = a^2
114zz_pX sqr(const zz_pX& a);
115
116// PROMOTIONS: operator * and procedure mul promote {long, zz_p} to zz_pX
117// on (a, b).
118
119void power(zz_pX& x, const zz_pX& a, long e);  // x = a^e (e >= 0)
120zz_pX power(const zz_pX& a, long e);
121
122
123/**************************************************************************\
124
125                               Shift Operations
126
127LeftShift by n means multiplication by X^n
128RightShift by n means division by X^n
129
130A negative shift amount reverses the direction of the shift.
131
132\**************************************************************************/
133
134// operator notation:
135
136zz_pX operator<<(const zz_pX& a, long n);
137zz_pX operator>>(const zz_pX& a, long n);
138
139zz_pX& operator<<=(zz_pX& x, long n);
140zz_pX& operator>>=(zz_pX& x, long n);
141
142// procedural versions:
143
144void LeftShift(zz_pX& x, const zz_pX& a, long n);
145zz_pX LeftShift(const zz_pX& a, long n);
146
147void RightShift(zz_pX& x, const zz_pX& a, long n);
148zz_pX RightShift(const zz_pX& a, long n);
149
150
151
152/**************************************************************************\
153
154                                  Division
155
156\**************************************************************************/
157
158// operator notation:
159
160zz_pX operator/(const zz_pX& a, const zz_pX& b);
161zz_pX operator%(const zz_pX& a, const zz_pX& b);
162
163zz_pX& operator/=(zz_pX& x, const zz_pX& a);
164zz_pX& operator/=(zz_pX& x, zz_p a);
165zz_pX& operator/=(zz_pX& x, long a);
166
167zz_pX& operator%=(zz_pX& x, const zz_pX& b);
168
169
170// procedural versions:
171
172
173void DivRem(zz_pX& q, zz_pX& r, const zz_pX& a, const zz_pX& b);
174// q = a/b, r = a%b
175
176void div(zz_pX& q, const zz_pX& a, const zz_pX& b);
177// q = a/b
178
179void rem(zz_pX& r, const zz_pX& a, const zz_pX& b);
180// r = a%b
181
182long divide(zz_pX& q, const zz_pX& a, const zz_pX& b);
183// if b | a, sets q = a/b and returns 1; otherwise returns 0
184
185long divide(const zz_pX& a, const zz_pX& b);
186// if b | a, sets q = a/b and returns 1; otherwise returns 0
187
188// PROMOTIONS: operator / and procedure div promote {long, zz_p} to zz_pX
189// on (a, b).
190
191
192/**************************************************************************\
193
194                                   GCD's
195
196These routines are intended for use when p is prime.
197
198\**************************************************************************/
199
200
201void GCD(zz_pX& x, const zz_pX& a, const zz_pX& b);
202zz_pX GCD(const zz_pX& a, const zz_pX& b);
203// x = GCD(a, b),  x is always monic (or zero if a==b==0).
204
205
206void XGCD(zz_pX& d, zz_pX& s, zz_pX& t, const zz_pX& a, const zz_pX& b);
207// d = gcd(a,b), a s + b t = d
208
209
210// NOTE: A classical algorithm is used, switching over to a
211// "half-GCD" algorithm for large degree
212
213
214/**************************************************************************\
215
216                                  Input/Output
217
218I/O format:
219
220   [a_0 a_1 ... a_n],
221
222represents the polynomial a_0 + a_1*X + ... + a_n*X^n.
223
224On output, all coefficients will be integers between 0 and p-1, amd
225a_n not zero (the zero polynomial is [ ]).  On input, the coefficients
226are arbitrary integers which are reduced modulo p, and leading zeros
227stripped.
228
229\**************************************************************************/
230
231istream& operator>>(istream& s, zz_pX& x);
232ostream& operator<<(ostream& s, const zz_pX& a);
233
234
235/**************************************************************************\
236
237                              Some utility routines
238
239\**************************************************************************/
240
241long deg(const zz_pX& a);  // return deg(a); deg(0) == -1.
242
243zz_p coeff(const zz_pX& a, long i);
244// returns the coefficient of X^i, or zero if i not in range
245
246zz_p LeadCoeff(const zz_pX& a);
247// returns leading term of a, or zero if a == 0
248
249zz_p ConstTerm(const zz_pX& a);
250// returns constant term of a, or zero if a == 0
251
252void SetCoeff(zz_pX& x, long i, zz_p a);
253void SetCoeff(zz_pX& x, long i, long a);
254// makes coefficient of X^i equal to a; error is raised if i < 0
255
256void SetCoeff(zz_pX& x, long i);
257// makes coefficient of X^i equal to 1;  error is raised if i < 0
258
259void SetX(zz_pX& x); // x is set to the monomial X
260
261long IsX(const zz_pX& a); // test if x = X
262
263void diff(zz_pX& x, const zz_pX& a);
264zz_pX diff(const zz_pX& a);
265// x = derivative of a
266
267
268void MakeMonic(zz_pX& x);
269// if x != 0 makes x into its monic associate; LeadCoeff(x) must be
270// invertible in this case.
271
272void reverse(zz_pX& x, const zz_pX& a, long hi);
273zz_pX reverse(const zz_pX& a, long hi);
274
275void reverse(zz_pX& x, const zz_pX& a);
276zz_pX reverse(const zz_pX& a);
277
278// x = reverse of a[0]..a[hi] (hi >= -1);
279// hi defaults to deg(a) in second version
280
281void VectorCopy(vec_zz_p& x, const zz_pX& a, long n);
282vec_zz_p VectorCopy(const zz_pX& a, long n);
283// x = copy of coefficient vector of a of length exactly n.
284// input is truncated or padded with zeroes as appropriate.
285
286
287
288
289
290/**************************************************************************\
291
292                             Random Polynomials
293
294\**************************************************************************/
295
296void random(zz_pX& x, long n);
297zz_pX random_zz_pX(long n);
298// x = random polynomial of degree < n
299
300
301/**************************************************************************\
302
303                    Polynomial Evaluation and related problems
304
305\**************************************************************************/
306
307
308void BuildFromRoots(zz_pX& x, const vec_zz_p& a);
309zz_pX BuildFromRoots(const vec_zz_p& a);
310// computes the polynomial (X-a[0]) ... (X-a[n-1]), where n =
311// a.length()
312
313void eval(zz_p& b, const zz_pX& f, zz_p a);
314zz_p eval(const zz_pX& f, zz_p a);
315// b = f(a)
316
317void eval(vec_zz_p& b, const zz_pX& f, const vec_zz_p& a);
318vec_zz_p eval(const zz_pX& f, const vec_zz_p& a);
319//  b.SetLength(a.length());  b[i] = f(a[i]) for 0 <= i < a.length()
320
321void interpolate(zz_pX& f, const vec_zz_p& a, const vec_zz_p& b);
322zz_pX interpolate(const vec_zz_p& a, const vec_zz_p& b);
323// interpolates the polynomial f satisfying f(a[i]) = b[i].  p should
324// be prime.
325
326/**************************************************************************\
327
328                       Arithmetic mod X^n
329
330It is required that n >= 0, otherwise an error is raised.
331
332\**************************************************************************/
333
334void trunc(zz_pX& x, const zz_pX& a, long n); // x = a % X^n
335zz_pX trunc(const zz_pX& a, long n);
336
337void MulTrunc(zz_pX& x, const zz_pX& a, const zz_pX& b, long n);
338zz_pX MulTrunc(const zz_pX& a, const zz_pX& b, long n);
339// x = a * b % X^n
340
341void SqrTrunc(zz_pX& x, const zz_pX& a, long n);
342zz_pX SqrTrunc(const zz_pX& a, long n);
343// x = a^2 % X^n
344
345void InvTrunc(zz_pX& x, const zz_pX& a, long n);
346zz_pX InvTrunc(const zz_pX& a, long n);
347// computes x = a^{-1} % X^n.  Must have ConstTerm(a) invertible.
348
349/**************************************************************************\
350
351                Modular Arithmetic (without pre-conditioning)
352
353Arithmetic mod f.
354
355All inputs and outputs are polynomials of degree less than deg(f), and
356deg(f) > 0.
357
358NOTE: if you want to do many computations with a fixed f, use the
359zz_pXModulus data structure and associated routines below for better
360performance.
361
362\**************************************************************************/
363
364void MulMod(zz_pX& x, const zz_pX& a, const zz_pX& b, const zz_pX& f);
365zz_pX MulMod(const zz_pX& a, const zz_pX& b, const zz_pX& f);
366// x = (a * b) % f
367
368void SqrMod(zz_pX& x, const zz_pX& a, const zz_pX& f);
369zz_pX SqrMod(const zz_pX& a, const zz_pX& f);
370// x = a^2 % f
371
372void MulByXMod(zz_pX& x, const zz_pX& a, const zz_pX& f);
373zz_pX MulByXMod(const zz_pX& a, const zz_pX& f);
374// x = (a * X) mod f
375
376void InvMod(zz_pX& x, const zz_pX& a, const zz_pX& f);
377zz_pX InvMod(const zz_pX& a, const zz_pX& f);
378// x = a^{-1} % f, error is a is not invertible
379
380long InvModStatus(zz_pX& x, const zz_pX& a, const zz_pX& f);
381// if (a, f) = 1, returns 0 and sets x = a^{-1} % f; otherwise,
382// returns 1 and sets x = (a, f)
383
384
385// for modular exponentiation, see below
386
387
388
389/**************************************************************************\
390
391                     Modular Arithmetic with Pre-Conditioning
392
393If you need to do a lot of arithmetic modulo a fixed f, build
394zz_pXModulus F for f.  This pre-computes information about f that
395speeds up subsequent computations. Required: deg(f) > 0 and LeadCoeff(f)
396invertible.
397
398As an example, the following routine computes the product modulo f of a vector
399of polynomials.
400
401#include "zz_pX.h"
402
403void product(zz_pX& x, const vec_zz_pX& v, const zz_pX& f)
404{
405   zz_pXModulus F(f);
406   zz_pX res;
407   res = 1;
408   long i;
409   for (i = 0; i < v.length(); i++)
410      MulMod(res, res, v[i], F);
411   x = res;
412}
413
414
415Note that automatic conversions are provided so that a zz_pX can
416be used wherever a zz_pXModulus is required, and a zz_pXModulus
417can be used wherever a zz_pX is required.
418
419
420
421\**************************************************************************/
422
423class zz_pXModulus {
424public:
425   zz_pXModulus(); // initially in an unusable state
426   ~zz_pXModulus();
427
428   zz_pXModulus(const zz_pXModulus&);  // copy
429
430   zz_pXModulus& operator=(const zz_pXModulus&);  // assignment
431
432   zz_pXModulus(const zz_pX& f); // initialize with f, deg(f) > 0
433
434   operator const zz_pX& () const;
435   // read-only access to f, implicit conversion operator
436
437   const zz_pX& val() const;
438   // read-only access to f, explicit notation
439
440};
441
442void build(zz_pXModulus& F, const zz_pX& f);
443// pre-computes information about f and stores it in F.
444// Note that the declaration zz_pXModulus F(f) is equivalent to
445// zz_pXModulus F; build(F, f).
446
447// In the following, f refers to the polynomial f supplied to the
448// build routine, and n = deg(f).
449
450long deg(const zz_pXModulus& F);  // return deg(f)
451
452void MulMod(zz_pX& x, const zz_pX& a, const zz_pX& b, const zz_pXModulus& F);
453zz_pX MulMod(const zz_pX& a, const zz_pX& b, const zz_pXModulus& F);
454// x = (a * b) % f; deg(a), deg(b) < n
455
456void SqrMod(zz_pX& x, const zz_pX& a, const zz_pXModulus& F);
457zz_pX SqrMod(const zz_pX& a, const zz_pXModulus& F);
458// x = a^2 % f; deg(a) < n
459
460void PowerMod(zz_pX& x, const zz_pX& a, const ZZ& e, const zz_pXModulus& F);
461zz_pX PowerMod(const zz_pX& a, const ZZ& e, const zz_pXModulus& F);
462
463void PowerMod(zz_pX& x, const zz_pX& a, long e, const zz_pXModulus& F);
464zz_pX PowerMod(const zz_pX& a, long e, const zz_pXModulus& F);
465
466// x = a^e % f; deg(a) < n (e may be negative)
467
468void PowerXMod(zz_pX& x, const ZZ& e, const zz_pXModulus& F);
469zz_pX PowerXMod(const ZZ& e, const zz_pXModulus& F);
470
471void PowerXMod(zz_pX& x, long e, const zz_pXModulus& F);
472zz_pX PowerXMod(long e, const zz_pXModulus& F);
473
474// x = X^e % f (e may be negative)
475
476void PowerXPlusAMod(zz_pX& x, const zz_p& a, const ZZ& e,
477                    const zz_pXModulus& F);
478
479zz_pX PowerXPlusAMod(const zz_p& a, const ZZ& e,
480                           const zz_pXModulus& F);
481
482void PowerXPlusAMod(zz_pX& x, const zz_p& a, long e,
483                    const zz_pXModulus& F);
484
485zz_pX PowerXPlusAMod(const zz_p& a, long e,
486                           const zz_pXModulus& F);
487
488// x = (X + a)^e % f (e may be negative)
489
490
491void rem(zz_pX& x, const zz_pX& a, const zz_pXModulus& F);
492// x = a % f
493
494void DivRem(zz_pX& q, zz_pX& r, const zz_pX& a, const zz_pXModulus& F);
495// q = a/f, r = a%f
496
497void div(zz_pX& q, const zz_pX& a, const zz_pXModulus& F);
498// q = a/f
499
500// operator notation:
501
502zz_pX operator/(const zz_pX& a, const zz_pXModulus& F);
503zz_pX operator%(const zz_pX& a, const zz_pXModulus& F);
504
505zz_pX& operator/=(zz_pX& x, const zz_pXModulus& F);
506zz_pX& operator%=(zz_pX& x, const zz_pXModulus& F);
507
508
509
510
511/**************************************************************************\
512
513
514                        More Pre-Conditioning
515
516If you need to compute a * b % f for a fixed b, but for many a's, it
517is much more efficient to first build a zz_pXMultiplier B for b, and
518then use the MulMod routine below.
519
520Here is an example that multiplies each element of a vector by a fixed
521polynomial modulo f.
522
523#include "zz_pX.h"
524
525void mul(vec_zz_pX& v, const zz_pX& b, const zz_pX& f)
526{
527   zz_pXModulus F(f);
528   zz_pXMultiplier B(b, F);
529   long i;
530   for (i = 0; i < v.length(); i++)
531      MulMod(v[i], v[i], B, F);
532}
533
534Note that a (trivial) conversion operator from zz_pXMultiplier to zz_pX
535is provided, so that a zz_pXMultiplier can be used in a context
536where a zz_pX is required.
537
538
539\**************************************************************************/
540
541
542class zz_pXMultiplier {
543public:
544   zz_pXMultiplier(); // initially zero
545
546   zz_pXMultiplier(const zz_pX& b, const zz_pXModulus& F);
547      // initializes with b mod F, where deg(b) < deg(F)
548
549   zz_pXMultiplier(const zz_pXMultiplier&);
550   zz_pXMultiplier& operator=(const zz_pXMultiplier&);
551
552   ~zz_pXMultiplier();
553
554   const zz_pX& val() const; // read-only access to b
555
556};
557
558void build(zz_pXMultiplier& B, const zz_pX& b, const zz_pXModulus& F);
559// pre-computes information about b and stores it in B; deg(b) <
560// deg(F)
561
562void MulMod(zz_pX& x, const zz_pX& a, const zz_pXMultiplier& B,
563                                      const zz_pXModulus& F);
564
565zz_pX MulMod(const zz_pX& a, const zz_pXMultiplier& B,
566             const zz_pXModulus& F);
567
568// x = (a * b) % F; deg(a) < deg(F)
569
570/**************************************************************************\
571
572                             vectors of zz_pX's
573
574\**************************************************************************/
575
576NTL_vector_decl(zz_pX,vec_zz_pX)
577// vec_zz_pX
578
579NTL_eq_vector_decl(zz_pX,vec_zz_pX)
580// == and !=
581
582NTL_io_vector_decl(zz_pX,vec_zz_pX)
583// I/O operators
584
585
586/**************************************************************************\
587
588                              Modular Composition
589
590Modular composition is the problem of computing g(h) mod f for
591polynomials f, g, and h.
592
593The algorithm employed is that of Brent & Kung (Fast algorithms for
594manipulating formal power series, JACM 25:581-595, 1978), which uses
595O(n^{1/2}) modular polynomial multiplications, and O(n^2) scalar
596operations.
597
598
599
600\**************************************************************************/
601
602void CompMod(zz_pX& x, const zz_pX& g, const zz_pX& h, const zz_pXModulus& F);
603zz_pX CompMod(const zz_pX& g, const zz_pX& h, const zz_pXModulus& F);
604// x = g(h) mod f; deg(h) < n
605
606void Comp2Mod(zz_pX& x1, zz_pX& x2, const zz_pX& g1, const zz_pX& g2,
607              const zz_pX& h, const zz_pXModulus& F);
608// xi = gi(h) mod f (i=1,2), deg(h) < n.
609
610void CompMod3(zz_pX& x1, zz_pX& x2, zz_pX& x3,
611              const zz_pX& g1, const zz_pX& g2, const zz_pX& g3,
612              const zz_pX& h, const zz_pXModulus& F);
613// xi = gi(h) mod f (i=1..3), deg(h) < n
614
615
616/**************************************************************************\
617
618                     Composition with Pre-Conditioning
619
620If a single h is going to be used with many g's then you should build
621a zz_pXArgument for h, and then use the compose routine below.  The
622routine build computes and stores h, h^2, ..., h^m mod f.  After this
623pre-computation, composing a polynomial of degree roughly n with h
624takes n/m multiplies mod f, plus n^2 scalar multiplies.  Thus,
625increasing m increases the space requirement and the pre-computation
626time, but reduces the composition time.
627
628\**************************************************************************/
629
630
631struct zz_pXArgument {
632   vec_zz_pX H;
633};
634
635void build(zz_pXArgument& H, const zz_pX& h, const zz_pXModulus& F, long m);
636// Pre-Computes information about h.  m > 0, deg(h) < n
637
638void CompMod(zz_pX& x, const zz_pX& g, const zz_pXArgument& H,
639             const zz_pXModulus& F);
640
641zz_pX CompMod(const zz_pX& g, const zz_pXArgument& H,
642             const zz_pXModulus& F);
643
644
645extern long zz_pXArgBound;
646
647// Initially 0.  If this is set to a value greater than zero, then
648// composition routines will allocate a table of no than about
649// zz_pXArgBound KB.  Setting this value affects all compose routines
650// and the power projection and minimal polynomial routines below,
651// and indirectly affects many routines in zz_pXFactoring.
652
653/**************************************************************************\
654
655                     power projection routines
656
657\**************************************************************************/
658
659void project(zz_p& x, const zz_pVector& a, const zz_pX& b);
660zz_p project(const zz_pVector& a, const zz_pX& b);
661// x = inner product of a with coefficient vector of b
662
663
664void ProjectPowers(vec_zz_p& x, const vec_zz_p& a, long k,
665                   const zz_pX& h, const zz_pXModulus& F);
666
667vec_zz_p ProjectPowers(const vec_zz_p& a, long k,
668                   const zz_pX& h, const zz_pXModulus& F);
669
670// Computes the vector
671
672//    project(a, 1), project(a, h), ..., project(a, h^{k-1} % f). 
673
674// This operation is the "transpose" of the modular composition operation.
675// Input and output may have "high order" zeroes stripped.
676
677void ProjectPowers(vec_zz_p& x, const vec_zz_p& a, long k,
678                   const zz_pXArgument& H, const zz_pXModulus& F);
679
680vec_zz_p ProjectPowers(const vec_zz_p& a, long k,
681                   const zz_pXArgument& H, const zz_pXModulus& F);
682
683// same as above, but uses a pre-computed zz_pXArgument
684
685
686void UpdateMap(vec_zz_p& x, const vec_zz_p& a,
687               const zz_pXMultiplier& B, const zz_pXModulus& F);
688
689vec_zz_p UpdateMap(const vec_zz_p& a,
690               const zz_pXMultiplier& B, const zz_pXModulus& F);
691
692// Computes the vector
693
694//    project(a, b), project(a, (b*X)%f), ..., project(a, (b*X^{n-1})%f)
695
696// Restriction: a.length() <= deg(F).
697// This is "transposed" MulMod by B.
698// Input vector may have "high order" zeroes striped.
699// The output will always have high order zeroes stripped.
700
701
702/**************************************************************************\
703
704                              Minimum Polynomials
705
706These routines should be used with prime p.
707
708All of these routines implement the algorithm from [Shoup, J. Symbolic
709Comp. 17:371-391, 1994] and [Shoup, J. Symbolic Comp. 20:363-397,
7101995], based on transposed modular composition and the
711Berlekamp/Massey algorithm.
712
713\**************************************************************************/
714
715
716void MinPolySeq(zz_pX& h, const vec_zz_p& a, long m);
717// computes the minimum polynomial of a linealy generated sequence; m
718// is a bound on the degree of the polynomial; required: a.length() >=
719// 2*m
720
721void ProbMinPolyMod(zz_pX& h, const zz_pX& g, const zz_pXModulus& F, long m);
722zz_pX ProbMinPolyMod(const zz_pX& g, const zz_pXModulus& F, long m);
723
724void ProbMinPolyMod(zz_pX& h, const zz_pX& g, const zz_pXModulus& F);
725zz_pX ProbMinPolyMod(const zz_pX& g, const zz_pXModulus& F);
726
727// computes the monic minimal polynomial if (g mod f).  m = a bound on
728// the degree of the minimal polynomial; in the second version, this
729// argument defaults to n.  The algorithm is probabilistic, always
730// returns a divisor of the minimal polynomial, and returns a proper
731// divisor with probability at most m/p.
732
733void MinPolyMod(zz_pX& h, const zz_pX& g, const zz_pXModulus& F, long m);
734zz_pX MinPolyMod(const zz_pX& g, const zz_pXModulus& F, long m);
735
736void MinPolyMod(zz_pX& h, const zz_pX& g, const zz_pXModulus& F);
737zz_pX MinPolyMod(const zz_pX& g, const zz_pXModulus& F);
738// same as above, but guarantees that result is correct
739
740void IrredPoly(zz_pX& h, const zz_pX& g, const zz_pXModulus& F, long m);
741zz_pX IrredPoly(const zz_pX& g, const zz_pXModulus& F, long m);
742
743void IrredPoly(zz_pX& h, const zz_pX& g, const zz_pXModulus& F);
744zz_pX IrredPoly(const zz_pX& g, const zz_pXModulus& F);
745
746// same as above, but assumes that f is irreducible, or at least that
747// the minimal poly of g is itself irreducible.  The algorithm is
748// deterministic (and is always correct).
749
750
751/**************************************************************************\
752
753                   Traces, norms, resultants
754
755These routines should be used with prime p.
756
757\**************************************************************************/
758
759
760void TraceMod(zz_p& x, const zz_pX& a, const zz_pXModulus& F);
761zz_p TraceMod(const zz_pX& a, const zz_pXModulus& F);
762
763void TraceMod(zz_p& x, const zz_pX& a, const zz_pX& f);
764zz_p TraceMod(const zz_pX& a, const zz_pXModulus& f);
765// x = Trace(a mod f); deg(a) < deg(f)
766
767
768void TraceVec(vec_zz_p& S, const zz_pX& f);
769vec_zz_p TraceVec(const zz_pX& f);
770// S[i] = Trace(X^i mod f), i = 0..deg(f)-1; 0 < deg(f)
771
772// The above routines implement the asymptotically fast trace
773// algorithm from [von zur Gathen and Shoup, Computational Complexity,
774// 1992].
775
776void NormMod(zz_p& x, const zz_pX& a, const zz_pX& f);
777zz_p NormMod(const zz_pX& a, const zz_pX& f);
778// x = Norm(a mod f); 0 < deg(f), deg(a) < deg(f)
779
780
781void resultant(zz_p& x, const zz_pX& a, const zz_pX& b);
782zz_pX resultant(zz_p& x, const zz_pX& a, const zz_pX& b);
783// x = resultant(a, b)
784
785
786void CharPolyMod(zz_pX& g, const zz_pX& a, const zz_pX& f);
787zz_pX CharPolyMod(const zz_pX& a, const zz_pX& f);
788// g = charcteristic polynomial of (a mod f); 0 < deg(f), deg(g) <
789// deg(f).  This routine works for arbitrary f.  For irreducible f,
790// is it faster to use IrredPolyMod, and then exponentiate as
791// necessary, since in this case the characterstic polynomial
792// is a power of the minimal polynomial.
793
794
795/**************************************************************************\
796
797                           Miscellany
798
799A zz_pX f is represented as a vec_zz_p, which can be accessed as
800f.rep.  The constant term is f.rep[0] and the leading coefficient is
801f.rep[f.rep.length()-1], except if f is zero, in which case
802f.rep.length() == 0.  Note that the leading coefficient is always
803nonzero (unless f is zero).  One can freely access and modify f.rep,
804but one should always ensure that the leading coefficient is nonzero,
805which can be done by invoking f.normalize().
806
807
808\**************************************************************************/
809
810
811void clear(zz_pX& x) // x = 0
812void set(zz_pX& x); // x = 1
813
814void zz_pX::normalize(); 
815// f.normalize() strips leading zeros from f.rep.
816
817void zz_pX::SetMaxLength(long n);
818// f.SetMaxLength(n) pre-allocate spaces for n coefficients.  The
819// polynomial that f represents is unchanged.
820
821void zz_pX::kill();
822// f.kill() sets f to 0 and frees all memory held by f.  Equivalent to
823// f.rep.kill().
824
825zz_pX::zz_pX(INIT_SIZE_TYPE, long n);
826// zz_pX(INIT_SIZE, n) initializes to zero, but space is pre-allocated
827// for n coefficients
828
829static const zz_pX& zero();
830// zz_pX::zero() is a read-only reference to 0
831
832void swap(zz_pX& x, zz_pX& y);
833// swap x and y (via "pointer swapping")
834
Note: See TracBrowser for help on using the repository browser.