#include "double_extras.h"
#include "fmpz_poly.h"
#include "fmpz_poly_factor.h"
#include "arb_fmpz_poly.h"
#include "acf.h"
#include "acb.h"
#include "gr.h"
#include "gr/impl.h"
#include "gr_generic.h"
#include "gr_vec.h"
#include "gr_poly.h"
typedef struct
{
slong prec;
arf_rnd_t rnd;
}
gr_acf_ctx;
#define ACF_CTX_PREC(ring_ctx) (((gr_acf_ctx *)((ring_ctx)))->prec)
#define ACF_CTX_RND(ring_ctx) (((gr_acf_ctx *)((ring_ctx)))->rnd)
static int _gr_acf_ctx_set_real_prec(gr_ctx_t ctx, slong prec)
{
prec = FLINT_MAX(prec, 2);
prec = FLINT_MIN(prec, WORD_MAX / 8);
ACF_CTX_PREC(ctx) = prec;
return GR_SUCCESS;
}
static int _gr_acf_ctx_get_real_prec(slong * res, gr_ctx_t ctx)
{
*res = ACF_CTX_PREC(ctx);
return GR_SUCCESS;
}
static int
_gr_acf_ctx_write(gr_stream_t out, gr_ctx_t ctx)
{
gr_stream_write(out, "Complex floating-point numbers (acf, prec = ");
gr_stream_write_si(out, ACF_CTX_PREC(ctx));
gr_stream_write(out, ")");
return GR_SUCCESS;
}
static void
_gr_acf_init(acf_t x, const gr_ctx_t ctx)
{
acf_init(x);
}
static void
_gr_acf_clear(acf_t x, const gr_ctx_t ctx)
{
acf_clear(x);
}
static void
_gr_acf_swap(acf_t x, acf_t y, const gr_ctx_t ctx)
{
acf_t t;
*t = *x;
*x = *y;
*y = *t;
}
static void
_gr_acf_set_shallow(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
*res = *x;
}
static int
_gr_acf_randtest(acf_t res, flint_rand_t state, const gr_ctx_t ctx)
{
arf_randtest(acf_realref(res), state, ACF_CTX_PREC(ctx), 10);
arf_randtest(acf_imagref(res), state, ACF_CTX_PREC(ctx), 10);
return GR_SUCCESS;
}
static int
_gr_acf_write(gr_stream_t out, const acf_t x, const gr_ctx_t ctx)
{
slong digits = ACF_CTX_PREC(ctx) * 0.30102999566398 + 1;
if (arf_is_zero(acf_imagref(x)))
{
gr_stream_write_free(out, arf_get_str(acf_realref(x), digits));
}
else if (arf_is_zero(acf_realref(x)))
{
gr_stream_write_free(out, arf_get_str(acf_imagref(x), digits));
gr_stream_write(out, "*I");
}
else
{
gr_stream_write(out, "(");
gr_stream_write_free(out, arf_get_str(acf_realref(x), digits));
if (arf_sgn(acf_imagref(x)) < 0)
{
arf_t t;
arf_init_neg_shallow(t, acf_imagref(x));
gr_stream_write(out, " - ");
gr_stream_write_free(out, arf_get_str(t, digits));
}
else
{
gr_stream_write(out, " + ");
gr_stream_write_free(out, arf_get_str(acf_imagref(x), digits));
}
gr_stream_write(out, "*I)");
}
return GR_SUCCESS;
}
static int
_gr_acf_zero(acf_t x, const gr_ctx_t ctx)
{
arf_zero(acf_realref(x));
arf_zero(acf_imagref(x));
return GR_SUCCESS;
}
static int
_gr_acf_one(acf_t x, const gr_ctx_t ctx)
{
arf_one(acf_realref(x));
arf_zero(acf_imagref(x));
return GR_SUCCESS;
}
static int
_gr_acf_set_si(acf_t res, slong v, const gr_ctx_t ctx)
{
arf_set_round_si(acf_realref(res), v, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_set_ui(acf_t res, ulong v, const gr_ctx_t ctx)
{
arf_set_round_ui(acf_realref(res), v, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_set_fmpz(acf_t res, const fmpz_t v, const gr_ctx_t ctx)
{
arf_set_round_fmpz(acf_realref(res), v, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_set_fmpq(acf_t res, const fmpq_t v, const gr_ctx_t ctx)
{
arf_set_fmpq(acf_realref(res), v, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_set_d(acf_t res, double x, const gr_ctx_t ctx)
{
arf_set_d(acf_realref(res), x);
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_set(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
acf_set(res, x);
return GR_SUCCESS;
}
static int
_gr_acf_set_other(acf_t res, gr_srcptr x, gr_ctx_t x_ctx, const gr_ctx_t ctx)
{
switch (x_ctx->which_ring)
{
case GR_CTX_FMPZ:
return _gr_acf_set_fmpz(res, x, ctx);
case GR_CTX_FMPQ:
return _gr_acf_set_fmpq(res, x, ctx);
case GR_CTX_REAL_FLOAT_ARF:
arf_set_round(acf_realref(res), x, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
case GR_CTX_COMPLEX_FLOAT_ACF:
return _gr_acf_set(res, x, ctx);
case GR_CTX_RR_ARB:
arf_set_round(acf_realref(res), arb_midref((arb_srcptr) x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
case GR_CTX_CC_ACB:
arf_set_round(acf_realref(res), arb_midref(acb_realref((acb_srcptr) x)), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), arb_midref(acb_imagref((acb_srcptr) x)), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
default:
{
gr_ctx_t cctx;
acb_t z;
int status;
gr_ctx_init_complex_acb(cctx, ACF_CTX_PREC(ctx) + 20);
acb_init(z);
status = gr_set_other(z, x, x_ctx, cctx);
if (status == GR_SUCCESS)
{
arf_set_round(acf_realref(res), arb_midref(acb_realref(z)), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), arb_midref(acb_imagref(z)), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
}
acb_clear(z);
gr_ctx_clear(cctx);
return status;
}
}
}
static int
_gr_acf_get_fmpz(fmpz_t res, const acf_t x, const gr_ctx_t ctx)
{
if (!arf_is_zero(acf_imagref(x)))
return GR_DOMAIN;
if (!arf_is_int(acf_realref(x)))
return GR_DOMAIN;
if (arf_cmpabs_2exp_si(acf_realref(x), WORD_MAX) >= 0)
return GR_UNABLE;
arf_get_fmpz(res, acf_realref(x), ARF_RND_DOWN);
return GR_SUCCESS;
}
static int
_gr_acf_get_si(slong * res, const acf_t x, const gr_ctx_t ctx)
{
fmpz_t t;
if (!arf_is_zero(acf_imagref(x)))
return GR_DOMAIN;
if (!arf_is_int(acf_realref(x)))
return GR_DOMAIN;
if (arf_cmp_si(acf_realref(x), WORD_MIN) < 0 || arf_cmp_si(acf_realref(x), WORD_MAX) > 0)
return GR_DOMAIN;
fmpz_init(t);
arf_get_fmpz(t, acf_realref(x), ARF_RND_DOWN);
*res = fmpz_get_si(t);
fmpz_clear(t);
return GR_SUCCESS;
}
static int
_gr_acf_get_ui(ulong * res, const acf_t x, const gr_ctx_t ctx)
{
fmpz_t t;
if (!arf_is_zero(acf_imagref(x)))
return GR_DOMAIN;
if (!arf_is_int(acf_realref(x)))
return GR_DOMAIN;
if (arf_sgn(acf_realref(x)) < 0 || arf_cmp_ui(acf_realref(x), UWORD_MAX) > 0)
return GR_DOMAIN;
fmpz_init(t);
arf_get_fmpz(t, acf_realref(x), ARF_RND_DOWN);
*res = fmpz_get_ui(t);
fmpz_clear(t);
return GR_SUCCESS;
}
static int
_gr_acf_get_d(double * res, const acf_t x, const gr_ctx_t ctx)
{
if (!arf_is_zero(acf_imagref(x)))
return GR_DOMAIN;
*res = arf_get_d(acf_realref(x), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static truth_t
_gr_acf_is_zero(const acf_t x, const gr_ctx_t ctx)
{
return (arf_is_zero(acf_realref(x)) && arf_is_zero(acf_imagref(x))) ? T_TRUE : T_FALSE;
}
static truth_t
_gr_acf_is_one(const acf_t x, const gr_ctx_t ctx)
{
return (arf_is_one(acf_realref(x)) && arf_is_zero(acf_imagref(x))) ? T_TRUE : T_FALSE;
}
static truth_t
_gr_acf_is_neg_one(const acf_t x, const gr_ctx_t ctx)
{
return (arf_equal_si(acf_realref(x), -1) && arf_is_zero(acf_imagref(x))) ? T_TRUE : T_FALSE;
}
static truth_t
_gr_acf_equal(const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
if (arf_is_nan(acf_realref(x)) || arf_is_nan(acf_imagref(x)) ||
arf_is_nan(acf_realref(y)) || arf_is_nan(acf_imagref(y)))
return T_UNKNOWN;
return acf_equal(x, y) ? T_TRUE : T_FALSE;
}
static int
_gr_acf_neg(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
arf_neg(acf_realref(res), acf_realref(x));
arf_neg(acf_imagref(res), acf_imagref(x));
return GR_SUCCESS;
}
static int
_gr_acf_add(acf_t res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
acf_add(res, x, y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_add_si(acf_t res, const acf_t x, slong y, const gr_ctx_t ctx)
{
arf_add_si(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_add_ui(acf_t res, const acf_t x, ulong y, const gr_ctx_t ctx)
{
arf_add_ui(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_add_fmpz(acf_t res, const acf_t x, const fmpz_t y, const gr_ctx_t ctx)
{
arf_add_fmpz(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_sub(acf_t res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
acf_sub(res, x, y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_sub_si(acf_t res, const acf_t x, slong y, const gr_ctx_t ctx)
{
arf_sub_si(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_sub_ui(acf_t res, const acf_t x, ulong y, const gr_ctx_t ctx)
{
arf_sub_ui(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_sub_fmpz(acf_t res, const acf_t x, const fmpz_t y, const gr_ctx_t ctx)
{
arf_sub_fmpz(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_set_round(acf_imagref(res), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_mul(acf_t res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
acf_mul(res, x, y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_mul_si(acf_t res, const acf_t x, slong y, const gr_ctx_t ctx)
{
arf_mul_si(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_mul_si(acf_imagref(res), acf_imagref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_mul_ui(acf_t res, const acf_t x, ulong y, const gr_ctx_t ctx)
{
arf_mul_ui(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_mul_ui(acf_imagref(res), acf_imagref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_mul_fmpz(acf_t res, const acf_t x, const fmpz_t y, const gr_ctx_t ctx)
{
arf_mul_fmpz(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_mul_fmpz(acf_imagref(res), acf_imagref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_mul_two(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
arf_mul_2exp_si(acf_realref(res), acf_realref(x), 1);
arf_mul_2exp_si(acf_imagref(res), acf_imagref(x), 1);
return GR_SUCCESS;
}
static int
_gr_acf_sqr(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
acf_mul(res, x, x, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_mul_2exp_si(acf_t res, const acf_t x, slong y, const gr_ctx_t ctx)
{
arf_mul_2exp_si(acf_realref(res), acf_realref(x), y);
arf_mul_2exp_si(acf_imagref(res), acf_imagref(x), y);
return GR_SUCCESS;
}
static int
_gr_acf_mul_2exp_fmpz(acf_t res, const acf_t x, const fmpz_t y, const gr_ctx_t ctx)
{
arf_mul_2exp_fmpz(acf_realref(res), acf_realref(x), y);
arf_mul_2exp_fmpz(acf_imagref(res), acf_imagref(x), y);
return GR_SUCCESS;
}
static int
_gr_acf_set_fmpz_2exp_fmpz(acf_t res, const fmpz_t x, const fmpz_t y, const gr_ctx_t ctx)
{
arf_set_fmpz_2exp(acf_realref(res), x, y);
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_get_fmpz_2exp_fmpz(fmpz_t res1, fmpz_t res2, const acf_t x, const gr_ctx_t ctx)
{
if (!arf_is_zero(acf_imagref(x)) || !arf_is_finite(acf_realref(x)))
return GR_DOMAIN;
arf_get_fmpz_2exp(res1, res2, acf_realref(x));
return GR_SUCCESS;
}
static int
_gr_acf_inv(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
acf_approx_inv(res, x, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_div(acf_t res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
acf_approx_div(res, x, y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_div_si(acf_t res, const acf_t x, slong y, const gr_ctx_t ctx)
{
arf_div_si(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_div_si(acf_imagref(res), acf_imagref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_div_ui(acf_t res, const acf_t x, ulong y, const gr_ctx_t ctx)
{
arf_div_ui(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_div_ui(acf_imagref(res), acf_imagref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_div_fmpz(acf_t res, const acf_t x, const fmpz_t y, const gr_ctx_t ctx)
{
arf_div_fmpz(acf_realref(res), acf_realref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_div_fmpz(acf_imagref(res), acf_imagref(x), y, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_sqrt(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
acf_approx_sqrt(res, x, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_pos_inf(acf_t res, const gr_ctx_t ctx)
{
arf_pos_inf(acf_realref(res));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_neg_inf(acf_t res, const gr_ctx_t ctx)
{
arf_neg_inf(acf_realref(res));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_nan(acf_t res, const gr_ctx_t ctx)
{
arf_nan(acf_realref(res));
arf_nan(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_abs(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
if (arf_is_zero(acf_imagref(x)))
{
arf_abs(acf_realref(res), acf_realref(x));
}
else if (arf_is_zero(acf_realref(x)))
{
arf_abs(acf_realref(res), acf_imagref(x));
}
else
{
arf_sosq(acf_realref(res), acf_realref(x), acf_imagref(x), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_sqrt(acf_realref(res), acf_realref(res), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
}
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_conj(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
arf_set(acf_realref(res), acf_realref(x));
arf_neg(acf_imagref(res), acf_imagref(x));
return GR_SUCCESS;
}
static int
_gr_acf_re(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
arf_set(acf_realref(res), acf_realref(x));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_im(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
arf_set(acf_realref(res), acf_imagref(x));
arf_zero(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_cmp(int * res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
if (!arf_is_zero(acf_imagref(x)) || !arf_is_zero(acf_imagref(y)))
return GR_DOMAIN;
*res = arf_cmp(acf_realref(x), acf_realref(y));
return GR_SUCCESS;
}
static int
_gr_acf_cmpabs(int * res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
arf_srcptr a = acf_realref(x);
arf_srcptr b = acf_imagref(x);
arf_srcptr c = acf_realref(y);
arf_srcptr d = acf_imagref(y);
if (arf_is_zero(b))
{
if (arf_is_zero(d))
return _gr_arf_cmpabs(res, a, c, ctx);
if (arf_is_zero(c))
return _gr_arf_cmpabs(res, a, d, ctx);
if (arf_is_zero(a))
{
*res = -1;
return GR_SUCCESS;
}
}
if (arf_is_zero(a))
{
if (arf_is_zero(d))
return _gr_arf_cmpabs(res, b, c, ctx);
if (arf_is_zero(c))
return _gr_arf_cmpabs(res, b, d, ctx);
}
if (arf_is_zero(c) && arf_is_zero(d))
{
*res = 1;
return GR_SUCCESS;
}
if (ARF_IS_LAGOM(a) && ARF_IS_LAGOM(b) && ARF_IS_LAGOM(c) && ARF_IS_LAGOM(d))
{
slong aexp, bexp, cexp, dexp, xexp, yexp, exp;
aexp = arf_is_zero(a) ? WORD_MIN : ARF_EXP(a);
bexp = arf_is_zero(b) ? WORD_MIN : ARF_EXP(b);
cexp = arf_is_zero(c) ? WORD_MIN : ARF_EXP(c);
dexp = arf_is_zero(d) ? WORD_MIN : ARF_EXP(d);
xexp = FLINT_MAX(aexp, bexp);
yexp = FLINT_MAX(cexp, dexp);
if (xexp + 2 < yexp)
{
*res = -1;
return GR_SUCCESS;
}
if (xexp > yexp + 2)
{
*res = 1;
return GR_SUCCESS;
}
exp = FLINT_MAX(xexp, yexp);
double tt, xx = 0.0, yy = 0.0;
nn_srcptr xp;
slong xn;
if (aexp >= exp - 53)
{
ARF_GET_MPN_READONLY(xp, xn, a);
tt = d_mul_2exp_inrange(xp[xn - 1], aexp - exp - FLINT_BITS);
xx += tt * tt;
}
if (bexp >= exp - 53)
{
ARF_GET_MPN_READONLY(xp, xn, b);
tt = d_mul_2exp_inrange(xp[xn - 1], bexp - exp - FLINT_BITS);
xx += tt * tt;
}
if (cexp >= exp - 53)
{
ARF_GET_MPN_READONLY(xp, xn, c);
tt = d_mul_2exp_inrange(xp[xn - 1], cexp - exp - FLINT_BITS);
yy += tt * tt;
}
if (dexp >= exp - 53)
{
ARF_GET_MPN_READONLY(xp, xn, d);
tt = d_mul_2exp_inrange(xp[xn - 1], dexp - exp - FLINT_BITS);
yy += tt * tt;
}
if (xx < yy * 0.999999)
{
*res = -1;
return GR_SUCCESS;
}
if (xx * 0.999999 > yy)
{
*res = 1;
return GR_SUCCESS;
}
}
arf_struct s[5];
arf_init(s + 0);
arf_init(s + 1);
arf_init(s + 2);
arf_init(s + 3);
arf_init(s + 4);
arf_mul(s + 0, a, a, ARF_PREC_EXACT, ARF_RND_DOWN);
arf_mul(s + 1, b, b, ARF_PREC_EXACT, ARF_RND_DOWN);
arf_mul(s + 2, c, c, ARF_PREC_EXACT, ARF_RND_DOWN);
arf_mul(s + 3, d, d, ARF_PREC_EXACT, ARF_RND_DOWN);
arf_neg(s + 2, s + 2);
arf_neg(s + 3, s + 3);
arf_sum(s + 4, s, 4, 30, ARF_RND_DOWN);
*res = arf_sgn(s + 4);
arf_clear(s + 0);
arf_clear(s + 1);
arf_clear(s + 2);
arf_clear(s + 3);
arf_clear(s + 4);
return GR_SUCCESS;
}
#define ACF_FUNC_VIA_ACB(res, acb_func, x) \
acb_t r, t; \
slong prec, wp, extra; \
int status = GR_SUCCESS; \
prec = ACF_CTX_PREC(ctx); \
acb_init(r); \
*arb_midref(acb_realref(t)) = *acf_realref(x); \
*arb_midref(acb_imagref(t)) = *acf_imagref(x); \
mag_init(arb_radref(acb_realref(t))); \
mag_init(arb_radref(acb_imagref(t))); \
for (extra = 10 + prec * 0.01; ; extra += FLINT_MAX(extra, 32)) \
{ \
wp = prec + extra; \
if (wp > 10 * prec + 1000) \
{ \
status = GR_UNABLE; \
arf_nan(acf_realref(res)); \
arf_nan(acf_imagref(res)); \
break; \
} \
acb_func(r, t, wp); \
if (acb_rel_accuracy_bits(r) >= prec) \
{ \
arf_set_round(acf_realref(res), arb_midref(acb_realref(r)), prec, ACF_CTX_RND(ctx)); \
arf_set_round(acf_imagref(res), arb_midref(acb_imagref(r)), prec, ACF_CTX_RND(ctx)); \
break; \
} \
} \
acb_clear(r); \
return status; \
#define ACF_FUNC2_VIA_ACB(res, acb_func, x, y) \
acb_t r, t, u; \
slong prec, wp, extra; \
int status = GR_SUCCESS; \
prec = ACF_CTX_PREC(ctx); \
acb_init(r); \
*arb_midref(acb_realref(t)) = *acf_realref(x); \
*arb_midref(acb_imagref(t)) = *acf_imagref(x); \
mag_init(arb_radref(acb_realref(t))); \
mag_init(arb_radref(acb_imagref(t))); \
*arb_midref(acb_realref(u)) = *acf_realref(y); \
*arb_midref(acb_imagref(u)) = *acf_imagref(y); \
mag_init(arb_radref(acb_realref(u))); \
mag_init(arb_radref(acb_imagref(u))); \
for (extra = 10 + prec * 0.01; ; extra += FLINT_MAX(extra, 32)) \
{ \
wp = prec + extra; \
if (wp > 10 * prec + 1000) \
{ \
status = GR_UNABLE; \
arf_nan(acf_realref(res)); \
arf_nan(acf_imagref(res)); \
break; \
} \
acb_func(r, t, u, wp); \
if (acb_rel_accuracy_bits(r) >= prec) \
{ \
arf_set_round(acf_realref(res), arb_midref(acb_realref(r)), prec, ACF_CTX_RND(ctx)); \
arf_set_round(acf_imagref(res), arb_midref(acb_imagref(r)), prec, ACF_CTX_RND(ctx)); \
break; \
} \
} \
acb_clear(r); \
return status; \
static int
_gr_acf_pow(acf_t res, const acf_t x, const acf_t y, const gr_ctx_t ctx)
{
ACF_FUNC2_VIA_ACB(res, acb_pow, x, y)
}
static int
_gr_acf_i(acf_t res, const gr_ctx_t ctx)
{
arf_zero(acf_realref(res));
arf_one(acf_imagref(res));
return GR_SUCCESS;
}
static int
_gr_acf_pi(acf_t res, const gr_ctx_t ctx)
{
arb_t t;
arb_init(t);
arb_const_pi(t, ACF_CTX_PREC(ctx) + 30);
arf_set_round(acf_realref(res), arb_midref(t), ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
arf_zero(acf_imagref(res));
arb_clear(t);
return GR_SUCCESS;
}
static int
_gr_acf_exp(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
ACF_FUNC_VIA_ACB(res, acb_exp, x)
}
static int
_gr_acf_expm1(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
ACF_FUNC_VIA_ACB(res, acb_expm1, x)
}
static int
_gr_acf_log(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
ACF_FUNC_VIA_ACB(res, acb_log, x)
}
static int
_gr_acf_log1p(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
ACF_FUNC_VIA_ACB(res, acb_log1p, x)
}
static int
_gr_acf_sin(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
ACF_FUNC_VIA_ACB(res, acb_sin, x)
}
static int
_gr_acf_cos(acf_t res, const acf_t x, const gr_ctx_t ctx)
{
ACF_FUNC_VIA_ACB(res, acb_cos, x)
}
static int
_gr_acf_vec_dot(acf_t res, const acf_t initial, int subtract, acf_srcptr vec1, acf_srcptr vec2, slong len, gr_ctx_t ctx)
{
acf_approx_dot(res, initial, subtract, vec1, 1, vec2, 1, len, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
static int
_gr_acf_vec_dot_rev(acf_t res, const acf_t initial, int subtract, acf_srcptr vec1, acf_srcptr vec2, slong len, gr_ctx_t ctx)
{
acf_approx_dot(res, initial, subtract, vec1, 1, vec2 + len - 1, -1, len, ACF_CTX_PREC(ctx), ACF_CTX_RND(ctx));
return GR_SUCCESS;
}
#include "gr_poly.h"
#include "acb_poly.h"
static int
_gr_acf_poly_mulmid(acf_ptr res,
acf_srcptr poly1, slong len1,
acf_srcptr poly2, slong len2, slong nlo, slong nhi, gr_ctx_t ctx)
{
len1 = FLINT_MIN(len1, nhi);
len2 = FLINT_MIN(len2, nhi);
if (nlo != 0)
{
slong nlo2 = (len1 + len2 - 1) - nlo;
if (len1 > nlo2)
{
slong trunc = len1 - nlo2;
poly1 += trunc;
len1 -= trunc;
nlo -= trunc;
nhi -= trunc;
}
if (len2 > nlo2)
{
slong trunc = len2 - nlo2;
poly2 += trunc;
len2 -= trunc;
nlo -= trunc;
nhi -= trunc;
}
}
if (len1 <= 10 || len2 <= 10 || 2 * (nhi - nlo) <= 10)
{
return _gr_poly_mulmid_classical(res, poly1, len1, poly2, len2, nlo, nhi, ctx);
}
else
{
acb_ptr tmp, t1, t2, t3;
slong i, n = nhi - nlo;
int squaring = (poly1 == poly2 && len1 == len2);
if (!squaring)
{
tmp = flint_malloc(sizeof(acb_struct) * (len1 + len2 + n));
t1 = tmp;
t2 = t1 + len1;
t3 = t2 + len2;
}
else
{
tmp = flint_malloc(sizeof(acb_struct) * (len1 + n));
t1 = tmp;
t2 = t1;
t3 = t2 + len2;
}
for (i = 0; i < len1; i++)
{
*arb_midref(acb_realref(t1 + i)) = *acf_realref(poly1 + i);
*arb_midref(acb_imagref(t1 + i)) = *acf_imagref(poly1 + i);
mag_init(arb_radref(acb_realref(t1 + i)));
mag_init(arb_radref(acb_imagref(t1 + i)));
}
if (!squaring)
{
for (i = 0; i < len2; i++)
{
*arb_midref(acb_realref(t2 + i)) = *acf_realref(poly2 + i);
*arb_midref(acb_imagref(t2 + i)) = *acf_imagref(poly2 + i);
mag_init(arb_radref(acb_realref(t2 + i)));
mag_init(arb_radref(acb_imagref(t2 + i)));
}
}
for (i = 0; i < n; i++)
{
*arb_midref(acb_realref(t3 + i)) = *acf_realref(res + i);
*arb_midref(acb_imagref(t3 + i)) = *acf_imagref(res + i);
mag_init(arb_radref(acb_realref(t3 + i)));
mag_init(arb_radref(acb_imagref(t3 + i)));
}
_acb_poly_mulmid(t3, t1, len1, t2, len2, nlo, nhi, ACF_CTX_PREC(ctx));
for (i = 0; i < n; i++)
{
*acf_realref(res + i) = *arb_midref(acb_realref(t3 + i));
*acf_imagref(res + i) = *arb_midref(acb_imagref(t3 + i));
mag_clear(arb_radref(acb_realref(t3 + i)));
mag_clear(arb_radref(acb_imagref(t3 + i)));
}
flint_free(tmp);
return GR_SUCCESS;
}
}
static int
_gr_acf_poly_mullow(acf_ptr res,
acf_srcptr poly1, slong len1,
acf_srcptr poly2, slong len2, slong n, gr_ctx_t ctx)
{
return _gr_acf_poly_mulmid(res, poly1, len1, poly2, len2, 0, n, ctx);
}
static int
_gr_acf_poly_roots_other(gr_vec_t roots, gr_vec_t mult, const gr_poly_t poly, gr_ctx_t other_ctx, int flags, gr_ctx_t ctx)
{
if (poly->length == 0)
return GR_DOMAIN;
if (other_ctx->which_ring == GR_CTX_FMPZ)
{
gr_ctx_t ZZ;
slong i, j, deg, deg2;
acb_ptr croots;
int status = GR_SUCCESS;
deg = poly->length - 1;
gr_ctx_init_fmpz(ZZ);
gr_vec_set_length(roots, 0, ctx);
gr_vec_set_length(mult, 0, ZZ);
if (deg != 0)
{
fmpz_poly_factor_t fac;
fmpz_poly_factor_init(fac);
fmpz_poly_factor_squarefree(fac, (const fmpz_poly_struct *) poly);
for (i = 0; i < fac->num; i++)
{
deg2 = fmpz_poly_degree(fac->p + i);
croots = _acb_vec_init(deg2);
arb_fmpz_poly_complex_roots(croots, fac->p + i, 0, ACF_CTX_PREC(ctx));
for (j = 0; j < deg2; j++)
{
acf_t t;
fmpz m2 = fac->exp[i];
*acf_realref(t) = *arb_midref(acb_realref(croots + j));
*acf_imagref(t) = *arb_midref(acb_imagref(croots + j));
GR_MUST_SUCCEED(gr_vec_append(roots, t, ctx));
GR_MUST_SUCCEED(gr_vec_append(mult, &m2, ZZ));
}
_acb_vec_clear(croots, deg2);
}
fmpz_poly_factor_clear(fac);
}
gr_ctx_clear(ZZ);
return status;
}
return GR_UNABLE;
}
#include "gr_mat.h"
#include "acb_mat.h"
#define ACF_MAT_ENTRY(mat, ii, jj) (((acf_ptr) (mat)->entries) + (ii) * (mat)->stride + (jj))
static int
_gr_acf_mat_mul(gr_mat_t C, const gr_mat_t A, const gr_mat_t B, gr_ctx_t ctx)
{
slong prec;
slong cutoff;
prec = ACF_CTX_PREC(ctx);
if (prec <= 2 * FLINT_BITS)
cutoff = 120;
else if (prec <= 16 * FLINT_BITS)
cutoff = 60;
else
cutoff = 40;
if (A->r <= cutoff || A->c <= cutoff || B->c <= cutoff)
{
return gr_mat_mul_classical(C, A, B, ctx);
}
else
{
acb_mat_t RC, RB, RA;
slong i, j;
acf_t zero;
acb_mat_init(RA, A->r, A->c);
acb_mat_init(RB, B->r, B->c);
acb_mat_init(RC, C->r, C->c);
acf_init(zero);
for (i = 0; i < A->r; i++)
{
for (j = 0; j < A->c; j++)
{
*arb_midref(acb_realref(acb_mat_entry(RA, i, j))) = *acf_realref(ACF_MAT_ENTRY(A, i, j));
*arb_midref(acb_imagref(acb_mat_entry(RA, i, j))) = *acf_imagref(ACF_MAT_ENTRY(A, i, j));
}
}
for (i = 0; i < B->r; i++)
{
for (j = 0; j < B->c; j++)
{
*arb_midref(acb_realref(acb_mat_entry(RB, i, j))) = *acf_realref(ACF_MAT_ENTRY(B, i, j));
*arb_midref(acb_imagref(acb_mat_entry(RB, i, j))) = *acf_imagref(ACF_MAT_ENTRY(B, i, j));
}
}
acb_mat_approx_mul(RC, RA, RB, prec);
for (i = 0; i < A->r; i++)
{
for (j = 0; j < A->c; j++)
{
*arb_midref(acb_realref(acb_mat_entry(RA, i, j))) = *acf_realref(zero);
*arb_midref(acb_imagref(acb_mat_entry(RA, i, j))) = *acf_imagref(zero);
}
}
for (i = 0; i < B->r; i++)
{
for (j = 0; j < B->c; j++)
{
*arb_midref(acb_realref(acb_mat_entry(RB, i, j))) = *acf_realref(zero);
*arb_midref(acb_imagref(acb_mat_entry(RB, i, j))) = *acf_imagref(zero);
}
}
for (i = 0; i < C->r; i++)
{
for (j = 0; j < C->c; j++)
{
arf_swap(acf_realref(ACF_MAT_ENTRY(C, i, j)), arb_midref(acb_realref(acb_mat_entry(RC, i, j))));
arf_swap(acf_imagref(ACF_MAT_ENTRY(C, i, j)), arb_midref(acb_imagref(acb_mat_entry(RC, i, j))));
}
}
acb_mat_clear(RA);
acb_mat_clear(RB);
acb_mat_clear(RC);
return GR_SUCCESS;
}
}
static int
_gr_acf_mat_diagonalization(gr_vec_t D, gr_mat_t L, gr_mat_t R, const gr_mat_t A, int flags, gr_ctx_t ctx)
{
int status;
slong n, i, j;
acb_mat_t A_acb, R_acb;
acb_ptr D_acb;
n = gr_mat_nrows(A, ctx);
if (n != gr_mat_ncols(A, ctx))
return GR_DOMAIN;
acb_mat_init(A_acb, n, n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
arf_set(arb_midref(acb_realref(acb_mat_entry(A_acb, i, j))), acf_realref(ACF_MAT_ENTRY(A, i, j)));
arf_set(arb_midref(acb_imagref(acb_mat_entry(A_acb, i, j))), acf_imagref(ACF_MAT_ENTRY(A, i, j)));
}
}
acb_mat_init(R_acb, n, n);
D_acb = _acb_vec_init(n);
gr_vec_set_length(D, n, ctx);
status = acb_mat_approx_eig_qr(D_acb, NULL, R_acb, A_acb, NULL, 0, ACF_CTX_PREC(ctx)) ? GR_SUCCESS : GR_UNABLE;
if (status == GR_SUCCESS)
{
if (R != NULL)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
arf_set(acf_realref(ACF_MAT_ENTRY(R, i, j)), arb_midref(acb_realref(acb_mat_entry(R_acb, i, j))));
arf_set(acf_imagref(ACF_MAT_ENTRY(R, i, j)), arb_midref(acb_imagref(acb_mat_entry(R_acb, i, j))));
}
}
}
if (L != NULL)
{
status = gr_mat_inv(L, R, ctx);
}
for (i = 0; i < n; i++)
{
arf_set(acb_realref(((acf_ptr) D->entries) + i), arb_midref(acb_realref(D_acb + i)));
arf_set(acb_imagref(((acf_ptr) D->entries) + i), arb_midref(acb_imagref(D_acb + i)));
}
}
acb_mat_clear(R_acb);
acb_mat_clear(A_acb);
return status;
}
int _acf_methods_initialized = 0;
gr_static_method_table _acf_methods;
gr_method_tab_input _acf_methods_input[] =
{
{GR_METHOD_CTX_WRITE, (gr_funcptr) _gr_acf_ctx_write},
{GR_METHOD_CTX_IS_RING, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_FIELD, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_UNIQUE_FACTORIZATION_DOMAIN,
(gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_FINITE,
(gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_FINITE_CHARACTERISTIC,
(gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_ALGEBRAICALLY_CLOSED,
(gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_ORDERED_RING,
(gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_APPROX_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_IS_CANONICAL,
(gr_funcptr) gr_generic_ctx_predicate_false},
{GR_METHOD_CTX_HAS_REAL_PREC, (gr_funcptr) gr_generic_ctx_predicate_true},
{GR_METHOD_CTX_SET_REAL_PREC, (gr_funcptr) _gr_acf_ctx_set_real_prec},
{GR_METHOD_CTX_GET_REAL_PREC, (gr_funcptr) _gr_acf_ctx_get_real_prec},
{GR_METHOD_INIT, (gr_funcptr) _gr_acf_init},
{GR_METHOD_CLEAR, (gr_funcptr) _gr_acf_clear},
{GR_METHOD_SWAP, (gr_funcptr) _gr_acf_swap},
{GR_METHOD_SET_SHALLOW, (gr_funcptr) _gr_acf_set_shallow},
{GR_METHOD_RANDTEST, (gr_funcptr) _gr_acf_randtest},
{GR_METHOD_WRITE, (gr_funcptr) _gr_acf_write},
{GR_METHOD_ZERO, (gr_funcptr) _gr_acf_zero},
{GR_METHOD_ONE, (gr_funcptr) _gr_acf_one},
{GR_METHOD_IS_ZERO, (gr_funcptr) _gr_acf_is_zero},
{GR_METHOD_IS_ONE, (gr_funcptr) _gr_acf_is_one},
{GR_METHOD_IS_NEG_ONE, (gr_funcptr) _gr_acf_is_neg_one},
{GR_METHOD_EQUAL, (gr_funcptr) _gr_acf_equal},
{GR_METHOD_SET, (gr_funcptr) _gr_acf_set},
{GR_METHOD_SET_SI, (gr_funcptr) _gr_acf_set_si},
{GR_METHOD_SET_UI, (gr_funcptr) _gr_acf_set_ui},
{GR_METHOD_SET_FMPZ, (gr_funcptr) _gr_acf_set_fmpz},
{GR_METHOD_SET_FMPQ, (gr_funcptr) _gr_acf_set_fmpq},
{GR_METHOD_SET_D, (gr_funcptr) _gr_acf_set_d},
{GR_METHOD_SET_STR, (gr_funcptr) gr_generic_set_str_ring_exponents},
{GR_METHOD_SET_OTHER, (gr_funcptr) _gr_acf_set_other},
{GR_METHOD_GET_FMPZ, (gr_funcptr) _gr_acf_get_fmpz},
{GR_METHOD_GET_UI, (gr_funcptr) _gr_acf_get_ui},
{GR_METHOD_GET_SI, (gr_funcptr) _gr_acf_get_si},
{GR_METHOD_GET_D, (gr_funcptr) _gr_acf_get_d},
{GR_METHOD_NEG, (gr_funcptr) _gr_acf_neg},
{GR_METHOD_ADD, (gr_funcptr) _gr_acf_add},
{GR_METHOD_ADD_UI, (gr_funcptr) _gr_acf_add_ui},
{GR_METHOD_ADD_SI, (gr_funcptr) _gr_acf_add_si},
{GR_METHOD_ADD_FMPZ, (gr_funcptr) _gr_acf_add_fmpz},
{GR_METHOD_SUB, (gr_funcptr) _gr_acf_sub},
{GR_METHOD_SUB_UI, (gr_funcptr) _gr_acf_sub_ui},
{GR_METHOD_SUB_SI, (gr_funcptr) _gr_acf_sub_si},
{GR_METHOD_SUB_FMPZ, (gr_funcptr) _gr_acf_sub_fmpz},
{GR_METHOD_MUL, (gr_funcptr) _gr_acf_mul},
{GR_METHOD_MUL_UI, (gr_funcptr) _gr_acf_mul_ui},
{GR_METHOD_MUL_SI, (gr_funcptr) _gr_acf_mul_si},
{GR_METHOD_MUL_FMPZ, (gr_funcptr) _gr_acf_mul_fmpz},
{GR_METHOD_MUL_TWO, (gr_funcptr) _gr_acf_mul_two},
{GR_METHOD_SQR, (gr_funcptr) _gr_acf_sqr},
{GR_METHOD_MUL_2EXP_SI, (gr_funcptr) _gr_acf_mul_2exp_si},
{GR_METHOD_MUL_2EXP_FMPZ, (gr_funcptr) _gr_acf_mul_2exp_fmpz},
{GR_METHOD_SET_FMPZ_2EXP_FMPZ, (gr_funcptr) _gr_acf_set_fmpz_2exp_fmpz},
{GR_METHOD_GET_FMPZ_2EXP_FMPZ, (gr_funcptr) _gr_acf_get_fmpz_2exp_fmpz},
{GR_METHOD_DIV, (gr_funcptr) _gr_acf_div},
{GR_METHOD_DIV_UI, (gr_funcptr) _gr_acf_div_ui},
{GR_METHOD_DIV_SI, (gr_funcptr) _gr_acf_div_si},
{GR_METHOD_DIV_FMPZ, (gr_funcptr) _gr_acf_div_fmpz},
{GR_METHOD_INV, (gr_funcptr) _gr_acf_inv},
{GR_METHOD_POW, (gr_funcptr) _gr_acf_pow},
{GR_METHOD_SQRT, (gr_funcptr) _gr_acf_sqrt},
{GR_METHOD_POS_INF, (gr_funcptr) _gr_acf_pos_inf},
{GR_METHOD_NEG_INF, (gr_funcptr) _gr_acf_neg_inf},
{GR_METHOD_UINF, (gr_funcptr) gr_not_in_domain},
{GR_METHOD_UNDEFINED, (gr_funcptr) _gr_acf_nan},
{GR_METHOD_UNKNOWN, (gr_funcptr) _gr_acf_nan},
{GR_METHOD_ABS, (gr_funcptr) _gr_acf_abs},
{GR_METHOD_CONJ, (gr_funcptr) _gr_acf_conj},
{GR_METHOD_RE, (gr_funcptr) _gr_acf_re},
{GR_METHOD_IM, (gr_funcptr) _gr_acf_im},
{GR_METHOD_CMP, (gr_funcptr) _gr_acf_cmp},
{GR_METHOD_CMPABS, (gr_funcptr) _gr_acf_cmpabs},
{GR_METHOD_I, (gr_funcptr) _gr_acf_i},
{GR_METHOD_PI, (gr_funcptr) _gr_acf_pi},
{GR_METHOD_EXP, (gr_funcptr) _gr_acf_exp},
{GR_METHOD_EXPM1, (gr_funcptr) _gr_acf_expm1},
{GR_METHOD_LOG, (gr_funcptr) _gr_acf_log},
{GR_METHOD_LOG1P, (gr_funcptr) _gr_acf_log1p},
{GR_METHOD_SIN, (gr_funcptr) _gr_acf_sin},
{GR_METHOD_COS, (gr_funcptr) _gr_acf_cos},
{GR_METHOD_VEC_DOT, (gr_funcptr) _gr_acf_vec_dot},
{GR_METHOD_VEC_DOT_REV, (gr_funcptr) _gr_acf_vec_dot_rev},
{GR_METHOD_POLY_MULMID, (gr_funcptr) _gr_acf_poly_mulmid},
{GR_METHOD_POLY_MULLOW, (gr_funcptr) _gr_acf_poly_mullow},
{GR_METHOD_POLY_FACTOR, (gr_funcptr) gr_generic_poly_factor_roots},
{GR_METHOD_POLY_ROOTS_OTHER,(gr_funcptr) _gr_acf_poly_roots_other},
{GR_METHOD_MAT_MUL, (gr_funcptr) _gr_acf_mat_mul},
{GR_METHOD_MAT_DET, (gr_funcptr) gr_mat_det_generic_field},
{GR_METHOD_MAT_FIND_NONZERO_PIVOT, (gr_funcptr) gr_mat_find_nonzero_pivot_large_abs},
{GR_METHOD_MAT_DIAGONALIZATION, (gr_funcptr) _gr_acf_mat_diagonalization},
{0, (gr_funcptr) NULL},
};
void
gr_ctx_init_complex_float_acf(gr_ctx_t ctx, slong prec)
{
ctx->which_ring = GR_CTX_COMPLEX_FLOAT_ACF;
ctx->sizeof_elem = sizeof(acf_struct);
ctx->size_limit = WORD_MAX;
ACF_CTX_PREC(ctx) = FLINT_MAX(2, FLINT_MIN(prec, WORD_MAX / 8));
ACF_CTX_RND(ctx) = ARF_RND_NEAR;
ctx->methods = _acf_methods;
if (!_acf_methods_initialized)
{
gr_method_tab_init(_acf_methods, _acf_methods_input);
_acf_methods_initialized = 1;
}
}