Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:15:17

0001 /*
0002     Copyright (C) 2021 William Hart
0003     Copyright (C) 2021 Daniel Schultz
0004 
0005     This file is part of FLINT.
0006 
0007     FLINT is free software: you can redistribute it and/or modify it under
0008     the terms of the GNU Lesser General Public License (LGPL) as published
0009     by the Free Software Foundation; either version 3 of the License, or
0010     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
0011 */
0012 
0013 #ifndef FQ_DEFAULT_H
0014 #define FQ_DEFAULT_H
0015 
0016 #ifdef FQ_DEFAULT_INLINES_C
0017 #define FQ_DEFAULT_INLINE
0018 #else
0019 #define FQ_DEFAULT_INLINE static inline
0020 #endif
0021 
0022 #include "nmod.h"
0023 #include "nmod_poly.h"
0024 #include "fmpz.h"
0025 #include "fmpz_mod.h"
0026 #include "fmpz_mod_poly.h"
0027 #include "fq.h"
0028 #include "fq_nmod.h"
0029 #include "fq_zech.h"
0030 #include "gr.h"
0031 
0032 /* Internal type codes */
0033 #define _FQ_DEFAULT_FQ_ZECH  GR_CTX_FQ_ZECH
0034 #define _FQ_DEFAULT_FQ_NMOD  GR_CTX_FQ_NMOD
0035 #define _FQ_DEFAULT_FQ       GR_CTX_FQ
0036 #define _FQ_DEFAULT_NMOD     GR_CTX_NMOD
0037 #define _FQ_DEFAULT_FMPZ_MOD GR_CTX_FMPZ_MOD
0038 
0039 /* Original type codes for backward compatibility. */
0040 #define FQ_DEFAULT_FQ_ZECH  1
0041 #define FQ_DEFAULT_FQ_NMOD  2
0042 #define FQ_DEFAULT_FQ       3
0043 #define FQ_DEFAULT_NMOD     4
0044 #define FQ_DEFAULT_FMPZ_MOD 5
0045 
0046 /* Data types and context ****************************************************/
0047 
0048 #ifdef __cplusplus
0049 extern "C" {
0050 #endif
0051 
0052 typedef union fq_default_struct
0053 {
0054     fq_t fq;
0055     fq_nmod_t fq_nmod;
0056     fq_zech_t fq_zech;
0057     ulong nmod;
0058     fmpz_t fmpz_mod;
0059 } fq_default_struct;
0060 
0061 typedef fq_default_struct fq_default_t[1];
0062 
0063 typedef gr_ctx_struct fq_default_ctx_struct;
0064 typedef fq_default_ctx_struct fq_default_ctx_t[1];
0065 
0066 #define FQ_DEFAULT_GR_CTX(ctx) ((gr_ctx_struct *) (ctx))
0067 #define _FQ_DEFAULT_TYPE(ctx) (FQ_DEFAULT_GR_CTX(ctx)->which_ring)
0068 
0069 #define FQ_DEFAULT_CTX_FQ(ctx) ((fq_ctx_struct *) GR_CTX_DATA_AS_PTR(FQ_DEFAULT_GR_CTX(ctx)))
0070 #define FQ_DEFAULT_CTX_FQ_ZECH(ctx) ((fq_zech_ctx_struct *) GR_CTX_DATA_AS_PTR(FQ_DEFAULT_GR_CTX(ctx)))
0071 #define FQ_DEFAULT_CTX_FQ_NMOD(ctx) ((fq_nmod_ctx_struct *) GR_CTX_DATA_AS_PTR(FQ_DEFAULT_GR_CTX(ctx)))
0072 #define FQ_DEFAULT_CTX_NMOD(ctx) ((nmod_t *) FQ_DEFAULT_GR_CTX(ctx))[0]
0073 #define FQ_DEFAULT_CTX_FMPZ_MOD(ctx) ((fmpz_mod_ctx_struct *) GR_CTX_DATA_AS_PTR(FQ_DEFAULT_GR_CTX(ctx)))
0074 
0075 /* hack: access to gr_ctx internals for nmod and fmpz_mod; this will
0076    be removed after further refactoring */
0077 
0078 typedef struct
0079 {
0080     fmpz_mod_ctx_struct * ctx;
0081     truth_t is_prime;
0082     fmpz a;    /* when used as finite field with defining polynomial x - a */
0083 }
0084 _gr_fmpz_mod_ctx_struct;
0085 
0086 /* end hack */
0087 
0088 #define NMOD_CTX_A(ring_ctx) (&((((_gr_nmod_ctx_struct *)(ring_ctx))->a)))
0089 #define FMPZ_MOD_CTX_A(ring_ctx) (&((((_gr_fmpz_mod_ctx_struct *)(ring_ctx))->a)))
0090 #define FQ_DEFAULT_CTX_NMOD_A(ctx) NMOD_CTX_A(ctx)
0091 #define FQ_DEFAULT_CTX_FMPZ_MOD_A(ctx) FMPZ_MOD_CTX_A(ctx)
0092 
0093 
0094 void fq_default_ctx_init_type(fq_default_ctx_t ctx,
0095                             const fmpz_t p, slong d, const char *var, int type);
0096 
0097 FQ_DEFAULT_INLINE void fq_default_ctx_init(fq_default_ctx_t ctx,
0098                                       const fmpz_t p, slong d, const char *var)
0099 {
0100     fq_default_ctx_init_type(ctx, p, d, var, 0);
0101 }
0102 
0103 FQ_DEFAULT_INLINE void * fq_default_ctx_inner(const fq_default_ctx_t ctx)
0104 {
0105     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0106         return (void *) &FQ_DEFAULT_CTX_NMOD(ctx);
0107     else
0108         return (void *) GR_CTX_DATA_AS_PTR(ctx);
0109 }
0110 
0111 void fq_default_ctx_init_modulus_type(fq_default_ctx_t ctx,
0112                 const fmpz_mod_poly_t modulus, fmpz_mod_ctx_t mod_ctx,
0113                                                    const char * var, int type);
0114 
0115 void fq_default_ctx_init_modulus(fq_default_ctx_t ctx,
0116       const fmpz_mod_poly_t modulus, fmpz_mod_ctx_t mod_ctx, const char * var);
0117 
0118 
0119 void fq_default_ctx_init_modulus_nmod_type(fq_default_ctx_t ctx,
0120                         const nmod_poly_t modulus, const char * var, int type);
0121 
0122 
0123 void fq_default_ctx_init_modulus_nmod(fq_default_ctx_t ctx,
0124                                   const nmod_poly_t modulus, const char * var);
0125 
0126 FQ_DEFAULT_INLINE void fq_default_ctx_clear(fq_default_ctx_t ctx)
0127 {
0128     gr_ctx_clear(FQ_DEFAULT_GR_CTX(ctx));
0129 }
0130 
0131 FQ_DEFAULT_INLINE int fq_default_ctx_type(const fq_default_ctx_t ctx)
0132 {
0133     int type = FQ_DEFAULT_GR_CTX(ctx)->which_ring;
0134 
0135     if (type == _FQ_DEFAULT_FQ_ZECH)  return FQ_DEFAULT_FQ_ZECH;
0136     if (type == _FQ_DEFAULT_FQ_NMOD)  return FQ_DEFAULT_FQ_NMOD;
0137     if (type == _FQ_DEFAULT_FQ)       return FQ_DEFAULT_FQ;
0138     if (type == _FQ_DEFAULT_NMOD)     return FQ_DEFAULT_NMOD;
0139     if (type == _FQ_DEFAULT_FMPZ_MOD) return FQ_DEFAULT_FMPZ_MOD;
0140     FLINT_UNREACHABLE;
0141 }
0142 
0143 FQ_DEFAULT_INLINE slong fq_default_ctx_degree(const fq_default_ctx_t ctx)
0144 {
0145     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0146     {
0147         return fq_zech_ctx_degree(FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0148     }
0149     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0150     {
0151         return fq_nmod_ctx_degree(FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0152     }
0153     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0154     {
0155         return 1;
0156     }
0157     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0158     {
0159         return 1;
0160     }
0161     else
0162     {
0163         return fq_ctx_degree(FQ_DEFAULT_CTX_FQ(ctx));
0164     }
0165 }
0166 
0167 FQ_DEFAULT_INLINE void fq_default_ctx_prime(fmpz_t prime,
0168                                                     const fq_default_ctx_t ctx)
0169 {
0170     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0171     {
0172         fmpz_set_ui(prime, fq_zech_ctx_prime(FQ_DEFAULT_CTX_FQ_ZECH(ctx)));
0173     }
0174     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0175     {
0176         fmpz_set_ui(prime, fq_nmod_ctx_prime(FQ_DEFAULT_CTX_FQ_NMOD(ctx)));
0177     }
0178     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0179     {
0180         fmpz_set_ui(prime, FQ_DEFAULT_CTX_NMOD(ctx).n);
0181     }
0182     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0183     {
0184         fmpz_set(prime, fmpz_mod_ctx_modulus(FQ_DEFAULT_CTX_FMPZ_MOD(ctx)));
0185     }
0186     else
0187     {
0188         fmpz_set(prime, fq_ctx_prime(FQ_DEFAULT_CTX_FQ(ctx)));
0189     }
0190 }
0191 
0192 void fq_default_ctx_modulus(fmpz_mod_poly_t p,
0193                                            const fq_default_ctx_t ctx);
0194 
0195 FQ_DEFAULT_INLINE void fq_default_ctx_order(fmpz_t f,
0196                                             const fq_default_ctx_t ctx)
0197 {
0198     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0199     {
0200         fmpz_set_ui(f, fq_zech_ctx_order_ui(FQ_DEFAULT_CTX_FQ_ZECH(ctx)));
0201     }
0202     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0203     {
0204         fq_nmod_ctx_order(f, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0205     }
0206     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0207     {
0208         fmpz_set_ui(f, FQ_DEFAULT_CTX_NMOD(ctx).n);
0209     }
0210     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0211     {
0212         fmpz_set(f, fmpz_mod_ctx_modulus(FQ_DEFAULT_CTX_FMPZ_MOD(ctx)));
0213     }
0214     else
0215     {
0216         fq_ctx_order(f, FQ_DEFAULT_CTX_FQ(ctx));
0217     }
0218 }
0219 
0220 #ifdef FLINT_HAVE_FILE
0221 int fq_default_ctx_fprint(FILE * file, const fq_default_ctx_t ctx);
0222 #endif
0223 
0224 void fq_default_ctx_print(const fq_default_ctx_t ctx);
0225 void fq_default_ctx_init_randtest(fq_default_ctx_t ctx, flint_rand_t state);
0226 
0227 /* Memory management  *********************************************************/
0228 
0229 FQ_DEFAULT_INLINE void fq_default_init(fq_default_t rop,
0230                                             const fq_default_ctx_t ctx)
0231 {
0232     gr_init(rop, FQ_DEFAULT_GR_CTX(ctx));
0233 }
0234 
0235 FQ_DEFAULT_INLINE void fq_default_init2(fq_default_t rop,
0236                                             const fq_default_ctx_t ctx)
0237 {
0238     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0239     {
0240         fq_zech_init2(rop->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0241     }
0242     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0243     {
0244         fq_nmod_init2(rop->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0245     }
0246     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0247     {
0248         rop->nmod = 0;
0249     }
0250     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0251     {
0252         fmpz_init(rop->fmpz_mod);
0253     }
0254     else
0255     {
0256         fq_init2(rop->fq, FQ_DEFAULT_CTX_FQ(ctx));
0257     }
0258 }
0259 
0260 FQ_DEFAULT_INLINE void fq_default_clear(fq_default_t rop,
0261                                             const fq_default_ctx_t ctx)
0262 {
0263     gr_clear(rop, FQ_DEFAULT_GR_CTX(ctx));
0264 }
0265 
0266 /* Basic arithmetic **********************************************************/
0267 
0268 /* GR_IGNORE(...) because we assume that basic arithmetic is well-implemented */
0269 
0270 FQ_DEFAULT_INLINE void fq_default_add(fq_default_t rop, const fq_default_t op1,
0271                     const fq_default_t op2, const fq_default_ctx_t ctx)
0272 {
0273     GR_IGNORE(gr_add(rop, op1, op2, FQ_DEFAULT_GR_CTX(ctx)));
0274 }
0275 
0276 FQ_DEFAULT_INLINE void fq_default_sub(fq_default_t rop, const fq_default_t op1,
0277                     const fq_default_t op2, const fq_default_ctx_t ctx)
0278 {
0279     GR_IGNORE(gr_sub(rop, op1, op2, FQ_DEFAULT_GR_CTX(ctx)));
0280 }
0281 
0282 FQ_DEFAULT_INLINE void fq_default_sub_one(fq_default_t rop,
0283                     const fq_default_t op1, const fq_default_ctx_t ctx)
0284 {
0285     GR_IGNORE(gr_sub_ui(rop, op1, 1, FQ_DEFAULT_GR_CTX(ctx)));
0286 }
0287 
0288 FQ_DEFAULT_INLINE void fq_default_neg(fq_default_t rop,
0289                     const fq_default_t op1, const fq_default_ctx_t ctx)
0290 {
0291     GR_IGNORE(gr_neg(rop, op1, FQ_DEFAULT_GR_CTX(ctx)));
0292 }
0293 
0294 FQ_DEFAULT_INLINE void fq_default_mul(fq_default_t rop, const fq_default_t op1,
0295                             const fq_default_t op2, const fq_default_ctx_t ctx)
0296 {
0297     GR_IGNORE(gr_mul(rop, op1, op2, FQ_DEFAULT_GR_CTX(ctx)));
0298 }
0299 
0300 FQ_DEFAULT_INLINE void fq_default_mul_fmpz(fq_default_t rop,
0301              const fq_default_t op, const fmpz_t x, const fq_default_ctx_t ctx)
0302 {
0303     GR_IGNORE(gr_mul_fmpz(rop, op, x, FQ_DEFAULT_GR_CTX(ctx)));
0304 }
0305 
0306 FQ_DEFAULT_INLINE void fq_default_mul_si(fq_default_t rop,
0307             const fq_default_t op, slong x, const fq_default_ctx_t ctx)
0308 {
0309     GR_IGNORE(gr_mul_si(rop, op, x, FQ_DEFAULT_GR_CTX(ctx)));
0310 }
0311 
0312 FQ_DEFAULT_INLINE void fq_default_mul_ui(fq_default_t rop,
0313             const fq_default_t op, ulong x, const fq_default_ctx_t ctx)
0314 {
0315     GR_IGNORE(gr_mul_ui(rop, op, x, FQ_DEFAULT_GR_CTX(ctx)));
0316 }
0317 
0318 FQ_DEFAULT_INLINE void fq_default_sqr(fq_default_t rop,
0319                              const fq_default_t op, const fq_default_ctx_t ctx)
0320 {
0321     GR_IGNORE(gr_sqr(rop, op, FQ_DEFAULT_GR_CTX(ctx)));
0322 }
0323 
0324 FQ_DEFAULT_INLINE int fq_default_is_invertible(const fq_default_t op,
0325                                             const fq_default_ctx_t ctx)
0326 {
0327     truth_t is_inv = gr_is_invertible(op, FQ_DEFAULT_GR_CTX(ctx));
0328     if (is_inv == T_UNKNOWN)
0329         flint_throw(FLINT_ERROR, "is_invertible failed");
0330     return (is_inv == T_TRUE);
0331 
0332 }
0333 
0334 FQ_DEFAULT_INLINE void fq_default_inv(fq_default_t rop,
0335                     const fq_default_t op1, const fq_default_ctx_t ctx)
0336 {
0337     GR_MUST_SUCCEED(gr_inv(rop, op1, FQ_DEFAULT_GR_CTX(ctx)));
0338 }
0339 
0340 FQ_DEFAULT_INLINE void fq_default_div(fq_default_t rop, fq_default_t op1,
0341                                   fq_default_t op2, const fq_default_ctx_t ctx)
0342 {
0343     GR_MUST_SUCCEED(gr_div(rop, op1, op2, FQ_DEFAULT_GR_CTX(ctx)));
0344 }
0345 
0346 FQ_DEFAULT_INLINE void fq_default_pow(fq_default_t rop,
0347         const fq_default_t op1, const fmpz_t e, const fq_default_ctx_t ctx)
0348 {
0349     GR_MUST_SUCCEED(gr_pow_fmpz(rop, op1, e, FQ_DEFAULT_GR_CTX(ctx)));
0350 }
0351 
0352 FQ_DEFAULT_INLINE void fq_default_pow_ui(fq_default_t rop,
0353               const fq_default_t op, const ulong e, const fq_default_ctx_t ctx)
0354 {
0355     GR_MUST_SUCCEED(gr_pow_ui(rop, op, e, FQ_DEFAULT_GR_CTX(ctx)));
0356 }
0357 
0358 /* Roots *********************************************************************/
0359 
0360 FQ_DEFAULT_INLINE int fq_default_is_square(const fq_default_t op,
0361                                             const fq_default_ctx_t ctx)
0362 {
0363     truth_t is_square = gr_is_square(op, FQ_DEFAULT_GR_CTX(ctx));
0364     if (is_square == T_UNKNOWN)
0365         flint_throw(FLINT_ERROR, "sqrt failed");
0366     return (is_square == T_TRUE);
0367 }
0368 
0369 FQ_DEFAULT_INLINE int fq_default_sqrt(fq_default_t rop,
0370                      const fq_default_t op, const fq_default_ctx_t ctx)
0371 {
0372     int status = gr_sqrt(rop, op, FQ_DEFAULT_GR_CTX(ctx));
0373     if (status == GR_UNABLE)
0374         flint_throw(FLINT_ERROR, "sqrt failed");
0375     return (status == GR_SUCCESS);
0376 }
0377 
0378 FQ_DEFAULT_INLINE void fq_default_pth_root(fq_default_t rop,
0379                     const fq_default_t op1, const fq_default_ctx_t ctx)
0380 {
0381     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0382     {
0383         fq_zech_pth_root(rop->fq_zech, op1->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0384     }
0385     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0386     {
0387         fq_nmod_pth_root(rop->fq_nmod, op1->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0388     }
0389     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0390     {
0391         rop->nmod = op1->nmod;
0392     }
0393     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0394     {
0395         fmpz_set(rop->fmpz_mod, op1->fmpz_mod);
0396     }
0397     else
0398     {
0399         fq_pth_root(rop->fq, op1->fq, FQ_DEFAULT_CTX_FQ(ctx));
0400     }
0401 }
0402 
0403 /* Randomisation *************************************************************/
0404 
0405 FQ_DEFAULT_INLINE void fq_default_randtest(fq_default_t rop,
0406                         flint_rand_t state, const fq_default_ctx_t ctx)
0407 {
0408     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0409     {
0410         fq_zech_randtest(rop->fq_zech, state, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0411     }
0412     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0413     {
0414         fq_nmod_randtest(rop->fq_nmod, state, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0415     }
0416     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0417     {
0418         rop->nmod = n_randint(state, FQ_DEFAULT_CTX_NMOD(ctx).n);
0419     }
0420     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0421     {
0422         fmpz_mod_rand(rop->fmpz_mod, state, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0423     }
0424     else
0425     {
0426         fq_randtest(rop->fq, state, FQ_DEFAULT_CTX_FQ(ctx));
0427     }
0428 }
0429 
0430 FQ_DEFAULT_INLINE void fq_default_randtest_not_zero(fq_default_t rop,
0431                         flint_rand_t state, const fq_default_ctx_t ctx)
0432 {
0433     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0434     {
0435         fq_zech_randtest_not_zero(rop->fq_zech, state, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0436     }
0437     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0438     {
0439         fq_nmod_randtest_not_zero(rop->fq_nmod, state, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0440     }
0441     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0442     {
0443         rop->nmod = n_randint(state, FQ_DEFAULT_CTX_NMOD(ctx).n - 1) + 1;
0444     }
0445     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0446     {
0447         fmpz_mod_rand_not_zero(rop->fmpz_mod, state, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0448     }
0449     else
0450     {
0451         fq_randtest_not_zero(rop->fq, state, FQ_DEFAULT_CTX_FQ(ctx));
0452     }
0453 }
0454 
0455 FQ_DEFAULT_INLINE void fq_default_rand(fq_default_t rop,
0456                         flint_rand_t state, const fq_default_ctx_t ctx)
0457 {
0458     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0459     {
0460         fq_zech_rand(rop->fq_zech, state, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0461     }
0462     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0463     {
0464         fq_nmod_rand(rop->fq_nmod, state, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0465     }
0466     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0467     {
0468         rop->nmod = n_randint(state, FQ_DEFAULT_CTX_NMOD(ctx).n);
0469     }
0470     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0471     {
0472         fmpz_mod_rand(rop->fmpz_mod, state, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0473     }
0474     else
0475     {
0476         fq_rand(rop->fq, state, FQ_DEFAULT_CTX_FQ(ctx));
0477     }
0478 }
0479 
0480 FQ_DEFAULT_INLINE void fq_default_rand_not_zero(fq_default_t rop,
0481                         flint_rand_t state, const fq_default_ctx_t ctx)
0482 {
0483     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0484     {
0485         fq_zech_rand_not_zero(rop->fq_zech, state, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0486     }
0487     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0488     {
0489         fq_nmod_rand_not_zero(rop->fq_nmod, state, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0490     }
0491     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0492     {
0493         rop->nmod = n_randint(state, FQ_DEFAULT_CTX_NMOD(ctx).n - 1) + 1;
0494     }
0495     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0496     {
0497         fmpz_mod_rand_not_zero(rop->fmpz_mod, state, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0498     }
0499     else
0500     {
0501         fq_rand_not_zero(rop->fq, state, FQ_DEFAULT_CTX_FQ(ctx));
0502     }
0503 }
0504 
0505 /* Comparison ****************************************************************/
0506 
0507 FQ_DEFAULT_INLINE int fq_default_equal(const fq_default_t op1,
0508                     const fq_default_t op2, const fq_default_ctx_t ctx)
0509 {
0510     return gr_equal(op1, op2, FQ_DEFAULT_GR_CTX(ctx)) == T_TRUE;
0511 }
0512 
0513 FQ_DEFAULT_INLINE int fq_default_is_zero(const fq_default_t op,
0514                                             const fq_default_ctx_t ctx)
0515 {
0516     return gr_is_zero(op, FQ_DEFAULT_GR_CTX(ctx)) == T_TRUE;
0517 }
0518 
0519 FQ_DEFAULT_INLINE int fq_default_is_one(const fq_default_t op,
0520                                             const fq_default_ctx_t ctx)
0521 {
0522     return gr_is_one(op, FQ_DEFAULT_GR_CTX(ctx)) == T_TRUE;
0523 }
0524 
0525 /* Assignments and conversions ***********************************************/
0526 
0527 FQ_DEFAULT_INLINE void fq_default_set(fq_default_t rop,
0528                      const fq_default_t op, const fq_default_ctx_t ctx)
0529 {
0530     GR_IGNORE(gr_set(rop, op, FQ_DEFAULT_GR_CTX(ctx)));
0531 }
0532 
0533 FQ_DEFAULT_INLINE void fq_default_set_fmpz(fq_default_t rop,
0534                             const fmpz_t x, const fq_default_ctx_t ctx)
0535 {
0536     GR_IGNORE(gr_set_fmpz(rop, x, FQ_DEFAULT_GR_CTX(ctx)));
0537 }
0538 
0539 FQ_DEFAULT_INLINE void fq_default_set_ui(fq_default_t rop,
0540                              const ulong x, const fq_default_ctx_t ctx)
0541 {
0542     GR_IGNORE(gr_set_ui(rop, x, FQ_DEFAULT_GR_CTX(ctx)));
0543 }
0544 
0545 FQ_DEFAULT_INLINE void fq_default_set_si(fq_default_t rop,
0546                              const slong x, const fq_default_ctx_t ctx)
0547 {
0548     GR_IGNORE(gr_set_si(rop, x, FQ_DEFAULT_GR_CTX(ctx)));
0549 }
0550 
0551 FQ_DEFAULT_INLINE void fq_default_zero(fq_default_t rop,
0552                                             const fq_default_ctx_t ctx)
0553 {
0554     GR_IGNORE(gr_zero(rop, FQ_DEFAULT_GR_CTX(ctx)));
0555 }
0556 
0557 FQ_DEFAULT_INLINE void fq_default_one(fq_default_t rop,
0558                                             const fq_default_ctx_t ctx)
0559 {
0560     GR_IGNORE(gr_one(rop, FQ_DEFAULT_GR_CTX(ctx)));
0561 }
0562 
0563 /* todo: should this swap the fq_default_struct? */
0564 FQ_DEFAULT_INLINE void fq_default_swap(fq_default_t op1,
0565                           fq_default_t op2, const fq_default_ctx_t ctx)
0566 {
0567     gr_swap(op1, op2, FQ_DEFAULT_GR_CTX(ctx));
0568 }
0569 
0570 FQ_DEFAULT_INLINE void fq_default_gen(fq_default_t rop,
0571                                             const fq_default_ctx_t ctx)
0572 {
0573     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0574     {
0575         fq_zech_gen(rop->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0576     }
0577     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0578     {
0579         fq_nmod_gen(rop->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0580     }
0581     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0582     {
0583         rop->nmod = *FQ_DEFAULT_CTX_NMOD_A(ctx);
0584     }
0585     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0586     {
0587         fmpz_set(rop->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD_A(ctx));
0588     }
0589     else
0590     {
0591         fq_gen(rop->fq, FQ_DEFAULT_CTX_FQ(ctx));
0592     }
0593 }
0594 
0595 FQ_DEFAULT_INLINE void fq_default_get_nmod_poly(nmod_poly_t poly,
0596                              const fq_default_t op, const fq_default_ctx_t ctx)
0597 {
0598     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0599     {
0600         fq_zech_get_nmod_poly(poly, op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0601     }
0602     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0603     {
0604         fq_nmod_get_nmod_poly(poly, op->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0605     }
0606     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0607     {
0608         nmod_poly_fit_length(poly, 1);
0609         poly->length = (op->nmod != 0);
0610         poly->coeffs[0] = op->nmod;
0611     }
0612     else
0613     {
0614         flint_throw(FLINT_ERROR, "Impossible conversion\n");
0615     }
0616 }
0617 
0618 FQ_DEFAULT_INLINE void fq_default_set_nmod_poly(fq_default_t op,
0619                             const nmod_poly_t poly, const fq_default_ctx_t ctx)
0620 {
0621     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0622     {
0623         fq_zech_set_nmod_poly(op->fq_zech, poly, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0624     }
0625     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0626     {
0627         fq_nmod_set_nmod_poly(op->fq_nmod, poly, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0628     }
0629     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0630     {
0631         op->nmod = nmod_poly_evaluate_nmod(poly, *FQ_DEFAULT_CTX_NMOD_A(ctx));
0632     }
0633     else
0634     {
0635         flint_throw(FLINT_ERROR, "Impossible conversion\n");
0636     }
0637 }
0638 
0639 FQ_DEFAULT_INLINE int fq_default_get_fmpz(fmpz_t z, const fq_default_t op,
0640                                                     const fq_default_ctx_t ctx)
0641 {
0642     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0643     {
0644         return fq_zech_get_fmpz(z, op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0645     }
0646     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0647     {
0648         return fq_nmod_get_fmpz(z, op->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0649     }
0650     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0651     {
0652         fmpz_set_ui(z, op->nmod);
0653         return 1;
0654     }
0655     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0656     {
0657         fmpz_set(z, op->fmpz_mod);
0658         return 1;
0659     }
0660     else
0661     {
0662         return fq_get_fmpz(z, op->fq, FQ_DEFAULT_CTX_FQ(ctx));
0663     }
0664 }
0665 
0666 void fq_default_get_fmpz_mod_poly(fmpz_mod_poly_t poly,
0667                             const fq_default_t op, const fq_default_ctx_t ctx);
0668 
0669 void fq_default_set_fmpz_mod_poly(fq_default_t op,
0670                        const fmpz_mod_poly_t poly, const fq_default_ctx_t ctx);
0671 
0672 void fq_default_get_fmpz_poly(fmpz_poly_t poly,
0673                             const fq_default_t op, const fq_default_ctx_t ctx);
0674 
0675 void fq_default_set_fmpz_poly(fq_default_t op,
0676                            const fmpz_poly_t poly, const fq_default_ctx_t ctx);
0677 
0678 FQ_DEFAULT_INLINE void fq_default_get_coeff_fmpz(fmpz_t c,
0679                           fq_default_t op, slong n, const fq_default_ctx_t ctx)
0680 {
0681     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0682     {
0683         nmod_poly_t p;
0684         ulong c0;
0685         nmod_poly_init(p, fq_zech_ctx_prime(FQ_DEFAULT_CTX_FQ_ZECH(ctx)));
0686         fq_zech_get_nmod_poly(p, op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0687         c0 = nmod_poly_get_coeff_ui(p, n);
0688         fmpz_set_ui(c, c0);
0689         nmod_poly_clear(p);
0690     }
0691     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0692     {
0693         ulong c0 = nmod_poly_get_coeff_ui((nmod_poly_struct *) op->fq_nmod, n);
0694         fmpz_set_ui(c, c0);
0695     }
0696     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0697     {
0698         if (n != 0)
0699             fmpz_zero(c);
0700         else
0701             fmpz_set_ui(c, op->nmod);
0702     }
0703     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0704     {
0705         if (n != 0)
0706             fmpz_zero(c);
0707         else
0708             fmpz_set(c, op->fmpz_mod);
0709     }
0710     else
0711     {
0712         fmpz_mod_ctx_t mod_ctx;
0713         fmpz_mod_ctx_init(mod_ctx, fq_ctx_prime(FQ_DEFAULT_CTX_FQ(ctx)));
0714         fmpz_mod_poly_get_coeff_fmpz(c,
0715                           (fmpz_mod_poly_struct *) op->fq, n, mod_ctx);
0716         fmpz_mod_ctx_clear(mod_ctx);
0717     }
0718 }
0719 
0720 /* Output ********************************************************************/
0721 
0722 #ifdef FLINT_HAVE_FILE
0723 int fq_default_fprint(FILE * file, const fq_default_t op, const fq_default_ctx_t ctx);
0724 int fq_default_fprint_pretty(FILE * file, const fq_default_t op, const fq_default_ctx_t ctx);
0725 #endif
0726 
0727 void fq_default_print(const fq_default_t op, const fq_default_ctx_t ctx);
0728 void fq_default_print_pretty(const fq_default_t op, const fq_default_ctx_t ctx);
0729 
0730 FQ_DEFAULT_INLINE char * fq_default_get_str(const fq_default_t op,
0731                                             const fq_default_ctx_t ctx)
0732 {
0733     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0734     {
0735         return fq_zech_get_str(op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0736     }
0737     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0738     {
0739         return fq_nmod_get_str(op->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0740     }
0741     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0742     {
0743         fmpz_t f;
0744         char* s;
0745         fmpz_init_set_ui(f, op->nmod);
0746         s = fmpz_get_str(NULL, 10, f);
0747         fmpz_clear(f);
0748         return s;
0749     }
0750     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0751     {
0752         return fmpz_get_str(NULL, 10, op->fmpz_mod);
0753     }
0754     else
0755     {
0756         return fq_get_str(op->fq, FQ_DEFAULT_CTX_FQ(ctx));
0757     }
0758 }
0759 
0760 FQ_DEFAULT_INLINE char * fq_default_get_str_pretty(const fq_default_t op,
0761                                             const fq_default_ctx_t ctx)
0762 {
0763     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0764     {
0765         return fq_zech_get_str_pretty(op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0766     }
0767     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0768     {
0769         return fq_nmod_get_str_pretty(op->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0770     }
0771     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0772     {
0773         fmpz_t f;
0774         char* s;
0775         fmpz_init_set_ui(f, op->nmod);
0776         s = fmpz_get_str(NULL, 10, f);
0777         fmpz_clear(f);
0778         return s;
0779     }
0780     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0781     {
0782         return fmpz_get_str(NULL, 10, op->fmpz_mod);
0783     }
0784     else
0785     {
0786         return fq_get_str_pretty(op->fq, FQ_DEFAULT_CTX_FQ(ctx));
0787     }
0788 }
0789 
0790 /* Special functions *********************************************************/
0791 
0792 FQ_DEFAULT_INLINE void fq_default_trace(fmpz_t rop,
0793                      const fq_default_t op, const fq_default_ctx_t ctx)
0794 {
0795     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0796     {
0797         fq_zech_trace(rop, op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0798     }
0799     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0800     {
0801         fq_nmod_trace(rop, op->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0802     }
0803     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0804     {
0805         fmpz_set_ui(rop, op->nmod);
0806     }
0807     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0808     {
0809         fmpz_set(rop, op->fmpz_mod);
0810     }
0811     else
0812     {
0813         fq_trace(rop, op->fq, FQ_DEFAULT_CTX_FQ(ctx));
0814     }
0815 }
0816 
0817 FQ_DEFAULT_INLINE void fq_default_frobenius(fq_default_t rop,
0818             const fq_default_t op, slong e, const fq_default_ctx_t ctx)
0819 {
0820     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0821     {
0822         fq_zech_frobenius(rop->fq_zech, op->fq_zech, e, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0823     }
0824     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0825     {
0826         fq_nmod_frobenius(rop->fq_nmod, op->fq_nmod, e, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0827     }
0828     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0829     {
0830         rop->nmod = op->nmod;
0831     }
0832     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0833     {
0834         fmpz_set(rop->fmpz_mod, op->fmpz_mod);
0835     }
0836     else
0837     {
0838         fq_frobenius(rop->fq, op->fq, e, FQ_DEFAULT_CTX_FQ(ctx));
0839     }
0840 }
0841 
0842 FQ_DEFAULT_INLINE void fq_default_norm(fmpz_t rop,
0843                      const fq_default_t op, const fq_default_ctx_t ctx)
0844 {
0845     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0846     {
0847         fq_zech_norm(rop, op->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0848     }
0849     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0850     {
0851         fq_nmod_norm(rop, op->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0852     }
0853     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0854     {
0855         fmpz_set_ui(rop, op->nmod);
0856     }
0857     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0858     {
0859         fmpz_set(rop, op->fmpz_mod);
0860     }
0861     else
0862     {
0863         fq_norm(rop, op->fq, FQ_DEFAULT_CTX_FQ(ctx));
0864     }
0865 }
0866 
0867 #ifdef __cplusplus
0868 }
0869 #endif
0870 
0871 #endif