#include "ulong_extras.h"
#include "mpoly.h"
static void mpoly_used_vars_or_sp(
int * used,
const ulong * Aexps, slong Alen, flint_bitcnt_t Abits,
const mpoly_ctx_t mctx)
{
slong Ai, i, j, m, dir;
slong N = mpoly_words_per_exp(Abits, mctx);
slong nvars = mctx->nvars;
ulong * t;
slong Aimod, Amodulus = n_sqrt(Alen);
ulong mask = (-UWORD(1)) >> (FLINT_BITS - Abits);
ulong u;
flint_bitcnt_t shift;
const ulong * exp2;
TMP_INIT;
TMP_START;
t = TMP_ARRAY_ALLOC(N, ulong);
mpoly_monomial_zero(t, N);
m = 0;
for (Aimod = 0; Aimod < Amodulus; Aimod++)
{
while (m < nvars && used[m])
m++;
if (m >= nvars)
goto cleanup;
for (Ai = Aimod; Ai < Alen; Ai += Amodulus)
{
for (j = 0; j < N; j++)
t[j] |= Aexps[N*Ai + j];
}
j = mctx->rev ? 0 : nvars - 1;
dir = mctx->rev ? 1 : -1;
exp2 = t;
i = 0;
u = *exp2++;
shift = 0;
FLINT_ASSERT(0 <= j && j < nvars);
used[j] |= (u & mask) != 0;
j += dir;
u = u >> Abits;
shift += Abits;
while (++i < nvars)
{
if (shift + Abits > FLINT_BITS)
{
u = *exp2++;
shift = 0;
}
FLINT_ASSERT(0 <= j && j < nvars);
used[j] |= (u & mask) != 0;
j += dir;
u = u >> Abits;
shift += Abits;
}
}
cleanup:
TMP_END;
}
static void mpoly_used_vars_or_mp(
int * used,
const ulong * Aexps, slong Alen, flint_bitcnt_t Abits,
const mpoly_ctx_t mctx)
{
slong Ai, i, j, m;
slong N = mpoly_words_per_exp(Abits, mctx);
slong wpf = Abits/FLINT_BITS;
slong nvars = mctx->nvars;
slong Aimod, Amodulus = n_sqrt(Alen);
FLINT_ASSERT(Abits%FLINT_BITS == 0);
m = 0;
for (Aimod = 0; Aimod < Amodulus; Aimod++)
{
while (m < nvars && used[m])
m++;
if (m >= nvars)
return;
if (mctx->rev)
{
for (Ai = Aimod; Ai < Alen; Ai += Amodulus)
{
for (j = m; j < nvars; j++)
for (i = 0; i < wpf && !used[j]; i++)
used[j] |= Aexps[N*Ai + wpf*j + i] != 0;
}
}
else
{
for (Ai = Aimod; Ai < Alen; Ai += Amodulus)
{
for (j = m; j < nvars; j++)
for (i = wpf - 1; i >= 0 && !used[j]; i--)
used[j] |= Aexps[N*Ai + wpf*(nvars - 1 - j) + i] != 0;
}
}
}
}
void mpoly_used_vars_or(
int * used,
const ulong * Aexps, slong Alen, flint_bitcnt_t Abits,
const mpoly_ctx_t mctx)
{
if (Abits <= FLINT_BITS)
mpoly_used_vars_or_sp(used, Aexps, Alen, Abits, mctx);
else
mpoly_used_vars_or_mp(used, Aexps, Alen, Abits, mctx);
}