int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { long i, dim = fmpz_mat_nrows(A); if (dim == 0) { fmpz_one(den); return 1; } else if (dim == 1) { fmpz_set(den, fmpz_mat_entry(A, 0, 0)); if (fmpz_is_zero(den)) return 0; if (!fmpz_mat_is_empty(B)) _fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B)); return 1; } else if (dim == 2) { fmpz_t t, u; _fmpz_mat_det_cofactor_2x2(den, A->rows); if (fmpz_is_zero(den)) return 0; fmpz_init(t); fmpz_init(u); for (i = 0; i < fmpz_mat_ncols(B); i++) { fmpz_mul (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i)); fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i)); fmpz_mul (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i)); fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i)); fmpz_swap(fmpz_mat_entry(X, 0, i), t); fmpz_swap(fmpz_mat_entry(X, 1, i), u); } fmpz_clear(t); fmpz_clear(u); return 1; } else if (dim == 3) { return _fmpz_mat_solve_cramer_3x3(X, den, A, B); } else { printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
void _fmpz_holonomic_bsplit_hypgeom_fmpz(fmpz_t P, fmpz_t Q, const fmpz_poly_t R0, const fmpz_poly_t R1, long start, long a, long b) { if (b - a == 1) { fmpz c = start + a; fmpz_poly_evaluate_fmpz(P, R0, &c); fmpz_poly_evaluate_fmpz(Q, R1, &c); fmpz_neg(P, P); } else { fmpz_t P2, Q2; long m = a + (b - a) / 2; fmpz_init(P2); fmpz_init(Q2); _fmpz_holonomic_bsplit_hypgeom_fmpz(P, Q, R0, R1, start, a, m); _fmpz_holonomic_bsplit_hypgeom_fmpz(P2, Q2, R0, R1, start, m, b); fmpz_mul(P, P, P2); fmpz_mul(Q, Q, Q2); fmpz_clear(P2); fmpz_clear(Q2); } }
void _fmpq_poly_integral(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, slong len) { slong k; fmpz_t t; fmpz_init(t); fmpz_one(t); for (k = len - 1; k > 0; k--) { fmpz_mul(rpoly + k, poly + k - 1, t); fmpz_mul_ui(t, t, k); } fmpz_mul(rden, den, t); fmpz_set_ui(t, UWORD(2)); for (k = 3; k < len; k++) { fmpz_mul(rpoly + k, rpoly + k, t); fmpz_mul_ui(t, t, k); } fmpz_zero(rpoly); _fmpq_poly_canonicalise(rpoly, rden, len); fmpz_clear(t); }
int _fmpq_poly_is_squarefree(const fmpz * poly, const fmpz_t den, long len) { if (len < 3) return 1; else if (len == 3) { int ans; fmpz_t lhs, rhs; fmpz_init(lhs); fmpz_init(rhs); fmpz_mul(lhs, poly + 1, poly + 1); fmpz_mul(rhs, poly, poly + 2); fmpz_mul_ui(rhs, rhs, 4); ans = !fmpz_equal(lhs, rhs); fmpz_clear(lhs); fmpz_clear(rhs); return ans; } else { long gdeg; fmpz * w = _fmpz_vec_init(2 * len); _fmpz_poly_derivative(w, poly, len); _fmpz_poly_gcd(w + len, poly, len, w, len - 1L); for (gdeg = len - 2L; w[gdeg] == 0L; gdeg--) ; _fmpz_vec_clear(w, 2 * len); return (gdeg == 0); } }
void _fmpz_mat_solve_cramer_2x2(fmpz * x, fmpz_t d, fmpz ** const a, const fmpz * b) { fmpz_mul (&x[0], &a[1][1], &b[0]); fmpz_submul(&x[0], &a[0][1], &b[1]); fmpz_mul (&x[1], &a[0][0], &b[1]); fmpz_submul(&x[1], &a[1][0], &b[0]); _fmpz_mat_det_cofactor_2x2(d, a); }
static void entry(fmpz_t rop_u, long *rop_v, const long *u, const long *v, const fmpz *a, const fmpz *dinv, const fmpz **mu, long M, const long **C, const long *lenC, long n, long d, long p, long N, long N2) { const long ku = diagfrob_k(u, n, d); const long kv = diagfrob_k(v, n, d); fmpz_t f, g, P; fmpz_init(f); fmpz_init(g); fmpz_init_set_ui(P, p); /* Compute $g := (u'-1)! \alpha_{u+1,v+1}$ to precision $N2$. */ fmpz_fac_ui(f, ku - 1); alpha(g, u, v, a, dinv, mu, M, C, lenC, n, d, p, N2); fmpz_mul(g, f, g); /* Compute $f := (-1)^{u'+v'} (v'-1)!$ exactly. */ fmpz_fac_ui(f, kv - 1); if ((ku + kv) % 2 != 0) { fmpz_neg(f, f); } /* Set rop to the product of $f$ and $g^{-1} mod $p^N$. */ *rop_v = fmpz_remove(f, f, P) + n - fmpz_remove(g, g, P); if (*rop_v >= N) { fmpz_zero(rop_u); *rop_v = 0; } else { _padic_inv(g, g, P, N - *rop_v); fmpz_mul(rop_u, f, g); fmpz_pow_ui(f, P, N - *rop_v); fmpz_mod(rop_u, rop_u, f); } fmpz_clear(f); fmpz_clear(g); fmpz_clear(P); }
static void dsum_p( fmpz_t rop, const fmpz *dinv, const fmpz *mu, long M, const long *C, long lenC, const fmpz_t a, long ui, long vi, long n, long d, long p, long N) { long m, r, idx; fmpz_t apm1, apow, f, g, P, PN; fmpz_init(apm1); fmpz_init(apow); fmpz_init(f); fmpz_init(g); fmpz_init_set_ui(P, p); fmpz_init(PN); fmpz_pow_ui(PN, P, N); fmpz_zero(rop); r = 0; m = (p * (ui + 1) - (vi + 1)) / d; if (m <= M) /* Step {r = 0} */ { idx = _bsearch(C, 0, lenC, m % p); fmpz_powm_ui(apm1, a, p - 1, PN); fmpz_one(apow); fmpz_one(f); fmpz_mod(rop, mu + idx + lenC * (m / p), PN); } for (r = 1, m += p; m <= M; r++, m += p) { idx = _bsearch(C, 0, lenC, m % p); fmpz_mul(apow, apow, apm1); fmpz_mod(apow, apow, PN); fmpz_mul_ui(f, f, ui + 1 + (r - 1) * d); fmpz_mod(f, f, PN); fmpz_mul(g, f, dinv + r); fmpz_mul(g, g, apow); fmpz_mul(g, g, mu + idx + lenC * (m / p)); fmpz_mod(g, g, PN); fmpz_add(rop, rop, g); } fmpz_mod(rop, rop, PN); fmpz_clear(apm1); fmpz_clear(apow); fmpz_clear(f); fmpz_clear(g); fmpz_clear(P); fmpz_clear(PN); }
void _fmprb_get_rand_fmpq(fmpz_t num, fmpz_t den, flint_rand_t state, const fmpz_t den_mult, const fmprb_t x) { fmpz_t a, b, exp; fmpz_init(a); fmpz_init(b); fmpz_init(exp); fmprb_get_interval_fmpz_2exp(a, b, exp, x); if (COEFF_IS_MPZ(*exp)) { printf("exception: fmprb_get_rand_fmpq: too large exponent\n"); abort(); } if (*exp >= 0) { fmpz_mul_2exp(a, a, *exp); fmpz_mul_2exp(b, b, *exp); } /* generate random integer in [a*den, b*den] */ fmpz_mul(a, a, den_mult); fmpz_mul(b, b, den_mult); fmpz_add_ui(b, b, 1UL); fmpz_sub(b, b, a); /* return one endpoint with high probability (used for stress testing rounding) */ if (n_randint(state, 6) == 0) { if (n_randint(state, 2)) fmpz_zero(num); else fmpz_sub_ui(num, b, 1UL); } else { fmpz_randtest_mod(num, state, b); } fmpz_add(num, num, a); fmpz_set(den, den_mult); if (*exp < 0) fmpz_mul_2exp(den, den, -(*exp)); fmpz_clear(a); fmpz_clear(b); fmpz_clear(exp); }
void fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A) { fmpz_mat_t X, B; fmpz_t t, u, v, mod; long i, n; int success; n = A->r; fmpz_mat_init(B, n, 1); fmpz_mat_init(X, n, 1); fmpz_init(t); fmpz_init(u); fmpz_init(v); fmpz_init(mod); /* Create a "random" vector */ for (i = 0; i < n; i++) { fmpz_set_si(fmpz_mat_entry(B, i, 0), 2*(i % 2) - 1); } success = fmpz_mat_solve_dixon(X, mod, A, B); if (success) { fmpz_one(d); for (i = 0; i < n; i++) { fmpz_mul(t, d, fmpz_mat_entry(X, i, 0)); fmpz_fdiv_qr(u, t, t, mod); if (!_fmpq_reconstruct_fmpz(u, v, t, mod)) { printf("Exception: fmpz_mat_det_divisor: " "rational reconstruction failed!\n"); abort(); } fmpz_mul(d, v, d); } } else { fmpz_zero(d); } fmpz_mat_clear(B); fmpz_mat_clear(X); fmpz_clear(t); fmpz_clear(u); fmpz_clear(v); fmpz_clear(mod); }
void _padic_log_balanced(fmpz_t z, const fmpz_t y, long v, const fmpz_t p, long N) { fmpz_t pv, pN, r, t, u; long val; padic_inv_t S; fmpz_init(pv); fmpz_init(pN); fmpz_init(r); fmpz_init(t); fmpz_init(u); _padic_inv_precompute(S, p, N); fmpz_set(t, y); fmpz_set(pv, p); fmpz_pow_ui(pN, p, N); fmpz_zero(z); val = 1; /* TODO: Abort earlier if larger than $p^N$, possible with variable precision? */ while (!fmpz_is_zero(t)) { fmpz_mul(pv, pv, pv); fmpz_fdiv_qr(t, r, t, pv); if (!fmpz_is_zero(t)) { fmpz_mul(t, t, pv); fmpz_add_ui(u, r, 1); _padic_inv_precomp(u, u, S); fmpz_mul(t, t, u); fmpz_mod(t, t, pN); } if (!fmpz_is_zero(r)) { fmpz_neg(r, r); _padic_log_bsplit(r, r, val, p, N); fmpz_sub(z, z, r); } val *= 2; } fmpz_clear(pv); fmpz_clear(pN); fmpz_clear(r); fmpz_clear(t); fmpz_clear(u); _padic_inv_clear(S); }
void _fmpz_ramanujan_tau(fmpz_t res, fmpz_factor_t factors) { fmpz_poly_t poly; fmpz_t tau_p, p_11, next, this, prev; long k, r; ulong max_prime; max_prime = 1UL; for (k = 0; k < factors->length; k++) { /* TODO: handle overflow properly */ max_prime = FLINT_MAX(max_prime, fmpz_get_ui(factors->p + k)); } fmpz_poly_init(poly); fmpz_poly_ramanujan_tau(poly, max_prime + 1); fmpz_set_ui(res, 1); fmpz_init(tau_p); fmpz_init(p_11); fmpz_init(next); fmpz_init(this); fmpz_init(prev); for (k = 0; k < factors->length; k++) { ulong p = fmpz_get_ui(factors->p + k); fmpz_set(tau_p, poly->coeffs + p); fmpz_set_ui(p_11, p); fmpz_pow_ui(p_11, p_11, 11); fmpz_set_ui(prev, 1); fmpz_set(this, tau_p); for (r = 1; r < fmpz_get_ui(factors->exp + k); r++) { fmpz_mul(next, tau_p, this); fmpz_submul(next, p_11, prev); fmpz_set(prev, this); fmpz_set(this, next); } fmpz_mul(res, res, this); } fmpz_clear(tau_p); fmpz_clear(p_11); fmpz_clear(next); fmpz_clear(this); fmpz_clear(prev); fmpz_poly_clear(poly); }
static __inline__ long _zeta_function(const fmpz_t p, long a, long n, long d) { const long b = gmc_basis_size(n, d); long i, N; fmpz_t f, g, max; fmpz_init(f); fmpz_init(g); fmpz_init(max); if (n == 3 && fmpz_cmp_ui(p, 2) != 0) { fmpz_bin_uiui(f, d-1, 3); fmpz_bin_uiui(g, b, b / 2); fmpz_mul_ui(g, g, 2); N = a * (*f) + fmpz_clog(g, p); } else if (n % 2L == 0) /* n even implies b even */ { fmpz_bin_uiui(f, b, b / 2); fmpz_pow_ui(g, p, (a * (b / 2) * (n - 1) + 1) / 2); fmpz_mul(f, f, g); fmpz_mul_ui(f, f, 2); N = fmpz_flog(f, p) + 1; } else { for (i = b / 2; i <= b; i++) { fmpz_bin_uiui(f, b, i); fmpz_pow_ui(g, p, (a * i * (n - 1) + 1) / 2); fmpz_mul(f, f, g); fmpz_mul_ui(f, f, 2); if (fmpz_cmp(max, f) < 0) fmpz_swap(max, f); } N = fmpz_flog(max, p) + 1; } fmpz_clear(f); fmpz_clear(g); fmpz_clear(max); return N; }
static void bsplit_recursive_fmpz(fmpz_t P, fmpz_t Q, fmpz_t B, fmpz_t T, const hypgeom_t hyp, long a, long b, int cont) { if (b - a == 1) { if (a == 0) { fmpz_one(P); fmpz_one(Q); } else { fmpz_poly_evaluate_si(P, hyp->P, a); fmpz_poly_evaluate_si(Q, hyp->Q, a); } fmpz_poly_evaluate_si(B, hyp->B, a); fmpz_poly_evaluate_si(T, hyp->A, a); fmpz_mul(T, T, P); } else { long m; fmpz_t P2, Q2, B2, T2; m = (a + b) / 2; fmpz_init(P2); fmpz_init(Q2); fmpz_init(B2); fmpz_init(T2); bsplit_recursive_fmpz(P, Q, B, T, hyp, a, m, 1); bsplit_recursive_fmpz(P2, Q2, B2, T2, hyp, m, b, 1); if (fmpz_is_one(B) && fmpz_is_one(B2)) { fmpz_mul(T, T, Q2); fmpz_addmul(T, P, T2); } else { fmpz_mul(T, T, B2); fmpz_mul(T, T, Q2); fmpz_mul(T2, T2, B); fmpz_addmul(T, P, T2); } fmpz_mul(B, B, B2); fmpz_mul(Q, Q, Q2); if (cont) fmpz_mul(P, P, P2); fmpz_clear(P2); fmpz_clear(Q2); fmpz_clear(B2); fmpz_clear(T2); } }
void _fmpz_mod_poly_evaluate_fmpz(fmpz_t res, const fmpz *poly, slong len, const fmpz_t a, const fmpz_t p) { if (len == 0) { fmpz_zero(res); } else if (len == 1 || fmpz_is_zero(a)) { fmpz_set(res, poly); } else { slong i = len - 1; fmpz_t t; fmpz_init(t); fmpz_set(res, poly + i); for (i = len - 2; i >= 0; i--) { fmpz_mul(t, res, a); fmpz_mod(t, t, p); fmpz_add(res, poly + i, t); } fmpz_clear(t); if (fmpz_cmpabs(res, p) >= 0) fmpz_sub(res, res, p); } }
/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */ void _fmpz_poly_mul_karatsuba(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2) { fmpz *rev1, *rev2, *out, *temp; long length, loglen = 0; if (len1 == 1) { fmpz_mul(res, poly1, poly2); return; } while ((1L << loglen) < len1) loglen++; length = (1L << loglen); rev1 = (fmpz *) flint_calloc(4 * length, sizeof(fmpz *)); rev2 = rev1 + length; out = rev1 + 2 * length; temp = _fmpz_vec_init(2 * length); revbin1(rev1, poly1, len1, loglen); revbin1(rev2, poly2, len2, loglen); _fmpz_poly_mul_kara_recursive(out, rev1, rev2, temp, loglen); _fmpz_vec_zero(res, len1 + len2 - 1); revbin2(res, out, len1 + len2 - 1, loglen + 1); _fmpz_vec_clear(temp, 2 * length); flint_free(rev1); }
void fmpq_poly_set_coeff_mpz(fmpq_poly_t poly, long n, const mpz_t x) { long len = poly->length; const int replace = (n < len && !fmpz_is_zero(poly->coeffs + n)); if (!replace && mpz_sgn(x) == 0) return; if (n + 1 > len) { fmpq_poly_fit_length(poly, n + 1); _fmpq_poly_set_length(poly, n + 1); mpn_zero((mp_ptr) poly->coeffs + len, (n + 1) - len); } if (*poly->den == 1L) { fmpz_set_mpz(poly->coeffs + n, x); if (replace) _fmpq_poly_normalise(poly); } else { fmpz_set_mpz(poly->coeffs + n, x); fmpz_mul(poly->coeffs + n, poly->coeffs + n, poly->den); if (replace) fmpq_poly_canonicalise(poly); } }
/* Assumes poly1 and poly2 are not length 0 and 0 < n <= len1 + len2 - 1. */ void _fmpz_poly_mullow_classical(fmpz * res, const fmpz * poly1, long len1, const fmpz * poly2, long len2, long n) { if ((len1 == 1 && len2 == 1) || n == 1) /* Special case if the length of output is 1 */ { fmpz_mul(res, poly1, poly2); } else /* Ordinary case */ { long i; /* Set res[i] = poly1[i]*poly2[0] */ _fmpz_vec_scalar_mul_fmpz(res, poly1, FLINT_MIN(len1, n), poly2); /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ if (n > len1) _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, n - len1, poly1 + len1 - 1); /* out[i+j] += in1[i]*in2[j] */ for (i = 0; i < FLINT_MIN(len1, n) - 1; i++) _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1, FLINT_MIN(len2, n - i) - 1, poly1 + i); } }
static __inline__ void fmpz_mat_window_unsh_mul_general_triu( MUL_TYPE_ARG ) // R := A*B where B is upper-triangular square { slong d0=R->r, d1=B->c, i,j,k; fmpz* p,* q,* rho; fmpz** r=R->rows; fmpz** b=B->rows; fmpz** a=A->rows; slong B_delta=B->delta; fmpz_t B_00; fmpz_init_set( B_00, b[0] ); for( i=0; i<d0; i++ ) { rho=r[i]; p=a[i]; fmpz_mul( rho, p, B_00 ); rho++; for( j=1; j<d1; j++ ) { fmpz_clear_and_zero( rho ); q=b[0]+j; // multiply j entries for( k=0; k<j; k++,q += B_delta ) fmpz_addmul( rho, p+k, q ); // multiply j'th entry fmpz_addmul( rho, p+j, q ); rho++; } } fmpz_clear( B_00 ); }
void _fmpz_holonomic_forward_bsplit_fmpz(fmpz_mat_t M, fmpz_t Q, const fmpz_holonomic_t op, long start, long a, long b) { long r = fmpz_holonomic_order(op); if (b - a == 1) { _fmpz_holonomic_eval_companion_matrix_fmpz(M, Q, op, start + a); } else { fmpz_mat_t L, R; fmpz_t Q2; long m = a + (b - a) / 2; fmpz_mat_init(L, r, r); fmpz_mat_init(R, r, r); fmpz_init(Q2); _fmpz_holonomic_forward_bsplit_fmpz(L, Q, op, start, a, m); _fmpz_holonomic_forward_bsplit_fmpz(R, Q2, op, start, m, b); fmpz_mat_mul(M, R, L); fmpz_mul(Q, Q, Q2); fmpz_mat_clear(L); fmpz_mat_clear(R); fmpz_clear(Q2); } }
void _fmpz_poly_evaluate_horner_fmpz(fmpz_t res, const fmpz * f, long len, const fmpz_t a) { if (len == 0) { fmpz_zero(res); } else if (len == 1 || fmpz_is_zero(a)) { fmpz_set(res, f); } else { long i = len - 1; fmpz_t t; fmpz_init(t); fmpz_set(res, f + i); for (i = len - 2; i >= 0; i--) { fmpz_mul(t, res, a); fmpz_add(res, f + i, t); } fmpz_clear(t); } }
static void _padic_log_bsplit(fmpz_t z, const fmpz_t y, long v, const fmpz_t p, long N) { fmpz_t P, B, T; long n; if (fmpz_fits_si(p)) n = _padic_log_bound(v, N, fmpz_get_si(p)); else n = (N - 1) / v; n = FLINT_MAX(n, 2); fmpz_init(P); fmpz_init(B); fmpz_init(T); _padic_log_bsplit_series(P, B, T, y, 1, n); n = fmpz_remove(B, B, p); fmpz_pow_ui(P, p, n); fmpz_divexact(T, T, P); _padic_inv(B, B, p, N); fmpz_mul(z, T, B); fmpz_clear(P); fmpz_clear(B); fmpz_clear(T); }
/* Recursive Karatsuba assuming polynomials are in revbin format. Assumes rev1 and rev2 are both of length 2^bits and that temp has space for 2^bits coefficients. */ void _fmpz_poly_mul_kara_recursive(fmpz * out, fmpz * rev1, fmpz * rev2, fmpz * temp, long bits) { long length = (1L << bits); long m = length / 2; if (length == 1) { fmpz_mul(out, rev1, rev2); fmpz_zero(out + 1); return; } _fmpz_vec_add(temp, rev1, rev1 + m, m); _fmpz_vec_add(temp + m, rev2, rev2 + m, m); _fmpz_poly_mul_kara_recursive(out, rev1, rev2, temp + 2 * m, bits - 1); _fmpz_poly_mul_kara_recursive(out + length, temp, temp + m, temp + 2 * m, bits - 1); _fmpz_poly_mul_kara_recursive(temp, rev1 + m, rev2 + m, temp + 2 * m, bits - 1); _fmpz_vec_sub(out + length, out + length, out, length); _fmpz_vec_sub(out + length, out + length, temp, length); _fmpz_vec_add_rev(out, temp, bits); }
/* Assumes poly1 and poly2 are not length 0. */ void _fmpz_poly_mul_classical(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2) { if (len1 == 1 && len2 == 1) /* Special case if the length of both inputs is 1 */ { fmpz_mul(res, poly1, poly2); } else /* Ordinary case */ { slong i; /* Set res[i] = poly1[i]*poly2[0] */ _fmpz_vec_scalar_mul_fmpz(res, poly1, len1, poly2); /* Set res[i+len1-1] = in1[len1-1]*in2[i] */ _fmpz_vec_scalar_mul_fmpz(res + len1, poly2 + 1, len2 - 1, poly1 + len1 - 1); /* out[i+j] += in1[i]*in2[j] */ for (i = 0; i < len1 - 1; i++) _fmpz_vec_scalar_addmul_fmpz(res + i + 1, poly2 + 1, len2 - 1, poly1 + i); } }
void fmpz_mat_mul_classical(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) { long ar, bc, br; long i, j, k; ar = A->r; br = B->r; bc = B->c; if (br == 0) { fmpz_mat_zero(C); return; } for (i = 0; i < ar; i++) { for (j = 0; j < bc; j++) { fmpz_mul(fmpz_mat_entry(C, i, j), fmpz_mat_entry(A, i, 0), fmpz_mat_entry(B, 0, j)); for (k = 1; k < br; k++) { fmpz_addmul(fmpz_mat_entry(C, i, j), fmpz_mat_entry(A, i, k), fmpz_mat_entry(B, k, j)); } } } }
static void precompute_dinv_p(fmpz *list, long M, long d, long p, long N) { fmpz_one(list + 0); if (M >= p) { fmpz_t P, PN; long r; fmpz_init_set_ui(P, p); fmpz_init(PN); fmpz_pow_ui(PN, P, N); fmpz_set_ui(list + 1, d); _padic_inv(list + 1, list + 1, P, N); for (r = 2; r <= M / p; r++) { fmpz_mul(list + r, list + (r - 1), list + 1); fmpz_mod(list + r, list + r, PN); } fmpz_clear(P); fmpz_clear(PN); } }
/* Assumes poly1 and poly2 are not length 0 and len1 >= len2. */ void _fmpz_poly_mulmid_classical(fmpz * res, const fmpz * poly1, slong len1, const fmpz * poly2, slong len2) { if ((len1 == 1) && (len2 == 1)) /* Special case if the length of both inputs is 1 */ { fmpz_mul(res, poly1, poly2); } else /* Ordinary case */ { slong i; /* Set res[i] = poly1[i]*poly2[0] */ _fmpz_vec_scalar_mul_fmpz(res, poly1 + len2 - 1, len1 - len2 + 1, poly2); /* out[i+j] += in1[i]*in2[j] */ for (i = 0; i < len2 - 1; i++) _fmpz_vec_scalar_addmul_fmpz(res, poly2 + len2 - i - 1, FLINT_MIN(i + 1, len1 - len2 + 1), poly1 + i); for (; i < len1 - 1; i++) _fmpz_vec_scalar_addmul_fmpz(res + i - len2 + 2, poly2 + 1, FLINT_MIN(len2 - 1, len1 - i - 1), poly1 + i); } }
void padic_ctx_init(padic_ctx_t ctx, const fmpz_t p, long N, enum padic_print_mode mode) { fmpz_init(ctx->p); fmpz_set(ctx->p, p); ctx->N = N; ctx->pinv = (!COEFF_IS_MPZ(*p)) ? n_precompute_inverse(fmpz_get_ui(p)) : 0; if (N > 0) { long i, len; ctx->min = FLINT_MAX(1, N - 10); ctx->max = N + 10; len = ctx->max - ctx->min; ctx->pow = _fmpz_vec_init(len); fmpz_pow_ui(ctx->pow, p, ctx->min); for (i = 1; i < len; i++) fmpz_mul(ctx->pow + i, ctx->pow + (i - 1), p); } else { ctx->min = 0; ctx->max = 0; ctx->pow = NULL; } ctx->mode = mode; }
void padic_val_fac(fmpz_t rop, const fmpz_t op, const fmpz_t p) { fmpz_t t, q, pow; if (fmpz_sgn(op) <= 0) { printf("Exception (padic_val_fac). op is non-positive.\n"); abort(); } fmpz_init(t); fmpz_init(q); fmpz_init(pow); fmpz_one(pow); do { fmpz_mul(pow, pow, p); fmpz_fdiv_q(q, op, pow); fmpz_add(t, t, q); } while (!fmpz_is_zero(q)); fmpz_swap(rop, t); fmpz_clear(t); fmpz_clear(q); fmpz_clear(pow); }
// Compute a*b mod m void fmpz_mulmod(fmpz_t res, fmpz_t a, fmpz_t b, fmpz_t m) { fmpz_t ab = fmpz_init(fmpz_size(a) + fmpz_size(b)); fmpz_mul(ab, a, b); fmpz_mod(res, ab, m); fmpz_clear(ab); }
void fmpz_mat_scalar_mul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c) { slong i, j; for (i = 0; i < A->r; i++) for (j = 0; j < A->c; j++) fmpz_mul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c); }