/*============================================================================= This file is part of FLINT. FLINT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. FLINT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FLINT; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =============================================================================*/ /****************************************************************************** Copyright (C) 2013 Tom Bachmann ******************************************************************************/ #ifndef FMPQ_POLYXX_H #define FMPQ_POLYXX_H #include #include #include "flint.h" #include "fmpq_poly.h" #include "fmpqxx.h" #include "flintxx/expression.h" #include "flintxx/flint_classes.h" #include "flintxx/traits.h" // TODO exhibit this as a specialisation of a generic poly // TODO lazy version of numref? namespace flint { // function "declarations" FLINT_DEFINE_BINOP(fmpq_polyxx_get_coeff) FLINT_DEFINE_BINOP(fmpq_polyxx_interpolate) FLINT_DEFINE_UNOP(fmpq_polyxx_den) // TODO move to stdmath? // TODO move to stdmath? FLINT_DEFINE_BINOP(rescale) namespace detail { template struct fmpq_poly_traits { typedef FLINT_UNOP_BUILD_RETTYPE(fmpq_polyxx_den, fmpzxx, Poly) coeff_ref_t; typedef coeff_ref_t coeff_srcref_t; static coeff_srcref_t den(const Poly& p) {return fmpq_polyxx_den(p);} }; } // detail template class fmpq_polyxx_expression : public expression, Operation, Data> { public: typedef expression, Operation, Data> base_t; typedef detail::fmpq_poly_traits poly_traits_t; typedef typename poly_traits_t::coeff_ref_t coeff_ref_t; typedef typename poly_traits_t::coeff_srcref_t coeff_srcref_t; FLINTXX_DEFINE_BASICS(fmpq_polyxx_expression) FLINTXX_DEFINE_CTORS(fmpq_polyxx_expression) FLINTXX_DEFINE_C_REF(fmpq_polyxx_expression, fmpq_poly_struct, _poly) // static methods which only make sense with fmpq_polyxx static fmpq_polyxx_expression randtest(frandxx& state, slong len, mp_bitcnt_t bits) { fmpq_polyxx_expression res; fmpq_poly_randtest(res._poly(), state._data(), len, bits); return res; } static fmpq_polyxx_expression randtest_unsigned(frandxx& state, slong len, mp_bitcnt_t bits) { fmpq_polyxx_expression res; fmpq_poly_randtest_unsigned(res._poly(), state._data(), len, bits); return res; } static fmpq_polyxx_expression randtest_not_zero(frandxx& state, slong len, mp_bitcnt_t bits) { fmpq_polyxx_expression res; fmpq_poly_randtest_not_zero(res._poly(), state._data(), len, bits); return res; } // TODO make lazy // TODO perhaps as member function (non-static?) template static fmpq_polyxx_expression get_slice(const Poly& p, slong i, slong j) { fmpq_polyxx_expression res; fmpq_poly_get_slice(res._poly(), p.evaluate()._poly(), i, j); return res; } template static FLINT_BINOP_ENABLE_RETTYPE(fmpq_polyxx_interpolate, Fmpq_vec1, Fmpq_vec2) interpolate(const Fmpq_vec1& xs, const Fmpq_vec2& ys) { return fmpq_polyxx_interpolate(xs, ys); } static fmpq_polyxx_expression zero() {return fmpq_polyxx_expression();} static fmpq_polyxx_expression one() { fmpq_polyxx_expression res; res.set_one(); return res; } // These only make sense with immediates void realloc(slong alloc) {fmpq_poly_realloc(_poly(), alloc);} void fit_length(slong len) {fmpq_poly_fit_length(_poly(), len);} void _normalise() {_fmpq_poly_normalise(_poly());} void _set_length(slong len) {_fmpq_poly_set_length(_poly(), len);} void canonicalise() {fmpq_poly_canonicalise(_poly());} bool is_canonical() const {return fmpq_poly_is_canonical(_poly());} void set_zero() {fmpq_poly_zero(_poly());} void set_one() {fmpq_poly_one(_poly());} coeff_ref_t get_coeff_numref(slong n) { return coeff_ref_t::make(fmpq_poly_numref(_poly()) + n); } coeff_srcref_t get_coeff_numref(slong n) const { return coeff_srcref_t::make(fmpq_poly_numref(_poly()) + n); } coeff_ref_t den() {return poly_traits_t::den(*this);} coeff_srcref_t den() const {return poly_traits_t::den(*this);} // These only make sense with target immediates template typename mp::enable_if >::type set_coeff(slong n, const Fmpz& x) { fmpq_poly_set_coeff_fmpz(_poly(), n, x.evaluate()._fmpz()); } template typename mp::enable_if >::type set_coeff(slong n, const Fmpq& x) { fmpq_poly_set_coeff_fmpq(_poly(), n, x.evaluate()._fmpq()); } template typename mp::enable_if >::type set_coeff(slong n, T x) { fmpq_poly_set_coeff_si(_poly(), n, x); } template typename mp::enable_if >::type set_coeff(slong n, T x) { fmpq_poly_set_coeff_ui(_poly(), n, x); } void truncate(slong n) {fmpq_poly_truncate(_poly(), n);} // These cause evaluation slong length() const {return fmpq_poly_length(this->evaluate()._poly());} slong degree() const {return fmpq_poly_degree(this->evaluate()._poly());} bool is_one() const {return fmpq_poly_is_one(this->evaluate()._poly());} bool is_zero() const {return fmpq_poly_is_zero(this->evaluate()._poly());} bool is_monic() const {return fmpq_poly_is_monic(this->evaluate()._poly());} bool is_squarefree() const {return fmpq_poly_is_squarefree(this->evaluate()._poly());} std::string pretty(const char* x) const { char* str = fmpq_poly_get_str_pretty(this->evaluate()._poly(), x); std::string res(str); flint_free(str); return res; } // lazy members FLINTXX_DEFINE_MEMBER_BINOP_(operator(), compeval) template // NB: template to instantiate lazily FLINT_BINOP_ENABLE_RETTYPE( fmpq_polyxx_get_coeff, fmpq_polyxx_expression, Slong) get_coeff(const Slong& n) const { return fmpq_polyxx_get_coeff(*this, n); } FLINTXX_DEFINE_MEMBER_3OP(compose_series) FLINTXX_DEFINE_MEMBER_3OP(compose_series_brent_kung) FLINTXX_DEFINE_MEMBER_3OP(compose_series_horner) FLINTXX_DEFINE_MEMBER_3OP(div_series) FLINTXX_DEFINE_MEMBER_3OP(mullow) FLINTXX_DEFINE_MEMBER_BINOP(asinh_series) FLINTXX_DEFINE_MEMBER_BINOP(asin_series) FLINTXX_DEFINE_MEMBER_BINOP(atanh_series) FLINTXX_DEFINE_MEMBER_BINOP(atan_series) FLINTXX_DEFINE_MEMBER_BINOP(cosh_series) FLINTXX_DEFINE_MEMBER_BINOP(cos_series) FLINTXX_DEFINE_MEMBER_BINOP(divrem) FLINTXX_DEFINE_MEMBER_BINOP(exp_series) FLINTXX_DEFINE_MEMBER_BINOP(gcd) FLINTXX_DEFINE_MEMBER_BINOP(inv_series) FLINTXX_DEFINE_MEMBER_BINOP(inv_series_newton) FLINTXX_DEFINE_MEMBER_BINOP(invsqrt_series) FLINTXX_DEFINE_MEMBER_BINOP(lcm) FLINTXX_DEFINE_MEMBER_BINOP(log_series) FLINTXX_DEFINE_MEMBER_BINOP(pow) FLINTXX_DEFINE_MEMBER_BINOP_(rescale, rescale) FLINTXX_DEFINE_MEMBER_BINOP(resultant) FLINTXX_DEFINE_MEMBER_BINOP(reverse) FLINTXX_DEFINE_MEMBER_BINOP(revert_series) FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange) FLINTXX_DEFINE_MEMBER_BINOP(revert_series_lagrange_fast) FLINTXX_DEFINE_MEMBER_BINOP(revert_series_newton) FLINTXX_DEFINE_MEMBER_BINOP_(shift_left, shift_left) FLINTXX_DEFINE_MEMBER_BINOP_(shift_right, shift_right) FLINTXX_DEFINE_MEMBER_BINOP(sinh_series) FLINTXX_DEFINE_MEMBER_BINOP(sin_series) FLINTXX_DEFINE_MEMBER_BINOP(sqrt_series) FLINTXX_DEFINE_MEMBER_BINOP(tanh_series) FLINTXX_DEFINE_MEMBER_BINOP(tan_series) FLINTXX_DEFINE_MEMBER_BINOP(xgcd) FLINTXX_DEFINE_MEMBER_UNOP(derivative) FLINTXX_DEFINE_MEMBER_UNOP(integral) FLINTXX_DEFINE_MEMBER_UNOP(inv) FLINTXX_DEFINE_MEMBER_UNOP(make_monic) FLINTXX_DEFINE_MEMBER_UNOP(primitive_part) FLINTXX_DEFINE_MEMBER_UNOP_RTYPE(fmpqxx, content) }; namespace detail { struct fmpq_poly_data; } typedef fmpq_polyxx_expression fmpq_polyxx; typedef fmpq_polyxx_expression > fmpq_polyxx_ref; typedef fmpq_polyxx_expression > fmpq_polyxx_srcref; namespace detail { template<> struct fmpq_poly_traits { typedef fmpzxx_srcref coeff_ref_t; typedef fmpzxx_srcref coeff_srcref_t; template static coeff_srcref_t den(const P& p) {return coeff_srcref_t::make(fmpq_poly_denref(p._poly()));} }; template<> struct fmpq_poly_traits { typedef fmpzxx_ref coeff_ref_t; typedef fmpzxx_ref coeff_srcref_t; template static coeff_ref_t den(P p) {return coeff_ref_t::make(fmpq_poly_denref(p._poly()));} }; template<> struct fmpq_poly_traits { typedef fmpzxx_ref coeff_ref_t; typedef fmpzxx_srcref coeff_srcref_t; template static coeff_ref_t den(P& p) {return coeff_ref_t::make(fmpq_poly_denref(p._poly()));} template static coeff_srcref_t den(const P& p) {return coeff_srcref_t::make(fmpq_poly_denref(p._poly()));} }; struct fmpq_poly_data { fmpq_poly_t inner; typedef fmpq_poly_t& data_ref_t; typedef const fmpq_poly_t& data_srcref_t; fmpq_poly_data() {fmpq_poly_init(inner);} ~fmpq_poly_data() {fmpq_poly_clear(inner);} fmpq_poly_data(const fmpq_poly_data& o) { fmpq_poly_init(inner); fmpq_poly_set(inner, o.inner); } fmpq_poly_data(fmpq_polyxx_srcref r) { fmpq_poly_init(inner); fmpq_poly_set(inner, r._poly()); } fmpq_poly_data(slong alloc) { fmpq_poly_init2(inner, alloc); } fmpq_poly_data(const char* str) { fmpq_poly_init(inner); execution_check(!fmpq_poly_set_str(inner, str), "construct from string", "fmpq_polyxx"); } }; } // detail namespace traits { template struct is_fmpq_polyxx : mp::or_< traits::is_T_expr, flint_classes::is_source > { }; } // traits namespace mp { template struct all_fmpq_polyxx : mp::and_, all_fmpq_polyxx > { }; template struct all_fmpq_polyxx : traits::is_fmpq_polyxx { }; template struct enable_all_fmpq_polyxx : mp::enable_if, Out> { }; } // mp } // flint // here to deal with circular dependencies... #include "fmpz_polyxx.h" namespace flint { namespace rules { #define FMPQ_POLYXX_COND_S FLINTXX_COND_S(fmpq_polyxx) #define FMPQ_POLYXX_COND_T FLINTXX_COND_T(fmpq_polyxx) FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPQ_POLYXX_COND_S, fmpq_poly_set(to._poly(), from._poly())) FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, traits::is_signed_integer, fmpq_poly_set_si(to._poly(), from)) FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, traits::is_unsigned_integer, fmpq_poly_set_ui(to._poly(), from)) FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPZXX_COND_S, fmpq_poly_set_fmpz(to._poly(), from._fmpz())) FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPQXX_COND_S, fmpq_poly_set_fmpq(to._poly(), from._fmpq())) FLINT_DEFINE_DOIT_COND2(assignment, FMPQ_POLYXX_COND_T, FMPZ_POLYXX_COND_S, fmpq_poly_set_fmpz_poly(to._poly(), from._poly())) FLINTXX_DEFINE_ASSIGN_STR(fmpq_polyxx, execution_check( !fmpq_poly_set_str(to._poly(), from), "assign string", "fmpq_polyxx")) FLINTXX_DEFINE_TO_STR(fmpq_polyxx, fmpq_poly_get_str(from._poly())) FLINTXX_DEFINE_SWAP(fmpq_polyxx, fmpq_poly_swap(e1._poly(), e2._poly())) FLINT_DEFINE_PRINT_COND(FMPQ_POLYXX_COND_S, fmpq_poly_fprint(to, from._poly())) FLINT_DEFINE_PRINT_PRETTY_COND_2(FMPQ_POLYXX_COND_S, const char*, fmpq_poly_fprint_pretty(to, from._poly(), extra)) FLINT_DEFINE_READ_COND(FMPQ_POLYXX_COND_T, fmpq_poly_fread(from, to._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(reverse_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_reverse(to._poly(), e1._poly(), e2)) FLINTXX_DEFINE_CMP(fmpq_polyxx, fmpq_poly_cmp(e1._poly(), e2._poly())) FLINT_DEFINE_UNARY_EXPR_COND(negate, fmpq_polyxx, FMPQ_POLYXX_COND_S, fmpq_poly_neg(to._poly(), from._poly())) FLINT_DEFINE_UNARY_EXPR_COND(inv_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, fmpq_poly_inv(to._poly(), from._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(fmpq_polyxx_get_coeff_op, fmpqxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_get_coeff_fmpq(to._fmpq(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(plus, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_add(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(minus, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_sub(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPZXX_COND_S, fmpq_poly_scalar_mul_fmpz(to._poly(), e1._poly(), e2._fmpz())) FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQXX_COND_S, fmpq_poly_scalar_mul_fmpq(to._poly(), e1._poly(), e2._fmpq())) FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::is_signed_integer, fmpq_poly_scalar_mul_si(to._poly(), e1._poly(), e2)) FLINT_DEFINE_CBINARY_EXPR_COND2(times, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::is_unsigned_integer, fmpq_poly_scalar_mul_ui(to._poly(), e1._poly(), e2)) FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQXX_COND_S, fmpq_poly_scalar_div_fmpq(to._poly(), e1._poly(), e2._fmpq())) FLINT_DEFINE_CBINARY_EXPR_COND2(divided_by, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPZXX_COND_S, fmpq_poly_scalar_div_fmpz(to._poly(), e1._poly(), e2._fmpz())) FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::is_unsigned_integer, fmpq_poly_scalar_div_ui(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::is_signed_integer, fmpq_poly_scalar_div_si(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(times, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_mul(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(pow_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::is_unsigned_integer, fmpq_poly_pow(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(shift_left_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_shift_left(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(shift_right_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_shift_right(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(divided_by, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_div(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(modulo, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_rem(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_newton_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_inv_series_newton(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(inv_series_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_inv_series(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(gcd_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_gcd(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(lcm_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_lcm(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(resultant_op, fmpqxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_resultant(to._fmpq(), e1._poly(), e2._poly())) FLINT_DEFINE_UNARY_EXPR_COND(derivative_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, fmpq_poly_derivative(to._poly(), from._poly())) FLINT_DEFINE_UNARY_EXPR_COND(integral_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, fmpq_poly_integral(to._poly(), from._poly())) #define FMPQ_POLYXX_DEFINE_SERIES(name) \ FLINT_DEFINE_BINARY_EXPR_COND2(name##_series_op, fmpq_polyxx, \ FMPQ_POLYXX_COND_S, traits::fits_into_slong, \ fmpq_poly_##name##_series(to._poly(), e1._poly(), e2)) FMPQ_POLYXX_DEFINE_SERIES(sqrt) FMPQ_POLYXX_DEFINE_SERIES(invsqrt) FMPQ_POLYXX_DEFINE_SERIES(exp) FMPQ_POLYXX_DEFINE_SERIES(log) FMPQ_POLYXX_DEFINE_SERIES(atan) FMPQ_POLYXX_DEFINE_SERIES(atanh) FMPQ_POLYXX_DEFINE_SERIES(asin) FMPQ_POLYXX_DEFINE_SERIES(asinh) FMPQ_POLYXX_DEFINE_SERIES(tan) FMPQ_POLYXX_DEFINE_SERIES(sin) FMPQ_POLYXX_DEFINE_SERIES(cos) FMPQ_POLYXX_DEFINE_SERIES(sinh) FMPQ_POLYXX_DEFINE_SERIES(cosh) FMPQ_POLYXX_DEFINE_SERIES(tanh) FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpqxx, FMPQ_POLYXX_COND_S, FMPQXX_COND_S, fmpq_poly_evaluate_fmpq(to._fmpq(), e1._poly(), e2._fmpq())) FLINT_DEFINE_BINARY_EXPR_COND2(evaluate_op, fmpqxx, FMPQ_POLYXX_COND_S, FMPZXX_COND_S, fmpq_poly_evaluate_fmpz(to._fmpq(), e1._poly(), e2._fmpz())) FLINT_DEFINE_BINARY_EXPR_COND2(compose_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_compose(to._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(fmpq_polyxx_interpolate_op, fmpq_polyxx, FMPZ_VECXX_COND_S, FMPZ_VECXX_COND_S, fmpq_poly_interpolate_fmpz_vec(to._poly(), e1._data().array, e2._data().array, e2.size())) FLINT_DEFINE_BINARY_EXPR_COND2(rescale_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, FMPQXX_COND_S, fmpq_poly_rescale(to._poly(), e1._poly(), e2._fmpq())) FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_revert_series(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_lagrange_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_revert_series_lagrange(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_lagrange_fast_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_revert_series_lagrange_fast(to._poly(), e1._poly(), e2)) FLINT_DEFINE_BINARY_EXPR_COND2(revert_series_newton_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, traits::fits_into_slong, fmpq_poly_revert_series_newton(to._poly(), e1._poly(), e2)) FLINT_DEFINE_UNARY_EXPR_COND(content_op, fmpqxx, FMPQ_POLYXX_COND_S, fmpq_poly_content(to._fmpq(), from._poly())) FLINT_DEFINE_UNARY_EXPR_COND(primitive_part_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, fmpq_poly_primitive_part(to._poly(), from._poly())) FLINT_DEFINE_UNARY_EXPR_COND(make_monic_op, fmpq_polyxx, FMPQ_POLYXX_COND_S, fmpq_poly_make_monic(to._poly(), from._poly())) FLINT_DEFINE_UNARY_EXPR_COND(fmpq_polyxx_den_op, fmpzxx, FMPQ_POLYXX_COND_S, fmpz_set(to._fmpz(), fmpq_poly_denref(from._poly()))) namespace rdetail { typedef make_ltuple::type>::type fmpq_polyxx_triple; typedef make_ltuple::type>::type fmpq_polyxx_pair; } // rdetail FLINT_DEFINE_BINARY_EXPR_COND2(xgcd_op, rdetail::fmpq_polyxx_triple, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_xgcd(to.template get<0>()._poly(), to.template get<1>()._poly(), to.template get<2>()._poly(), e1._poly(), e2._poly())) FLINT_DEFINE_BINARY_EXPR_COND2(divrem_op, rdetail::fmpq_polyxx_pair, FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, fmpq_poly_divrem(to.template get<0>()._poly(), to.template get<1>()._poly(), e1._poly(), e2._poly())) #define FMPQ_POLYXX_DEFINE_SERIES_FUNC(name) \ FLINT_DEFINE_THREEARY_EXPR_COND3(name##_op, fmpq_polyxx, \ FMPQ_POLYXX_COND_S, FMPQ_POLYXX_COND_S, traits::fits_into_slong, \ fmpq_poly_##name(to._poly(), e1._poly(), e2._poly(), e3)) FMPQ_POLYXX_DEFINE_SERIES_FUNC(mullow) FMPQ_POLYXX_DEFINE_SERIES_FUNC(div_series) FMPQ_POLYXX_DEFINE_SERIES_FUNC(compose_series) FMPQ_POLYXX_DEFINE_SERIES_FUNC(compose_series_brent_kung) FMPQ_POLYXX_DEFINE_SERIES_FUNC(compose_series_horner) } // rules // NB: fmpq_poly addmul is just done by hand currently, no need to wrap that .. } // flint #endif