#ifdef T
#include "templates.h"
void
_TEMPLATE4(T, poly_evaluate, T, vec_fast_precomp)
(TEMPLATE(T, struct) * vs,
const TEMPLATE(T, struct) * poly, slong plen,
TEMPLATE(T, poly_struct) * const * tree, slong len,
const TEMPLATE(T, ctx_t) ctx)
{
slong height, i, j, pow, left;
slong tree_height;
TEMPLATE(T, t) temp, inv;
TEMPLATE(T, struct) * t, * u, * pb, * pc, * swap;
TEMPLATE(T, poly_struct) * pa;
TEMPLATE(T, init)(temp, ctx);
TEMPLATE(T, init)(inv, ctx);
if (len < 2 || plen < 2)
{
if (len == 1)
{
TEMPLATE(T, neg)(temp, tree[0]->coeffs, ctx);
_TEMPLATE3(T, poly_evaluate, T)(vs, poly, plen, temp, ctx);
} else if (len != 0 && plen == 0)
_TEMPLATE(T, vec_zero)(vs, len, ctx);
else if (len != 0 && plen == 1)
for (i = 0; i < len; i++)
TEMPLATE(T, set)(vs + i, poly, ctx);
TEMPLATE(T, clear)(temp, ctx);
TEMPLATE(T, clear)(inv, ctx);
return;
}
t = _TEMPLATE(T, vec_init)(2*len, ctx);
u = _TEMPLATE(T, vec_init)(2*len, ctx);
left = len;
height = FLINT_BIT_COUNT(plen - 1) - 1;
tree_height = FLINT_CLOG2(len);
while (height >= tree_height)
height--;
pow = WORD(1) << height;
for (i = j = 0; i < len; i += pow, j++)
{
pa = tree[height] + j;
TEMPLATE(T, inv)(inv, pa->coeffs + pa->length - 1, ctx);
_TEMPLATE(T, poly_rem)(t + i, poly, plen, pa->coeffs, pa->length, inv, ctx);
}
for (i = height - 1; i >= 0; i--)
{
pow = WORD(1) << i;
left = len;
pa = tree[i];
pb = t;
pc = u;
left = len;
while (left >= 2 * pow)
{
TEMPLATE(T, inv)(inv, pa->coeffs + pa->length - 1, ctx);
_TEMPLATE(T, poly_rem)(pc, pb, 2 * pow, pa->coeffs, pa->length, inv, ctx);
pa++;
TEMPLATE(T, inv)(inv, pa->coeffs + pa->length - 1, ctx);
_TEMPLATE(T, poly_rem)(pc + pow, pb, 2 * pow, pa->coeffs, pa->length, inv, ctx);
pa++;
pb += 2 * pow;
pc += 2 * pow;
left -= 2 * pow;
}
if (left > pow)
{
TEMPLATE(T, inv)(inv, pa->coeffs + pa->length - 1, ctx);
_TEMPLATE(T, poly_rem)(pc, pb, left, pa->coeffs, pa->length, inv, ctx);
pa ++;
TEMPLATE(T, inv)(inv, pa->coeffs + pa->length - 1, ctx);
_TEMPLATE(T, poly_rem)(pc + pow, pb, left, pa->coeffs, pa->length, inv, ctx);
}
else if (left > 0)
_TEMPLATE(T, vec_set)(pc, pb, left, ctx);
swap = t;
t = u;
u = swap;
}
TEMPLATE(T, clear)(temp, ctx);
TEMPLATE(T, clear)(inv, ctx);
_TEMPLATE(T, vec_set)(vs, t, len, ctx);
_TEMPLATE(T, vec_clear)(t, 2*len, ctx);
_TEMPLATE(T, vec_clear)(u, 2*len, ctx);
}
void
_TEMPLATE4(T, poly_evaluate, T, vec_fast)(TEMPLATE(T, struct) * ys,
const TEMPLATE(T, struct) * poly, slong plen,
const TEMPLATE(T, struct) * xs, slong n,
const TEMPLATE(T, ctx_t) ctx)
{
TEMPLATE(T, poly_struct) ** tree;
tree = _TEMPLATE(T, poly_tree_alloc)(n, ctx);
_TEMPLATE(T, poly_tree_build)(tree, xs, n, ctx);
_TEMPLATE4(T, poly_evaluate, T, vec_fast_precomp)(ys, poly, plen, tree, n, ctx);
_TEMPLATE(T, poly_tree_free)(tree, n, ctx);
}
void
TEMPLATE4(T, poly_evaluate, T, vec_fast)(TEMPLATE(T, struct) * ys,
const TEMPLATE(T, poly_t) poly,
const TEMPLATE(T, struct) *xs, slong n,
const TEMPLATE(T, ctx_t) ctx)
{
_TEMPLATE4(T, poly_evaluate, T, vec_fast)(ys, poly->coeffs, poly->length,
xs, n, ctx);
}
#endif