#ifndef QQBAR_H
#define QQBAR_H
#ifdef QQBAR_INLINES_C
#define QQBAR_INLINE
#else
#define QQBAR_INLINE static inline
#endif
#include "fmpz_types.h"
#include "fmpq_types.h"
#include "mpoly_types.h"
#include "acb.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
fmpz_poly_struct poly;
acb_struct enclosure;
}
qqbar_struct;
typedef qqbar_struct qqbar_t[1];
typedef qqbar_struct * qqbar_ptr;
typedef const qqbar_struct * qqbar_srcptr;
#define QQBAR_POLY(x) (&((x)->poly))
#define QQBAR_COEFFS(x) ((&((x)->poly))->coeffs)
#define QQBAR_ENCLOSURE(x) (&((x)->enclosure))
#define QQBAR_DEFAULT_PREC 128
void qqbar_init(qqbar_t res);
void qqbar_clear(qqbar_t res);
QQBAR_INLINE qqbar_ptr
_qqbar_vec_init(slong len)
{
slong i;
qqbar_ptr vec = (qqbar_ptr) flint_malloc(len * sizeof(qqbar_struct));
for (i = 0; i < len; i++)
qqbar_init(vec + i);
return vec;
}
QQBAR_INLINE void
_qqbar_vec_clear(qqbar_ptr vec, slong len)
{
slong i;
for (i = 0; i < len; i++)
qqbar_clear(vec + i);
flint_free(vec);
}
void qqbar_swap(qqbar_t x, qqbar_t y);
void qqbar_set(qqbar_t res, const qqbar_t x);
void qqbar_set_si(qqbar_t res, slong x);
void qqbar_set_ui(qqbar_t res, ulong x);
void qqbar_set_fmpz(qqbar_t res, const fmpz_t x);
void qqbar_set_fmpq(qqbar_t res, const fmpq_t x);
void qqbar_set_re_im(qqbar_t res, const qqbar_t x, const qqbar_t y);
int qqbar_set_d(qqbar_t res, double x);
int qqbar_set_re_im_d(qqbar_t res, double x, double y);
QQBAR_INLINE slong
qqbar_degree(const qqbar_t x)
{
return QQBAR_POLY(x)->length - 1;
}
QQBAR_INLINE int
qqbar_is_rational(const qqbar_t x)
{
return (qqbar_degree(x) == 1);
}
QQBAR_INLINE int
qqbar_is_integer(const qqbar_t x)
{
return qqbar_is_rational(x) && fmpz_is_one(QQBAR_COEFFS(x) + 1);
}
QQBAR_INLINE int
qqbar_is_algebraic_integer(const qqbar_t x)
{
return fmpz_is_one(QQBAR_COEFFS(x) + qqbar_degree(x));
}
QQBAR_INLINE int
qqbar_is_zero(const qqbar_t x)
{
return qqbar_is_integer(x) && fmpz_is_zero(QQBAR_COEFFS(x));
}
QQBAR_INLINE int
qqbar_is_one(const qqbar_t x)
{
return qqbar_is_integer(x) && (fmpz_equal_si(QQBAR_COEFFS(x), -1));
}
QQBAR_INLINE int
qqbar_is_neg_one(const qqbar_t x)
{
return qqbar_is_integer(x) && fmpz_is_one(QQBAR_COEFFS(x));
}
QQBAR_INLINE int
qqbar_is_i(const qqbar_t x)
{
return (qqbar_degree(x) == 2) && fmpz_is_one(QQBAR_COEFFS(x)) &&
fmpz_is_zero(QQBAR_COEFFS(x) + 1) && fmpz_is_one(QQBAR_COEFFS(x) + 2) &&
arf_sgn(arb_midref(acb_imagref(QQBAR_ENCLOSURE(x)))) > 0;
}
QQBAR_INLINE int
qqbar_is_neg_i(const qqbar_t x)
{
return (qqbar_degree(x) == 2) && fmpz_is_one(QQBAR_COEFFS(x)) &&
fmpz_is_zero(QQBAR_COEFFS(x) + 1) && fmpz_is_one(QQBAR_COEFFS(x) + 2) &&
arf_sgn(arb_midref(acb_imagref(QQBAR_ENCLOSURE(x)))) < 0;
}
int qqbar_sgn_re(const qqbar_t x);
int qqbar_sgn_im(const qqbar_t x);
QQBAR_INLINE int
qqbar_is_real(const qqbar_t x)
{
return qqbar_sgn_im(x) == 0;
}
slong qqbar_height_bits(const qqbar_t x);
void qqbar_height(fmpz_t res, const qqbar_t x);
QQBAR_INLINE int
qqbar_within_limits(const qqbar_t x, slong deg_limit, slong bits_limit)
{
return (deg_limit == 0 || (qqbar_degree(x) <= deg_limit)) &&
(bits_limit == 0 || (qqbar_height_bits(x) <= bits_limit));
}
QQBAR_INLINE int
qqbar_binop_within_limits(const qqbar_t x, const qqbar_t y, slong deg_limit, slong bits_limit)
{
return (deg_limit == 0 || (qqbar_degree(x) * qqbar_degree(y) <= deg_limit)) &&
(bits_limit == 0 || (qqbar_height_bits(x) + qqbar_height_bits(y) <= bits_limit));
}
void _qqbar_get_fmpq(fmpz_t num, fmpz_t den, const qqbar_t x);
void qqbar_get_fmpq(fmpq_t res, const qqbar_t x);
void qqbar_get_fmpz(fmpz_t res, const qqbar_t x);
QQBAR_INLINE void
qqbar_zero(qqbar_t res)
{
qqbar_set_ui(res, 0);
}
QQBAR_INLINE void
qqbar_one(qqbar_t res)
{
qqbar_set_ui(res, 1);
}
void qqbar_i(qqbar_t res);
void qqbar_phi(qqbar_t res);
void qqbar_randtest(qqbar_t res, flint_rand_t state, slong deg, slong bits);
void qqbar_randtest_real(qqbar_t res, flint_rand_t state, slong deg, slong bits);
void qqbar_randtest_nonreal(qqbar_t res, flint_rand_t state, slong deg, slong bits);
void qqbar_print(const qqbar_t x);
void qqbar_printn(const qqbar_t x, slong n);
void qqbar_printnd(const qqbar_t x, slong n);
char * qqbar_get_str_nd(const qqbar_t x, slong n);
int qqbar_equal(const qqbar_t x, const qqbar_t y);
int qqbar_equal_fmpq_poly_val(const qqbar_t x, const fmpq_poly_t f, const qqbar_t y);
int qqbar_cmp_re(const qqbar_t x, const qqbar_t y);
int qqbar_cmp_im(const qqbar_t x, const qqbar_t y);
int qqbar_cmpabs_re(const qqbar_t x, const qqbar_t y);
int qqbar_cmpabs_im(const qqbar_t x, const qqbar_t y);
int qqbar_cmpabs(const qqbar_t x, const qqbar_t y);
int qqbar_cmp_root_order(const qqbar_t x, const qqbar_t y);
ulong qqbar_hash(const qqbar_t x);
void qqbar_conj(qqbar_t res, const qqbar_t x);
void qqbar_re(qqbar_t res, const qqbar_t x);
void qqbar_im(qqbar_t res, const qqbar_t x);
void qqbar_re_im(qqbar_t res1, qqbar_t res2, const qqbar_t x);
void qqbar_abs(qqbar_t res, const qqbar_t x);
void qqbar_abs2(qqbar_t res, const qqbar_t x);
void qqbar_sgn(qqbar_t res, const qqbar_t x);
int qqbar_csgn(const qqbar_t x);
void qqbar_floor(fmpz_t res, const qqbar_t x);
void qqbar_ceil(fmpz_t res, const qqbar_t x);
void qqbar_numerator(qqbar_t res, const qqbar_t y);
void qqbar_denominator(fmpz_t res, const qqbar_t y);
void qqbar_neg(qqbar_t res, const qqbar_t x);
void qqbar_add(qqbar_t res, const qqbar_t x, const qqbar_t y);
void qqbar_add_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y);
void qqbar_add_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y);
void qqbar_add_ui(qqbar_t res, const qqbar_t x, ulong y);
void qqbar_add_si(qqbar_t res, const qqbar_t x, slong y);
void qqbar_sub(qqbar_t res, const qqbar_t x, const qqbar_t y);
void qqbar_sub_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y);
void qqbar_sub_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y);
void qqbar_sub_ui(qqbar_t res, const qqbar_t x, ulong y);
void qqbar_sub_si(qqbar_t res, const qqbar_t x, slong y);
void qqbar_fmpq_sub(qqbar_t res, const fmpq_t x, const qqbar_t y);
void qqbar_fmpz_sub(qqbar_t res, const fmpz_t x, const qqbar_t y);
void qqbar_ui_sub(qqbar_t res, ulong x, const qqbar_t y);
void qqbar_si_sub(qqbar_t res, slong x, const qqbar_t y);
void qqbar_mul(qqbar_t res, const qqbar_t x, const qqbar_t y);
void qqbar_mul_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y);
void qqbar_mul_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y);
void qqbar_mul_ui(qqbar_t res, const qqbar_t x, ulong y);
void qqbar_mul_si(qqbar_t res, const qqbar_t x, slong y);
void qqbar_div(qqbar_t res, const qqbar_t x, const qqbar_t y);
void qqbar_div_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t y);
void qqbar_div_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t y);
void qqbar_div_ui(qqbar_t res, const qqbar_t x, ulong y);
void qqbar_div_si(qqbar_t res, const qqbar_t x, slong y);
void qqbar_fmpq_div(qqbar_t res, const fmpq_t x, const qqbar_t y);
void qqbar_fmpz_div(qqbar_t res, const fmpz_t x, const qqbar_t y);
void qqbar_ui_div(qqbar_t res, ulong x, const qqbar_t y);
void qqbar_si_div(qqbar_t res, slong x, const qqbar_t y);
QQBAR_INLINE void
qqbar_sqr(qqbar_t res, const qqbar_t x)
{
qqbar_mul(res, x, x);
}
void qqbar_inv(qqbar_t res, const qqbar_t x);
void qqbar_mul_2exp_si(qqbar_t res, const qqbar_t x, slong exp);
void qqbar_pow_ui(qqbar_t res, const qqbar_t x, ulong e);
void qqbar_pow_si(qqbar_t res, const qqbar_t x, slong n);
void qqbar_pow_fmpz(qqbar_t res, const qqbar_t x, const fmpz_t n);
void qqbar_pow_fmpq(qqbar_t res, const qqbar_t x, const fmpq_t n);
int qqbar_pow(qqbar_t res, const qqbar_t x, const qqbar_t e);
int _qqbar_fast_detect_simple_principal_surd(const qqbar_t x);
void qqbar_root_ui(qqbar_t res, const qqbar_t x, ulong n);
QQBAR_INLINE void
qqbar_sqrt(qqbar_t res, const qqbar_t x)
{
qqbar_root_ui(res, x, 2);
}
QQBAR_INLINE void
qqbar_sqrt_ui(qqbar_t res, ulong x)
{
qqbar_set_ui(res, x);
qqbar_sqrt(res, res);
}
QQBAR_INLINE void
qqbar_rsqrt(qqbar_t res, const qqbar_t x)
{
qqbar_sqrt(res, x);
qqbar_inv(res, res);
}
void qqbar_fmpq_root_ui(qqbar_t res, const fmpq_t x, ulong b);
void qqbar_fmpq_pow_si_ui(qqbar_t res, const fmpq_t x, slong a, ulong b);
void qqbar_cache_enclosure(qqbar_t res, slong prec);
void qqbar_get_arb(arb_t res, const qqbar_t x, slong prec);
void qqbar_get_acb(acb_t res, const qqbar_t x, slong prec);
void qqbar_get_arb_re(arb_t res, const qqbar_t x, slong prec);
void qqbar_get_arb_im(arb_t res, const qqbar_t x, slong prec);
void qqbar_conjugates(qqbar_ptr res, const qqbar_t x);
void _qqbar_evaluate_fmpq_poly(qqbar_t res, const fmpz * poly, const fmpz_t den, slong len, const qqbar_t x);
void qqbar_evaluate_fmpq_poly(qqbar_t res, const fmpq_poly_t poly, const qqbar_t x);
void _qqbar_evaluate_fmpz_poly(qqbar_t res, const fmpz * poly, slong len, const qqbar_t x);
void qqbar_evaluate_fmpz_poly(qqbar_t res, const fmpz_poly_t poly, const qqbar_t x);
int qqbar_evaluate_fmpz_mpoly_iter(qqbar_t res, const fmpz_mpoly_t f, qqbar_srcptr x, slong deg_limit, slong bits_limit, const fmpz_mpoly_ctx_t ctx);
int qqbar_evaluate_fmpz_mpoly_horner(qqbar_t res, const fmpz_mpoly_t f, qqbar_srcptr x, slong deg_limit, slong bits_limit, const fmpz_mpoly_ctx_t ctx);
int qqbar_evaluate_fmpz_mpoly(qqbar_t res, const fmpz_mpoly_t f, qqbar_srcptr x, slong deg_limit, slong bits_limit, const fmpz_mpoly_ctx_t ctx);
#define QQBAR_ROOTS_IRREDUCIBLE 1
#define QQBAR_ROOTS_UNSORTED 2
void qqbar_roots_fmpz_poly(qqbar_ptr res, const fmpz_poly_t poly, int flags);
void qqbar_roots_fmpq_poly(qqbar_ptr res, const fmpq_poly_t poly, int flags);
int _qqbar_roots_poly_squarefree(qqbar_ptr roots, qqbar_srcptr coeffs, slong len, slong deg_limit, slong bits_limit);
void qqbar_eigenvalues_fmpz_mat(qqbar_ptr res, const fmpz_mat_t mat, int flags);
void qqbar_eigenvalues_fmpq_mat(qqbar_ptr res, const fmpq_mat_t mat, int flags);
void qqbar_root_of_unity(qqbar_t res, slong p, ulong q);
int qqbar_is_root_of_unity(slong * p, ulong * q, const qqbar_t x);
void qqbar_exp_pi_i(qqbar_t res, slong p, ulong q);
void qqbar_cos_pi(qqbar_t res, slong p, ulong q);
void qqbar_sin_pi(qqbar_t res, slong p, ulong q);
int qqbar_tan_pi(qqbar_t res, slong p, ulong q);
int qqbar_cot_pi(qqbar_t res, slong p, ulong q);
int qqbar_sec_pi(qqbar_t res, slong p, ulong q);
int qqbar_csc_pi(qqbar_t res, slong p, ulong q);
int qqbar_log_pi_i(slong * p, ulong * q, const qqbar_t x);
int qqbar_atan_pi(slong * p, ulong * q, const qqbar_t x);
int qqbar_asin_pi(slong * p, ulong * q, const qqbar_t x);
int qqbar_acos_pi(slong * p, ulong * q, const qqbar_t x);
int qqbar_acot_pi(slong * p, ulong * q, const qqbar_t x);
int qqbar_asec_pi(slong * p, ulong * q, const qqbar_t x);
int qqbar_acsc_pi(slong * p, ulong * q, const qqbar_t x);
int qqbar_guess(qqbar_t res, const acb_t z, slong max_deg, slong max_bits, int flags, slong prec);
int qqbar_express_in_field(fmpq_poly_t res, const qqbar_t alpha, const qqbar_t x, slong max_bits, int flags, slong prec);
void qqbar_get_quadratic(fmpz_t res_a, fmpz_t res_b, fmpz_t res_c, fmpz_t res_q, const qqbar_t x, int factoring);
#ifdef FEXPR_H
void qqbar_get_fexpr_repr(fexpr_t res, const qqbar_t x);
void qqbar_get_fexpr_root_nearest(fexpr_t res, const qqbar_t x);
void qqbar_get_fexpr_root_indexed(fexpr_t res, const qqbar_t x);
int qqbar_get_fexpr_formula(fexpr_t res, const qqbar_t x, ulong flags);
#define QQBAR_FORMULA_GAUSSIANS 1
#define QQBAR_FORMULA_QUADRATICS 2
#define QQBAR_FORMULA_CYCLOTOMICS 4
#define QQBAR_FORMULA_CUBICS 8
#define QQBAR_FORMULA_QUARTICS 16
#define QQBAR_FORMULA_QUINTICS 32
#define QQBAR_FORMULA_DEPRESSION 64
#define QQBAR_FORMULA_DEFLATION 128
#define QQBAR_FORMULA_SEPARATION 256
#define QQBAR_FORMULA_EXP_FORM 2048
#define QQBAR_FORMULA_TRIG_FORM 4096
#define QQBAR_FORMULA_RADICAL_FORM 8192
#define QQBAR_FORMULA_AUTO_FORM 0
#define QQBAR_FORMULA_ALL ((2 * QQBAR_FORMULA_SEPARATION - 1) | QQBAR_FORMULA_AUTO_FORM)
int qqbar_set_fexpr(qqbar_t res, const fexpr_t expr);
#endif
void qqbar_scalar_op(qqbar_t res, const qqbar_t x, const fmpz_t a, const fmpz_t b, const fmpz_t c);
void qqbar_fmpz_poly_composed_op(fmpz_poly_t res, const fmpz_poly_t A, const fmpz_poly_t B, int op);
void qqbar_binary_op(qqbar_t res, const qqbar_t x, const qqbar_t y, int op);
int _qqbar_validate_uniqueness(acb_t res, const fmpz_poly_t poly, const acb_t z, slong max_prec);
int _qqbar_validate_existence_uniqueness(acb_t res, const fmpz_poly_t poly, const acb_t z, slong prec);
void _qqbar_enclosure_raw(acb_t res, const fmpz_poly_t poly, const acb_t zin, slong prec);
void qqbar_enclosure_raw(acb_t res, const qqbar_t x, slong prec);
int _qqbar_acb_lindep(fmpz * rel, acb_srcptr vec, slong len, int check, slong prec);
#ifdef __cplusplus
}
#endif
#endif