#include "fmpz.h"
#include "fmpz_poly.h"
#include "mpoly.h"
#include "fmpz_mpoly_factor.h"
void fmpz_bpoly_clear(fmpz_bpoly_t A)
{
if (A->alloc > 0)
{
slong i;
for (i = 0; i < A->alloc; i++)
fmpz_poly_clear(A->coeffs + i);
flint_free(A->coeffs);
}
}
void fmpz_bpoly_print_pretty(fmpz_bpoly_t A, const char * var0, const char * var1)
{
slong i;
int first = 1;
for (i = A->length - 1; i >= 0; i--)
{
if (fmpz_poly_is_zero(A->coeffs + i))
continue;
if (!first)
flint_printf(" + ");
first = 0;
flint_printf("(");
fmpz_poly_print_pretty(A->coeffs + i, var1);
flint_printf(")*%s^%wd", var0, i);
}
if (first)
flint_printf("0");
}
void fmpz_bpoly_realloc(fmpz_bpoly_t A, slong len)
{
slong i;
slong old_alloc = A->alloc;
if (len <= old_alloc)
return;
len = FLINT_MAX(len, 2*old_alloc);
if (A->alloc == 0)
A->coeffs = (fmpz_poly_struct *) flint_malloc(
len * sizeof(fmpz_poly_struct));
else
A->coeffs = (fmpz_poly_struct *) flint_realloc(A->coeffs,
len * sizeof(fmpz_poly_struct));
for (i = old_alloc; i < len; i++)
fmpz_poly_init(A->coeffs + i);
A->alloc = len;
}
slong fmpz_bpoly_degree1(const fmpz_bpoly_t A)
{
slong i, len = 0;
for (i = 0; i < A->length; i++)
len = FLINT_MAX(len, A->coeffs[i].length);
return len - 1;
}
void fmpz_bpoly_set_coeff(fmpz_bpoly_t A, slong xi, slong yi, const fmpz_t c)
{
slong i;
FLINT_ASSERT(!fmpz_is_zero(c));
if (xi >= A->length)
{
fmpz_bpoly_fit_length(A, xi + 1);
for (i = A->length; i <= xi; i++)
fmpz_poly_zero(A->coeffs + i);
A->length = xi + 1;
}
fmpz_poly_set_coeff_fmpz(A->coeffs + xi, yi, c);
}
void fmpz_mpoly_set_fmpz_bpoly(
fmpz_mpoly_t A,
flint_bitcnt_t Abits,
const fmpz_bpoly_t B,
slong varx,
slong vary,
const fmpz_mpoly_ctx_t ctx)
{
slong n = ctx->minfo->nvars;
slong i, j;
slong NA;
slong Alen;
fmpz * Acoeff;
ulong * Aexp;
slong Aalloc;
ulong * Aexps;
TMP_INIT;
FLINT_ASSERT(B->length > 0);
FLINT_ASSERT(Abits <= FLINT_BITS);
TMP_START;
Aexps = (ulong *) TMP_ALLOC(n*sizeof(ulong));
for (i = 0; i < n; i++)
Aexps[i] = 0;
NA = mpoly_words_per_exp(Abits, ctx->minfo);
fmpz_mpoly_fit_bits(A, Abits, ctx);
A->bits = Abits;
Acoeff = A->coeffs;
Aexp = A->exps;
Aalloc = A->alloc;
Alen = 0;
for (i = 0; i < B->length; i++)
{
fmpz_poly_struct * Bc = B->coeffs + i;
_fmpz_mpoly_fit_length(&Acoeff, &Aexp, &Aalloc, Alen + Bc->length, NA);
for (j = 0; j < Bc->length; j++)
{
if (fmpz_is_zero(Bc->coeffs + j))
continue;
Aexps[varx] = i;
Aexps[vary] = j;
fmpz_set(Acoeff + Alen, Bc->coeffs + j);
mpoly_set_monomial_ui(Aexp + NA*Alen, Aexps, Abits, ctx->minfo);
Alen++;
}
}
A->coeffs = Acoeff;
A->exps = Aexp;
A->alloc = Aalloc;
_fmpz_mpoly_set_length(A, Alen, ctx);
fmpz_mpoly_sort_terms(A, ctx);
TMP_END;
}
void fmpz_mpoly_get_bpoly(
fmpz_bpoly_t A,
const fmpz_mpoly_t B,
slong varx,
slong vary,
const fmpz_mpoly_ctx_t ctx)
{
slong j;
slong NB;
ulong Bexpx, Bexpy;
slong Boffx, Bshiftx, Boffy, Bshifty;
ulong mask;
FLINT_ASSERT(B->bits <= FLINT_BITS);
NB = mpoly_words_per_exp_sp(B->bits, ctx->minfo);
mpoly_gen_offset_shift_sp(&Boffx, &Bshiftx, varx, B->bits, ctx->minfo);
mpoly_gen_offset_shift_sp(&Boffy, &Bshifty, vary, B->bits, ctx->minfo);
mask = (-UWORD(1)) >> (FLINT_BITS - B->bits);
fmpz_bpoly_zero(A);
for (j = 0; j < B->length; j++)
{
Bexpx = ((B->exps + NB*j)[Boffx] >> Bshiftx) & mask;
Bexpy = ((B->exps + NB*j)[Boffy] >> Bshifty) & mask;
fmpz_bpoly_set_coeff(A, Bexpx, Bexpy, B->coeffs + j);
}
}