void _fmpcb_poly_interpolation_weights(fmpcb_ptr w, fmpcb_ptr * tree, long len, long prec) { fmpcb_ptr tmp; long i, n, height; if (len == 0) return; if (len == 1) { fmpcb_one(w); return; } tmp = _fmpcb_vec_init(len + 1); height = FLINT_CLOG2(len); n = 1L << (height - 1); _fmpcb_poly_mul_monic(tmp, tree[height-1], n + 1, tree[height-1] + (n + 1), (len - n + 1), prec); _fmpcb_poly_derivative(tmp, tmp, len + 1, prec); _fmpcb_poly_evaluate_vec_fast_precomp(w, tmp, len, tree, len, prec); for (i = 0; i < len; i++) fmpcb_inv(w + i, w + i, prec); _fmpcb_vec_clear(tmp, len + 1); }
void _fmpcb_poly_interpolate_fast_precomp(fmpcb_ptr poly, fmpcb_srcptr ys, fmpcb_ptr * tree, fmpcb_srcptr weights, long len, long prec) { fmpcb_ptr t, u, pa, pb; long i, pow, left; if (len == 0) return; t = _fmpcb_vec_init(len); u = _fmpcb_vec_init(len); for (i = 0; i < len; i++) fmpcb_mul(poly + i, weights + i, ys + i, prec); for (i = 0; i < FLINT_CLOG2(len); i++) { pow = (1L << i); pa = tree[i]; pb = poly; left = len; while (left >= 2 * pow) { _fmpcb_poly_mul(t, pa, pow + 1, pb + pow, pow, prec); _fmpcb_poly_mul(u, pa + pow + 1, pow + 1, pb, pow, prec); _fmpcb_vec_add(pb, t, u, 2 * pow, prec); left -= 2 * pow; pa += 2 * pow + 2; pb += 2 * pow; } if (left > pow) { _fmpcb_poly_mul(t, pa, pow + 1, pb + pow, left - pow, prec); _fmpcb_poly_mul(u, pb, pow, pa + pow + 1, left - pow + 1, prec); _fmpcb_vec_add(pb, t, u, left, prec); } } _fmpcb_vec_clear(t, len); _fmpcb_vec_clear(u, len); }
void arb_const_e_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->A, "1 1"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "1 1"); fmpz_poly_set_str(series->Q, "2 0 1"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); }
void arb_const_catalan_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->A, "3 19 56 40"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "5 0 0 0 32 -64"); fmpz_poly_set_str(series->Q, "5 9 96 352 512 256"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_ui(t, t, 18, prec); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); }
void arb_const_log2_hypgeom_eval(arb_t s, slong prec) { hypgeom_t series; arb_t t; arb_init(t); hypgeom_init(series); fmpz_poly_set_str(series->A, "1 1"); fmpz_poly_set_str(series->B, "1 1"); fmpz_poly_set_str(series->P, "2 0 -1"); fmpz_poly_set_str(series->Q, "2 4 8"); prec += FLINT_CLOG2(prec); arb_hypgeom_infsum(s, t, series, prec, prec); arb_mul_ui(s, s, 3, prec); arb_mul_2exp_si(t, t, 2); arb_div(s, s, t, prec); hypgeom_clear(series); arb_clear(t); }
void _fmprb_poly_evaluate_vec_fast_precomp(fmprb_ptr vs, fmprb_srcptr poly, long plen, fmprb_ptr * tree, long len, long prec) { long height, i, j, pow, left; long tree_height; long tlen; fmprb_ptr t, u, swap, pa, pb, pc; /* avoid worrying about some degenerate cases */ if (len < 2 || plen < 2) { if (len == 1) { fmprb_t tmp; fmprb_init(tmp); fmprb_neg(tmp, tree[0] + 0); _fmprb_poly_evaluate(vs + 0, poly, plen, tmp, prec); fmprb_clear(tmp); } else if (len != 0 && plen == 0) { _fmprb_vec_zero(vs, len); } else if (len != 0 && plen == 1) { for (i = 0; i < len; i++) fmprb_set(vs + i, poly + 0); } return; } t = _fmprb_vec_init(len); u = _fmprb_vec_init(len); left = len; /* Initial reduction. We allow the polynomial to be larger or smaller than the number of points. */ height = FLINT_BIT_COUNT(plen - 1) - 1; tree_height = FLINT_CLOG2(len); while (height >= tree_height) height--; pow = 1L << height; for (i = j = 0; i < len; i += pow, j += (pow + 1)) { tlen = ((i + pow) <= len) ? pow : len % pow; _fmprb_poly_rem(t + i, poly, plen, tree[height] + j, tlen + 1, prec); } for (i = height - 1; i >= 0; i--) { pow = 1L << i; left = len; pa = tree[i]; pb = t; pc = u; while (left >= 2 * pow) { _fmprb_poly_rem_2(pc, pb, 2 * pow, pa, pow + 1, prec); _fmprb_poly_rem_2(pc + pow, pb, 2 * pow, pa + pow + 1, pow + 1, prec); pa += 2 * pow + 2; pb += 2 * pow; pc += 2 * pow; left -= 2 * pow; } if (left > pow) { _fmprb_poly_rem(pc, pb, left, pa, pow + 1, prec); _fmprb_poly_rem(pc + pow, pb, left, pa + pow + 1, left - pow + 1, prec); } else if (left > 0) _fmprb_vec_set(pc, pb, left); swap = t; t = u; u = swap; } _fmprb_vec_set(vs, t, len); _fmprb_vec_clear(t, len); _fmprb_vec_clear(u, len); }
long _fmpz_poly_hensel_start_lift(fmpz_poly_factor_t lifted_fac, long *link, fmpz_poly_t *v, fmpz_poly_t *w, const fmpz_poly_t f, const nmod_poly_factor_t local_fac, long N) { const long r = local_fac->num; long i, preve; fmpz_t p, P; fmpz_poly_t monic_f; fmpz_init(p); fmpz_init(P); fmpz_poly_init(monic_f); fmpz_set_ui(p, (local_fac->p + 0)->mod.n); fmpz_pow_ui(P, p, N); if (fmpz_is_one(fmpz_poly_lead(f))) { fmpz_poly_set(monic_f, f); } else if (fmpz_cmp_si(fmpz_poly_lead(f), -1) == 0) { fmpz_poly_neg(monic_f, f); } else { fmpz_t t; fmpz_init(t); fmpz_mod(t, fmpz_poly_lead(f), P); if (fmpz_invmod(t, t, P) == 0) { printf("Exception in fmpz_poly_start_hensel_lift.\n"); abort(); } fmpz_poly_scalar_mul_fmpz(monic_f, f, t); fmpz_poly_scalar_mod_fmpz(monic_f, monic_f, P); fmpz_clear(t); } fmpz_poly_hensel_build_tree(link, v, w, local_fac); { long *e, n = FLINT_CLOG2(N) + 1; e = flint_malloc(n * sizeof(long)); for (e[i = 0] = N; e[i] > 1; i++) e[i + 1] = (e[i] + 1) / 2; for (i--; i > 0; i--) { fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, p, e[i+1], e[i], 1); } if (N > 1) { fmpz_poly_hensel_lift_tree(link, v, w, monic_f, r, p, e[i+1], e[i], 0); } preve = e[i+1]; flint_free(e); } /* Now everything is lifted to p^N, we just need to insert the factors into their correct places in lifted_fac. */ fmpz_poly_factor_fit_length(lifted_fac, r); for (i = 0; i < 2*r - 2; i++) { if (link[i] < 0) { fmpz_poly_scalar_smod_fmpz(lifted_fac->p + (- link[i] - 1), v[i], P); lifted_fac->exp[- link[i] - 1] = 1L; } } lifted_fac->num = r; fmpz_clear(p); fmpz_clear(P); fmpz_poly_clear(monic_f); return preve; }