#include "ca_ext.h"
#include "ca_field/impl.h"
#include "ca_vec.h"
static ulong hash_func(calcium_func_code func, ca_srcptr args, slong nargs, ca_ctx_t ctx)
{
ulong s;
slong i;
s = func;
for (i = 0; i < nargs; i++)
s = ca_hash_repr(args + i, ctx) * 1000003 + s;
return s;
}
void
ca_ext_init_qqbar(ca_ext_t res, const qqbar_t x, ca_ctx_t ctx)
{
fmpq_poly_t t;
res->head = CA_QQBar;
qqbar_init(CA_EXT_QQBAR(res));
qqbar_set(CA_EXT_QQBAR(res), x);
t->coeffs = QQBAR_POLY(x)->coeffs;
t->den[0] = 1;
t->length = QQBAR_POLY(x)->length;
t->alloc = QQBAR_POLY(x)->alloc;
CA_EXT_QQBAR_NF(res) = flint_malloc(sizeof(nf_struct));
nf_init(CA_EXT_QQBAR_NF(res), t);
res->hash = qqbar_hash(CA_EXT_QQBAR(res));
res->depth = 0;
}
static void _ca_ext_init_func(ca_ext_t res, ca_ctx_t ctx)
{
slong i, d;
CA_EXT_FUNC_PREC(res) = 0;
acb_init(CA_EXT_FUNC_ENCLOSURE(res));
acb_indeterminate(CA_EXT_FUNC_ENCLOSURE(res));
res->hash = hash_func(CA_EXT_HEAD(res), CA_EXT_FUNC_ARGS(res), CA_EXT_FUNC_NARGS(res), ctx);
res->depth = 0;
for (i = 0; i < CA_EXT_FUNC_NARGS(res); i++)
{
d = ca_depth(CA_EXT_FUNC_ARGS(res) + i, ctx);
res->depth = FLINT_MAX(res->depth, d + 1);
}
res->data.func_data.qqbar = NULL;
}
void
ca_ext_init_const(ca_ext_t res, calcium_func_code func, ca_ctx_t ctx)
{
res->head = func;
CA_EXT_FUNC_NARGS(res) = 0;
CA_EXT_FUNC_ARGS(res) = NULL;
_ca_ext_init_func(res, ctx);
}
void
ca_ext_init_fx(ca_ext_t res, calcium_func_code func, const ca_t x, ca_ctx_t ctx)
{
res->head = func;
res->hash = 0;
CA_EXT_FUNC_NARGS(res) = 1;
CA_EXT_FUNC_ARGS(res) = _ca_vec_init(1, ctx);
ca_set(CA_EXT_FUNC_ARGS(res), x, ctx);
_ca_ext_init_func(res, ctx);
}
void
ca_ext_init_fxy(ca_ext_t res, calcium_func_code func, const ca_t x, const ca_t y, ca_ctx_t ctx)
{
res->head = func;
res->hash = 0;
CA_EXT_FUNC_NARGS(res) = 2;
CA_EXT_FUNC_ARGS(res) = _ca_vec_init(2, ctx);
ca_set(CA_EXT_FUNC_ARGS(res), x, ctx);
ca_set(CA_EXT_FUNC_ARGS(res) + 1, y, ctx);
_ca_ext_init_func(res, ctx);
}
void
ca_ext_init_fxn(ca_ext_t res, calcium_func_code func, ca_srcptr x, slong nargs, ca_ctx_t ctx)
{
res->head = func;
CA_EXT_FUNC_NARGS(res) = nargs;
if (nargs == 0)
CA_EXT_FUNC_ARGS(res) = NULL;
else
CA_EXT_FUNC_ARGS(res) = _ca_vec_init(nargs, ctx);
_ca_vec_set(CA_EXT_FUNC_ARGS(res), x, nargs, ctx);
_ca_ext_init_func(res, ctx);
}