#include "fmpz.h"
#include "fmpz_vec.h"
#include "mpoly.h"
int mpoly_monomial_cofactors(
fmpz * Abarexps,
fmpz * Bbarexps,
const ulong * Aexps, flint_bitcnt_t Abits,
const ulong * Bexps, flint_bitcnt_t Bbits,
slong length,
const mpoly_ctx_t mctx)
{
int success;
slong i, j;
slong nvars = mctx->nvars;
slong NA = mpoly_words_per_exp(Abits, mctx);
slong NB = mpoly_words_per_exp(Bbits, mctx);
fmpz * Aexp, * Bexp, * minAexp, * minBexp;
fmpz_t t1, t2;
TMP_INIT;
FLINT_ASSERT(length > 0);
fmpz_init(t1);
fmpz_init(t2);
TMP_START;
Aexp = (fmpz *) TMP_ALLOC(4*nvars*sizeof(fmpz));
Bexp = Aexp + 1*nvars;
minAexp = Aexp + 2*nvars;
minBexp = Aexp + 3*nvars;
for (j = 0; j < nvars; j++)
{
fmpz_init(Aexp + j);
fmpz_init(Bexp + j);
fmpz_init(minAexp + j);
fmpz_init(minBexp + j);
}
mpoly_get_monomial_ffmpz(Abarexps, Aexps + NA*0, Abits, mctx);
mpoly_get_monomial_ffmpz(Bbarexps, Bexps + NB*0, Bbits, mctx);
_fmpz_vec_set(minAexp, Abarexps, nvars);
_fmpz_vec_set(minBexp, Bbarexps, nvars);
for (i = 0; i < length; i++)
{
mpoly_get_monomial_ffmpz(Aexp, Aexps + NA*i, Abits, mctx);
mpoly_get_monomial_ffmpz(Bexp, Bexps + NB*i, Bbits, mctx);
_fmpz_vec_min_inplace(minAexp, Aexp, nvars);
_fmpz_vec_min_inplace(minBexp, Bexp, nvars);
for (j = 0; j < nvars; j++)
{
fmpz_add(t1, Abarexps + j, Bexp + j);
fmpz_add(t2, Bbarexps + j, Aexp + j);
success = fmpz_equal(t1, t2);
if (!success)
goto cleanup;
}
}
_fmpz_vec_max(Bbarexps, minAexp, minBexp, nvars);
_fmpz_vec_sub(Abarexps, Bbarexps, minBexp, nvars);
_fmpz_vec_sub(Bbarexps, Bbarexps, minAexp, nvars);
success = 1;
cleanup:
for (j = 0; j < nvars; j++)
{
fmpz_clear(Aexp + j);
fmpz_clear(Bexp + j);
fmpz_clear(minAexp + j);
fmpz_clear(minBexp + j);
}
TMP_END;
fmpz_clear(t1);
fmpz_clear(t2);
return success;
}