void target(void* y, unsigned long count) { arg_t* arg = (arg_t*) y; mpz_t x; mpz_init(x); mpz_poly_t in1, in2, out; mpz_poly_init(in1); mpz_poly_init(in2); mpz_poly_init(out); fmpz_poly_t in1f, in2f, outf; fmpz_poly_init2(in1f, arg->length1, (arg->bits1-1)/FLINT_BITS+1); fmpz_poly_init2(in2f, arg->length2, (arg->bits2-1)/FLINT_BITS+1); _fmpz_poly_stack_init(outf, arg->length1 + arg->length2 - 1, in1f->limbs + in2f->limbs + 1); for (unsigned long i = 0; i < arg->length1; i++) { mpz_urandomb(x, randstate, arg->bits1); mpz_poly_set_coeff(in1, i, x); } mpz_poly_to_fmpz_poly(in1f, in1); for (unsigned long i = 0; i < arg->length2; i++) { mpz_urandomb(x, randstate, arg->bits2); mpz_poly_set_coeff(in2, i, x); } mpz_poly_to_fmpz_poly(in2f, in2); start_clock(0); if (arg->which) { for (unsigned long i = 0; i < count; i++) _fmpz_poly_mul_karatsuba(outf, in1f, in2f); } else { for (unsigned long i = 0; i < count; i++) mpz_poly_mul_karatsuba(out, in1, in2); } stop_clock(0); _fmpz_poly_stack_clear(outf); fmpz_poly_clear(in2f); fmpz_poly_clear(in1f); mpz_poly_clear(out); mpz_poly_clear(in2); mpz_poly_clear(in1); mpz_clear(x); }
void fmpz_poly_sqr_classical(fmpz_poly_t rop, const fmpz_poly_t op) { long len; if (op->length == 0) { fmpz_poly_zero(rop); return; } len = 2 * op->length - 1; if (rop == op) { fmpz_poly_t t; fmpz_poly_init2(t, len); _fmpz_poly_sqr_classical(t->coeffs, op->coeffs, op->length); fmpz_poly_swap(rop, t); fmpz_poly_clear(t); } else { fmpz_poly_fit_length(rop, len); _fmpz_poly_sqr_classical(rop->coeffs, op->coeffs, op->length); } _fmpz_poly_set_length(rop, len); }
void fmpz_poly_mulhigh_classical(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, long start) { long len_out = poly1->length + poly2->length - 1; if (poly1->length == 0 || poly2->length == 0 || start >= len_out) { fmpz_poly_zero(res); return; } if (res == poly1 || res == poly2) { fmpz_poly_t temp; fmpz_poly_init2(temp, len_out); _fmpz_poly_mulhigh_classical(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, start); fmpz_poly_swap(res, temp); fmpz_poly_clear(temp); } else { fmpz_poly_fit_length(res, len_out); _fmpz_poly_mulhigh_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, start); } _fmpz_poly_set_length(res, len_out); }
void fmpz_poly_mullow_KS(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, long n) { const long len1 = poly1->length; const long len2 = poly2->length; if (len1 == 0 || len2 == 0 || n == 0) { fmpz_poly_zero(res); return; } if (res == poly1 || res == poly2) { fmpz_poly_t t; fmpz_poly_init2(t, n); fmpz_poly_mullow_KS(t, poly1, poly2, n); fmpz_poly_swap(res, t); fmpz_poly_clear(t); return; } fmpz_poly_fit_length(res, n); if (len1 >= len2) _fmpz_poly_mullow_KS(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, n); else _fmpz_poly_mullow_KS(res->coeffs, poly2->coeffs, len2, poly1->coeffs, len1, n); _fmpz_poly_set_length(res, n); _fmpz_poly_normalise(res); }
void fmpz_poly_mulmid_classical(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2) { slong len_out; if (poly1->length == 0 || poly2->length == 0) { fmpz_poly_zero(res); return; } len_out = poly1->length - poly2->length + 1; if (res == poly1 || res == poly2) { fmpz_poly_t temp; fmpz_poly_init2(temp, len_out); _fmpz_poly_mulmid_classical(temp->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length); fmpz_poly_swap(res, temp); fmpz_poly_clear(temp); } else { fmpz_poly_fit_length(res, len_out); _fmpz_poly_mulmid_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length); } _fmpz_poly_set_length(res, len_out); _fmpz_poly_normalise(res); }
void fmpz_poly_sqrlow(fmpz_poly_t res, const fmpz_poly_t poly, long n) { const long len = poly->length; if (len == 0 || n == 0) { fmpz_poly_zero(res); return; } if (res == poly) { fmpz_poly_t t; fmpz_poly_init2(t, n); fmpz_poly_sqrlow(t, poly, n); fmpz_poly_swap(res, t); fmpz_poly_clear(t); return; } n = FLINT_MIN(2 * len - 1, n); fmpz_poly_fit_length(res, n); _fmpz_poly_sqrlow(res->coeffs, poly->coeffs, len, n); _fmpz_poly_set_length(res, n); _fmpz_poly_normalise(res); }
void fmpz_poly_mullow_classical(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, long n) { long len_out; if (poly1->length == 0 || poly2->length == 0 || n == 0) { fmpz_poly_zero(res); return; } len_out = poly1->length + poly2->length - 1; if (n > len_out) n = len_out; if (res == poly1 || res == poly2) { fmpz_poly_t t; fmpz_poly_init2(t, n); _fmpz_poly_mullow_classical(t->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n); fmpz_poly_swap(res, t); fmpz_poly_clear(t); } else { fmpz_poly_fit_length(res, n); _fmpz_poly_mullow_classical(res->coeffs, poly1->coeffs, poly1->length, poly2->coeffs, poly2->length, n); } _fmpz_poly_set_length(res, n); _fmpz_poly_normalise(res); }
int main(void) { int i; flint_rand_t state; printf("init/init2/realloc/clear...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 10000; i++) { fmpz_poly_t a; fmpz_poly_init2(a, n_randint(state, 100)); fmpz_poly_clear(a); } for (i = 0; i < 10000; i++) { fmpz_poly_t a; fmpz_poly_init2(a, n_randint(state, 100)); fmpz_poly_realloc(a, n_randint(state, 100)); fmpz_poly_clear(a); } for (i = 0; i < 10000; i++) { fmpz_poly_t a; fmpz_poly_init(a); fmpz_poly_randtest(a, state, n_randint(state, 100), 200); fmpz_poly_clear(a); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return 0; }
explicit FlintZZX(const ZZX& a) { long da = deg(a); fmpz_poly_init2(value, da+1); for (long i = 0; i <= da; i++) { FlintZZ f_c(a[i]); fmpz_poly_set_coeff_fmpz(value, i, f_c.value); } }
fmpz_poly_ptr to_fmpz_poly(const Tuple& x){ uint n=x.size-1; fmpz_poly_ptr y = new fmpz_poly_struct; fmpz_poly_init2(y,n); fmpz_t temp; fmpz_init(temp); for(uint i=0;i<n;i++){ fmpz_set_mpz(temp,x[i+1].cast<Integer>().mpz); fmpz_poly_set_coeff_fmpz(y,i,temp); } return y; }
void fmpz_poly_revert_series_lagrange(fmpz_poly_t Qinv, const fmpz_poly_t Q, slong n) { fmpz *Qcopy; int Qalloc; slong Qlen = Q->length; if (Qlen < 2 || !fmpz_is_zero(Q->coeffs) || !fmpz_is_pm1(Q->coeffs + 1)) { flint_printf("Exception (fmpz_poly_revert_series_lagrange). Input must have \n" "zero constant term and +1 or -1 as coefficient of x^1.\n"); abort(); } if (Qlen >= n) { Qcopy = Q->coeffs; Qalloc = 0; } else { slong i; Qcopy = (fmpz *) flint_malloc(n * sizeof(fmpz)); for (i = 0; i < Qlen; i++) Qcopy[i] = Q->coeffs[i]; for ( ; i < n; i++) Qcopy[i] = 0; Qalloc = 1; } if (Qinv != Q) { fmpz_poly_fit_length(Qinv, n); _fmpz_poly_revert_series_lagrange(Qinv->coeffs, Qcopy, n); } else { fmpz_poly_t t; fmpz_poly_init2(t, n); _fmpz_poly_revert_series_lagrange(t->coeffs, Qcopy, n); fmpz_poly_swap(Qinv, t); fmpz_poly_clear(t); } _fmpz_poly_set_length(Qinv, n); _fmpz_poly_normalise(Qinv); if (Qalloc) flint_free(Qcopy); }
void fmpz_poly_compose_series(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2, long n) { long len1 = poly1->length; long len2 = poly2->length; long lenr; if (len2 != 0 && !fmpz_is_zero(poly2->coeffs)) { printf("exception: fmpz_poly_compose_series: inner polynomial " "must have zero constant term\n"); abort(); } if (len1 == 0 || n == 0) { fmpz_poly_zero(res); return; } if (len2 == 0 || len1 == 1) { fmpz_poly_set_fmpz(res, poly1->coeffs); return; } lenr = FLINT_MIN((len1 - 1) * (len2 - 1) + 1, n); len1 = FLINT_MIN(len1, lenr); len2 = FLINT_MIN(len2, lenr); if ((res != poly1) && (res != poly2)) { fmpz_poly_fit_length(res, lenr); _fmpz_poly_compose_series(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr); _fmpz_poly_set_length(res, lenr); _fmpz_poly_normalise(res); } else { fmpz_poly_t t; fmpz_poly_init2(t, lenr); _fmpz_poly_compose_series(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2, lenr); _fmpz_poly_set_length(t, lenr); _fmpz_poly_normalise(t); fmpz_poly_swap(res, t); fmpz_poly_clear(t); } }
void fmpz_poly_pow_multinomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) { const long len = poly->length; long rlen; if ((len < 2) | (e < 3UL)) { if (e == 0UL) fmpz_poly_set_ui(res, 1); else if (len == 0) fmpz_poly_zero(res); else if (len == 1) { fmpz_poly_fit_length(res, 1); fmpz_pow_ui(res->coeffs, poly->coeffs, e); _fmpz_poly_set_length(res, 1); } else if (e == 1UL) fmpz_poly_set(res, poly); else /* e == 2UL */ fmpz_poly_sqr(res, poly); return; } rlen = (long) e * (len - 1) + 1; if (res != poly) { fmpz_poly_fit_length(res, rlen); _fmpz_poly_pow_multinomial(res->coeffs, poly->coeffs, len, e); _fmpz_poly_set_length(res, rlen); } else { fmpz_poly_t t; fmpz_poly_init2(t, rlen); _fmpz_poly_pow_multinomial(t->coeffs, poly->coeffs, len, e); _fmpz_poly_set_length(t, rlen); fmpz_poly_swap(res, t); fmpz_poly_clear(t); } }
void fmpz_poly_pow_binomial(fmpz_poly_t res, const fmpz_poly_t poly, ulong e) { const long len = poly->length; long rlen; if (len != 2) { printf("Exception: poly->length not equal to 2 in fmpz_poly_pow_binomial\n"); abort(); } if (e < 3UL) { if (e == 0UL) fmpz_poly_set_ui(res, 1UL); else if (e == 1UL) fmpz_poly_set(res, poly); else /* e == 2UL */ fmpz_poly_sqr(res, poly); return; } rlen = (long) e + 1; if (res != poly) { fmpz_poly_fit_length(res, rlen); _fmpz_poly_set_length(res, rlen); _fmpz_poly_pow_binomial(res->coeffs, poly->coeffs, e); } else { fmpz_poly_t t; fmpz_poly_init2(t, rlen); _fmpz_poly_set_length(t, rlen); _fmpz_poly_pow_binomial(t->coeffs, poly->coeffs, e); fmpz_poly_swap(res, t); fmpz_poly_clear(t); } }
void fmpz_poly_compose_divconquer(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2) { const long len1 = poly1->length; const long len2 = poly2->length; long lenr; if (len1 == 0) { fmpz_poly_zero(res); return; } if (len1 == 1 || len2 == 0) { fmpz_poly_set_fmpz(res, poly1->coeffs); return; } lenr = (len1 - 1) * (len2 - 1) + 1; if (res != poly1 && res != poly2) { fmpz_poly_fit_length(res, lenr); _fmpz_poly_compose_divconquer(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2); _fmpz_poly_set_length(res, lenr); _fmpz_poly_normalise(res); } else { fmpz_poly_t t; fmpz_poly_init2(t, lenr); _fmpz_poly_compose_divconquer(t->coeffs, poly1->coeffs, len1, poly2->coeffs, len2); _fmpz_poly_set_length(t, lenr); _fmpz_poly_normalise(t); fmpz_poly_swap(res, t); fmpz_poly_clear(t); } }
void fmpz_poly_divrem_divconquer(fmpz_poly_t Q, fmpz_poly_t R, const fmpz_poly_t A, const fmpz_poly_t B) { const long lenA = A->length; const long lenB = B->length; fmpz_poly_t tQ, tR; fmpz *q, *r; if (lenB == 0) { printf("Exception: division by zero in fmpz_poly_divrem_divconquer\n"); abort(); } if (lenA < lenB) { fmpz_poly_set(R, A); fmpz_poly_zero(Q); return; } if (Q == A || Q == B) { fmpz_poly_init2(tQ, lenA - lenB + 1); q = tQ->coeffs; } else { fmpz_poly_fit_length(Q, lenA - lenB + 1); q = Q->coeffs; } if (R == A || R == B) { fmpz_poly_init2(tR, lenA); r = tR->coeffs; } else { fmpz_poly_fit_length(R, lenA); r = R->coeffs; } _fmpz_poly_divrem_divconquer(q, r, A->coeffs, lenA, B->coeffs, lenB); if (Q == A || Q == B) { _fmpz_poly_set_length(tQ, lenA - lenB + 1); fmpz_poly_swap(tQ, Q); fmpz_poly_clear(tQ); } else _fmpz_poly_set_length(Q, lenA - lenB + 1); if (R == A || R == B) { _fmpz_poly_set_length(tR, lenA); fmpz_poly_swap(tR, R); fmpz_poly_clear(tR); } else _fmpz_poly_set_length(R, lenA); _fmpz_poly_normalise(Q); _fmpz_poly_normalise(R); }
int fmpz_poly_gcd_heuristic(fmpz_poly_t res, const fmpz_poly_t poly1, const fmpz_poly_t poly2) { const long len1 = poly1->length; const long len2 = poly2->length; long rlen; int done = 0; if (len1 == 0) { if (len2 == 0) fmpz_poly_zero(res); else { if (fmpz_sgn(poly2->coeffs + (len2 - 1)) > 0) fmpz_poly_set(res, poly2); else fmpz_poly_neg(res, poly2); } return 1; } else { if (len2 == 0) { if (fmpz_sgn(poly1->coeffs + (len1 - 1)) > 0) fmpz_poly_set(res, poly1); else fmpz_poly_neg(res, poly1); return 1; } } rlen = FLINT_MIN(len1, len2); if (res == poly1 || res == poly2) { fmpz_poly_t temp; fmpz_poly_init2(temp, rlen); if (len1 >= len2) done = _fmpz_poly_gcd_heuristic(temp->coeffs, poly1->coeffs, len1, poly2->coeffs, len2); else done = _fmpz_poly_gcd_heuristic(temp->coeffs, poly2->coeffs, len2, poly1->coeffs, len1); fmpz_poly_swap(temp, res); fmpz_poly_clear(temp); } else { fmpz_poly_fit_length(res, rlen); if (len1 >= len2) done = _fmpz_poly_gcd_heuristic(res->coeffs, poly1->coeffs, len1, poly2->coeffs, len2); else done = _fmpz_poly_gcd_heuristic(res->coeffs, poly2->coeffs, len2, poly1->coeffs, len1); } if (done) { _fmpz_poly_set_length(res, rlen); _fmpz_poly_normalise(res); } return done; }
int main(void) { int i, j, len1, len2; int X[rows][cols]; double T[rows][cols][nalgs]; fmpz_poly_t f, g, h; flint_rand_t state; flint_randinit(state); fmpz_poly_init2(f, len1hi); fmpz_poly_init2(g, len2hi); fmpz_poly_init2(h, (len1hi-1) * (len2hi-1) + 1); for (len1 = len1lo, j = 0; len1 <= len1hi; len1 += len1h, j++) { long s[nalgs]; for (len2 = len2lo, i = 0; len2 <= len2hi; len2 += len2h, i++) { int c, n, reps = 0; for (c = 0; c < nalgs; c++) s[c] = 0L; for (n = 0; n < ncases; n++) { timeit_t t[nalgs]; int l, loops = 1; /* Construct random polynomials f and g */ { long k; for (k = 0; k < len1; k++) fmpz_randbits(f->coeffs + k, state, bits); if ((f->coeffs)[len1-1] == 0L) fmpz_randtest_not_zero(f->coeffs + (len1 - 1), state, bits); f->length = len1; } { long k; for (k = 0; k < len2; k++) fmpz_randbits(g->coeffs + k, state, bits); if ((g->coeffs)[len2-1] == 0L) fmpz_randtest_not_zero(g->coeffs + (len2 - 1), state, bits); g->length = len2; } loop: timeit_start(t[0]); for (l = 0; l < loops; l++) fmpz_poly_compose_horner(h, f, g); timeit_stop(t[0]); timeit_start(t[1]); for (l = 0; l < loops; l++) fmpz_poly_compose_divconquer(h, f, g); timeit_stop(t[1]); for (c = 0; c < nalgs; c++) if (t[c]->cpu <= cpumin) { loops *= 10; goto loop; } for (c = 0; c < nalgs; c++) s[c] += t[c]->cpu; reps += loops; } for (c = 0; c < nalgs; c++) T[i][j][c] = s[c] / (double) reps; if (s[0] <= s[1]) X[i][j] = 0; else X[i][j] = 1; } printf("len1 = %d, time = %ldms\n", len1, s[0] + s[1]), fflush(stdout); } fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_poly_clear(h); /* Print 2-D ASCII image of the winning algorithms */ for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) printf("%d", X[i][j]); printf("\n"); } flint_randclear(state); }