void _fmpq_poly_compose_series_horner(fmpz * res, fmpz_t den, const fmpz * poly1, const fmpz_t den1, long len1, const fmpz * poly2, const fmpz_t den2, long len2, long n) { if (fmpz_is_one(den2)) { _fmpz_poly_compose_series(res, poly1, len1, poly2, len2, n); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, n); } else if (n == 1) { fmpz_set(res, poly1); fmpz_set(den, den1); _fmpq_poly_canonicalise(res, den, 1); } else { long i = len1 - 1; long lenr; fmpz_t tden; fmpz * t = _fmpz_vec_init(n); fmpz_init(tden); _fmpz_vec_zero(res, n); lenr = len2; _fmpq_poly_scalar_mul_fmpz(res, den, poly2, den2, len2, poly1 + i); _fmpq_poly_scalar_div_fmpz(res, den, res, den, len2, den1); i--; _fmpq_poly_add(res, den, res, den, len2, poly1 + i, den1, 1); _fmpq_poly_canonicalise(res, den, lenr); while (i > 0) { i--; if (lenr + len2 - 1 < n) { _fmpq_poly_mul(t, tden, res, den, lenr, poly2, den2, len2); lenr = lenr + len2 - 1; } else { _fmpq_poly_mullow(t, tden, res, den, lenr, poly2, den2, len2, n); lenr = n; } _fmpq_poly_canonicalise(t, tden, lenr); _fmpq_poly_add(res, den, t, tden, lenr, poly1 + i, den1, 1); } _fmpq_poly_canonicalise(res, den, n); _fmpz_vec_clear(t, n); fmpz_clear(tden); } }
void _fmpq_poly_invsqrt_series(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long n) { long m; fmpz * t, * u; fmpz_t tden, uden; if (n == 1) { fmpz_one(rpoly); fmpz_one(rden); return; } m = (n + 1) / 2; _fmpq_poly_invsqrt_series(rpoly, rden, poly, den, m); fmpz_init(tden); fmpz_init(uden); t = _fmpz_vec_init(n); u = _fmpz_vec_init(n); _fmpz_vec_zero(rpoly + m, n - m); _fmpq_poly_mul(t, tden, rpoly, rden, m, rpoly, rden, m); if (2*m - 1 < n) fmpz_zero(t + n - 1); _fmpq_poly_mullow(u, uden, t, tden, n, rpoly, rden, n, n); _fmpq_poly_mullow(t, tden, u, uden, n, poly, den, n, n); _fmpz_vec_neg(t + m, t + m, n - m); _fmpz_vec_zero(t, m); fmpz_mul_ui(tden, tden, 2UL); _fmpq_poly_canonicalise(t, tden, n); _fmpq_poly_add(rpoly, rden, rpoly, rden, m, t, tden, n); fmpz_clear(tden); fmpz_clear(uden); _fmpz_vec_clear(t, n); _fmpz_vec_clear(u, n); }
void _fmpq_poly_sqrt_series(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, slong n) { fmpz * t; fmpz_t tden; t = _fmpz_vec_init(n); fmpz_init(tden); _fmpq_poly_invsqrt_series(t, tden, poly, den, n); _fmpq_poly_mullow(rpoly, rden, t, tden, n, poly, den, n, n); _fmpz_vec_clear(t, n); fmpz_clear(tden); }
void _fmpq_poly_log_series(fmpz * g, fmpz_t gden, const fmpz * f, const fmpz_t fden, long n) { fmpz * f_diff; fmpz * f_inv; fmpz_t f_diff_den; fmpz_t f_inv_den; f_diff = _fmpz_vec_init(n); f_inv = _fmpz_vec_init(n); fmpz_init(f_diff_den); fmpz_init(f_inv_den); _fmpq_poly_derivative(f_diff, f_diff_den, f, fden, n); _fmpq_poly_inv_series(f_inv, f_inv_den, f, fden, n); _fmpq_poly_mullow(g, gden, f_diff, f_diff_den, n - 1, f_inv, f_inv_den, n - 1, n - 1); _fmpq_poly_integral(g, gden, g, gden, n); _fmpz_vec_clear(f_diff, n); _fmpz_vec_clear(f_inv, n); fmpz_clear(f_diff_den); fmpz_clear(f_inv_den); }
void _fmpq_poly_exp_series(fmpz * g, fmpz_t gden, const fmpz * h, const fmpz_t hden, long n) { long m; fmpz * t, * u; fmpz_t tden, uden; if (n < 2) { fmpz_one(g); fmpz_one(gden); return; } m = (n + 1) / 2; _fmpq_poly_exp_series(g, gden, h, hden, m); _fmpz_vec_zero(g + m, n - m); t = _fmpz_vec_init(n); u = _fmpz_vec_init(n); fmpz_init(tden); fmpz_init(uden); _fmpq_poly_log_series(t, tden, g, gden, n); _fmpq_poly_sub(t, tden, t, tden, n, h, hden, n); /* TODO: half of product is redundant! */ _fmpq_poly_mullow(u, uden, g, gden, n, t, tden, n, n); _fmpq_poly_sub(g, gden, g, gden, n, u, uden, n); _fmpq_poly_canonicalise(g, gden, n); fmpz_clear(tden); fmpz_clear(uden); _fmpz_vec_clear(t, n); _fmpz_vec_clear(u, n); }
void _fmpq_poly_revert_series_lagrange_fast(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, slong n) { slong i, j, k, m; fmpz *R, *Rden, *S, *T, *dens, *tmp; fmpz_t Sden, Tden, t; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); return; } if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } return; } m = n_sqrt(n); fmpz_init(t); dens = _fmpz_vec_init(n); R = _fmpz_vec_init((n - 1) * m); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); Rden = _fmpz_vec_init(m); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); _fmpq_poly_inv_series(Ri(1), Rdeni(1), Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(Ri(1), Rdeni(1), n - 1); for (i = 2; i <= m; i++) { _fmpq_poly_mullow(Ri(i), Rdeni(i), Ri(i-1), Rdeni(i-1), n - 1, Ri(1), Rdeni(1), n - 1, n - 1); _fmpq_poly_canonicalise(Ri(i), Rdeni(i), n - 1); } for (i = 1; i < m; i++) { fmpz_set(Qinv + i, Ri(i) + i - 1); fmpz_mul_ui(dens + i, Rdeni(i), i); } _fmpz_vec_set(S, Ri(m), n - 1); fmpz_set(Sden, Rdeni(m)); for (i = m; i < n; i += m) { fmpz_set(Qinv + i, S + i - 1); fmpz_mul_ui(dens + i, Sden, i); for (j = 1; j < m && i + j < n; j++) { fmpz_mul(t, S + 0, Ri(j) + i + j - 1); for (k = 1; k <= i + j - 1; k++) fmpz_addmul(t, S + k, Ri(j) + i + j - 1 - k); fmpz_set(Qinv + i + j, t); fmpz_mul(dens + i + j, Sden, Rdeni(j)); fmpz_mul_ui(dens + i + j, dens + i + j, i + j); } if (i + 1 < n) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, Ri(m), Rdeni(m), n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_swap(Tden, Sden); tmp = S; S = T; T = tmp; } } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); fmpz_clear(t); _fmpz_vec_clear(dens, n); _fmpz_vec_clear(R, (n - 1) * m); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(Rden, m); fmpz_clear(Sden); fmpz_clear(Tden); }
void _fmpq_poly_revert_series_lagrange(fmpz * Qinv, fmpz_t den, const fmpz * Q, const fmpz_t Qden, long n) { long i; fmpz *R, *S, *T, *dens, *tmp; fmpz_t Rden, Sden, Tden; if (fmpz_is_one(Qden) && (n > 1) && fmpz_is_pm1(Q + 1)) { _fmpz_poly_revert_series(Qinv, Q, n); fmpz_one(den); } else if (n <= 2) { fmpz_zero(Qinv); if (n == 2) { fmpz_set(Qinv + 1, Qden); fmpz_set(den, Q + 1); _fmpq_poly_canonicalise(Qinv, den, 2); } } else { dens = _fmpz_vec_init(n); R = _fmpz_vec_init(n - 1); S = _fmpz_vec_init(n - 1); T = _fmpz_vec_init(n - 1); fmpz_init(Rden); fmpz_init(Sden); fmpz_init(Tden); fmpz_zero(Qinv); fmpz_one(dens); fmpz_set(Qinv + 1, Qden); fmpz_set(dens + 1, Q + 1); _fmpq_poly_inv_series(R, Rden, Q + 1, Qden, n - 1); _fmpq_poly_canonicalise(R, Rden, n - 1); _fmpz_vec_set(S, R, n - 1); fmpz_set(Sden, Rden); for (i = 2; i < n; i++) { _fmpq_poly_mullow(T, Tden, S, Sden, n - 1, R, Rden, n - 1, n - 1); _fmpq_poly_canonicalise(T, Tden, n - 1); fmpz_set(Qinv + i, T + i - 1); fmpz_mul_ui(dens + i, Tden, i); tmp = S; S = T; T = tmp; fmpz_swap(Sden, Tden); } _set_vec(Qinv, den, Qinv, dens, n); _fmpq_poly_canonicalise(Qinv, den, n); _fmpz_vec_clear(R, n - 1); _fmpz_vec_clear(S, n - 1); _fmpz_vec_clear(T, n - 1); _fmpz_vec_clear(dens, n); fmpz_clear(Rden); fmpz_clear(Sden); fmpz_clear(Tden); } }