void fmpz_mod_poly_mul(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) { const slong len1 = poly1->length; const slong len2 = poly2->length; const slong lenr = len1 + len2 - 1; if ((len1 == 0) || (len2 == 0)) { fmpz_mod_poly_zero(res); return; } if ((res == poly1) || (res == poly2)) { fmpz *t = _fmpz_vec_init(lenr); if (len1 >= len2) _fmpz_mod_poly_mul(t, poly1->coeffs, len1, poly2->coeffs, len2, &(res->p)); else _fmpz_mod_poly_mul(t, poly2->coeffs, len2, poly1->coeffs, len1, &(res->p)); _fmpz_vec_clear(res->coeffs, res->alloc); res->alloc = lenr; res->length = lenr; res->coeffs = t; } else { fmpz_mod_poly_fit_length(res, lenr); if (len1 >= len2) _fmpz_mod_poly_mul(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, &(res->p)); else _fmpz_mod_poly_mul(res->coeffs, poly2->coeffs, len2, poly1->coeffs, len1, &(res->p)); _fmpz_mod_poly_set_length(res, lenr); } _fmpz_mod_poly_normalise(res); }
void fmpz_mod_poly_div_basecase(fmpz_mod_poly_t Q, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) { const long lenA = A->length, lenB = B->length, lenQ = lenA - lenB + 1; fmpz *q; fmpz_t invB; if (lenA < lenB) { fmpz_mod_poly_zero(Q); return; } fmpz_init(invB); fmpz_invmod(invB, B->coeffs + (lenB - 1), &(B->p)); if (Q == A || Q == B) { q = _fmpz_vec_init(lenQ); } else { fmpz_mod_poly_fit_length(Q, lenQ); q = Q->coeffs; } _fmpz_mod_poly_div_basecase(q, NULL, A->coeffs, lenA, B->coeffs, lenB, invB, &(B->p)); if (Q == A || Q == B) { _fmpz_vec_clear(Q->coeffs, Q->alloc); Q->coeffs = q; Q->alloc = lenQ; Q->length = lenQ; } else { _fmpz_mod_poly_set_length(Q, lenQ); } fmpz_clear(invB); }
void fmpz_mod_poly_shift_right(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly, long n) { if (n == 0) { fmpz_mod_poly_set(res, poly); return; } if (poly->length <= n) { fmpz_mod_poly_zero(res); return; } fmpz_mod_poly_fit_length(res, poly->length - n); _fmpz_mod_poly_shift_right(res->coeffs, poly->coeffs, poly->length, n); _fmpz_mod_poly_set_length(res, poly->length - n); }
void fmpz_mod_poly_compose_horner(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly1, const fmpz_mod_poly_t poly2) { const long len1 = poly1->length; const long len2 = poly2->length; if (len1 == 0) { fmpz_mod_poly_zero(res); } else if (len1 == 1 || len2 == 0) { fmpz_mod_poly_set_fmpz(res, poly1->coeffs); } else { const long lenr = (len1 - 1) * (len2 - 1) + 1; if ((res != poly1) && (res != poly2)) { fmpz_mod_poly_fit_length(res, lenr); _fmpz_mod_poly_compose_horner(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, &(res->p)); } else { fmpz *t = _fmpz_vec_init(lenr); _fmpz_mod_poly_compose_horner(t, poly1->coeffs, len1, poly2->coeffs, len2, &(res->p)); _fmpz_vec_clear(res->coeffs, res->alloc); res->coeffs = t; res->alloc = lenr; res->length = lenr; } _fmpz_mod_poly_set_length(res, lenr); _fmpz_mod_poly_normalise(res); } }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("zero...."); fflush(stdout); for (i = 0; i < 10000; i++) { fmpz_t p; fmpz_mod_poly_t a; fmpz_init(p); fmpz_randtest_unsigned(p, state, 2 * FLINT_BITS); fmpz_add_ui(p, p, 2); fmpz_mod_poly_init(a, p); fmpz_mod_poly_randtest(a, state, n_randint(state, 100)); fmpz_mod_poly_zero(a); result = (fmpz_mod_poly_is_zero(a)); if (!result) { flint_printf("FAIL:\n"); flint_printf("a = "), fmpz_mod_poly_print(a), flint_printf("\n\n"); abort(); } fmpz_mod_poly_clear(a); fmpz_clear(p); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void fmpz_mod_poly_make_monic(fmpz_mod_poly_t res, const fmpz_mod_poly_t poly) { const slong len = poly->length; fmpz_t inv; if (len == 0) { fmpz_mod_poly_zero(res); return; } fmpz_init(inv); fmpz_invmod(inv, fmpz_mod_poly_lead(poly), &(poly->p)); fmpz_mod_poly_fit_length(res, len); _fmpz_mod_poly_set_length(res, len); _fmpz_mod_poly_scalar_mul_fmpz(res->coeffs, poly->coeffs, len, inv, &(poly->p)); fmpz_clear(inv); }
void fmpz_mod_poly_divrem_f(fmpz_t f, fmpz_mod_poly_t Q, fmpz_mod_poly_t R, const fmpz_mod_poly_t A, const fmpz_mod_poly_t B) { const slong lenA = A->length; const slong lenB = B->length; const slong lenQ = lenA - lenB + 1; fmpz *q, *r; fmpz_t invB; fmpz_init(invB); fmpz_gcdinv(f, invB, fmpz_poly_lead(B), &(B->p)); if (!fmpz_is_one(f)) { fmpz_clear(invB); return; } if (lenA < lenB) { fmpz_mod_poly_set(R, A); fmpz_mod_poly_zero(Q); fmpz_clear(invB); return; } if (Q == A || Q == B) { q = _fmpz_vec_init(lenQ); } else { fmpz_mod_poly_fit_length(Q, lenQ); q = Q->coeffs; } if (R == A || R == B) { r = _fmpz_vec_init(lenA); } else { fmpz_mod_poly_fit_length(R, lenA); r = R->coeffs; } _fmpz_mod_poly_divrem_divconquer(q, r, A->coeffs, lenA, B->coeffs, lenB, invB, &(B->p)); if (Q == A || Q == B) { _fmpz_vec_clear(Q->coeffs, Q->alloc); Q->coeffs = q; Q->alloc = lenQ; Q->length = lenQ; } else { _fmpz_mod_poly_set_length(Q, lenQ); } if (R == A || R == B) { _fmpz_vec_clear(R->coeffs, R->alloc); R->coeffs = r; R->alloc = lenA; R->length = lenA; } _fmpz_mod_poly_set_length(R, lenB - 1); _fmpz_mod_poly_normalise(R); fmpz_clear(invB); }
int main(void) { int iter; FLINT_TEST_INIT(state); flint_printf("factor_squarefree...."); fflush(stdout); for (iter = 0; iter < 300; iter++) { int result = 1; fmpz_mod_poly_t pol1, poly, quot, rem; fmpz_mod_poly_factor_t res; fmpz_t modulus; slong exp[5], prod1; slong length, i, j, num; fmpz_init_set_ui(modulus, n_randtest_prime(state, 0)); fmpz_mod_poly_init(pol1, modulus); fmpz_mod_poly_init(poly, modulus); fmpz_mod_poly_init(quot, modulus); fmpz_mod_poly_init(rem, modulus); fmpz_mod_poly_zero(pol1); fmpz_mod_poly_set_coeff_ui(pol1, 0, 1); length = n_randint(state, 7) + 2; do { fmpz_mod_poly_randtest(poly, state, length); fmpz_mod_poly_make_monic(poly, poly); } while ((!fmpz_mod_poly_is_irreducible(poly)) || (poly->length < 2)); exp[0] = n_randprime(state, 5, 0); prod1 = exp[0]; for (i = 0; i < exp[0]; i++) fmpz_mod_poly_mul(pol1, pol1, poly); num = n_randint(state, 5) + 1; for (i = 1; i < num; i++) { do { length = n_randint(state, 7) + 2; fmpz_mod_poly_randtest(poly, state, length); if (poly->length) { fmpz_mod_poly_make_monic(poly, poly); fmpz_mod_poly_divrem(quot, rem, pol1, poly); } } while ((!fmpz_mod_poly_is_irreducible(poly)) || (poly->length < 2) || (rem->length == 0)); do exp[i] = n_randprime(state, 5, 0); while (prod1 % exp[i] == 0); prod1 *= exp[i]; for (j = 0; j < exp[i]; j++) fmpz_mod_poly_mul(pol1, pol1, poly); } fmpz_mod_poly_factor_init(res); fmpz_mod_poly_factor_squarefree(res, pol1); result &= (res->num == num); if (result) { ulong prod2 = 1; for (i = 0; i < num; i++) prod2 *= res->exp[i]; result &= (prod1 == prod2); } if (!result) { flint_printf("Error: exp don't match. Modulus = "); fmpz_print(modulus); flint_printf("\n"); for (i = 0; i < res->num; i++) flint_printf("%wd ", res->exp[i]); flint_printf("\n"); for (i = 0; i < num; i++) flint_printf("%wd ", exp[i]); flint_printf("\n"); abort(); } fmpz_clear(modulus); fmpz_mod_poly_clear(quot); fmpz_mod_poly_clear(rem); fmpz_mod_poly_clear(pol1); fmpz_mod_poly_clear(poly); fmpz_mod_poly_factor_clear(res); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }