#include "fmpz.h"
#include "mpoly.h"
void _mpoly_gen_shift_right(ulong * Aexp, flint_bitcnt_t Abits, slong Alength,
slong var, ulong amount, const mpoly_ctx_t mctx)
{
slong i, N;
ulong *one;
#if FLINT_WANT_ASSERT
ulong mask;
#endif
TMP_INIT;
FLINT_ASSERT(Abits <= FLINT_BITS);
#if FLINT_WANT_ASSERT
mask = 0;
for (i = 0; i < FLINT_BITS/Abits; i++)
mask = (mask << Abits) + (UWORD(1) << (Abits - 1));
#endif
TMP_START;
N = mpoly_words_per_exp(Abits, mctx);
one = (ulong *) TMP_ALLOC(N*sizeof(ulong));
mpoly_gen_monomial_sp(one, var, Abits, mctx);
for (i = 0; i < Alength; i++)
{
mpoly_monomial_msub(Aexp + N*i, Aexp + N*i, amount, one, N);
FLINT_ASSERT(!mpoly_monomial_overflows(Aexp + N*i, N, mask));
}
TMP_END;
}
void _mpoly_gen_shift_right_fmpz(
ulong * Aexp,
flint_bitcnt_t Abits,
slong Alength,
slong var,
const fmpz_t amount,
const mpoly_ctx_t mctx)
{
slong i, N;
ulong * gen;
TMP_INIT;
FLINT_ASSERT(fmpz_sgn(amount) >= 0);
if (fmpz_is_zero(amount))
return;
TMP_START;
N = mpoly_words_per_exp(Abits, mctx);
gen = (ulong *) TMP_ALLOC(N*sizeof(ulong));
if (Abits > FLINT_BITS)
{
mpoly_gen_monomial_offset_mp(gen, var, Abits, mctx);
mpoly_monomial_mul_fmpz(gen, gen, N, amount);
for (i = 0; i < Alength; i++)
mpoly_monomial_sub_mp(Aexp + N*i, Aexp + N*i, gen, N);
}
else
{
mpoly_gen_monomial_sp(gen, var, Abits, mctx);
FLINT_ASSERT(fmpz_abs_fits_ui(amount));
mpoly_monomial_mul_ui(gen, gen, N, fmpz_get_ui(amount));
for (i = 0; i < Alength; i++)
mpoly_monomial_sub(Aexp + N*i, Aexp + N*i, gen, N);
}
TMP_END;
}
void _mpoly_gen_shift_left(ulong * Aexp, flint_bitcnt_t Abits, slong Alength,
slong var, ulong amount, const mpoly_ctx_t mctx)
{
slong i, N;
ulong *one;
#if FLINT_WANT_ASSERT
ulong mask;
#endif
TMP_INIT;
FLINT_ASSERT(Abits <= FLINT_BITS);
#if FLINT_WANT_ASSERT
mask = 0;
for (i = 0; i < FLINT_BITS/Abits; i++)
mask = (mask << Abits) + (UWORD(1) << (Abits - 1));
#endif
TMP_START;
N = mpoly_words_per_exp(Abits, mctx);
one = (ulong *) TMP_ALLOC(N*sizeof(ulong));
mpoly_gen_monomial_sp(one, var, Abits, mctx);
for (i = 0; i < Alength; i++)
{
mpoly_monomial_madd(Aexp + N*i, Aexp + N*i, amount, one, N);
FLINT_ASSERT(!mpoly_monomial_overflows(Aexp + N*i, N, mask));
}
TMP_END;
}