int arb_poly_divrem(arb_poly_t Q, arb_poly_t R, const arb_poly_t A, const arb_poly_t B, slong prec) { const slong lenA = A->length, lenB = B->length; if (lenB == 0 || arb_contains_zero(B->coeffs + lenB - 1)) { return 0; } if (lenA < lenB) { arb_poly_set(R, A); arb_poly_zero(Q); return 1; } if (Q == A || Q == B) { arb_poly_t T; arb_poly_init(T); arb_poly_divrem(T, R, A, B, prec); arb_poly_swap(Q, T); arb_poly_clear(T); return 1; } if (R == A || R == B) { arb_poly_t U; arb_poly_init(U); arb_poly_divrem(Q, U, A, B, prec); arb_poly_swap(R, U); arb_poly_clear(U); return 1; } arb_poly_fit_length(Q, lenA - lenB + 1); arb_poly_fit_length(R, lenB - 1); _arb_poly_divrem(Q->coeffs, R->coeffs, A->coeffs, lenA, B->coeffs, lenB, prec); _arb_poly_set_length(Q, lenA - lenB + 1); _arb_poly_set_length(R, lenB - 1); _arb_poly_normalise(R); return 1; }
void arb_poly_mul(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { slong len_out; if ((poly1->length == 0) || (poly2->length == 0)) { arb_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (res == poly1 || res == poly2) { arb_poly_t temp; arb_poly_init2(temp, len_out); _arb_poly_mul(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); arb_poly_swap(res, temp); arb_poly_clear(temp); } else { arb_poly_fit_length(res, len_out); _arb_poly_mul(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, prec); } _arb_poly_set_length(res, len_out); _arb_poly_normalise(res); }
void arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, long n, long prec) { if (n == 0 || B->length == 0) { printf("arb_poly_inv_series: require n > 0 and nonzero input\n"); abort(); } if (A->length == 0) { arb_poly_zero(Q); return; } if (Q == A || Q == B) { arb_poly_t t; arb_poly_init(t); arb_poly_div_series(t, A, B, n, prec); arb_poly_swap(Q, t); arb_poly_clear(t); return; } arb_poly_fit_length(Q, n); _arb_poly_div_series(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, n, prec); _arb_poly_set_length(Q, n); _arb_poly_normalise(Q); }
void arb_poly_inv_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { if (n == 0) { arb_poly_zero(Qinv); return; } if (Q->length == 0) { arb_poly_fit_length(Qinv, n); _arb_vec_indeterminate(Qinv->coeffs, n); _arb_poly_set_length(Qinv, n); return; } if (Qinv == Q) { arb_poly_t t; arb_poly_init(t); arb_poly_inv_series(t, Q, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); return; } arb_poly_fit_length(Qinv, n); _arb_poly_inv_series(Qinv->coeffs, Q->coeffs, Q->length, n, prec); _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); }
void arb_poly_revert_series(arb_poly_t Qinv, const arb_poly_t Q, slong n, slong prec) { slong Qlen = Q->length; if (Qlen < 2 || !arb_is_zero(Q->coeffs) || arb_contains_zero(Q->coeffs + 1)) { flint_printf("Exception (arb_poly_revert_series). Input must \n" "have zero constant term and nonzero coefficient of x^1.\n"); abort(); } if (Qinv != Q) { arb_poly_fit_length(Qinv, n); _arb_poly_revert_series(Qinv->coeffs, Q->coeffs, Qlen, n, prec); } else { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_revert_series(t->coeffs, Q->coeffs, Qlen, n, prec); arb_poly_swap(Qinv, t); arb_poly_clear(t); } _arb_poly_set_length(Qinv, n); _arb_poly_normalise(Qinv); }
void arb_poly_sqrt_series(arb_poly_t g, const arb_poly_t h, long n, long prec) { if (n == 0) { arb_poly_zero(g); return; } if (g == h) { arb_poly_t t; arb_poly_init(t); arb_poly_sqrt_series(t, h, n, prec); arb_poly_swap(g, t); arb_poly_clear(t); return; } arb_poly_fit_length(g, n); if (h->length == 0) _arb_vec_indeterminate(g->coeffs, n); else _arb_poly_sqrt_series(g->coeffs, h->coeffs, h->length, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); }
void arb_poly_rising_ui_series(arb_poly_t res, const arb_poly_t f, ulong r, slong trunc, slong prec) { slong len; if ((f->length == 0 && r != 0) || trunc == 0) { arb_poly_zero(res); return; } if (r == 0) { arb_poly_one(res); return; } len = poly_pow_length(f->length, r, trunc); if (f == res) { arb_poly_t tmp; arb_poly_init(tmp); arb_poly_rising_ui_series(tmp, f, r, len, prec); arb_poly_swap(tmp, res); arb_poly_clear(tmp); } else { arb_poly_fit_length(res, len); _arb_poly_rising_ui_series(res->coeffs, f->coeffs, f->length, r, len, prec); _arb_poly_set_length(res, len); _arb_poly_normalise(res); } }
void arb_poly_binomial_transform(arb_poly_t b, const arb_poly_t a, slong len, slong prec) { if (len == 0 || a->length == 0) { arb_poly_zero(b); return; } if (b == a) { arb_poly_t c; arb_poly_init2(c, len); _arb_poly_binomial_transform(c->coeffs, a->coeffs, a->length, len, prec); arb_poly_swap(b, c); arb_poly_clear(c); } else { arb_poly_fit_length(b, len); _arb_poly_binomial_transform(b->coeffs, a->coeffs, a->length, len, prec); } _arb_poly_set_length(b, len); _arb_poly_normalise(b); }
void arb_poly_compose_series(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong len1 = poly1->length; slong len2 = poly2->length; slong lenr; if (len2 != 0 && !arb_is_zero(poly2->coeffs)) { flint_printf("exception: compose_series: inner " "polynomial must have zero constant term\n"); abort(); } if (len1 == 0 || n == 0) { arb_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { arb_poly_set_arb(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { arb_poly_fit_length(res, lenr); _arb_poly_compose_series(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose_series(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr, prec); _arb_poly_set_length(t, lenr); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } }
void arb_poly_pow_ui_trunc_binexp(arb_poly_t res, const arb_poly_t poly, ulong exp, slong len, slong prec) { slong flen, rlen; flen = poly->length; if (exp == 0 && len != 0) { arb_poly_one(res); } else if (flen == 0 || len == 0) { arb_poly_zero(res); } else { rlen = poly_pow_length(flen, exp, len); if (res != poly) { arb_poly_fit_length(res, rlen); _arb_poly_pow_ui_trunc_binexp(res->coeffs, poly->coeffs, flen, exp, rlen, prec); _arb_poly_set_length(res, rlen); _arb_poly_normalise(res); } else { arb_poly_t t; arb_poly_init2(t, rlen); _arb_poly_pow_ui_trunc_binexp(t->coeffs, poly->coeffs, flen, exp, rlen, prec); _arb_poly_set_length(t, rlen); _arb_poly_normalise(t); arb_poly_swap(res, t); arb_poly_clear(t); } } }
void arb_poly_mullow_block(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong n, slong prec) { slong xlen, ylen, zlen; xlen = poly1->length; ylen = poly2->length; if (xlen == 0 || ylen == 0 || n == 0) { arb_poly_zero(res); return; } xlen = FLINT_MIN(xlen, n); ylen = FLINT_MIN(ylen, n); zlen = FLINT_MIN(xlen + ylen - 1, n); if (res == poly1 || res == poly2) { arb_poly_t tmp; arb_poly_init2(tmp, zlen); _arb_poly_mullow_block(tmp->coeffs, poly1->coeffs, xlen, poly2->coeffs, ylen, zlen, prec); arb_poly_swap(res, tmp); arb_poly_clear(tmp); } else { arb_poly_fit_length(res, zlen); _arb_poly_mullow_block(res->coeffs, poly1->coeffs, xlen, poly2->coeffs, ylen, zlen, prec); } _arb_poly_set_length(res, zlen); _arb_poly_normalise(res); }
void arb_poly_compose(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, slong prec) { const slong len1 = poly1->length; const slong len2 = poly2->length; if (len1 == 0) { arb_poly_zero(res); } else if (len1 == 1 || len2 == 0) { arb_poly_set_arb(res, poly1->coeffs); } else { const slong lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { arb_poly_fit_length(res, lenr); _arb_poly_compose(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); } else { arb_poly_t t; arb_poly_init2(t, lenr); _arb_poly_compose(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, prec); arb_poly_swap(res, t); arb_poly_clear(t); } _arb_poly_set_length(res, lenr); _arb_poly_normalise(res); } }
void arb_poly_div_series(arb_poly_t Q, const arb_poly_t A, const arb_poly_t B, long n, long prec) { if (n == 0) { arb_poly_zero(Q); return; } if (B->length == 0) { arb_poly_fit_length(Q, n); _arb_vec_indeterminate(Q->coeffs, n); _arb_poly_set_length(Q, n); return; } if (A->length == 0) { arb_poly_zero(Q); return; } if (Q == A || Q == B) { arb_poly_t t; arb_poly_init(t); arb_poly_div_series(t, A, B, n, prec); arb_poly_swap(Q, t); arb_poly_clear(t); return; } arb_poly_fit_length(Q, n); _arb_poly_div_series(Q->coeffs, A->coeffs, A->length, B->coeffs, B->length, n, prec); _arb_poly_set_length(Q, n); _arb_poly_normalise(Q); }
void arb_poly_tan_series(arb_poly_t g, const arb_poly_t h, slong n, slong prec) { if (h->length == 0 || n == 0) { arb_poly_zero(g); return; } if (g == h) { arb_poly_t t; arb_poly_init(t); arb_poly_tan_series(t, h, n, prec); arb_poly_swap(g, t); arb_poly_clear(t); return; } arb_poly_fit_length(g, n); _arb_poly_tan_series(g->coeffs, h->coeffs, h->length, n, prec); _arb_poly_set_length(g, n); _arb_poly_normalise(g); }
void arb_poly_mullow_classical(arb_poly_t res, const arb_poly_t poly1, const arb_poly_t poly2, long n, long prec) { long len_out; if (poly1->length == 0 || poly2->length == 0 || n == 0) { arb_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (n > len_out) n = len_out; if (res == poly1 || res == poly2) { arb_poly_t t; arb_poly_init2(t, n); _arb_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n, prec); arb_poly_swap(res, t); arb_poly_clear(t); } else { arb_poly_fit_length(res, n); _arb_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n, prec); } _arb_poly_set_length(res, n); _arb_poly_normalise(res); }