File indexing completed on 2026-11-07 10:15:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef MPN_MOD_H
0013 #define MPN_MOD_H
0014
0015 #ifdef MPN_MOD_INLINES_C
0016 #define MPN_MOD_INLINE
0017 #else
0018 #define MPN_MOD_INLINE static inline
0019 #endif
0020
0021 #include "mpn_extras.h"
0022 #include "gr_types.h"
0023
0024 #ifdef __cplusplus
0025 extern "C" {
0026 #endif
0027
0028
0029
0030 #define MPN_MOD_MIN_LIMBS 2
0031
0032
0033
0034
0035
0036
0037 #define MPN_MOD_MAX_LIMBS 16
0038
0039 typedef struct
0040 {
0041 slong nlimbs;
0042 ulong d[MPN_MOD_MAX_LIMBS];
0043 ulong dinv[MPN_MOD_MAX_LIMBS];
0044 ulong dnormed[MPN_MOD_MAX_LIMBS];
0045 flint_bitcnt_t norm;
0046 truth_t is_prime;
0047 }
0048 _mpn_mod_ctx_struct;
0049
0050 #define MPN_MOD_CTX(ctx) ((_mpn_mod_ctx_struct *)(GR_CTX_DATA_AS_PTR(ctx)))
0051 #define MPN_MOD_CTX_NLIMBS(ctx) (MPN_MOD_CTX(ctx)->nlimbs)
0052 #define MPN_MOD_CTX_MODULUS(ctx) (MPN_MOD_CTX(ctx)->d)
0053 #define MPN_MOD_CTX_MODULUS_NORMED(ctx) (MPN_MOD_CTX(ctx)->dnormed)
0054 #define MPN_MOD_CTX_MODULUS_PREINV(ctx) (MPN_MOD_CTX(ctx)->dinv)
0055 #define MPN_MOD_CTX_NORM(ctx) (MPN_MOD_CTX(ctx)->norm)
0056 #define MPN_MOD_CTX_IS_PRIME(ctx) (MPN_MOD_CTX(ctx)->is_prime)
0057 #define MPN_MOD_CTX_MODULUS_BITS(ctx) ((MPN_MOD_CTX_NLIMBS(ctx) - 1) * FLINT_BITS + (FLINT_BITS - MPN_MOD_CTX_NORM(ctx)))
0058
0059 MPN_MOD_INLINE int
0060 mpn_mod_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field)
0061 {
0062 MPN_MOD_CTX_IS_PRIME(ctx) = is_field;
0063 return GR_SUCCESS;
0064 }
0065
0066
0067
0068 int gr_ctx_init_mpn_mod(gr_ctx_t ctx, const fmpz_t n);
0069 int _gr_ctx_init_mpn_mod(gr_ctx_t ctx, nn_srcptr n, slong nlimbs);
0070 void gr_ctx_init_mpn_mod_randtest(gr_ctx_t ctx, flint_rand_t state);
0071
0072 int mpn_mod_ctx_write(gr_stream_t out, gr_ctx_t ctx);
0073 void mpn_mod_ctx_clear(gr_ctx_t ctx);
0074
0075 MPN_MOD_INLINE truth_t
0076 mpn_mod_ctx_is_field(gr_ctx_t ctx)
0077 {
0078 return MPN_MOD_CTX_IS_PRIME(ctx);
0079 }
0080
0081 MPN_MOD_INLINE void
0082 mpn_mod_init(nn_ptr x, gr_ctx_t ctx)
0083 {
0084 flint_mpn_zero(x, MPN_MOD_CTX_NLIMBS(ctx));
0085 }
0086
0087 MPN_MOD_INLINE void
0088 mpn_mod_clear(nn_ptr FLINT_UNUSED(x), gr_ctx_t FLINT_UNUSED(ctx))
0089 {
0090 }
0091
0092 MPN_MOD_INLINE void
0093 mpn_mod_swap(nn_ptr x, nn_ptr y, gr_ctx_t ctx)
0094 {
0095 slong i = 0, n = MPN_MOD_CTX_NLIMBS(ctx);
0096 for (i = 0; i < n; i++)
0097 FLINT_SWAP(ulong, x[i], y[i]);
0098 }
0099
0100 MPN_MOD_INLINE int
0101 mpn_mod_set(nn_ptr res, nn_srcptr x, gr_ctx_t ctx)
0102 {
0103 flint_mpn_copyi(res, x, MPN_MOD_CTX_NLIMBS(ctx));
0104 return GR_SUCCESS;
0105 }
0106
0107 MPN_MOD_INLINE int
0108 mpn_mod_zero(nn_ptr res, gr_ctx_t ctx)
0109 {
0110 flint_mpn_zero(res, MPN_MOD_CTX_NLIMBS(ctx));
0111 return GR_SUCCESS;
0112 }
0113
0114 MPN_MOD_INLINE
0115 int mpn_mod_one(nn_ptr res, gr_ctx_t ctx)
0116 {
0117 res[0] = 1;
0118 flint_mpn_zero(res + 1, MPN_MOD_CTX_NLIMBS(ctx) - 1);
0119 return GR_SUCCESS;
0120 }
0121
0122 int mpn_mod_set_ui(nn_ptr res, ulong x, gr_ctx_t ctx);
0123 int mpn_mod_set_si(nn_ptr res, slong x, gr_ctx_t ctx);
0124 int mpn_mod_neg_one(nn_ptr res, gr_ctx_t ctx);
0125
0126 int mpn_mod_set_mpn(nn_ptr res, nn_srcptr x, slong xn, gr_ctx_t ctx);
0127 int mpn_mod_set_fmpz(nn_ptr res, const fmpz_t x, gr_ctx_t ctx);
0128 int mpn_mod_set_other(nn_ptr res, gr_ptr v, gr_ctx_t v_ctx, gr_ctx_t ctx);
0129 int mpn_mod_randtest(nn_ptr res, flint_rand_t state, gr_ctx_t ctx);
0130 int mpn_mod_write(gr_stream_t out, nn_srcptr x, gr_ctx_t ctx);
0131
0132 int mpn_mod_get_fmpz(fmpz_t res, nn_srcptr x, gr_ctx_t ctx);
0133
0134 MPN_MOD_INLINE truth_t
0135 mpn_mod_is_zero(nn_srcptr x, gr_ctx_t ctx)
0136 {
0137 return flint_mpn_zero_p(x, MPN_MOD_CTX_NLIMBS(ctx)) ? T_TRUE : T_FALSE;
0138 }
0139
0140 MPN_MOD_INLINE truth_t
0141 mpn_mod_is_one(nn_srcptr x, gr_ctx_t ctx)
0142 {
0143 return (x[0] == 1 && flint_mpn_zero_p(x + 1, MPN_MOD_CTX_NLIMBS(ctx) - 1)) ? T_TRUE : T_FALSE;
0144 }
0145
0146 truth_t mpn_mod_is_neg_one(gr_srcptr x, gr_ctx_t ctx);
0147
0148 MPN_MOD_INLINE truth_t
0149 mpn_mod_equal(nn_srcptr x, nn_srcptr y, gr_ctx_t ctx)
0150 {
0151 return flint_mpn_equal_p(x, y, MPN_MOD_CTX_NLIMBS(ctx)) ? T_TRUE : T_FALSE;
0152 }
0153
0154 int mpn_mod_neg(nn_ptr res, nn_srcptr x, gr_ctx_t ctx);
0155 int mpn_mod_add(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx);
0156 int mpn_mod_sub(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx);
0157 int mpn_mod_add_ui(nn_ptr res, nn_srcptr x, ulong y, gr_ctx_t ctx);
0158 int mpn_mod_sub_ui(nn_ptr res, nn_srcptr x, ulong y, gr_ctx_t ctx);
0159 int mpn_mod_add_si(nn_ptr res, nn_srcptr x, slong y, gr_ctx_t ctx);
0160 int mpn_mod_sub_si(nn_ptr res, nn_srcptr x, slong y, gr_ctx_t ctx);
0161 int mpn_mod_add_fmpz(nn_ptr res, nn_srcptr x, const fmpz_t y, gr_ctx_t ctx);
0162 int mpn_mod_sub_fmpz(nn_ptr res, nn_srcptr x, const fmpz_t y, gr_ctx_t ctx);
0163
0164 int mpn_mod_mul(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx);
0165
0166 int mpn_mod_mul_ui(nn_ptr res, nn_srcptr x, ulong y, gr_ctx_t ctx);
0167 int mpn_mod_mul_si(nn_ptr res, nn_srcptr x, slong y, gr_ctx_t ctx);
0168 int mpn_mod_mul_fmpz(nn_ptr res, nn_srcptr x, const fmpz_t y, gr_ctx_t ctx);
0169 int mpn_mod_addmul(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx);
0170 int mpn_mod_addmul_ui(nn_ptr res, nn_srcptr x, ulong y, gr_ctx_t ctx);
0171 int mpn_mod_addmul_si(nn_ptr res, nn_srcptr x, slong y, gr_ctx_t ctx);
0172 int mpn_mod_addmul_fmpz(nn_ptr res, nn_srcptr x, const fmpz_t y, gr_ctx_t ctx);
0173 int mpn_mod_submul(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx);
0174 int mpn_mod_submul_ui(nn_ptr res, nn_srcptr x, ulong y, gr_ctx_t ctx);
0175 int mpn_mod_submul_si(nn_ptr res, nn_srcptr x, slong y, gr_ctx_t ctx);
0176 int mpn_mod_submul_fmpz(nn_ptr res, nn_srcptr x, const fmpz_t y, gr_ctx_t ctx);
0177
0178 MPN_MOD_INLINE int
0179 mpn_mod_sqr(nn_ptr res, nn_srcptr x, gr_ctx_t ctx)
0180 {
0181 return mpn_mod_mul(res, x, x, ctx);
0182 }
0183
0184 int mpn_mod_fmma(nn_ptr res, nn_srcptr x1, nn_srcptr y1, nn_srcptr x2, nn_srcptr y2, gr_ctx_t ctx);
0185
0186 int mpn_mod_inv(nn_ptr res, nn_srcptr x, gr_ctx_t ctx);
0187 int mpn_mod_div(nn_ptr res, nn_srcptr x, nn_srcptr y, gr_ctx_t ctx);
0188
0189
0190
0191 int _mpn_mod_vec_zero(nn_ptr res, slong len, gr_ctx_t ctx);
0192 int _mpn_mod_vec_clear(nn_ptr FLINT_UNUSED(res), slong FLINT_UNUSED(len), gr_ctx_t FLINT_UNUSED(ctx));
0193 int _mpn_mod_vec_set(nn_ptr res, nn_srcptr x, slong len, gr_ctx_t ctx);
0194 void _mpn_mod_vec_swap(nn_ptr vec1, nn_ptr vec2, slong len, gr_ctx_t ctx);
0195 int _mpn_mod_vec_neg(nn_ptr res, nn_srcptr x, slong len, gr_ctx_t ctx);
0196 int _mpn_mod_vec_add(nn_ptr res, nn_srcptr x, nn_srcptr y, slong len, gr_ctx_t ctx);
0197 int _mpn_mod_vec_sub(nn_ptr res, nn_srcptr x, nn_srcptr y, slong len, gr_ctx_t ctx);
0198 int _mpn_mod_vec_mul(nn_ptr res, nn_srcptr x, nn_srcptr y, slong len, gr_ctx_t ctx);
0199 int _mpn_mod_vec_mul_scalar(nn_ptr res, nn_srcptr x, slong len, nn_srcptr y, gr_ctx_t ctx);
0200 int _mpn_mod_scalar_mul_vec(nn_ptr res, nn_srcptr y, nn_srcptr x, slong len, gr_ctx_t ctx);
0201 int _mpn_mod_vec_addmul_scalar(nn_ptr res, nn_srcptr x, slong len, nn_srcptr y, gr_ctx_t ctx);
0202 int _mpn_mod_vec_submul_scalar(nn_ptr res, nn_srcptr x, slong len, nn_srcptr y, gr_ctx_t ctx);
0203 int _mpn_mod_vec_dot(nn_ptr res, nn_srcptr initial, int subtract, nn_srcptr vec1, nn_srcptr vec2, slong len, gr_ctx_t ctx);
0204 int _mpn_mod_vec_dot_rev(nn_ptr res, nn_srcptr initial, int subtract, nn_srcptr vec1, nn_srcptr vec2, slong len, gr_ctx_t ctx);
0205 int _mpn_mod_vec_dot_strided(nn_ptr res, nn_srcptr initial, int subtract, nn_srcptr vec1, slong stride1, nn_srcptr vec2, slong stride2, slong len, gr_ctx_t ctx);
0206
0207
0208
0209 int mpn_mod_mat_mul_waksman(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx);
0210 int mpn_mod_mat_mul_multi_mod(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx);
0211 int mpn_mod_mat_mul(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx);
0212
0213 int mpn_mod_mat_nonsingular_solve_tril(gr_mat_t X, const gr_mat_t L, const gr_mat_t B, int unit, gr_ctx_t ctx);
0214 int mpn_mod_mat_nonsingular_solve_triu(gr_mat_t X, const gr_mat_t U, const gr_mat_t B, int unit, gr_ctx_t ctx);
0215 int mpn_mod_mat_lu_classical_delayed(slong * res_rank, slong * P, gr_mat_t A, const gr_mat_t A_in, int rank_check, gr_ctx_t ctx);
0216 int mpn_mod_mat_lu(slong * rank, slong * P, gr_mat_t LU, const gr_mat_t A, int rank_check, gr_ctx_t ctx);
0217 int mpn_mod_mat_det(nn_ptr res, const gr_mat_t A, gr_ctx_t ctx);
0218 int _mpn_mod_mat_charpoly(nn_ptr res, const gr_mat_t mat, gr_ctx_t ctx);
0219 int mpn_mod_mat_reduce_row(slong * column, gr_mat_t A, slong * P, slong * L, slong m, gr_ctx_t ctx);
0220
0221
0222
0223 int _mpn_mod_poly_mulmid_classical(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx);
0224 int _mpn_mod_poly_mulmid_karatsuba(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, slong cutoff, gr_ctx_t ctx);
0225 int _mpn_mod_poly_mulmid_KS(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx);
0226 int _mpn_mod_poly_mulmid_fft_small(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx);
0227 int _mpn_mod_poly_mulmid(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx);
0228
0229 int _mpn_mod_poly_mullow_classical(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong len, gr_ctx_t ctx);
0230 int _mpn_mod_poly_mullow_karatsuba(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong len, slong cutoff, gr_ctx_t ctx);
0231 int _mpn_mod_poly_mullow_KS(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong len, gr_ctx_t ctx);
0232 int _mpn_mod_poly_mullow_fft_small(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong len, gr_ctx_t ctx);
0233 int _mpn_mod_poly_mullow(nn_ptr res, nn_srcptr poly1, slong len1, nn_srcptr poly2, slong len2, slong len, gr_ctx_t ctx);
0234
0235 int _mpn_mod_poly_inv_series(nn_ptr Q, nn_srcptr B, slong lenB, slong len, gr_ctx_t ctx);
0236 int _mpn_mod_poly_div_series(nn_ptr Q, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, slong len, gr_ctx_t ctx);
0237
0238 int _mpn_mod_poly_divrem_q1_preinv1_fmma(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nn_srcptr invL, gr_ctx_t ctx);
0239 int _mpn_mod_poly_divrem_q1_preinv1_fmma_precond(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nn_srcptr invL, gr_ctx_t ctx);
0240 int _mpn_mod_poly_divrem_q1_preinv1_karatsuba_precond(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nn_srcptr invL, gr_ctx_t ctx);
0241 int _mpn_mod_poly_divrem_q1_preinv1(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nn_srcptr invL, gr_ctx_t ctx);
0242
0243 int _mpn_mod_poly_divrem_basecase_preinv1(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, nn_srcptr invL, gr_ctx_t ctx);
0244 int _mpn_mod_poly_divrem_basecase(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, gr_ctx_t ctx);
0245 int _mpn_mod_poly_divrem(nn_ptr Q, nn_ptr R, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, gr_ctx_t ctx);
0246 int _mpn_mod_poly_div(nn_ptr Q, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, gr_ctx_t ctx);
0247
0248 int _mpn_mod_poly_gcd(nn_ptr G, slong * lenG, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, gr_ctx_t ctx);
0249 int _mpn_mod_poly_xgcd(slong * lenG, nn_ptr G, nn_ptr S, nn_ptr T, nn_srcptr A, slong lenA, nn_srcptr B, slong lenB, gr_ctx_t ctx);
0250
0251 #ifdef __cplusplus
0252 }
0253 #endif
0254
0255 #endif