1 /*
2     Copyright (C) 2021 William Hart
3 
4     This file is part of FLINT.
5 
6     FLINT is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
10 */
11 
12 #ifndef FQ_DEFAULT_POLY_H
13 #define FQ_DEFAULT_POLY_H
14 
15 #ifdef FQ_DEFAULT_POLY_INLINES_C
16 #define FQ_DEFAULT_POLY_INLINE FLINT_DLL
17 #else
18 #define FQ_DEFAULT_POLY_INLINE static __inline__
19 #endif
20 
21 #include "ulong_extras.h"
22 #include "fmpz.h"
23 #include "fq.h"
24 #include "fq_nmod.h"
25 #include "fq_zech.h"
26 #include "fq_default.h"
27 #include "fq_poly.h"
28 #include "fq_nmod_poly.h"
29 #include "fq_zech_poly.h"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /*  Type definitions *********************************************************/
36 
37 typedef union fq_default_poly_struct
38 {
39     fq_poly_t fq;
40     fq_nmod_poly_t fq_nmod;
41     fq_zech_poly_t fq_zech;
42 }
43 fq_default_poly_struct;
44 
45 typedef fq_default_poly_struct fq_default_poly_t[1];
46 
47 /*  Memory management ********************************************************/
48 
fq_default_poly_init(fq_default_poly_t poly,const fq_default_ctx_t ctx)49 FQ_DEFAULT_POLY_INLINE void fq_default_poly_init(fq_default_poly_t poly,
50                                                     const fq_default_ctx_t ctx)
51 {
52    if (ctx->type == 1)
53    {
54       fq_zech_poly_init(poly->fq_zech, ctx->ctx.fq_zech);
55    } else if (ctx->type == 2)
56    {
57       fq_nmod_poly_init(poly->fq_nmod, ctx->ctx.fq_nmod);
58    } else
59    {
60       fq_poly_init(poly->fq, ctx->ctx.fq);
61    }
62 }
63 
fq_default_poly_init2(fq_default_poly_t poly,slong alloc,const fq_default_ctx_t ctx)64 FQ_DEFAULT_POLY_INLINE void fq_default_poly_init2(fq_default_poly_t poly,
65                                        slong alloc, const fq_default_ctx_t ctx)
66 {
67    if (ctx->type == 1)
68    {
69       fq_zech_poly_init2(poly->fq_zech, alloc, ctx->ctx.fq_zech);
70    } else if (ctx->type == 2)
71    {
72       fq_nmod_poly_init2(poly->fq_nmod, alloc, ctx->ctx.fq_nmod);
73    } else
74    {
75       fq_poly_init2(poly->fq, alloc, ctx->ctx.fq);
76    }
77 }
78 
fq_default_poly_realloc(fq_default_poly_t poly,slong alloc,const fq_default_ctx_t ctx)79 FQ_DEFAULT_POLY_INLINE void fq_default_poly_realloc(fq_default_poly_t poly,
80                                        slong alloc, const fq_default_ctx_t ctx)
81 {
82    if (ctx->type == 1)
83    {
84       fq_zech_poly_realloc(poly->fq_zech, alloc, ctx->ctx.fq_zech);
85    } else if (ctx->type == 2)
86    {
87       fq_nmod_poly_realloc(poly->fq_nmod, alloc, ctx->ctx.fq_nmod);
88    } else
89    {
90       fq_poly_realloc(poly->fq, alloc, ctx->ctx.fq);
91    }
92 }
93 
fq_default_poly_truncate(fq_default_poly_t poly,slong len,const fq_default_ctx_t ctx)94 FQ_DEFAULT_POLY_INLINE void fq_default_poly_truncate(fq_default_poly_t poly,
95                                          slong len, const fq_default_ctx_t ctx)
96 {
97    if (ctx->type == 1)
98    {
99       fq_zech_poly_truncate(poly->fq_zech, len, ctx->ctx.fq_zech);
100    } else if (ctx->type == 2)
101    {
102       fq_nmod_poly_truncate(poly->fq_nmod, len, ctx->ctx.fq_nmod);
103    } else
104    {
105       fq_poly_truncate(poly->fq, len, ctx->ctx.fq);
106    }
107 }
108 
fq_default_poly_set_trunc(fq_default_poly_t poly1,fq_default_poly_t poly2,slong len,const fq_default_ctx_t ctx)109 FQ_DEFAULT_POLY_INLINE void fq_default_poly_set_trunc(fq_default_poly_t poly1,
110                 fq_default_poly_t poly2, slong len, const fq_default_ctx_t ctx)
111 {
112    if (ctx->type == 1)
113    {
114       fq_zech_poly_set_trunc(poly1->fq_zech,
115 		                        poly2->fq_zech, len, ctx->ctx.fq_zech);
116    } else if (ctx->type == 2)
117    {
118       fq_nmod_poly_set_trunc(poly1->fq_nmod,
119 		                        poly2->fq_nmod, len, ctx->ctx.fq_nmod);
120    } else
121    {
122       fq_poly_set_trunc(poly1->fq, poly2->fq, len, ctx->ctx.fq);
123    }
124 }
125 
fq_default_poly_fit_length(fq_default_poly_t poly,slong len,const fq_default_ctx_t ctx)126 FQ_DEFAULT_POLY_INLINE void fq_default_poly_fit_length(fq_default_poly_t poly,
127                                          slong len, const fq_default_ctx_t ctx)
128 {
129    if (ctx->type == 1)
130    {
131       fq_zech_poly_fit_length(poly->fq_zech, len, ctx->ctx.fq_zech);
132    } else if (ctx->type == 2)
133    {
134       fq_nmod_poly_fit_length(poly->fq_nmod, len, ctx->ctx.fq_nmod);
135    } else
136    {
137       fq_poly_fit_length(poly->fq, len, ctx->ctx.fq);
138    }
139 }
140 
141 FQ_DEFAULT_POLY_INLINE
_fq_default_poly_set_length(fq_default_poly_t poly,slong len,const fq_default_ctx_t ctx)142 void _fq_default_poly_set_length(fq_default_poly_t poly,
143                                          slong len, const fq_default_ctx_t ctx)
144 {
145    if (ctx->type == 1)
146    {
147       _fq_zech_poly_set_length(poly->fq_zech, len, ctx->ctx.fq_zech);
148    } else if (ctx->type == 2)
149    {
150       _fq_nmod_poly_set_length(poly->fq_nmod, len, ctx->ctx.fq_nmod);
151    } else
152    {
153       _fq_poly_set_length(poly->fq, len, ctx->ctx.fq);
154    }
155 }
156 
fq_default_poly_clear(fq_default_poly_t poly,const fq_default_ctx_t ctx)157 FQ_DEFAULT_POLY_INLINE void fq_default_poly_clear(fq_default_poly_t poly,
158                                                     const fq_default_ctx_t ctx)
159 {
160    if (ctx->type == 1)
161    {
162       fq_zech_poly_clear(poly->fq_zech, ctx->ctx.fq_zech);
163    } else if (ctx->type == 2)
164    {
165       fq_nmod_poly_clear(poly->fq_nmod, ctx->ctx.fq_nmod);
166    } else
167    {
168       fq_poly_clear(poly->fq, ctx->ctx.fq);
169    }
170 }
171 
172 /*  Polynomial parameters  ***************************************************/
173 
174 FQ_DEFAULT_POLY_INLINE slong
fq_default_poly_length(const fq_default_poly_t poly,const fq_default_ctx_t ctx)175 fq_default_poly_length(const fq_default_poly_t poly,
176 		                                    const fq_default_ctx_t ctx)
177 {
178    if (ctx->type == 1)
179    {
180       return fq_zech_poly_length(poly->fq_zech, ctx->ctx.fq_zech);
181    } else if (ctx->type == 2)
182    {
183       return fq_nmod_poly_length(poly->fq_nmod, ctx->ctx.fq_nmod);
184    }
185    return fq_poly_length(poly->fq, ctx->ctx.fq);
186 }
187 
188 FQ_DEFAULT_POLY_INLINE slong
fq_default_poly_degree(const fq_default_poly_t poly,const fq_default_ctx_t ctx)189 fq_default_poly_degree(const fq_default_poly_t poly,
190                                                     const fq_default_ctx_t ctx)
191 {
192    if (ctx->type == 1)
193    {
194       return fq_zech_poly_degree(poly->fq_zech, ctx->ctx.fq_zech);
195    } else if (ctx->type == 2)
196    {
197       return fq_nmod_poly_degree(poly->fq_nmod, ctx->ctx.fq_nmod);
198    }
199    return fq_poly_degree(poly->fq, ctx->ctx.fq);
200 }
201 
202 /*  Randomisation  ***********************************************************/
203 
fq_default_poly_randtest(fq_default_poly_t f,flint_rand_t state,slong len,const fq_default_ctx_t ctx)204 FQ_DEFAULT_POLY_INLINE void fq_default_poly_randtest(fq_default_poly_t f,
205                      flint_rand_t state, slong len, const fq_default_ctx_t ctx)
206 {
207    if (ctx->type == 1)
208    {
209       fq_zech_poly_randtest(f->fq_zech, state, len, ctx->ctx.fq_zech);
210    } else if (ctx->type == 2)
211    {
212       fq_nmod_poly_randtest(f->fq_nmod, state, len, ctx->ctx.fq_nmod);
213    } else
214    {
215       fq_poly_randtest(f->fq, state, len, ctx->ctx.fq);
216    }
217 }
218 
219 FQ_DEFAULT_POLY_INLINE
fq_default_poly_randtest_not_zero(fq_default_poly_t f,flint_rand_t state,slong len,const fq_default_ctx_t ctx)220 void fq_default_poly_randtest_not_zero(fq_default_poly_t f,
221                      flint_rand_t state, slong len, const fq_default_ctx_t ctx)
222 {
223    if (ctx->type == 1)
224    {
225       fq_zech_poly_randtest_not_zero(f->fq_zech, state, len, ctx->ctx.fq_zech);
226    } else if (ctx->type == 2)
227    {
228       fq_nmod_poly_randtest_not_zero(f->fq_nmod, state, len, ctx->ctx.fq_nmod);
229    } else
230    {
231       fq_poly_randtest_not_zero(f->fq, state, len, ctx->ctx.fq);
232    }
233 }
234 
235 FQ_DEFAULT_POLY_INLINE
fq_default_poly_randtest_monic(fq_default_poly_t f,flint_rand_t state,slong len,const fq_default_ctx_t ctx)236 void fq_default_poly_randtest_monic(fq_default_poly_t f,
237                      flint_rand_t state, slong len, const fq_default_ctx_t ctx)
238 {
239    if (ctx->type == 1)
240    {
241       fq_zech_poly_randtest_monic(f->fq_zech, state, len, ctx->ctx.fq_zech);
242    } else if (ctx->type == 2)
243    {
244       fq_nmod_poly_randtest_monic(f->fq_nmod, state, len, ctx->ctx.fq_nmod);
245    } else
246    {
247       fq_poly_randtest_monic(f->fq, state, len, ctx->ctx.fq);
248    }
249 }
250 
251 FQ_DEFAULT_POLY_INLINE
fq_default_poly_randtest_irreducible(fq_default_poly_t f,flint_rand_t state,slong len,const fq_default_ctx_t ctx)252 void fq_default_poly_randtest_irreducible(fq_default_poly_t f,
253                      flint_rand_t state, slong len, const fq_default_ctx_t ctx)
254 {
255    if (ctx->type == 1)
256    {
257       fq_zech_poly_randtest_irreducible(f->fq_zech,
258                                                  state, len, ctx->ctx.fq_zech);
259    } else if (ctx->type == 2)
260    {
261       fq_nmod_poly_randtest_irreducible(f->fq_nmod,
262                                                  state, len, ctx->ctx.fq_nmod);
263    } else
264    {
265       fq_poly_randtest_irreducible(f->fq, state, len, ctx->ctx.fq);
266    }
267 }
268 
269 /*  Assignment and basic manipulation  ***************************************/
270 
fq_default_poly_set(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_ctx_t ctx)271 FQ_DEFAULT_POLY_INLINE void fq_default_poly_set(fq_default_poly_t rop,
272                         const fq_default_poly_t op, const fq_default_ctx_t ctx)
273 {
274    if (ctx->type == 1)
275    {
276       fq_zech_poly_set(rop->fq_zech, op->fq_zech, ctx->ctx.fq_zech);
277    } else if (ctx->type == 2)
278    {
279       fq_nmod_poly_set(rop->fq_nmod, op->fq_nmod, ctx->ctx.fq_nmod);
280    } else
281    {
282       fq_poly_set(rop->fq, op->fq, ctx->ctx.fq);
283    }
284 }
285 
286 FQ_DEFAULT_POLY_INLINE
fq_default_poly_set_fq_default(fq_default_poly_t poly,const fq_default_t c,const fq_default_ctx_t ctx)287 void fq_default_poly_set_fq_default(fq_default_poly_t poly,
288                               const fq_default_t c, const fq_default_ctx_t ctx)
289 {
290    if (ctx->type == 1)
291    {
292       fq_zech_poly_set_fq_zech(poly->fq_zech, c->fq_zech, ctx->ctx.fq_zech);
293    } else if (ctx->type == 2)
294    {
295       fq_nmod_poly_set_fq_nmod(poly->fq_nmod, c->fq_nmod, ctx->ctx.fq_nmod);
296    } else
297    {
298       fq_poly_set_fq(poly->fq, c->fq, ctx->ctx.fq);
299    }
300 }
301 
fq_default_poly_swap(fq_default_poly_t op1,fq_default_poly_t op2,const fq_default_ctx_t ctx)302 FQ_DEFAULT_POLY_INLINE void fq_default_poly_swap(fq_default_poly_t op1,
303                              fq_default_poly_t op2, const fq_default_ctx_t ctx)
304 {
305    if (ctx->type == 1)
306    {
307       fq_zech_poly_swap(op1->fq_zech, op2->fq_zech, ctx->ctx.fq_zech);
308    } else if (ctx->type == 2)
309    {
310       fq_nmod_poly_swap(op1->fq_nmod, op2->fq_nmod, ctx->ctx.fq_nmod);
311    } else
312    {
313       fq_poly_swap(op1->fq, op2->fq, ctx->ctx.fq);
314    }
315 }
316 
317 FQ_DEFAULT_POLY_INLINE void
fq_default_poly_zero(fq_default_poly_t poly,const fq_default_ctx_t ctx)318 fq_default_poly_zero(fq_default_poly_t poly, const fq_default_ctx_t ctx)
319 {
320    if (ctx->type == 1)
321    {
322       fq_zech_poly_zero(poly->fq_zech, ctx->ctx.fq_zech);
323    } else if (ctx->type == 2)
324    {
325       fq_nmod_poly_zero(poly->fq_nmod, ctx->ctx.fq_nmod);
326    } else
327    {
328       fq_poly_zero(poly->fq, ctx->ctx.fq);
329    }
330 }
331 
fq_default_poly_one(fq_default_poly_t poly,const fq_default_ctx_t ctx)332 FQ_DEFAULT_POLY_INLINE void fq_default_poly_one(fq_default_poly_t poly,
333                                                     const fq_default_ctx_t ctx)
334 {
335    if (ctx->type == 1)
336    {
337       fq_zech_poly_one(poly->fq_zech, ctx->ctx.fq_zech);
338    } else if (ctx->type == 2)
339    {
340       fq_nmod_poly_one(poly->fq_nmod, ctx->ctx.fq_nmod);
341    } else
342    {
343       fq_poly_one(poly->fq, ctx->ctx.fq);
344    }
345 }
346 
fq_default_poly_gen(fq_default_poly_t f,const fq_default_ctx_t ctx)347 FQ_DEFAULT_POLY_INLINE void fq_default_poly_gen(fq_default_poly_t f,
348                                                     const fq_default_ctx_t ctx)
349 {
350    if (ctx->type == 1)
351    {
352       fq_zech_poly_gen(f->fq_zech, ctx->ctx.fq_zech);
353    } else if (ctx->type == 2)
354    {
355       fq_nmod_poly_gen(f->fq_nmod, ctx->ctx.fq_nmod);
356    } else
357    {
358       fq_poly_gen(f->fq, ctx->ctx.fq);
359    }
360 }
361 
fq_default_poly_make_monic(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_ctx_t ctx)362 FQ_DEFAULT_POLY_INLINE void fq_default_poly_make_monic(fq_default_poly_t rop,
363                         const fq_default_poly_t op, const fq_default_ctx_t ctx)
364 {
365    if (ctx->type == 1)
366    {
367       fq_zech_poly_make_monic(rop->fq_zech, op->fq_zech, ctx->ctx.fq_zech);
368    } else if (ctx->type == 2)
369    {
370       fq_nmod_poly_make_monic(rop->fq_nmod, op->fq_nmod, ctx->ctx.fq_nmod);
371    } else
372    {
373       fq_poly_make_monic(rop->fq, op->fq, ctx->ctx.fq);
374    }
375 }
376 
fq_default_poly_reverse(fq_default_poly_t res,const fq_default_poly_t poly,slong n,const fq_default_ctx_t ctx)377 FQ_DEFAULT_POLY_INLINE void fq_default_poly_reverse(fq_default_poly_t res,
378              const fq_default_poly_t poly, slong n, const fq_default_ctx_t ctx)
379 {
380    if (ctx->type == 1)
381    {
382       fq_zech_poly_reverse(res->fq_zech, poly->fq_zech, n, ctx->ctx.fq_zech);
383    } else if (ctx->type == 2)
384    {
385       fq_nmod_poly_reverse(res->fq_nmod, poly->fq_nmod, n, ctx->ctx.fq_nmod);
386    } else
387    {
388       fq_poly_reverse(res->fq, poly->fq, n, ctx->ctx.fq);
389    }
390 }
391 
392 FQ_DEFAULT_POLY_INLINE
fq_default_poly_deflation(const fq_default_poly_t input,const fq_default_ctx_t ctx)393 ulong fq_default_poly_deflation(const fq_default_poly_t input,
394                                                     const fq_default_ctx_t ctx)
395 {
396    if (ctx->type == 1)
397    {
398       return fq_zech_poly_deflation(input->fq_zech, ctx->ctx.fq_zech);
399    } else if (ctx->type == 2)
400    {
401       return fq_nmod_poly_deflation(input->fq_nmod, ctx->ctx.fq_nmod);
402    }
403    return fq_poly_deflation(input->fq, ctx->ctx.fq);
404 }
405 
fq_default_poly_deflate(fq_default_poly_t result,const fq_default_poly_t input,ulong deflation,const fq_default_ctx_t ctx)406 FQ_DEFAULT_POLY_INLINE void fq_default_poly_deflate(fq_default_poly_t result,
407     const fq_default_poly_t input, ulong deflation, const fq_default_ctx_t ctx)
408 {
409    if (ctx->type == 1)
410    {
411       fq_zech_poly_deflate(result->fq_zech,
412                                   input->fq_zech, deflation, ctx->ctx.fq_zech);
413    } else if (ctx->type == 2)
414    {
415       fq_nmod_poly_deflate(result->fq_nmod,
416                                   input->fq_nmod, deflation, ctx->ctx.fq_nmod);
417    } else
418    {
419       fq_poly_deflate(result->fq, input->fq, deflation, ctx->ctx.fq);
420    }
421 }
422 
fq_default_poly_inflate(fq_default_poly_t result,const fq_default_poly_t input,ulong inflation,const fq_default_ctx_t ctx)423 FQ_DEFAULT_POLY_INLINE void fq_default_poly_inflate(fq_default_poly_t result,
424     const fq_default_poly_t input, ulong inflation, const fq_default_ctx_t ctx)
425 {
426    if (ctx->type == 1)
427    {
428       fq_zech_poly_inflate(result->fq_zech,
429                                   input->fq_zech, inflation, ctx->ctx.fq_zech);
430    } else if (ctx->type == 2)
431    {
432       fq_nmod_poly_inflate(result->fq_nmod,
433                                   input->fq_nmod, inflation, ctx->ctx.fq_nmod);
434    } else
435    {
436       fq_poly_inflate(result->fq, input->fq, inflation, ctx->ctx.fq);
437    }
438 }
439 
440 /*  Getting and setting coefficients  ****************************************/
441 
fq_default_poly_get_coeff(fq_default_t x,const fq_default_poly_t poly,slong n,const fq_default_ctx_t ctx)442 FQ_DEFAULT_POLY_INLINE void fq_default_poly_get_coeff(fq_default_t x,
443              const fq_default_poly_t poly, slong n, const fq_default_ctx_t ctx)
444 {
445    if (ctx->type == 1)
446    {
447       fq_zech_poly_get_coeff(x->fq_zech, poly->fq_zech, n, ctx->ctx.fq_zech);
448    } else if (ctx->type == 2)
449    {
450       fq_nmod_poly_get_coeff(x->fq_nmod, poly->fq_nmod, n, ctx->ctx.fq_nmod);
451    } else
452    {
453       fq_poly_get_coeff(x->fq, poly->fq, n, ctx->ctx.fq);
454    }
455 }
456 
fq_default_poly_set_coeff(fq_default_poly_t poly,slong n,const fq_default_t x,const fq_default_ctx_t ctx)457 FQ_DEFAULT_POLY_INLINE void fq_default_poly_set_coeff(fq_default_poly_t poly,
458                      slong n, const fq_default_t x, const fq_default_ctx_t ctx)
459 {
460    if (ctx->type == 1)
461    {
462       fq_zech_poly_set_coeff(poly->fq_zech, n, x->fq_zech, ctx->ctx.fq_zech);
463    } else if (ctx->type == 2)
464    {
465       fq_nmod_poly_set_coeff(poly->fq_nmod, n, x->fq_nmod, ctx->ctx.fq_nmod);
466    } else
467    {
468       fq_poly_set_coeff(poly->fq, n, x->fq, ctx->ctx.fq);
469    }
470 }
471 
472 FQ_DEFAULT_POLY_INLINE void
fq_default_poly_set_coeff_fmpz(fq_default_poly_t poly,slong n,const fmpz_t x,const fq_default_ctx_t ctx)473 fq_default_poly_set_coeff_fmpz(fq_default_poly_t poly,
474                            slong n, const fmpz_t x, const fq_default_ctx_t ctx)
475 {
476    if (ctx->type == 1)
477    {
478       fq_zech_poly_set_coeff_fmpz(poly->fq_zech, n, x, ctx->ctx.fq_zech);
479    } else if (ctx->type == 2)
480    {
481       fq_nmod_poly_set_coeff_fmpz(poly->fq_nmod, n, x, ctx->ctx.fq_nmod);
482    } else
483    {
484       fq_poly_set_coeff_fmpz(poly->fq, n, x, ctx->ctx.fq);
485    }
486 }
487 
488 FQ_DEFAULT_POLY_INLINE
fq_default_poly_set_nmod_poly(fq_default_poly_t rop,const nmod_poly_t op,const fq_default_ctx_t ctx)489 void fq_default_poly_set_nmod_poly(fq_default_poly_t rop,
490                           const     nmod_poly_t op, const fq_default_ctx_t ctx)
491 {
492    if (ctx->type == 1)
493    {
494       fq_zech_poly_set_nmod_poly(rop->fq_zech, op, ctx->ctx.fq_zech);
495    } else if (ctx->type == 2)
496    {
497       fq_nmod_poly_set_nmod_poly(rop->fq_nmod, op, ctx->ctx.fq_nmod);
498    } else
499    {
500       fq_poly_set_nmod_poly(rop->fq, op, ctx->ctx.fq);
501    }
502 }
503 
504 FQ_DEFAULT_POLY_INLINE
fq_default_poly_set_fmpz_mod_poly(fq_default_poly_t rop,const fmpz_mod_poly_t op,const fq_default_ctx_t ctx)505 void fq_default_poly_set_fmpz_mod_poly(fq_default_poly_t rop,
506                           const fmpz_mod_poly_t op, const fq_default_ctx_t ctx)
507 {
508    if (ctx->type == 1)
509    {
510       fq_zech_poly_set_fmpz_mod_poly(rop->fq_zech, op, ctx->ctx.fq_zech);
511    } else if (ctx->type == 2)
512    {
513       fq_nmod_poly_set_fmpz_mod_poly(rop->fq_nmod, op, ctx->ctx.fq_nmod);
514    } else
515    {
516       fq_poly_set_fmpz_mod_poly(rop->fq, op, ctx->ctx.fq);
517    }
518 }
519 
520 FLINT_DLL
521 void fq_default_poly_set_fmpz_poly(fq_default_poly_t rop,
522                              const fmpz_poly_t op, const fq_default_ctx_t ctx);
523 
524 /*  Comparison  **************************************************************/
525 
526 FQ_DEFAULT_POLY_INLINE
fq_default_poly_equal(const fq_default_poly_t poly1,const fq_default_poly_t poly2,const fq_default_ctx_t ctx)527 int fq_default_poly_equal(const fq_default_poly_t poly1,
528                      const fq_default_poly_t poly2, const fq_default_ctx_t ctx)
529 {
530    if (ctx->type == 1)
531    {
532       return fq_zech_poly_equal(poly1->fq_zech, poly2->fq_zech, ctx->ctx.fq_zech);
533    } else if (ctx->type == 2)
534    {
535       return fq_nmod_poly_equal(poly1->fq_nmod, poly2->fq_nmod, ctx->ctx.fq_nmod);
536    }
537    return fq_poly_equal(poly1->fq, poly2->fq, ctx->ctx.fq);
538 }
539 
540 FQ_DEFAULT_POLY_INLINE
fq_default_poly_equal_trunc(const fq_default_poly_t poly1,const fq_default_poly_t poly2,slong n,const fq_default_ctx_t ctx)541 int fq_default_poly_equal_trunc(const fq_default_poly_t poly1,
542             const fq_default_poly_t poly2, slong n, const fq_default_ctx_t ctx)
543 {
544    if (ctx->type == 1)
545    {
546       return fq_zech_poly_equal_trunc(poly1->fq_zech,
547                                           poly2->fq_zech, n, ctx->ctx.fq_zech);
548    } else if (ctx->type == 2)
549    {
550       return fq_nmod_poly_equal_trunc(poly1->fq_nmod,
551                                           poly2->fq_nmod, n, ctx->ctx.fq_nmod);
552    }
553    return fq_poly_equal_trunc(poly1->fq, poly2->fq, n, ctx->ctx.fq);
554 }
555 
556 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_is_zero(const fq_default_poly_t poly,const fq_default_ctx_t ctx)557 fq_default_poly_is_zero(const fq_default_poly_t poly,
558 		                                    const fq_default_ctx_t ctx)
559 {
560    if (ctx->type == 1)
561    {
562       return fq_zech_poly_is_zero(poly->fq_zech, ctx->ctx.fq_zech);
563    } else if (ctx->type == 2)
564    {
565       return fq_nmod_poly_is_zero(poly->fq_nmod, ctx->ctx.fq_nmod);
566    }
567    return fq_poly_is_zero(poly->fq, ctx->ctx.fq);
568 }
569 
570 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_is_one(const fq_default_poly_t op,const fq_default_ctx_t ctx)571 fq_default_poly_is_one(const fq_default_poly_t op, const fq_default_ctx_t ctx)
572 {
573    if (ctx->type == 1)
574    {
575       return fq_zech_poly_is_one(op->fq_zech, ctx->ctx.fq_zech);
576    } else if (ctx->type == 2)
577    {
578       return fq_nmod_poly_is_one(op->fq_nmod, ctx->ctx.fq_nmod);
579    }
580    return fq_poly_is_one(op->fq, ctx->ctx.fq);
581 }
582 
583 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_is_unit(const fq_default_poly_t op,const fq_default_ctx_t ctx)584 fq_default_poly_is_unit(const fq_default_poly_t op, const fq_default_ctx_t ctx)
585 {
586    if (ctx->type == 1)
587    {
588       return fq_zech_poly_is_unit(op->fq_zech, ctx->ctx.fq_zech);
589    } else if (ctx->type == 2)
590    {
591       return fq_nmod_poly_is_unit(op->fq_nmod, ctx->ctx.fq_nmod);
592    }
593    return fq_poly_is_unit(op->fq, ctx->ctx.fq);
594 }
595 
596 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_is_gen(const fq_default_poly_t poly,const fq_default_ctx_t ctx)597 fq_default_poly_is_gen(const fq_default_poly_t poly,
598 		                                    const fq_default_ctx_t ctx)
599 {
600    if (ctx->type == 1)
601    {
602       return fq_zech_poly_is_gen(poly->fq_zech, ctx->ctx.fq_zech);
603    } else if (ctx->type == 2)
604    {
605       return fq_nmod_poly_is_gen(poly->fq_nmod, ctx->ctx.fq_nmod);
606    }
607    return fq_poly_is_gen(poly->fq, ctx->ctx.fq);
608 }
609 
610 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_equal_fq_default(const fq_default_poly_t poly,const fq_default_t c,const fq_default_ctx_t ctx)611 fq_default_poly_equal_fq_default(const fq_default_poly_t poly,
612                               const fq_default_t c, const fq_default_ctx_t ctx)
613 {
614    if (ctx->type == 1)
615    {
616       return fq_zech_poly_equal_fq_zech(poly->fq_zech,
617 		                                 c->fq_zech, ctx->ctx.fq_zech);
618    } else if (ctx->type == 2)
619    {
620       return fq_nmod_poly_equal_fq_nmod(poly->fq_nmod,
621 		                                 c->fq_nmod, ctx->ctx.fq_nmod);
622    }
623    return fq_poly_equal_fq(poly->fq, c->fq, ctx->ctx.fq);
624 }
625 
626 /*  Addition and subtraction  ************************************************/
627 
628 FQ_DEFAULT_POLY_INLINE
fq_default_poly_add(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,const fq_default_ctx_t ctx)629 void fq_default_poly_add(fq_default_poly_t rop, const fq_default_poly_t op1,
630                        const fq_default_poly_t op2, const fq_default_ctx_t ctx)
631 {
632    if (ctx->type == 1)
633    {
634       fq_zech_poly_add(rop->fq_zech,
635                                  op1->fq_zech, op2->fq_zech, ctx->ctx.fq_zech);
636    } else if (ctx->type == 2)
637    {
638       fq_nmod_poly_add(rop->fq_nmod,
639                                  op1->fq_nmod, op2->fq_nmod, ctx->ctx.fq_nmod);
640    } else
641    {
642       fq_poly_add(rop->fq, op1->fq, op2->fq, ctx->ctx.fq);
643    }
644 }
645 
fq_default_poly_add_si(fq_default_poly_t rop,const fq_default_poly_t op1,slong c,const fq_default_ctx_t ctx)646 FQ_DEFAULT_POLY_INLINE void fq_default_poly_add_si(fq_default_poly_t rop,
647               const fq_default_poly_t op1, slong c, const fq_default_ctx_t ctx)
648 {
649    if (ctx->type == 1)
650    {
651       fq_zech_poly_add_si(rop->fq_zech, op1->fq_zech, c, ctx->ctx.fq_zech);
652    } else if (ctx->type == 2)
653    {
654       fq_nmod_poly_add_si(rop->fq_nmod, op1->fq_nmod, c, ctx->ctx.fq_nmod);
655    } else
656    {
657       fq_poly_add_si(rop->fq, op1->fq, c, ctx->ctx.fq);
658    }
659 }
660 
661 FQ_DEFAULT_POLY_INLINE
fq_default_poly_add_series(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,slong n,const fq_default_ctx_t ctx)662 void fq_default_poly_add_series(fq_default_poly_t rop,
663 		const fq_default_poly_t op1, const fq_default_poly_t op2,
664                                            slong n, const fq_default_ctx_t ctx)
665 {
666    if (ctx->type == 1)
667    {
668       fq_zech_poly_add_series(rop->fq_zech,
669                               op1->fq_zech, op2->fq_zech, n, ctx->ctx.fq_zech);
670    } else if (ctx->type == 2)
671    {
672       fq_nmod_poly_add_series(rop->fq_nmod,
673                               op1->fq_nmod, op2->fq_nmod, n, ctx->ctx.fq_nmod);
674    } else
675    {
676       fq_poly_add_series(rop->fq, op1->fq, op2->fq, n, ctx->ctx.fq);
677    }
678 }
679 
fq_default_poly_sub(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,const fq_default_ctx_t ctx)680 FQ_DEFAULT_POLY_INLINE void fq_default_poly_sub(fq_default_poly_t rop,
681                 const fq_default_poly_t op1, const fq_default_poly_t op2,
682                                                     const fq_default_ctx_t ctx)
683 {
684    if (ctx->type == 1)
685    {
686       fq_zech_poly_sub(rop->fq_zech,
687                                  op1->fq_zech, op2->fq_zech, ctx->ctx.fq_zech);
688    } else if (ctx->type == 2)
689    {
690       fq_nmod_poly_sub(rop->fq_nmod,
691                                  op1->fq_nmod, op2->fq_nmod, ctx->ctx.fq_nmod);
692    } else
693    {
694       fq_poly_sub(rop->fq, op1->fq, op2->fq, ctx->ctx.fq);
695    }
696 }
697 
fq_default_poly_sub_series(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,slong n,const fq_default_ctx_t ctx)698 FQ_DEFAULT_POLY_INLINE void fq_default_poly_sub_series(fq_default_poly_t rop,
699 		const fq_default_poly_t op1, const fq_default_poly_t op2,
700                                            slong n, const fq_default_ctx_t ctx)
701 {
702    if (ctx->type == 1)
703    {
704       fq_zech_poly_sub_series(rop->fq_zech,
705                               op1->fq_zech, op2->fq_zech, n, ctx->ctx.fq_zech);
706    } else if (ctx->type == 2)
707    {
708       fq_nmod_poly_sub_series(rop->fq_nmod,
709                               op1->fq_nmod, op2->fq_nmod, n, ctx->ctx.fq_nmod);
710    } else
711    {
712       fq_poly_sub_series(rop->fq, op1->fq, op2->fq, n, ctx->ctx.fq);
713    }
714 }
715 
fq_default_poly_neg(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_ctx_t ctx)716 FQ_DEFAULT_POLY_INLINE void fq_default_poly_neg(fq_default_poly_t rop,
717                         const fq_default_poly_t op, const fq_default_ctx_t ctx)
718 {
719    if (ctx->type == 1)
720    {
721       fq_zech_poly_neg(rop->fq_zech, op->fq_zech, ctx->ctx.fq_zech);
722    } else if (ctx->type == 2)
723    {
724       fq_nmod_poly_neg(rop->fq_nmod, op->fq_nmod, ctx->ctx.fq_nmod);
725    } else
726    {
727       fq_poly_neg(rop->fq, op->fq, ctx->ctx.fq);
728    }
729 }
730 
731 /*  Scalar multiplication and division  **************************************/
732 
733 FQ_DEFAULT_POLY_INLINE
fq_default_poly_scalar_mul_fq_default(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_t x,const fq_default_ctx_t ctx)734 void fq_default_poly_scalar_mul_fq_default(fq_default_poly_t rop,
735                  const fq_default_poly_t op, const fq_default_t x,
736                                                     const fq_default_ctx_t ctx)
737 {
738    if (ctx->type == 1)
739    {
740       fq_zech_poly_scalar_mul_fq_zech(rop->fq_zech,
741                                     op->fq_zech, x->fq_zech, ctx->ctx.fq_zech);
742    } else if (ctx->type == 2)
743    {
744       fq_nmod_poly_scalar_mul_fq_nmod(rop->fq_nmod,
745                                     op->fq_nmod, x->fq_nmod, ctx->ctx.fq_nmod);
746    } else
747    {
748       fq_poly_scalar_mul_fq(rop->fq, op->fq, x->fq, ctx->ctx.fq);
749    }
750 }
751 
752 FQ_DEFAULT_POLY_INLINE
fq_default_poly_scalar_div_fq_default(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_t x,const fq_default_ctx_t ctx)753 void fq_default_poly_scalar_div_fq_default(fq_default_poly_t rop,
754                  const fq_default_poly_t op, const fq_default_t x,
755                                                     const fq_default_ctx_t ctx)
756 {
757    if (ctx->type == 1)
758    {
759       fq_zech_poly_scalar_div_fq_zech(rop->fq_zech,
760                                     op->fq_zech, x->fq_zech, ctx->ctx.fq_zech);
761    } else if (ctx->type == 2)
762    {
763       fq_nmod_poly_scalar_div_fq_nmod(rop->fq_nmod,
764                                     op->fq_nmod, x->fq_nmod, ctx->ctx.fq_nmod);
765    } else
766    {
767       fq_poly_scalar_div_fq(rop->fq, op->fq, x->fq, ctx->ctx.fq);
768    }
769 }
770 
771 FQ_DEFAULT_POLY_INLINE
fq_default_poly_scalar_addmul_fq_default(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_t x,const fq_default_ctx_t ctx)772 void fq_default_poly_scalar_addmul_fq_default(fq_default_poly_t rop,
773                  const fq_default_poly_t op, const fq_default_t x,
774                                                     const fq_default_ctx_t ctx)
775 {
776    if (ctx->type == 1)
777    {
778       fq_zech_poly_scalar_addmul_fq_zech(rop->fq_zech,
779                                     op->fq_zech, x->fq_zech, ctx->ctx.fq_zech);
780    } else if (ctx->type == 2)
781    {
782       fq_nmod_poly_scalar_addmul_fq_nmod(rop->fq_nmod,
783                                     op->fq_nmod, x->fq_nmod, ctx->ctx.fq_nmod);
784    } else
785    {
786       fq_poly_scalar_addmul_fq(rop->fq, op->fq, x->fq, ctx->ctx.fq);
787    }
788 }
789 
790 FQ_DEFAULT_POLY_INLINE
fq_default_poly_scalar_submul_fq_default(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_t x,const fq_default_ctx_t ctx)791 void fq_default_poly_scalar_submul_fq_default(fq_default_poly_t rop,
792                  const fq_default_poly_t op, const fq_default_t x,
793                                                     const fq_default_ctx_t ctx)
794 {
795    if (ctx->type == 1)
796    {
797       fq_zech_poly_scalar_submul_fq_zech(rop->fq_zech,
798                                     op->fq_zech, x->fq_zech, ctx->ctx.fq_zech);
799    } else if (ctx->type == 2)
800    {
801       fq_nmod_poly_scalar_submul_fq_nmod(rop->fq_nmod,
802                                     op->fq_nmod, x->fq_nmod, ctx->ctx.fq_nmod);
803    } else
804    {
805       fq_poly_scalar_submul_fq(rop->fq, op->fq, x->fq, ctx->ctx.fq);
806    }
807 }
808 
809 /*  Multiplication  **********************************************************/
810 
fq_default_poly_mul(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,const fq_default_ctx_t ctx)811 FQ_DEFAULT_POLY_INLINE void fq_default_poly_mul(fq_default_poly_t rop,
812                  const fq_default_poly_t op1, const fq_default_poly_t op2,
813                                                     const fq_default_ctx_t ctx)
814 {
815    if (ctx->type == 1)
816    {
817       fq_zech_poly_mul(rop->fq_zech,
818                                  op1->fq_zech, op2->fq_zech, ctx->ctx.fq_zech);
819    } else if (ctx->type == 2)
820    {
821       fq_nmod_poly_mul(rop->fq_nmod,
822                                  op1->fq_nmod, op2->fq_nmod, ctx->ctx.fq_nmod);
823    } else
824    {
825       fq_poly_mul(rop->fq, op1->fq, op2->fq, ctx->ctx.fq);
826    }
827 }
828 
fq_default_poly_mullow(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,slong n,const fq_default_ctx_t ctx)829 FQ_DEFAULT_POLY_INLINE void fq_default_poly_mullow(fq_default_poly_t rop,
830                  const fq_default_poly_t op1, const fq_default_poly_t op2,
831                                            slong n, const fq_default_ctx_t ctx)
832 {
833    if (ctx->type == 1)
834    {
835       fq_zech_poly_mullow(rop->fq_zech,
836                               op1->fq_zech, op2->fq_zech, n, ctx->ctx.fq_zech);
837    } else if (ctx->type == 2)
838    {
839       fq_nmod_poly_mullow(rop->fq_nmod,
840                               op1->fq_nmod, op2->fq_nmod, n, ctx->ctx.fq_nmod);
841    } else
842    {
843       fq_poly_mullow(rop->fq, op1->fq, op2->fq, n, ctx->ctx.fq);
844    }
845 }
846 
fq_default_poly_mulhigh(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,slong start,const fq_default_ctx_t ctx)847 FQ_DEFAULT_POLY_INLINE void fq_default_poly_mulhigh(fq_default_poly_t rop,
848                  const fq_default_poly_t op1, const fq_default_poly_t op2,
849                                        slong start, const fq_default_ctx_t ctx)
850 {
851    if (ctx->type == 1)
852    {
853       fq_zech_poly_mulhigh(rop->fq_zech,
854                           op1->fq_zech, op2->fq_zech, start, ctx->ctx.fq_zech);
855    } else if (ctx->type == 2)
856    {
857       fq_nmod_poly_mulhigh(rop->fq_nmod,
858                           op1->fq_nmod, op2->fq_nmod, start, ctx->ctx.fq_nmod);
859    } else
860    {
861       fq_poly_mulhigh(rop->fq, op1->fq, op2->fq, start, ctx->ctx.fq);
862    }
863 }
864 
fq_default_poly_mulmod(fq_default_poly_t res,const fq_default_poly_t poly1,const fq_default_poly_t poly2,const fq_default_poly_t f,const fq_default_ctx_t ctx)865 FQ_DEFAULT_POLY_INLINE void fq_default_poly_mulmod(fq_default_poly_t res,
866                  const fq_default_poly_t poly1, const fq_default_poly_t poly2,
867                          const fq_default_poly_t f, const fq_default_ctx_t ctx)
868 {
869    if (ctx->type == 1)
870    {
871       fq_zech_poly_mulmod(res->fq_zech, poly1->fq_zech, poly2->fq_zech, f->fq_zech, ctx->ctx.fq_zech);
872    } else if (ctx->type == 2)
873    {
874       fq_nmod_poly_mulmod(res->fq_nmod, poly1->fq_nmod, poly2->fq_nmod, f->fq_nmod, ctx->ctx.fq_nmod);
875    } else
876    {
877       fq_poly_mulmod(res->fq, poly1->fq, poly2->fq, f->fq, ctx->ctx.fq);
878    }
879 }
880 
881 /* Squaring ******************************************************************/
882 
fq_default_poly_sqr(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_ctx_t ctx)883 FQ_DEFAULT_POLY_INLINE void fq_default_poly_sqr(fq_default_poly_t rop,
884                         const fq_default_poly_t op, const fq_default_ctx_t ctx)
885 {
886    if (ctx->type == 1)
887    {
888       fq_zech_poly_sqr(rop->fq_zech, op->fq_zech, ctx->ctx.fq_zech);
889    } else if (ctx->type == 2)
890    {
891       fq_nmod_poly_sqr(rop->fq_nmod, op->fq_nmod, ctx->ctx.fq_nmod);
892    } else
893    {
894       fq_poly_sqr(rop->fq, op->fq, ctx->ctx.fq);
895    }
896 }
897 
898 /*  Powering  ****************************************************************/
899 
fq_default_poly_pow(fq_default_poly_t rop,const fq_default_poly_t op,ulong e,const fq_default_ctx_t ctx)900 FQ_DEFAULT_POLY_INLINE void fq_default_poly_pow(fq_default_poly_t rop,
901                                       const fq_default_poly_t op, ulong e,
902                                                     const fq_default_ctx_t ctx)
903 {
904    if (ctx->type == 1)
905    {
906       fq_zech_poly_pow(rop->fq_zech, op->fq_zech, e, ctx->ctx.fq_zech);
907    } else if (ctx->type == 2)
908    {
909       fq_nmod_poly_pow(rop->fq_nmod, op->fq_nmod, e, ctx->ctx.fq_nmod);
910    } else
911    {
912       fq_poly_pow(rop->fq, op->fq, e, ctx->ctx.fq);
913    }
914 }
915 
916 FQ_DEFAULT_POLY_INLINE
fq_default_poly_pow_trunc(fq_default_poly_t res,const fq_default_poly_t poly,ulong e,slong trunc,const fq_default_ctx_t ctx)917 void fq_default_poly_pow_trunc(fq_default_poly_t res,
918                                     const fq_default_poly_t poly, ulong e,
919 				       slong trunc, const fq_default_ctx_t ctx)
920 {
921    if (ctx->type == 1)
922    {
923       fq_zech_poly_pow_trunc(res->fq_zech,
924                                     poly->fq_zech, e, trunc, ctx->ctx.fq_zech);
925    } else if (ctx->type == 2)
926    {
927       fq_nmod_poly_pow_trunc(res->fq_nmod,
928                                     poly->fq_nmod, e, trunc, ctx->ctx.fq_nmod);
929    } else
930    {
931       fq_poly_pow_trunc(res->fq, poly->fq, e, trunc, ctx->ctx.fq);
932    }
933 }
934 
935 FQ_DEFAULT_POLY_INLINE
fq_default_poly_powmod_fmpz_binexp(fq_default_poly_t res,const fq_default_poly_t poly,const fmpz_t e,const fq_default_poly_t f,const fq_default_ctx_t ctx)936 void fq_default_poly_powmod_fmpz_binexp(fq_default_poly_t res,
937                              const fq_default_poly_t poly, const fmpz_t e,
938                          const fq_default_poly_t f, const fq_default_ctx_t ctx)
939 {
940    if (ctx->type == 1)
941    {
942       fq_zech_poly_powmod_fmpz_binexp(res->fq_zech,
943                                poly->fq_zech, e, f->fq_zech, ctx->ctx.fq_zech);
944    } else if (ctx->type == 2)
945    {
946       fq_nmod_poly_powmod_fmpz_binexp(res->fq_nmod,
947                                poly->fq_nmod, e, f->fq_nmod, ctx->ctx.fq_nmod);
948    } else
949    {
950       fq_poly_powmod_fmpz_binexp(res->fq, poly->fq, e, f->fq, ctx->ctx.fq);
951    }
952 }
953 
954 FQ_DEFAULT_POLY_INLINE
fq_default_poly_powmod_ui_binexp(fq_default_poly_t res,const fq_default_poly_t poly,ulong e,const fq_default_poly_t f,const fq_default_ctx_t ctx)955 void fq_default_poly_powmod_ui_binexp(fq_default_poly_t res,
956                          const fq_default_poly_t poly, ulong e,
957                          const fq_default_poly_t f, const fq_default_ctx_t ctx)
958 {
959    if (ctx->type == 1)
960    {
961       fq_zech_poly_powmod_ui_binexp(res->fq_zech,
962                                poly->fq_zech, e, f->fq_zech, ctx->ctx.fq_zech);
963    } else if (ctx->type == 2)
964    {
965       fq_nmod_poly_powmod_ui_binexp(res->fq_nmod,
966                                poly->fq_nmod, e, f->fq_nmod, ctx->ctx.fq_nmod);
967    } else
968    {
969       fq_poly_powmod_ui_binexp(res->fq, poly->fq, e, f->fq, ctx->ctx.fq);
970    }
971 }
972 
973 /*  Shifting  ****************************************************************/
974 
975 FQ_DEFAULT_POLY_INLINE
fq_default_poly_shift_left(fq_default_poly_t rop,const fq_default_poly_t op,slong n,const fq_default_ctx_t ctx)976 void fq_default_poly_shift_left(fq_default_poly_t rop,
977                const fq_default_poly_t op, slong n, const fq_default_ctx_t ctx)
978 {
979    if (ctx->type == 1)
980    {
981       fq_zech_poly_shift_left(rop->fq_zech, op->fq_zech, n, ctx->ctx.fq_zech);
982    } else if (ctx->type == 2)
983    {
984       fq_nmod_poly_shift_left(rop->fq_nmod, op->fq_nmod, n, ctx->ctx.fq_nmod);
985    } else
986    {
987       fq_poly_shift_left(rop->fq, op->fq, n, ctx->ctx.fq);
988    }
989 }
990 
991 FQ_DEFAULT_POLY_INLINE
fq_default_poly_shift_right(fq_default_poly_t rop,const fq_default_poly_t op,slong n,const fq_default_ctx_t ctx)992 void fq_default_poly_shift_right(fq_default_poly_t rop,
993                const fq_default_poly_t op, slong n, const fq_default_ctx_t ctx)
994 {
995    if (ctx->type == 1)
996    {
997       fq_zech_poly_shift_right(rop->fq_zech, op->fq_zech, n, ctx->ctx.fq_zech);
998    } else if (ctx->type == 2)
999    {
1000       fq_nmod_poly_shift_right(rop->fq_nmod, op->fq_nmod, n, ctx->ctx.fq_nmod);
1001    } else
1002    {
1003       fq_poly_shift_right(rop->fq, op->fq, n, ctx->ctx.fq);
1004    }
1005 }
1006 
1007 /*  Norms  *******************************************************************/
1008 
1009 FQ_DEFAULT_POLY_INLINE
fq_default_poly_hamming_weight(const fq_default_poly_t op,const fq_default_ctx_t ctx)1010 slong fq_default_poly_hamming_weight(const fq_default_poly_t op,
1011                                                     const fq_default_ctx_t ctx)
1012 {
1013    if (ctx->type == 1)
1014    {
1015       return fq_zech_poly_hamming_weight(op->fq_zech, ctx->ctx.fq_zech);
1016    } else if (ctx->type == 2)
1017    {
1018       return fq_nmod_poly_hamming_weight(op->fq_nmod, ctx->ctx.fq_nmod);
1019    }
1020    return fq_poly_hamming_weight(op->fq, ctx->ctx.fq);
1021 }
1022 
1023 /*  Greatest common divisor  *************************************************/
1024 
fq_default_poly_gcd(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,const fq_default_ctx_t ctx)1025 FQ_DEFAULT_POLY_INLINE void fq_default_poly_gcd(fq_default_poly_t rop,
1026                   const fq_default_poly_t op1, const fq_default_poly_t op2,
1027                                                     const fq_default_ctx_t ctx)
1028 {
1029    if (ctx->type == 1)
1030    {
1031       fq_zech_poly_gcd(rop->fq_zech,
1032 		                 op1->fq_zech, op2->fq_zech, ctx->ctx.fq_zech);
1033    } else if (ctx->type == 2)
1034    {
1035       fq_nmod_poly_gcd(rop->fq_nmod,
1036 		                 op1->fq_nmod, op2->fq_nmod, ctx->ctx.fq_nmod);
1037    } else
1038    {
1039       fq_poly_gcd(rop->fq, op1->fq, op2->fq, ctx->ctx.fq);
1040    }
1041 }
1042 
1043 FQ_DEFAULT_POLY_INLINE void
fq_default_poly_xgcd(fq_default_poly_t G,fq_default_poly_t S,fq_default_poly_t T,const fq_default_poly_t A,const fq_default_poly_t B,const fq_default_ctx_t ctx)1044 fq_default_poly_xgcd(fq_default_poly_t G,
1045                        fq_default_poly_t S, fq_default_poly_t T,
1046                   const fq_default_poly_t A, const fq_default_poly_t B,
1047                                                     const fq_default_ctx_t ctx)
1048 {
1049    if (ctx->type == 1)
1050    {
1051       fq_zech_poly_xgcd(G->fq_zech,
1052              S->fq_zech, T->fq_zech, A->fq_zech, B->fq_zech, ctx->ctx.fq_zech);
1053    } else if (ctx->type == 2)
1054    {
1055       fq_nmod_poly_xgcd(G->fq_nmod,
1056              S->fq_nmod, T->fq_nmod, A->fq_nmod, B->fq_nmod, ctx->ctx.fq_nmod);
1057    } else
1058    {
1059       fq_poly_xgcd(G->fq, S->fq, T->fq, A->fq, B->fq, ctx->ctx.fq);
1060    }
1061 }
1062 
1063 /*  Euclidean division  ******************************************************/
1064 
fq_default_poly_remove(fq_default_poly_t f,const fq_default_poly_t g,const fq_default_ctx_t ctx)1065 FQ_DEFAULT_POLY_INLINE ulong fq_default_poly_remove(fq_default_poly_t f,
1066                          const fq_default_poly_t g, const fq_default_ctx_t ctx)
1067 {
1068    if (ctx->type == 1)
1069    {
1070       return fq_zech_poly_remove(f->fq_zech, g->fq_zech, ctx->ctx.fq_zech);
1071    } else if (ctx->type == 2)
1072    {
1073       return fq_nmod_poly_remove(f->fq_nmod, g->fq_nmod, ctx->ctx.fq_nmod);
1074    }
1075    return fq_poly_remove(f->fq, g->fq, ctx->ctx.fq);
1076 }
1077 
1078 FQ_DEFAULT_POLY_INLINE void
fq_default_poly_divrem(fq_default_poly_t Q,fq_default_poly_t R,const fq_default_poly_t A,const fq_default_poly_t B,const fq_default_ctx_t ctx)1079 fq_default_poly_divrem(fq_default_poly_t Q, fq_default_poly_t R,
1080                    const fq_default_poly_t A, const fq_default_poly_t B,
1081                                                     const fq_default_ctx_t ctx)
1082 {
1083    if (ctx->type == 1)
1084    {
1085       fq_zech_poly_divrem(Q->fq_zech,
1086                          R->fq_zech, A->fq_zech, B->fq_zech, ctx->ctx.fq_zech);
1087    } else if (ctx->type == 2)
1088    {
1089       fq_nmod_poly_divrem(Q->fq_nmod,
1090                          R->fq_nmod, A->fq_nmod, B->fq_nmod, ctx->ctx.fq_nmod);
1091    } else
1092    {
1093       fq_poly_divrem(Q->fq, R->fq, A->fq, B->fq, ctx->ctx.fq);
1094    }
1095 }
1096 
1097 FQ_DEFAULT_POLY_INLINE void
fq_default_poly_rem(fq_default_poly_t R,const fq_default_poly_t A,const fq_default_poly_t B,const fq_default_ctx_t ctx)1098 fq_default_poly_rem(fq_default_poly_t R,
1099              const fq_default_poly_t A, const fq_default_poly_t B,
1100                                                     const fq_default_ctx_t ctx)
1101 {
1102    if (ctx->type == 1)
1103    {
1104       fq_zech_poly_rem(R->fq_zech, A->fq_zech, B->fq_zech, ctx->ctx.fq_zech);
1105    } else if (ctx->type == 2)
1106    {
1107       fq_nmod_poly_rem(R->fq_nmod, A->fq_nmod, B->fq_nmod, ctx->ctx.fq_nmod);
1108    } else
1109    {
1110       fq_poly_rem(R->fq, A->fq, B->fq, ctx->ctx.fq);
1111    }
1112 }
1113 
1114 FQ_DEFAULT_POLY_INLINE void
fq_default_poly_inv_series(fq_default_poly_t Qinv,const fq_default_poly_t Q,slong n,const fq_default_ctx_t ctx)1115 fq_default_poly_inv_series(fq_default_poly_t Qinv,
1116                                const fq_default_poly_t Q, slong n,
1117                                                     const fq_default_ctx_t ctx)
1118 {
1119    if (ctx->type == 1)
1120    {
1121       fq_zech_poly_inv_series(Qinv->fq_zech, Q->fq_zech, n, ctx->ctx.fq_zech);
1122    } else if (ctx->type == 2)
1123    {
1124       fq_nmod_poly_inv_series(Qinv->fq_nmod, Q->fq_nmod, n, ctx->ctx.fq_nmod);
1125    } else
1126    {
1127       fq_poly_inv_series(Qinv->fq, Q->fq, n, ctx->ctx.fq);
1128    }
1129 }
1130 
fq_default_poly_div_series(fq_default_poly_t Q,const fq_default_poly_t A,const fq_default_poly_t B,slong n,const fq_default_ctx_t ctx)1131 FQ_DEFAULT_POLY_INLINE void fq_default_poly_div_series(fq_default_poly_t Q,
1132                const fq_default_poly_t A, const fq_default_poly_t B,
1133                                            slong n, const fq_default_ctx_t ctx)
1134 {
1135    if (ctx->type == 1)
1136    {
1137       fq_zech_poly_div_series(Q->fq_zech,
1138                                   A->fq_zech, B->fq_zech, n, ctx->ctx.fq_zech);
1139    } else if (ctx->type == 2)
1140    {
1141       fq_nmod_poly_div_series(Q->fq_nmod,
1142                                   A->fq_nmod, B->fq_nmod, n, ctx->ctx.fq_nmod);
1143    } else
1144    {
1145       fq_poly_div_series(Q->fq, A->fq, B->fq, n, ctx->ctx.fq);
1146    }
1147 }
1148 
1149 /*  Divisibility testing  ****************************************************/
1150 
fq_default_poly_divides(fq_default_poly_t Q,const fq_default_poly_t A,const fq_default_poly_t B,const fq_default_ctx_t ctx)1151 FQ_DEFAULT_POLY_INLINE int fq_default_poly_divides(fq_default_poly_t Q,
1152                       const fq_default_poly_t A, const fq_default_poly_t B,
1153                                                     const fq_default_ctx_t ctx)
1154 {
1155    if (ctx->type == 1)
1156    {
1157       return fq_zech_poly_divides(Q->fq_zech,
1158                                      A->fq_zech, B->fq_zech, ctx->ctx.fq_zech);
1159    } else if (ctx->type == 2)
1160    {
1161       return fq_nmod_poly_divides(Q->fq_nmod,
1162                                      A->fq_nmod, B->fq_nmod, ctx->ctx.fq_nmod);
1163    }
1164    return fq_poly_divides(Q->fq, A->fq, B->fq, ctx->ctx.fq);
1165 }
1166 
1167 /*  Derivative  **************************************************************/
1168 
1169 FQ_DEFAULT_POLY_INLINE
fq_default_poly_derivative(fq_default_poly_t rop,const fq_default_poly_t op,const fq_default_ctx_t ctx)1170 void fq_default_poly_derivative(fq_default_poly_t rop,
1171                         const fq_default_poly_t op, const fq_default_ctx_t ctx)
1172 {
1173    if (ctx->type == 1)
1174    {
1175       fq_zech_poly_derivative(rop->fq_zech, op->fq_zech, ctx->ctx.fq_zech);
1176    } else if (ctx->type == 2)
1177    {
1178       fq_nmod_poly_derivative(rop->fq_nmod, op->fq_nmod, ctx->ctx.fq_nmod);
1179    } else
1180    {
1181       fq_poly_derivative(rop->fq, op->fq, ctx->ctx.fq);
1182    }
1183 }
1184 
1185 /*  Evaluation  **************************************************************/
1186 
1187 FQ_DEFAULT_POLY_INLINE
fq_default_poly_evaluate_fq_default(fq_default_t res,const fq_default_poly_t f,const fq_default_t a,const fq_default_ctx_t ctx)1188 void fq_default_poly_evaluate_fq_default(fq_default_t res,
1189                            const fq_default_poly_t f, const fq_default_t a,
1190                                                     const fq_default_ctx_t ctx)
1191 {
1192    if (ctx->type == 1)
1193    {
1194       fq_zech_poly_evaluate_fq_zech(res->fq_zech,
1195 		                     f->fq_zech, a->fq_zech, ctx->ctx.fq_zech);
1196    } else if (ctx->type == 2)
1197    {
1198       fq_nmod_poly_evaluate_fq_nmod(res->fq_nmod,
1199 		                     f->fq_nmod, a->fq_nmod, ctx->ctx.fq_nmod);
1200    } else
1201    {
1202       fq_poly_evaluate_fq(res->fq, f->fq, a->fq, ctx->ctx.fq);
1203    }
1204 }
1205 
1206 /*  Composition  *************************************************************/
1207 
1208 FQ_DEFAULT_POLY_INLINE
fq_default_poly_compose(fq_default_poly_t rop,const fq_default_poly_t op1,const fq_default_poly_t op2,const fq_default_ctx_t ctx)1209 void fq_default_poly_compose(fq_default_poly_t rop,
1210             const fq_default_poly_t op1, const fq_default_poly_t op2,
1211                                                     const fq_default_ctx_t ctx)
1212 {
1213    if (ctx->type == 1)
1214    {
1215       fq_zech_poly_compose(rop->fq_zech,
1216                                  op1->fq_zech, op2->fq_zech, ctx->ctx.fq_zech);
1217    } else if (ctx->type == 2)
1218    {
1219       fq_nmod_poly_compose(rop->fq_nmod,
1220                                  op1->fq_nmod, op2->fq_nmod, ctx->ctx.fq_nmod);
1221    } else
1222    {
1223       fq_poly_compose(rop->fq, op1->fq, op2->fq, ctx->ctx.fq);
1224    }
1225 }
1226 
1227 FQ_DEFAULT_POLY_INLINE
fq_default_poly_compose_mod(fq_default_poly_t res,const fq_default_poly_t poly1,const fq_default_poly_t poly2,const fq_default_poly_t poly3,const fq_default_ctx_t ctx)1228 void fq_default_poly_compose_mod(fq_default_poly_t res,
1229             const fq_default_poly_t poly1, const fq_default_poly_t poly2,
1230                      const fq_default_poly_t poly3, const fq_default_ctx_t ctx)
1231 {
1232    if (ctx->type == 1)
1233    {
1234       fq_zech_poly_compose_mod(res->fq_zech,
1235              poly1->fq_zech, poly2->fq_zech, poly3->fq_zech, ctx->ctx.fq_zech);
1236    } else if (ctx->type == 2)
1237    {
1238       fq_nmod_poly_compose_mod(res->fq_nmod,
1239              poly1->fq_nmod, poly2->fq_nmod, poly3->fq_nmod, ctx->ctx.fq_nmod);
1240    } else
1241    {
1242       fq_poly_compose_mod(res->fq,
1243                                  poly1->fq, poly2->fq, poly3->fq, ctx->ctx.fq);
1244    }
1245 }
1246 
1247 /*  Input and output  ********************************************************/
1248 
fq_default_poly_fprint_pretty(FILE * file,const fq_default_poly_t poly,const char * x,const fq_default_ctx_t ctx)1249 FQ_DEFAULT_POLY_INLINE int fq_default_poly_fprint_pretty(FILE * file,
1250                              const fq_default_poly_t poly, const char *x,
1251                                                     const fq_default_ctx_t ctx)
1252 {
1253    if (ctx->type == 1)
1254    {
1255       return fq_zech_poly_fprint_pretty(file,
1256                                            poly->fq_zech, x, ctx->ctx.fq_zech);
1257    } else if (ctx->type == 2)
1258    {
1259       return fq_nmod_poly_fprint_pretty(file,
1260                                            poly->fq_nmod, x, ctx->ctx.fq_nmod);
1261    }
1262    return fq_poly_fprint_pretty(file, poly->fq, x, ctx->ctx.fq);
1263 }
1264 
fq_default_poly_fprint(FILE * file,const fq_default_poly_t poly,const fq_default_ctx_t ctx)1265 FQ_DEFAULT_POLY_INLINE int fq_default_poly_fprint(FILE * file,
1266                       const fq_default_poly_t poly, const fq_default_ctx_t ctx)
1267 {
1268    if (ctx->type == 1)
1269    {
1270       return fq_zech_poly_fprint(file, poly->fq_zech, ctx->ctx.fq_zech);
1271    } else if (ctx->type == 2)
1272    {
1273       return fq_nmod_poly_fprint(file, poly->fq_nmod, ctx->ctx.fq_nmod);
1274    }
1275    return fq_poly_fprint(file, poly->fq, ctx->ctx.fq);
1276 }
1277 
1278 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_print(const fq_default_poly_t poly,const fq_default_ctx_t ctx)1279 fq_default_poly_print(const fq_default_poly_t poly, const fq_default_ctx_t ctx)
1280 {
1281    if (ctx->type == 1)
1282    {
1283       return fq_zech_poly_print(poly->fq_zech, ctx->ctx.fq_zech);
1284    } else if (ctx->type == 2)
1285    {
1286       return fq_nmod_poly_print(poly->fq_nmod, ctx->ctx.fq_nmod);
1287    }
1288    return fq_poly_print(poly->fq, ctx->ctx.fq);
1289 }
1290 
1291 
1292 FQ_DEFAULT_POLY_INLINE int
fq_default_poly_print_pretty(const fq_default_poly_t poly,const char * x,const fq_default_ctx_t ctx)1293 fq_default_poly_print_pretty(const fq_default_poly_t poly,
1294                                      const char *x, const fq_default_ctx_t ctx)
1295 {
1296    if (ctx->type == 1)
1297    {
1298       return fq_zech_poly_print_pretty(poly->fq_zech, x, ctx->ctx.fq_zech);
1299    } else if (ctx->type == 2)
1300    {
1301       return fq_nmod_poly_print_pretty(poly->fq_nmod, x, ctx->ctx.fq_nmod);
1302    }
1303    return fq_poly_print_pretty(poly->fq, x, ctx->ctx.fq);
1304 }
1305 
1306 FQ_DEFAULT_POLY_INLINE
fq_default_poly_get_str_pretty(const fq_default_poly_t poly,const char * x,const fq_default_ctx_t ctx)1307 char * fq_default_poly_get_str_pretty(const fq_default_poly_t poly,
1308                                      const char *x, const fq_default_ctx_t ctx)
1309 {
1310    if (ctx->type == 1)
1311    {
1312       return fq_zech_poly_get_str_pretty(poly->fq_zech, x, ctx->ctx.fq_zech);
1313    } else if (ctx->type == 2)
1314    {
1315       return fq_nmod_poly_get_str_pretty(poly->fq_nmod, x, ctx->ctx.fq_nmod);
1316    }
1317    return fq_poly_get_str_pretty(poly->fq, x, ctx->ctx.fq);
1318 }
1319 
1320 FQ_DEFAULT_POLY_INLINE
fq_default_poly_get_str(const fq_default_poly_t poly,const fq_default_ctx_t ctx)1321 char * fq_default_poly_get_str(const fq_default_poly_t poly,
1322                                                     const fq_default_ctx_t ctx)
1323 {
1324    if (ctx->type == 1)
1325    {
1326       return fq_zech_poly_get_str(poly->fq_zech, ctx->ctx.fq_zech);
1327    } else if (ctx->type == 2)
1328    {
1329       return fq_nmod_poly_get_str(poly->fq_nmod, ctx->ctx.fq_nmod);
1330    }
1331    return fq_poly_get_str(poly->fq, ctx->ctx.fq);
1332 }
1333 
1334 #include "fq_default_mat.h"
1335 
1336 /* Characteristic polynomial *************************************************/
1337 
1338 FQ_DEFAULT_POLY_INLINE
fq_default_mat_charpoly(fq_default_poly_t p,const fq_default_mat_t M,const fq_default_ctx_t ctx)1339 void fq_default_mat_charpoly(fq_default_poly_t p,
1340                           const fq_default_mat_t M, const fq_default_ctx_t ctx)
1341 {
1342    if (ctx->type == 1)
1343    {
1344       fq_zech_mat_charpoly(p->fq_zech, M->fq_zech, ctx->ctx.fq_zech);
1345    } else if (ctx->type == 2)
1346    {
1347       fq_nmod_mat_charpoly(p->fq_nmod, M->fq_nmod, ctx->ctx.fq_nmod);
1348    } else
1349    {
1350       fq_mat_charpoly(p->fq, M->fq, ctx->ctx.fq);
1351    }
1352 }
1353 
1354 /* Minimal polynomial ********************************************************/
1355 
1356 FQ_DEFAULT_POLY_INLINE
fq_default_mat_minpoly(fq_default_poly_t p,const fq_default_mat_t X,const fq_default_ctx_t ctx)1357 void fq_default_mat_minpoly(fq_default_poly_t p,
1358                           const fq_default_mat_t X, const fq_default_ctx_t ctx)
1359 {
1360    if (ctx->type == 1)
1361    {
1362       fq_zech_mat_minpoly(p->fq_zech, X->fq_zech, ctx->ctx.fq_zech);
1363    } else if (ctx->type == 2)
1364    {
1365       fq_nmod_mat_minpoly(p->fq_nmod, X->fq_nmod, ctx->ctx.fq_nmod);
1366    } else
1367    {
1368       fq_mat_minpoly(p->fq, X->fq, ctx->ctx.fq);
1369    }
1370 }
1371 
1372 #ifdef __cplusplus
1373 }
1374 #endif
1375 
1376 #endif
1377