/* Copyright (C) 2017 Daniel Schultz This file is part of FLINT. FLINT is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include #include "flint.h" #include "mpoly.h" /* !!! this file DOES need to change with new orderings */ /* poly_exps (when unpacked) must contain the exponent of each variable in some field. These functions should place the exponent of each variable in the corresponding entry of user_exps. */ void mpoly_get_monomial_ui_unpacked_ffmpz(ulong * user_exps, const fmpz * poly_exps, const mpoly_ctx_t mctx) { slong i; /* poly_exps is already unpacked, just read of the correct fields */ for (i = 0; i < mctx->nvars; i++) { slong off = mctx->rev ? i : mctx->nvars - 1 - i; FLINT_ASSERT(fmpz_abs_fits_ui(poly_exps + off)); user_exps[i] = fmpz_get_ui(poly_exps + off); } } void mpoly_get_monomial_ffmpz_unpacked_ffmpz(fmpz * user_exps, const fmpz * poly_exps, const mpoly_ctx_t mctx) { slong i; /* poly_exps is already unpacked, just read of the correct fields */ for (i = 0; i < mctx->nvars; i++) { slong off = mctx->rev ? i : mctx->nvars - 1 - i; fmpz_set(user_exps + i, poly_exps + off); } } void mpoly_get_monomial_pfmpz_unpacked_ffmpz(fmpz ** user_exps, const fmpz * poly_exps, const mpoly_ctx_t mctx) { slong i; /* poly_exps is already unpacked, just read of the correct fields */ for (i = 0; i < mctx->nvars; i++) { slong off = mctx->rev ? i : mctx->nvars - 1 - i; fmpz_set(user_exps[i], poly_exps + off); } } void mpoly_get_monomial_ui_unpacked_ui(ulong * user_exps, const ulong * poly_exps, const mpoly_ctx_t mctx) { slong i; /* poly_exps is already unpacked, just read of the correct fields */ for (i = 0; i < mctx->nvars; i++) { slong off = mctx->rev ? i : mctx->nvars - 1 - i; user_exps[i] = poly_exps[off]; } } void mpoly_get_monomial_ui_sp(ulong * user_exps, const ulong * poly_exps, flint_bitcnt_t bits, const mpoly_ctx_t mctx) { slong nvars = mctx->nvars; slong i, shift; ulong u, mask = (-UWORD(1)) >> (FLINT_BITS - bits); ulong * exp1; const ulong * exp2; slong dir; FLINT_ASSERT(bits <= FLINT_BITS); exp2 = poly_exps; exp1 = user_exps + nvars - 1; dir = -WORD(1); if (mctx->rev) { exp1 = user_exps; dir = UWORD(1); } i = 0; u = *exp2++; shift = 0; *exp1 = u & mask; exp1 += dir; u = u >> bits; /* number of bits to encode 0th field */ shift += bits; /* number of bits to encode 0th field */ while (++i < nvars) { if (shift + bits > FLINT_BITS) { u = *exp2++; shift = 0; } *exp1 = u & mask; exp1 += dir; u = u >> bits; /* number of bits to encode ith field */ shift += bits; /* number of bits to encode ith field */ } } void mpoly_get_monomial_ui_mp(ulong * user_exps, const ulong * poly_exps, flint_bitcnt_t bits, const mpoly_ctx_t mctx) { slong nvars = mctx->nvars; slong i, j; ulong * exp1; const ulong * exp2; ulong words_per_field = bits/FLINT_BITS; ulong check_mask; slong dir; FLINT_ASSERT(bits%FLINT_BITS == 0); FLINT_ASSERT(bits > FLINT_BITS); exp2 = poly_exps; exp1 = user_exps + nvars - 1; dir = -WORD(1); if (mctx->rev) { exp1 = user_exps; dir = UWORD(1); } check_mask = 0; for (i = 0; i < nvars; i++) { *exp1 = *exp2; exp1 += dir; for (j = 1; j < words_per_field; j++) check_mask |= exp2[j]; exp2 += words_per_field; } if (check_mask != 0) flint_throw(FLINT_ERROR, "Exponent vector does not fit a ulong."); } void mpoly_get_monomial_si_mp(slong * user_exps, const ulong * poly_exps, flint_bitcnt_t bits, const mpoly_ctx_t mctx) { slong nvars = mctx->nvars; slong i, j; slong * exp1; const ulong * exp2; ulong words_per_field = bits/FLINT_BITS; ulong check_mask; slong dir; FLINT_ASSERT(bits%FLINT_BITS == 0); FLINT_ASSERT(bits > FLINT_BITS); exp2 = poly_exps; exp1 = user_exps + nvars - 1; dir = -WORD(1); if (mctx->rev) { exp1 = user_exps; dir = UWORD(1); } check_mask = 0; for (i = 0; i < nvars; i++) { *exp1 = (slong) *exp2; exp1 += dir; check_mask |= FLINT_SIGN_EXT(exp2[0]); for (j = 1; j < words_per_field; j++) check_mask |= exp2[j]; exp2 += words_per_field; } if (check_mask != 0) flint_throw(FLINT_ERROR, "Exponent vector does not fit an slong."); } void mpoly_get_monomial_ffmpz(fmpz * user_exps, const ulong * poly_exps, flint_bitcnt_t bits, const mpoly_ctx_t mctx) { slong i, nvars = mctx->nvars; fmpz * tmp_exps; TMP_INIT; TMP_START; tmp_exps = (fmpz *) TMP_ALLOC(mctx->nfields*sizeof(fmpz)); for (i = 0; i < mctx->nfields; i++) fmpz_init(tmp_exps + i); mpoly_unpack_vec_fmpz(tmp_exps, poly_exps, bits, mctx->nfields, 1); for (i = 0; i < nvars; i++) fmpz_swap(user_exps + i, tmp_exps + (mctx->rev ? i : nvars - 1 - i)); for (i = 0; i < mctx->nfields; i++) fmpz_clear(tmp_exps + i); TMP_END; } void mpoly_get_monomial_pfmpz(fmpz ** user_exps, const ulong * poly_exps, flint_bitcnt_t bits, const mpoly_ctx_t mctx) { slong i, nvars = mctx->nvars; fmpz * tmp_exps; TMP_INIT; TMP_START; tmp_exps = (fmpz *) TMP_ALLOC(mctx->nfields*sizeof(fmpz)); for (i = 0; i < mctx->nfields; i++) fmpz_init(tmp_exps + i); mpoly_unpack_vec_fmpz(tmp_exps, poly_exps, bits, mctx->nfields, 1); for (i = 0; i < nvars; i++) fmpz_swap(user_exps[i], tmp_exps + (mctx->rev ? i : nvars - 1 - i)); for (i = 0; i < mctx->nfields; i++) fmpz_clear(tmp_exps + i); TMP_END; }