/* Copyright (C) 2020 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 "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); } }