source: git/ntl/include/NTL/lzz_pEX.h @ a703156

fieker-DuValspielwiese
Last change on this file since a703156 was de6a29, checked in by Hans Schönemann <hannes@…>, 19 years ago
* hannes: NTL-5.4 git-svn-id: file:///usr/local/Singular/svn/trunk@8693 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 29.3 KB
Line 
1
2#ifndef NTL_zz_pEX__H
3#define NTL_zz_pEX__H
4
5#include <NTL/vec_lzz_pE.h>
6
7NTL_OPEN_NNS
8
9class zz_pEX {
10
11public:
12
13vec_zz_pE rep;
14
15
16/***************************************************************
17
18          Constructors, Destructors, and Assignment
19
20****************************************************************/
21
22
23zz_pEX()
24//  initial value 0
25
26   { }
27
28
29zz_pEX(INIT_SIZE_TYPE, long n) { rep.SetMaxLength(n); }
30
31~zz_pEX() { }
32
33void normalize();
34// strip leading zeros
35
36void SetMaxLength(long n) 
37// pre-allocate space for n coefficients.
38// Value is unchanged
39
40   { rep.SetMaxLength(n); }
41
42
43void kill() 
44// free space held by this polynomial.  Value becomes 0.
45
46   { rep.kill(); }
47
48static const zz_pEX& zero();
49
50inline zz_pEX(long i, const zz_pE& c);
51inline zz_pEX(long i, const zz_p& c);
52inline zz_pEX(long i, long c);
53
54
55inline zz_pEX& operator=(long a);
56inline zz_pEX& operator=(const zz_p& a);
57inline zz_pEX& operator=(const zz_pE& a);
58
59zz_pEX(zz_pEX& x, INIT_TRANS_TYPE) : rep(x.rep, INIT_TRANS) { }
60
61
62};
63
64
65
66/**********************************************************
67
68                   Some utility routines
69
70***********************************************************/
71
72
73inline long deg(const zz_pEX& a) { return a.rep.length() - 1; }
74// degree of a polynomial.
75// note that the zero polynomial has degree -1.
76
77const zz_pE& coeff(const zz_pEX& a, long i);
78// zero if i not in range
79
80const zz_pE& LeadCoeff(const zz_pEX& a);
81// zero if a == 0
82
83const zz_pE& ConstTerm(const zz_pEX& a);
84// zero if a == 0
85
86void SetCoeff(zz_pEX& x, long i, const zz_pE& a);
87void SetCoeff(zz_pEX& x, long i, const zz_p& a);
88void SetCoeff(zz_pEX& x, long i, long a);
89// x[i] = a, error is raised if i < 0
90
91inline zz_pEX::zz_pEX(long i, const zz_pE& a)
92   { SetCoeff(*this, i, a); }
93
94inline zz_pEX::zz_pEX(long i, const zz_p& a)
95   { SetCoeff(*this, i, a); }
96
97inline zz_pEX::zz_pEX(long i, long a)
98   { SetCoeff(*this, i, a); }
99
100void SetCoeff(zz_pEX& x, long i);
101// x[i] = 1, error is raised if i < 0
102
103void SetX(zz_pEX& x);
104// x is set to the monomial X
105
106long IsX(const zz_pEX& a);
107// test if x = X
108
109inline void clear(zz_pEX& x) 
110// x = 0
111
112   { x.rep.SetLength(0); }
113
114inline void set(zz_pEX& x)
115// x = 1
116
117   { x.rep.SetLength(1); set(x.rep[0]); }
118
119inline void swap(zz_pEX& x, zz_pEX& y)
120// swap x & y (only pointers are swapped)
121
122   { swap(x.rep, y.rep); }
123
124void random(zz_pEX& x, long n);
125inline zz_pEX random_zz_pEX(long n)
126   { zz_pEX x; random(x, n); NTL_OPT_RETURN(zz_pEX, x); }
127// generate a random polynomial of degree < n
128
129void trunc(zz_pEX& x, const zz_pEX& a, long m);
130inline zz_pEX trunc(const zz_pEX& a, long m)
131   { zz_pEX x; trunc(x, a, m);  NTL_OPT_RETURN(zz_pEX, x); }
132// x = a % X^m
133
134void RightShift(zz_pEX& x, const zz_pEX& a, long n);
135inline zz_pEX RightShift(const zz_pEX& a, long n)
136   { zz_pEX x; RightShift(x, a, n);  NTL_OPT_RETURN(zz_pEX, x); }
137// x = a/X^n
138
139void LeftShift(zz_pEX& x, const zz_pEX& a, long n);
140inline zz_pEX LeftShift(const zz_pEX& a, long n)
141   { zz_pEX x; LeftShift(x, a, n);  NTL_OPT_RETURN(zz_pEX, x); }
142// x = a*X^n
143
144#ifndef NTL_TRANSITION
145
146inline zz_pEX operator>>(const zz_pEX& a, long n)
147   { zz_pEX x; RightShift(x, a, n); NTL_OPT_RETURN(zz_pEX, x); }
148
149inline zz_pEX operator<<(const zz_pEX& a, long n)
150   { zz_pEX x; LeftShift(x, a, n); NTL_OPT_RETURN(zz_pEX, x); }
151
152inline zz_pEX& operator<<=(zz_pEX& x, long n)
153   { LeftShift(x, x, n); return x; }
154
155inline zz_pEX& operator>>=(zz_pEX& x, long n)
156   { RightShift(x, x, n); return x; }
157
158#endif
159
160
161
162void diff(zz_pEX& x, const zz_pEX& a);
163inline zz_pEX diff(const zz_pEX& a)
164   { zz_pEX x; diff(x, a);  NTL_OPT_RETURN(zz_pEX, x); }
165// x = derivative of a
166
167
168
169void MakeMonic(zz_pEX& x);
170
171void reverse(zz_pEX& c, const zz_pEX& a, long hi);
172
173inline zz_pEX reverse(const zz_pEX& a, long hi)
174   { zz_pEX x; reverse(x, a, hi); NTL_OPT_RETURN(zz_pEX, x); }
175
176inline void reverse(zz_pEX& c, const zz_pEX& a)
177{  reverse(c, a, deg(a)); }
178
179inline zz_pEX reverse(const zz_pEX& a)
180   { zz_pEX x; reverse(x, a); NTL_OPT_RETURN(zz_pEX, x); }
181
182inline void VectorCopy(vec_zz_pE& x, const zz_pEX& a, long n)
183   { VectorCopy(x, a.rep, n); }
184
185inline vec_zz_pE VectorCopy(const zz_pEX& a, long n)
186   { return VectorCopy(a.rep, n); }
187
188
189
190
191
192
193/*******************************************************************
194
195                        conversion routines
196
197********************************************************************/
198
199
200
201void conv(zz_pEX& x, long a);
202
203void conv(zz_pEX& x, const ZZ& a);
204
205void conv(zz_pEX& x, const zz_p& a);
206void conv(zz_pEX& x, const zz_pX& a);
207void conv(zz_pEX& x, const zz_pE& a);
208
209
210void conv(zz_pEX& x, const vec_zz_pE& a);
211
212inline zz_pEX to_zz_pEX(long a)
213   { zz_pEX x; conv(x, a); NTL_OPT_RETURN(zz_pEX, x); }
214
215inline zz_pEX to_zz_pEX(const ZZ& a)
216   { zz_pEX x; conv(x, a); NTL_OPT_RETURN(zz_pEX, x); }
217
218inline zz_pEX to_zz_pEX(const zz_p& a)
219   { zz_pEX x; conv(x, a); NTL_OPT_RETURN(zz_pEX, x); }
220
221inline zz_pEX to_zz_pEX(const zz_pX& a)
222   { zz_pEX x; conv(x, a); NTL_OPT_RETURN(zz_pEX, x); }
223
224inline zz_pEX to_zz_pEX(const zz_pE& a)
225   { zz_pEX x; conv(x, a); NTL_OPT_RETURN(zz_pEX, x); }
226
227inline zz_pEX to_zz_pEX(const vec_zz_pE& a)
228   { zz_pEX x; conv(x, a); NTL_OPT_RETURN(zz_pEX, x); }
229
230inline zz_pEX& zz_pEX::operator=(long a)
231   { conv(*this, a); return *this; }
232
233inline zz_pEX& zz_pEX::operator=(const zz_p& a)
234   { conv(*this, a); return *this; }
235
236inline zz_pEX& zz_pEX::operator=(const zz_pE& a)
237   { conv(*this, a); return *this; }
238
239
240/*************************************************************
241
242                        Comparison
243
244**************************************************************/
245
246long IsZero(const zz_pEX& a); 
247
248long IsOne(const zz_pEX& a);
249
250inline long operator==(const zz_pEX& a, const zz_pEX& b)
251{ return a.rep == b.rep; }
252
253long operator==(const zz_pEX& a, long b);
254long operator==(const zz_pEX& a, const zz_p& b);
255long operator==(const zz_pEX& a, const zz_pE& b);
256
257inline long operator==(long a, const zz_pEX& b)
258   { return (b == a); }
259inline long operator==(const zz_p& a, const zz_pEX& b)
260   { return (b == a); }
261inline long operator==(const zz_pE& a, const zz_pEX& b)
262   { return (b == a); }
263
264inline long operator!=(const zz_pEX& a, const zz_pEX& b)
265   { return !(a == b); }
266inline long operator!=(const zz_pEX& a, long b)
267   { return !(a == b); }
268inline long operator!=(const zz_pEX& a, const zz_p& b)
269   { return !(a == b); }
270inline long operator!=(const zz_pEX& a, const zz_pE& b)
271   { return !(a == b); }
272inline long operator!=(const long a, const zz_pEX& b)
273   { return !(a == b); }
274inline long operator!=(const zz_p& a, const zz_pEX& b)
275   { return !(a == b); }
276inline long operator!=(const zz_pE& a, const zz_pEX& b)
277   { return !(a == b); }
278
279
280/***************************************************************
281
282                         Addition
283
284****************************************************************/
285
286void add(zz_pEX& x, const zz_pEX& a, const zz_pEX& b);
287
288void sub(zz_pEX& x, const zz_pEX& a, const zz_pEX& b);
289
290void negate(zz_pEX& x, const zz_pEX& a);
291
292// scalar versions
293
294void add(zz_pEX & x, const zz_pEX& a, long b); 
295void add(zz_pEX & x, const zz_pEX& a, const zz_p& b); 
296void add(zz_pEX & x, const zz_pEX& a, const zz_pE& b); 
297
298inline void add(zz_pEX& x, const zz_pE& a, const zz_pEX& b)
299   { add(x, b, a); }
300inline void add(zz_pEX& x, const zz_p& a, const zz_pEX& b)
301   { add(x, b, a); }
302inline void add(zz_pEX& x, long a, const zz_pEX& b)
303   { add(x, b, a); }
304
305void sub(zz_pEX & x, const zz_pEX& a, long b); 
306void sub(zz_pEX & x, const zz_pEX& a, const zz_p& b); 
307void sub(zz_pEX & x, const zz_pEX& a, const zz_pE& b); 
308
309void sub(zz_pEX& x, const zz_pE& a, const zz_pEX& b);
310void sub(zz_pEX& x, const zz_p& a, const zz_pEX& b);
311void sub(zz_pEX& x, long a, const zz_pEX& b);
312
313
314
315inline zz_pEX operator+(const zz_pEX& a, const zz_pEX& b)
316   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
317
318inline zz_pEX operator+(const zz_pEX& a, const zz_pE& b)
319   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
320
321inline zz_pEX operator+(const zz_pEX& a, const zz_p& b)
322   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
323
324inline zz_pEX operator+(const zz_pEX& a, long b)
325   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
326
327inline zz_pEX operator+(const zz_pE& a, const zz_pEX& b)
328   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
329
330inline zz_pEX operator+(const zz_p& a, const zz_pEX& b)
331   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
332
333inline zz_pEX operator+(long a, const zz_pEX& b)
334   { zz_pEX x; add(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
335
336
337inline zz_pEX operator-(const zz_pEX& a, const zz_pEX& b)
338   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
339
340inline zz_pEX operator-(const zz_pEX& a, const zz_pE& b)
341   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
342
343inline zz_pEX operator-(const zz_pEX& a, const zz_p& b)
344   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
345
346inline zz_pEX operator-(const zz_pEX& a, long b)
347   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
348
349inline zz_pEX operator-(const zz_pE& a, const zz_pEX& b)
350   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
351
352inline zz_pEX operator-(const zz_p& a, const zz_pEX& b)
353   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
354
355inline zz_pEX operator-(long a, const zz_pEX& b)
356   { zz_pEX x; sub(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
357
358
359inline zz_pEX& operator+=(zz_pEX& x, const zz_pEX& b)
360   { add(x, x, b); return x; }
361
362inline zz_pEX& operator+=(zz_pEX& x, const zz_pE& b)
363   { add(x, x, b); return x; }
364
365inline zz_pEX& operator+=(zz_pEX& x, const zz_p& b)
366   { add(x, x, b); return x; }
367
368inline zz_pEX& operator+=(zz_pEX& x, long b)
369   { add(x, x, b); return x; }
370
371inline zz_pEX& operator-=(zz_pEX& x, const zz_pEX& b)
372   { sub(x, x, b); return x; }
373
374inline zz_pEX& operator-=(zz_pEX& x, const zz_pE& b)
375   { sub(x, x, b); return x; }
376
377inline zz_pEX& operator-=(zz_pEX& x, const zz_p& b)
378   { sub(x, x, b); return x; }
379
380inline zz_pEX& operator-=(zz_pEX& x, long b)
381   { sub(x, x, b); return x; }
382
383
384inline zz_pEX operator-(const zz_pEX& a) 
385   { zz_pEX x; negate(x, a); NTL_OPT_RETURN(zz_pEX, x); }
386
387inline zz_pEX& operator++(zz_pEX& x) { add(x, x, 1); return x; }
388inline void operator++(zz_pEX& x, int) { add(x, x, 1); }
389inline zz_pEX& operator--(zz_pEX& x) { sub(x, x, 1); return x; }
390inline void operator--(zz_pEX& x, int) { sub(x, x, 1); }
391
392
393
394/*****************************************************************
395
396                        Multiplication
397
398******************************************************************/
399
400
401void mul(zz_pEX& x, const zz_pEX& a, const zz_pEX& b);
402// x = a * b
403
404void sqr(zz_pEX& x, const zz_pEX& a);
405inline zz_pEX sqr(const zz_pEX& a) 
406   { zz_pEX x; sqr(x, a); NTL_OPT_RETURN(zz_pEX, x); }
407// x = a^2
408
409
410void mul(zz_pEX & x, const zz_pEX& a, long b); 
411void mul(zz_pEX & x, const zz_pEX& a, const zz_p& b); 
412void mul(zz_pEX & x, const zz_pEX& a, const zz_pE& b); 
413
414inline void mul(zz_pEX& x, long a, const zz_pEX& b)
415   { mul(x, b, a); }
416inline void mul(zz_pEX& x, const zz_p& a, const zz_pEX& b)
417   { mul(x, b, a); }
418inline void mul(zz_pEX& x, const zz_pE& a, const zz_pEX& b)
419   { mul(x, b, a); }
420
421void MulTrunc(zz_pEX& x, const zz_pEX& a, const zz_pEX& b, long n);
422inline zz_pEX MulTrunc(const zz_pEX& a, const zz_pEX& b, long n)
423   { zz_pEX x; MulTrunc(x, a, b, n); NTL_OPT_RETURN(zz_pEX, x); }
424// x = a * b % X^n
425
426void SqrTrunc(zz_pEX& x, const zz_pEX& a, long n);
427inline zz_pEX SqrTrunc(const zz_pEX& a, long n)
428   { zz_pEX x; SqrTrunc(x, a, n); NTL_OPT_RETURN(zz_pEX, x); }
429// x = a*a % X^n
430
431
432inline zz_pEX operator*(const zz_pEX& a, const zz_pEX& b)
433   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
434
435inline zz_pEX operator*(const zz_pEX& a, const zz_pE& b)
436   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
437
438inline zz_pEX operator*(const zz_pEX& a, const zz_p& b)
439   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
440
441inline zz_pEX operator*(const zz_pEX& a, long b)
442   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
443
444inline zz_pEX operator*(const zz_pE& a, const zz_pEX& b)
445   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
446
447inline zz_pEX operator*(const zz_p& a, const zz_pEX& b)
448   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
449
450inline zz_pEX operator*(long a, const zz_pEX& b)
451   { zz_pEX x; mul(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
452
453inline zz_pEX& operator*=(zz_pEX& x, const zz_pEX& b)
454   { mul(x, x, b); return x; }
455
456inline zz_pEX& operator*=(zz_pEX& x, const zz_pE& b)
457   { mul(x, x, b); return x; }
458
459inline zz_pEX& operator*=(zz_pEX& x, const zz_p& b)
460   { mul(x, x, b); return x; }
461
462inline zz_pEX& operator*=(zz_pEX& x, long b)
463   { mul(x, x, b); return x; }
464
465
466void power(zz_pEX& x, const zz_pEX& a, long e);
467inline zz_pEX power(const zz_pEX& a, long e)
468   { zz_pEX x; power(x, a, e); NTL_OPT_RETURN(zz_pEX, x); }
469
470
471
472
473
474/*************************************************************
475
476                      Division
477
478**************************************************************/
479
480void DivRem(zz_pEX& q, zz_pEX& r, const zz_pEX& a, const zz_pEX& b);
481// q = a/b, r = a%b
482
483void div(zz_pEX& q, const zz_pEX& a, const zz_pEX& b);
484void div(zz_pEX& q, const zz_pEX& a, const zz_pE& b);
485void div(zz_pEX& q, const zz_pEX& a, const zz_p& b);
486void div(zz_pEX& q, const zz_pEX& a, long b);
487// q = a/b
488
489void rem(zz_pEX& r, const zz_pEX& a, const zz_pEX& b);
490// r = a%b
491
492long divide(zz_pEX& q, const zz_pEX& a, const zz_pEX& b);
493// if b | a, sets q = a/b and returns 1; otherwise returns 0
494
495long divide(const zz_pEX& a, const zz_pEX& b);
496// if b | a, sets q = a/b and returns 1; otherwise returns 0
497
498void InvTrunc(zz_pEX& x, const zz_pEX& a, long m);
499inline zz_pEX InvTrunc(const zz_pEX& a, long m)
500   { zz_pEX x; InvTrunc(x, a, m); NTL_OPT_RETURN(zz_pEX, x); }
501// computes x = a^{-1} % X^m
502// constant term must be invertible
503
504
505inline zz_pEX operator/(const zz_pEX& a, const zz_pEX& b)
506   { zz_pEX x; div(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
507
508inline zz_pEX operator/(const zz_pEX& a, const zz_pE& b)
509   { zz_pEX x; div(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
510
511inline zz_pEX operator/(const zz_pEX& a, const zz_p& b)
512   { zz_pEX x; div(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
513
514inline zz_pEX operator/(const zz_pEX& a, long b)
515   { zz_pEX x; div(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
516
517inline zz_pEX& operator/=(zz_pEX& x, const zz_pEX& b)
518   { div(x, x, b); return x; }
519
520inline zz_pEX& operator/=(zz_pEX& x, const zz_pE& b)
521   { div(x, x, b); return x; }
522
523inline zz_pEX& operator/=(zz_pEX& x, const zz_p& b)
524   { div(x, x, b); return x; }
525
526inline zz_pEX& operator/=(zz_pEX& x, long b)
527   { div(x, x, b); return x; }
528
529
530inline zz_pEX operator%(const zz_pEX& a, const zz_pEX& b)
531   { zz_pEX x; rem(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
532
533inline zz_pEX& operator%=(zz_pEX& x, const zz_pEX& b)
534   { rem(x, x, b); return x; }
535
536
537
538/***********************************************************
539
540                         GCD's
541
542************************************************************/
543
544
545void GCD(zz_pEX& x, const zz_pEX& a, const zz_pEX& b);
546inline zz_pEX GCD(const zz_pEX& a, const zz_pEX& b)
547   { zz_pEX x; GCD(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
548// x = GCD(a, b),  x is always monic (or zero if a==b==0).
549
550void XGCD(zz_pEX& d, zz_pEX& s, zz_pEX& t, const zz_pEX& a, const zz_pEX& b);
551// d = gcd(a,b), a s + b t = d
552
553
554/*************************************************************
555
556             Modular Arithmetic without pre-conditioning
557
558**************************************************************/
559
560// arithmetic mod f.
561// all inputs and outputs are polynomials of degree less than deg(f).
562// ASSUMPTION: f is assumed monic, and deg(f) > 0.
563// NOTE: if you want to do many computations with a fixed f,
564//       use the zz_pEXModulus data structure and associated routines below.
565
566
567
568void MulMod(zz_pEX& x, const zz_pEX& a, const zz_pEX& b, const zz_pEX& f);
569inline zz_pEX MulMod(const zz_pEX& a, const zz_pEX& b, const zz_pEX& f)
570   { zz_pEX x; MulMod(x, a, b, f); NTL_OPT_RETURN(zz_pEX, x); }
571// x = (a * b) % f
572
573void SqrMod(zz_pEX& x, const zz_pEX& a, const zz_pEX& f);
574inline zz_pEX SqrMod(const zz_pEX& a, const zz_pEX& f)
575   { zz_pEX x; SqrMod(x, a, f); NTL_OPT_RETURN(zz_pEX, x); }
576// x = a^2 % f
577
578void MulByXMod(zz_pEX& x, const zz_pEX& a, const zz_pEX& f);
579inline zz_pEX MulByXMod(const zz_pEX& a, const zz_pEX& f)
580   { zz_pEX x; MulByXMod(x, a, f); NTL_OPT_RETURN(zz_pEX, x); }
581// x = (a * X) mod f
582
583void InvMod(zz_pEX& x, const zz_pEX& a, const zz_pEX& f);
584inline zz_pEX InvMod(const zz_pEX& a, const zz_pEX& f)
585   { zz_pEX x; InvMod(x, a, f); NTL_OPT_RETURN(zz_pEX, x); }
586// x = a^{-1} % f, error is a is not invertible
587
588long InvModStatus(zz_pEX& x, const zz_pEX& a, const zz_pEX& f);
589// if (a, f) = 1, returns 0 and sets x = a^{-1} % f
590// otherwise, returns 1 and sets x = (a, f)
591
592
593
594
595
596/******************************************************************
597
598        Modular Arithmetic with Pre-conditioning
599
600*******************************************************************/
601
602
603// If you need to do a lot of arithmetic modulo a fixed f,
604// build zz_pEXModulus F for f.  This pre-computes information about f
605// that speeds up the computation a great deal.
606
607class zz_pEXModulus {
608public:
609   zz_pEXModulus();
610   ~zz_pEXModulus();
611
612   zz_pEXModulus(const zz_pEX& ff);
613
614   zz_pEX f;   // the modulus
615
616   operator const zz_pEX& () const { return f; }
617   const zz_pEX& val() const { return f; }
618
619   long n; //  deg(f)
620
621   long method;
622
623   zz_pEX h0;
624   zz_pE hlc;
625   zz_pEX f0;
626
627   vec_zz_pE tracevec; // mutable
628
629}; 
630
631
632
633inline long deg(const zz_pEXModulus& F) { return F.n; }
634
635
636void build(zz_pEXModulus& F, const zz_pEX& f);
637
638void rem(zz_pEX& r, const zz_pEX& a, const zz_pEXModulus& F);
639   
640void DivRem(zz_pEX& q, zz_pEX& r, const zz_pEX& a, const zz_pEXModulus& F);
641
642void div(zz_pEX& q, const zz_pEX& a, const zz_pEXModulus& F);
643
644void MulMod(zz_pEX& c, const zz_pEX& a, const zz_pEX& b, 
645            const zz_pEXModulus& F);
646inline zz_pEX MulMod(const zz_pEX& a, const zz_pEX& b, 
647            const zz_pEXModulus& F)
648   { zz_pEX x; MulMod(x, a, b, F); NTL_OPT_RETURN(zz_pEX, x); }
649
650void SqrMod(zz_pEX& c, const zz_pEX& a, const zz_pEXModulus& F);
651inline zz_pEX SqrMod(const zz_pEX& a, const zz_pEXModulus& F)
652   { zz_pEX x; SqrMod(x, a, F); NTL_OPT_RETURN(zz_pEX, x); }
653
654
655void PowerMod(zz_pEX& h, const zz_pEX& g, const ZZ& e, const zz_pEXModulus& F);
656
657inline void PowerMod(zz_pEX& h, const zz_pEX& g, long e, 
658                     const zz_pEXModulus& F)
659   { PowerMod(h, g, ZZ_expo(e), F); }
660
661inline zz_pEX PowerMod(const zz_pEX& g, const ZZ& e, 
662                             const zz_pEXModulus& F)
663   { zz_pEX x; PowerMod(x, g, e, F);  NTL_OPT_RETURN(zz_pEX, x); }
664
665inline zz_pEX PowerMod(const zz_pEX& g, long e, const zz_pEXModulus& F)
666   { zz_pEX x; PowerMod(x, g, e, F);  NTL_OPT_RETURN(zz_pEX, x); }
667
668void PowerXMod(zz_pEX& hh, const ZZ& e, const zz_pEXModulus& F);
669
670inline void PowerXMod(zz_pEX& h, long e, const zz_pEXModulus& F)
671   { PowerXMod(h, ZZ_expo(e), F); }
672
673
674inline zz_pEX PowerXMod(const ZZ& e, const zz_pEXModulus& F)
675   { zz_pEX x; PowerXMod(x, e, F);  NTL_OPT_RETURN(zz_pEX, x); }
676
677inline zz_pEX PowerXMod(long e, const zz_pEXModulus& F)
678   { zz_pEX x; PowerXMod(x, e, F);  NTL_OPT_RETURN(zz_pEX, x); }
679
680
681inline zz_pEX operator%(const zz_pEX& a, const zz_pEXModulus& F)
682   { zz_pEX x; rem(x, a, F); NTL_OPT_RETURN(zz_pEX, x); }
683
684inline zz_pEX& operator%=(zz_pEX& x, const zz_pEXModulus& F)
685   { rem(x, x, F); return x; }
686
687inline zz_pEX operator/(const zz_pEX& a, const zz_pEXModulus& F)
688   { zz_pEX x; div(x, a, F); NTL_OPT_RETURN(zz_pEX, x); }
689
690inline zz_pEX& operator/=(zz_pEX& x, const zz_pEXModulus& F)
691   { div(x, x, F); return x; }
692
693
694
695/*****************************************************************
696
697                       vectors of zz_pEX's
698
699*****************************************************************/
700
701
702
703NTL_vector_decl(zz_pEX,vec_zz_pEX)
704
705NTL_eq_vector_decl(zz_pEX,vec_zz_pEX)
706
707
708
709
710
711/*******************************************************
712
713              Evaluation and related problems
714
715********************************************************/
716
717
718
719
720void BuildFromRoots(zz_pEX& x, const vec_zz_pE& a);
721inline zz_pEX BuildFromRoots(const vec_zz_pE& a)
722   { zz_pEX x; BuildFromRoots(x, a); NTL_OPT_RETURN(zz_pEX, x); }
723// computes the polynomial (X-a[0]) ... (X-a[n-1]), where n = a.length()
724
725
726void eval(zz_pE& b, const zz_pEX& f, const zz_pE& a);
727inline zz_pE eval(const zz_pEX& f, const zz_pE& a)
728   { zz_pE x; eval(x, f, a); NTL_OPT_RETURN(zz_pE, x); }
729// b = f(a)
730
731void eval(vec_zz_pE& b, const zz_pEX& f, const vec_zz_pE& a);
732inline vec_zz_pE eval(const zz_pEX& f, const vec_zz_pE& a)
733   { vec_zz_pE x; eval(x, f, a); NTL_OPT_RETURN(vec_zz_pE, x); }
734//  b[i] = f(a[i])
735
736inline void eval(zz_pE& b, const zz_pX& f, const zz_pE& a)
737   { conv(b, CompMod(f, rep(a), zz_pE::modulus())); }
738   
739inline zz_pE eval(const zz_pX& f, const zz_pE& a)
740   { zz_pE x; eval(x, f, a); NTL_OPT_RETURN(zz_pE, x); }
741// b = f(a)
742
743
744void interpolate(zz_pEX& f, const vec_zz_pE& a, const vec_zz_pE& b);
745inline zz_pEX interpolate(const vec_zz_pE& a, const vec_zz_pE& b)
746   { zz_pEX x; interpolate(x, a, b); NTL_OPT_RETURN(zz_pEX, x); }
747// computes f such that f(a[i]) = b[i]
748
749
750
751
752
753/**********************************************************
754
755         Modular Composition and Minimal Polynomials
756
757***********************************************************/
758
759
760
761void CompMod(zz_pEX& x, const zz_pEX& g, const zz_pEX& h, const zz_pEXModulus& F);
762inline zz_pEX
763CompMod(const zz_pEX& g, const zz_pEX& h, const zz_pEXModulus& F)
764   { zz_pEX x; CompMod(x, g, h, F); NTL_OPT_RETURN(zz_pEX, x); }
765// x = g(h) mod f
766
767void Comp2Mod(zz_pEX& x1, zz_pEX& x2, const zz_pEX& g1, const zz_pEX& g2,
768              const zz_pEX& h, const zz_pEXModulus& F);
769// xi = gi(h) mod f (i=1,2)
770
771void Comp3Mod(zz_pEX& x1, zz_pEX& x2, zz_pEX& x3, 
772              const zz_pEX& g1, const zz_pEX& g2, const zz_pEX& g3,
773              const zz_pEX& h, const zz_pEXModulus& F);
774// xi = gi(h) mod f (i=1..3)
775
776
777
778// The routine build (see below) which is implicitly called
779// by the various compose and UpdateMap routines builds a table
780// of polynomials. 
781// If zz_pEXArgBound > 0, then the table is limited in
782// size to approximamtely that many KB.
783// If zz_pEXArgBound <= 0, then it is ignored, and space is allocated
784// so as to maximize speed.
785// Initially, zz_pEXArgBound = 0.
786
787
788// If a single h is going to be used with many g's
789// then you should build a zz_pEXArgument for h,
790// and then use the compose routine below.
791// build computes and stores h, h^2, ..., h^m mod f.
792// After this pre-computation, composing a polynomial of degree
793// roughly n with h takes n/m multiplies mod f, plus n^2
794// scalar multiplies.
795// Thus, increasing m increases the space requirement and the pre-computation
796// time, but reduces the composition time.
797// If zz_pEXArgBound > 0, a table of size less than m may be built.
798
799struct zz_pEXArgument {
800   vec_zz_pEX H;
801};
802
803extern long zz_pEXArgBound;
804
805
806void build(zz_pEXArgument& H, const zz_pEX& h, const zz_pEXModulus& F, long m);
807
808// m must be > 0, otherwise an error is raised
809
810void CompMod(zz_pEX& x, const zz_pEX& g, const zz_pEXArgument& H, 
811             const zz_pEXModulus& F);
812
813inline zz_pEX
814CompMod(const zz_pEX& g, const zz_pEXArgument& H, const zz_pEXModulus& F)
815   { zz_pEX x; CompMod(x, g, H, F); NTL_OPT_RETURN(zz_pEX, x); }
816   
817
818
819
820void MinPolySeq(zz_pEX& h, const vec_zz_pE& a, long m);
821inline zz_pEX MinPolySeq(const vec_zz_pE& a, long m)
822   { zz_pEX x; MinPolySeq(x, a, m); NTL_OPT_RETURN(zz_pEX, x); }
823
824
825void MinPolyMod(zz_pEX& hh, const zz_pEX& g, const zz_pEXModulus& F);
826inline zz_pEX MinPolyMod(const zz_pEX& g, const zz_pEXModulus& F)
827   { zz_pEX x; MinPolyMod(x, g, F); NTL_OPT_RETURN(zz_pEX, x); }
828
829
830void MinPolyMod(zz_pEX& hh, const zz_pEX& g, const zz_pEXModulus& F, long m);
831inline zz_pEX MinPolyMod(const zz_pEX& g, const zz_pEXModulus& F, long m)
832   { zz_pEX x; MinPolyMod(x, g, F, m); NTL_OPT_RETURN(zz_pEX, x); }
833
834void ProbMinPolyMod(zz_pEX& hh, const zz_pEX& g, const zz_pEXModulus& F);
835inline zz_pEX ProbMinPolyMod(const zz_pEX& g, const zz_pEXModulus& F)
836   { zz_pEX x; ProbMinPolyMod(x, g, F); NTL_OPT_RETURN(zz_pEX, x); }
837
838void ProbMinPolyMod(zz_pEX& hh, const zz_pEX& g, const zz_pEXModulus& F, long m);
839inline zz_pEX ProbMinPolyMod(const zz_pEX& g, const zz_pEXModulus& F, long m)
840   { zz_pEX x; ProbMinPolyMod(x, g, F, m); NTL_OPT_RETURN(zz_pEX, x); }
841
842void IrredPolyMod(zz_pEX& h, const zz_pEX& g, const zz_pEXModulus& F);
843inline zz_pEX IrredPolyMod(const zz_pEX& g, const zz_pEXModulus& F)
844   { zz_pEX x; IrredPolyMod(x, g, F); NTL_OPT_RETURN(zz_pEX, x); }
845
846void IrredPolyMod(zz_pEX& h, const zz_pEX& g, const zz_pEXModulus& F, long m);
847inline zz_pEX IrredPolyMod(const zz_pEX& g, const zz_pEXModulus& F, long m)
848   { zz_pEX x; IrredPolyMod(x, g, F, m); NTL_OPT_RETURN(zz_pEX, x); }
849
850
851struct zz_pEXTransMultiplier {
852   zz_pEX f0, fbi, b;
853   long shamt, shamt_fbi, shamt_b;
854};
855
856void build(zz_pEXTransMultiplier& B, const zz_pEX& b, const zz_pEXModulus& F);
857
858void TransMulMod(zz_pEX& x, const zz_pEX& a, const zz_pEXTransMultiplier& B,
859               const zz_pEXModulus& F);
860
861void UpdateMap(vec_zz_pE& x, const vec_zz_pE& a, 
862         const zz_pEXTransMultiplier& B, const zz_pEXModulus& F);
863
864inline vec_zz_pE UpdateMap(const vec_zz_pE& a,
865         const zz_pEXTransMultiplier& B, const zz_pEXModulus& F)
866   { vec_zz_pE x; UpdateMap(x, a, B, F); NTL_OPT_RETURN(vec_zz_pE, x); }
867
868void ProjectPowers(vec_zz_pE& x, const vec_zz_pE& a, long k, 
869                   const zz_pEXArgument& H, const zz_pEXModulus& F);
870inline vec_zz_pE ProjectPowers(const vec_zz_pE& a, long k, 
871                   const zz_pEXArgument& H, const zz_pEXModulus& F)
872   { vec_zz_pE x; ProjectPowers(x, a, k, H, F); NTL_OPT_RETURN(vec_zz_pE, x); }
873
874void ProjectPowers(vec_zz_pE& x, const vec_zz_pE& a, long k, const zz_pEX& h, 
875                   const zz_pEXModulus& F);
876inline vec_zz_pE ProjectPowers(const vec_zz_pE& a, long k, 
877                   const zz_pEX& H, const zz_pEXModulus& F)
878   { vec_zz_pE x; ProjectPowers(x, a, k, H, F); NTL_OPT_RETURN(vec_zz_pE, x); }
879
880inline void project(zz_pE& x, const vec_zz_pE& a, const zz_pEX& b)
881   { InnerProduct(x, a, b.rep); }
882
883inline zz_pE project(const vec_zz_pE& a, const zz_pEX& b)
884   { zz_pE x; InnerProduct(x, a, b.rep); NTL_OPT_RETURN(zz_pE, x); }
885
886
887
888/*****************************************************************
889
890          modular composition and minimal polynonomials
891                         in towers
892
893******************************************************************/
894
895
896// composition
897
898void CompTower(zz_pEX& x, const zz_pX& g, const zz_pEXArgument& A,
899             const zz_pEXModulus& F);
900
901inline zz_pEX CompTower(const zz_pX& g, const zz_pEXArgument& A,
902             const zz_pEXModulus& F)
903   { zz_pEX x; CompTower(x, g, A, F); NTL_OPT_RETURN(zz_pEX, x); }
904
905void CompTower(zz_pEX& x, const zz_pX& g, const zz_pEX& h,
906             const zz_pEXModulus& F);
907
908inline zz_pEX CompTower(const zz_pX& g, const zz_pEX& h,
909             const zz_pEXModulus& F)
910   { zz_pEX x; CompTower(x, g, h, F); NTL_OPT_RETURN(zz_pEX, x); }
911
912// prob min poly
913
914void ProbMinPolyTower(zz_pX& h, const zz_pEX& g, const zz_pEXModulus& F,
915                      long m);
916
917inline zz_pX ProbMinPolyTower(const zz_pEX& g, const zz_pEXModulus& F,
918                      long m)
919   { zz_pX x; ProbMinPolyTower(x, g, F, m); NTL_OPT_RETURN(zz_pX, x); }
920
921inline void ProbMinPolyTower(zz_pX& h, const zz_pEX& g, 
922                             const zz_pEXModulus& F)
923   { ProbMinPolyTower(h, g, F, deg(F)*zz_pE::degree()); }
924
925inline zz_pX ProbMinPolyTower(const zz_pEX& g, const zz_pEXModulus& F)
926   { zz_pX x; ProbMinPolyTower(x, g, F); NTL_OPT_RETURN(zz_pX, x); }
927
928
929// min poly
930
931
932void MinPolyTower(zz_pX& h, const zz_pEX& g, const zz_pEXModulus& F,
933                      long m);
934
935inline zz_pX MinPolyTower(const zz_pEX& g, const zz_pEXModulus& F,
936                      long m)
937   { zz_pX x; MinPolyTower(x, g, F, m); NTL_OPT_RETURN(zz_pX, x); }
938
939inline void MinPolyTower(zz_pX& h, const zz_pEX& g, 
940                             const zz_pEXModulus& F)
941   { MinPolyTower(h, g, F, deg(F)*zz_pE::degree()); }
942
943inline zz_pX MinPolyTower(const zz_pEX& g, const zz_pEXModulus& F)
944   { zz_pX x; MinPolyTower(x, g, F); NTL_OPT_RETURN(zz_pX, x); }
945
946// irred poly
947
948
949void IrredPolyTower(zz_pX& h, const zz_pEX& g, const zz_pEXModulus& F,
950                      long m);
951
952inline zz_pX IrredPolyTower(const zz_pEX& g, const zz_pEXModulus& F,
953                      long m)
954   { zz_pX x; IrredPolyTower(x, g, F, m); NTL_OPT_RETURN(zz_pX, x); }
955
956inline void IrredPolyTower(zz_pX& h, const zz_pEX& g, 
957                             const zz_pEXModulus& F)
958   { IrredPolyTower(h, g, F, deg(F)*zz_pE::degree()); }
959
960inline zz_pX IrredPolyTower(const zz_pEX& g, const zz_pEXModulus& F)
961   { zz_pX x; IrredPolyTower(x, g, F); NTL_OPT_RETURN(zz_pX, x); }
962
963/*****************************************************************
964
965                   Traces, norms, resultants
966
967******************************************************************/
968
969void TraceVec(vec_zz_pE& S, const zz_pEX& f);
970
971inline vec_zz_pE TraceVec(const zz_pEX& f)
972   { vec_zz_pE x; TraceVec(x, f); NTL_OPT_RETURN(vec_zz_pE, x); }
973
974
975void TraceMod(zz_pE& x, const zz_pEX& a, const zz_pEXModulus& F);
976
977inline zz_pE TraceMod(const zz_pEX& a, const zz_pEXModulus& F)
978   { zz_pE x; TraceMod(x, a, F); NTL_OPT_RETURN(zz_pE, x); }
979
980void TraceMod(zz_pE& x, const zz_pEX& a, const zz_pEX& f);
981
982inline zz_pE TraceMod(const zz_pEX& a, const zz_pEX& f)
983   { zz_pE x; TraceMod(x, a, f); NTL_OPT_RETURN(zz_pE, x); }
984
985
986
987
988
989void NormMod(zz_pE& x, const zz_pEX& a, const zz_pEX& f);
990
991inline zz_pE NormMod(const zz_pEX& a, const zz_pEX& f)
992   { zz_pE x; NormMod(x, a, f); NTL_OPT_RETURN(zz_pE, x); }
993
994void resultant(zz_pE& rres, const zz_pEX& a, const zz_pEX& b);
995
996inline zz_pE resultant(const zz_pEX& a, const zz_pEX& b)
997   { zz_pE x; resultant(x, a, b); NTL_OPT_RETURN(zz_pE, x); }
998
999NTL_CLOSE_NNS
1000
1001#endif
Note: See TracBrowser for help on using the repository browser.