void gmde_convert_soln(fmpz_poly_mat_t A, long *vA, const padic_mat_struct *C, long N, const fmpz_t p) { long i, j, k; fmpz_t s, t; assert(N > 0); assert(A->r == padic_mat(C)->r && A->c == padic_mat(C)->c); fmpz_init(s); fmpz_init(t); /* Find valuation */ *vA = LONG_MAX; for (k = 0; k < N; k++) *vA = FLINT_MIN(*vA, padic_mat_val(C + k)); fmpz_poly_mat_zero(A); for (k = N - 1; k >= 0; k--) { if (padic_mat_val(C + k) == *vA) { for (i = 0; i < A->r; i++) for (j = 0; j < A->c; j++) if (!fmpz_is_zero(padic_mat_entry(C + k, i, j))) fmpz_poly_set_coeff_fmpz(fmpz_poly_mat_entry(A, i, j), k, padic_mat_entry(C + k, i, j)); } else { fmpz_pow_ui(s, p, padic_mat_val(C + k) - *vA); for (i = 0; i < A->r; i++) for (j = 0; j < A->c; j++) if (!fmpz_is_zero(padic_mat_entry(C + k, i, j))) { fmpz_mul(t, s, padic_mat_entry(C + k, i, j)); fmpz_poly_set_coeff_fmpz(fmpz_poly_mat_entry(A, i, j), k, t); } } } fmpz_clear(s); fmpz_clear(t); }
void fmpz_poly_set_coeff_fmpz_n(fmpz_poly_t poly, slong n, const fmpz_t x) { if (x) fmpz_poly_set_coeff_fmpz(poly, n, x); else fmpz_poly_set_coeff_si(poly, n, 0); }
void poly_starmultiply(fmpz_poly_t c, const fmpz_poly_t a, const fmpz_poly_t b, const ntru_params *params, uint32_t modulus) { fmpz_poly_t a_tmp; fmpz_t c_coeff_k; fmpz_poly_init(a_tmp); fmpz_init(c_coeff_k); /* avoid side effects */ fmpz_poly_set(a_tmp, a); fmpz_poly_zero(c); for (int k = params->N - 1; k >= 0; k--) { int j; j = k + 1; fmpz_set_si(c_coeff_k, 0); for (int i = params->N - 1; i >= 0; i--) { fmpz *a_tmp_coeff_i, *b_coeff_j; if (j == (int)(params->N)) j = 0; a_tmp_coeff_i = fmpz_poly_get_coeff_ptr(a_tmp, i); b_coeff_j = fmpz_poly_get_coeff_ptr(b, j); if (fmpz_cmp_si_n(a_tmp_coeff_i, 0) && fmpz_cmp_si_n(b_coeff_j, 0)) { fmpz_t fmpz_tmp; fmpz_init(fmpz_tmp); fmpz_mul(fmpz_tmp, a_tmp_coeff_i, b_coeff_j); fmpz_add(fmpz_tmp, fmpz_tmp, c_coeff_k); fmpz_mod_ui(c_coeff_k, fmpz_tmp, modulus); fmpz_poly_set_coeff_fmpz(c, k, c_coeff_k); fmpz_clear(fmpz_tmp); } j++; } fmpz_clear(c_coeff_k); } fmpz_poly_clear(a_tmp); }
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; }
dgsl_rot_mp_t *dgsl_rot_mp_init(const long n, const fmpz_poly_t B, mpfr_t sigma, fmpq_poly_t c, const dgsl_alg_t algorithm, const oz_flag_t flags) { assert(mpfr_cmp_ui(sigma, 0) > 0); dgsl_rot_mp_t *self = (dgsl_rot_mp_t*)calloc(1, sizeof(dgsl_rot_mp_t)); if(!self) dgs_die("out of memory"); dgsl_alg_t alg = algorithm; self->n = n; self->prec = mpfr_get_prec(sigma); fmpz_poly_init(self->B); fmpz_poly_set(self->B, B); if(fmpz_poly_length(self->B) > n) dgs_die("polynomial is longer than length n"); else fmpz_poly_realloc(self->B, n); fmpz_poly_init(self->c_z); fmpq_poly_init(self->c); mpfr_init2(self->sigma, self->prec); mpfr_set(self->sigma, sigma, MPFR_RNDN); if (alg == DGSL_DETECT) { if (fmpz_poly_is_one(self->B) && (c && fmpq_poly_is_zero(c))) { alg = DGSL_IDENTITY; } else if (c && fmpq_poly_is_zero(c)) alg = DGSL_INLATTICE; else alg = DGSL_COSET; //TODO: we could test for lattice membership here } size_t tau = 3; if (2*ceil(sqrt(log2((double)n))) > tau) tau = 2*ceil(sqrt(log2((double)n))); switch(alg) { case DGSL_IDENTITY: { self->D = (dgs_disc_gauss_mp_t**)calloc(1, sizeof(dgs_disc_gauss_mp_t*)); mpfr_t c_; mpfr_init2(c_, self->prec); mpfr_set_d(c_, 0.0, MPFR_RNDN); self->D[0] = dgs_disc_gauss_mp_init(self->sigma, c_, tau, DGS_DISC_GAUSS_DEFAULT); self->call = dgsl_rot_mp_call_identity; mpfr_clear(c_); break; } case DGSL_GPV_INLATTICE: { self->D = (dgs_disc_gauss_mp_t**)calloc(n, sizeof(dgs_disc_gauss_mp_t*)); if (c && !fmpq_poly_is_zero(c)) { fmpq_t c_i; fmpq_init(c_i); for(int i=0; i<n; i++) { fmpq_poly_get_coeff_fmpq(c_i, c, i); fmpz_poly_set_coeff_fmpz(self->c_z, i, fmpq_numref(c_i)); } fmpq_clear(c_i); } mpfr_mat_t G; mpfr_mat_init(G, n, n, self->prec); mpfr_mat_set_fmpz_poly(G, B); mpfr_mat_gso(G, MPFR_RNDN); mpfr_t sigma_; mpfr_init2(sigma_, self->prec); mpfr_t norm; mpfr_init2(norm, self->prec); mpfr_t c_; mpfr_init2(c_, self->prec); mpfr_set_d(c_, 0.0, MPFR_RNDN); for(long i=0; i<n; i++) { _mpfr_vec_2norm(norm, G->rows[i], n, MPFR_RNDN); assert(mpfr_cmp_d(norm, 0.0) > 0); mpfr_div(sigma_, self->sigma, norm, MPFR_RNDN); assert(mpfr_cmp_d(sigma_, 0.0) > 0); self->D[i] = dgs_disc_gauss_mp_init(sigma_, c_, tau, DGS_DISC_GAUSS_DEFAULT); } mpfr_clear(sigma_); mpfr_clear(norm); mpfr_clear(c_); mpfr_mat_clear(G); self->call = dgsl_rot_mp_call_gpv_inlattice; break; } case DGSL_INLATTICE: { fmpq_poly_init(self->sigma_sqrt); long r= 2*ceil(sqrt(log(n))); fmpq_poly_t Bq; fmpq_poly_init(Bq); fmpq_poly_set_fmpz_poly(Bq, self->B); fmpq_poly_oz_invert_approx(self->B_inv, Bq, n, self->prec, flags); fmpq_poly_clear(Bq); _dgsl_rot_mp_sqrt_sigma_2(self->sigma_sqrt, self->B, sigma, r, n, self->prec, flags); mpfr_init2(self->r_f, self->prec); mpfr_set_ui(self->r_f, r, MPFR_RNDN); self->call = dgsl_rot_mp_call_inlattice; break; } case DGSL_COSET: dgs_die("not implemented"); default: dgs_die("not implemented"); } return self; }
void eis_series(fmpz_poly_t *eis, ulong k, ulong prec) { ulong i, p, ee, p_pow, ind; fmpz_t last, last_m1, mult, fp, t_coeff, term, term_m1; long bern_fac[15] = {0, 0, 0, 0, 240, 0, -504, 0, 480, 0, -264, 0, 0, 0, -24}; // Now, we compute the eisenstein series // First, compute primes by sieving. // allocate memory for the array. /* char *primes; primes = calloc(prec + 1, sizeof(char)); for(i = 0; i <= prec; i++) { primes[i] = 1; } primes[0] = 0; primes[1] = 0; p = 2; while(p*p <= prec) { j = p*p; while(j <= prec) { primes[j] = 0; j += p; } p += 1; while(primes[p] != 1) p += 1; } */ // Now, create the eisenstein series. // We build up each coefficient using the multiplicative properties of the // divisor sum function. fmpz_poly_set_coeff_si(*eis, 0, 1); for(i = 1; i <= prec; i++) fmpz_poly_set_coeff_si(*eis, i, bern_fac[k]); fmpz_init(last); fmpz_init(last_m1); fmpz_init(mult); fmpz_init(fp); fmpz_init(t_coeff); fmpz_init(term); fmpz_init(term_m1); ee = k - 1; p = 2; while(p <= prec) { p_pow = p; fmpz_set_ui(fp, p); fmpz_pow_ui(mult, fp, ee); fmpz_pow_ui(term, mult, 2); fmpz_set(last, mult); while(p_pow <= prec) { ind = p_pow; fmpz_sub_ui(term_m1, term, 1); fmpz_sub_ui(last_m1, last, 1); while(ind <= prec) { fmpz_poly_get_coeff_fmpz(t_coeff, *eis, ind); fmpz_mul(t_coeff, t_coeff, term_m1); fmpz_divexact(t_coeff, t_coeff, last_m1); fmpz_poly_set_coeff_fmpz(*eis, ind, t_coeff); ind += p_pow; } p_pow *= p; fmpz_set(last, term); fmpz_mul(term, term, mult); } p = n_nextprime(p, 1); } fmpz_clear(last); fmpz_clear(last_m1); fmpz_clear(mult); fmpz_clear(fp); fmpz_clear(t_coeff); fmpz_clear(term); fmpz_clear(term_m1); }
int test_jigsaw(const size_t lambda, const size_t kappa, int symmetric, aes_randstate_t randstate) { printf("λ: %4zu, κ: %2zu, symmetric: %d …", lambda, kappa, symmetric); gghlite_sk_t self; gghlite_flag_t flags = GGHLITE_FLAGS_QUIET; if (symmetric) gghlite_init(self, lambda, kappa, kappa, 0x0, flags | GGHLITE_FLAGS_GOOD_G_INV, randstate); else gghlite_jigsaw_init(self, lambda, kappa, flags, randstate); fmpz_t p; fmpz_init(p); fmpz_poly_oz_ideal_norm(p, self->g, self->params->n, 0); fmpz_t a[kappa]; fmpz_t acc; fmpz_init(acc); fmpz_set_ui(acc, 1); for(size_t k=0; k<kappa; k++) { fmpz_init(a[k]); fmpz_randm_aes(a[k], randstate, p); fmpz_mul(acc, acc, a[k]); fmpz_mod(acc, acc, p); } gghlite_clr_t e[kappa]; gghlite_enc_t u[kappa]; for(size_t k=0; k<kappa; k++) { gghlite_clr_init(e[k]); gghlite_enc_init(u[k], self->params); } gghlite_enc_t left; gghlite_enc_init(left, self->params); gghlite_enc_set_ui0(left, 1, self->params); for(size_t k=0; k<kappa; k++) { fmpz_poly_set_coeff_fmpz(e[k], 0, a[k]); const int i = (gghlite_sk_is_symmetric(self)) ? 0 : k; int group[GAMMA]; memset(group, 0, GAMMA * sizeof(int)); group[i] = 1; gghlite_enc_set_gghlite_clr(u[k], self, e[k], 1, group, 1); gghlite_enc_mul(left, self->params, left, u[k]); } gghlite_enc_t rght; gghlite_enc_init(rght, self->params); gghlite_enc_set_ui0(rght, 1, self->params); fmpz_poly_t tmp; fmpz_poly_init(tmp); fmpz_poly_set_coeff_fmpz(tmp, 0, acc); gghlite_enc_set_gghlite_clr0(rght, self, tmp); for(size_t k=0; k<kappa; k++) { const int i = (gghlite_sk_is_symmetric(self)) ? 0 : k; gghlite_enc_mul(rght, self->params, rght, self->z_inv[i]); } gghlite_enc_sub(rght, self->params, rght, left); int status = 1 - gghlite_enc_is_zero(self->params, rght); for(size_t i=0; i<kappa; i++) { fmpz_clear(a[i]); gghlite_clr_clear(e[i]); gghlite_enc_clear(u[i]); } gghlite_enc_clear(left); gghlite_enc_clear(rght); gghlite_clr_clear(tmp); fmpz_clear(p); gghlite_sk_clear(self, 1); if (status == 0) printf(" PASS\n"); else printf(" FAIL\n"); return status; }
/** * Testing the flexibility of large index sets with a smaller kappa */ int test_jigsaw_indices(const size_t lambda, const size_t kappa, const size_t gamma, aes_randstate_t randstate) { printf("lambda: %d, kappa: %d, gamma: %d", (int) lambda, (int) kappa, (int) gamma); gghlite_sk_t self; gghlite_flag_t flags = GGHLITE_FLAGS_QUIET; gghlite_jigsaw_init_gamma(self, lambda, kappa, gamma, flags, randstate); fmpz_t p; fmpz_init(p); fmpz_poly_oz_ideal_norm(p, self->g, self->params->n, 0); /* partitioning of the universe set */ int partition[GAMMA]; for (int i = 0; i < gamma; i++) { partition[i] = rand() % kappa; } fmpz_t a[kappa]; fmpz_t acc; fmpz_init(acc); fmpz_set_ui(acc, 1); for(size_t k=0; k<kappa; k++) { fmpz_init(a[k]); fmpz_randm_aes(a[k], randstate, p); fmpz_mul(acc, acc, a[k]); fmpz_mod(acc, acc, p); } gghlite_clr_t e[kappa]; gghlite_enc_t u[kappa]; for(size_t k=0; k<kappa; k++) { gghlite_clr_init(e[k]); gghlite_enc_init(u[k], self->params); } gghlite_enc_t left; gghlite_enc_init(left, self->params); gghlite_enc_set_ui0(left, 1, self->params); for(size_t k=0; k<kappa; k++) { fmpz_poly_set_coeff_fmpz(e[k], 0, a[k]); const int i = (gghlite_sk_is_symmetric(self)) ? 0 : k; int group[GAMMA]; memset(group, 0, GAMMA * sizeof(int)); for (int j = 0; j < gamma; j++) { if (partition[j] == k) { group[j] = 1; } } gghlite_enc_set_gghlite_clr(u[k], self, e[k], 1, group, 1); gghlite_enc_mul(left, self->params, left, u[k]); } gghlite_enc_t rght; gghlite_enc_init(rght, self->params); gghlite_enc_set_ui0(rght, 1, self->params); fmpz_poly_t tmp; fmpz_poly_init(tmp); fmpz_poly_set_coeff_fmpz(tmp, 0, acc); gghlite_enc_set_gghlite_clr0(rght, self, tmp); for(size_t k=0; k<gamma; k++) { gghlite_enc_mul(rght, self->params, rght, self->z_inv[k]); } gghlite_enc_sub(rght, self->params, rght, left); int status = 1 - gghlite_enc_is_zero(self->params, rght); for(size_t i=0; i<kappa; i++) { fmpz_clear(a[i]); gghlite_clr_clear(e[i]); gghlite_enc_clear(u[i]); } gghlite_enc_clear(left); gghlite_enc_clear(rght); gghlite_clr_clear(tmp); fmpz_clear(p); gghlite_sk_clear(self, 1); if (status == 0) printf(" PASS\n"); else printf(" FAIL\n"); return status; }
int main(int argc, char *argv[]) { cmdline_params_t cmdline_params; const char *name = "Jigsaw Puzzles"; parse_cmdline(cmdline_params, argc, argv, name, NULL); print_header(name, cmdline_params); aes_randstate_t randstate; aes_randinit_seed(randstate, cmdline_params->shaseed, NULL); uint64_t t = ggh_walltime(0); uint64_t t_total = ggh_walltime(0); uint64_t t_gen = 0; gghlite_sk_t self; gghlite_jigsaw_init(self, cmdline_params->lambda, cmdline_params->kappa, cmdline_params->flags, randstate); printf("\n"); gghlite_params_print(self->params); printf("\n---\n\n"); t_gen = ggh_walltime(t); printf("1. GGH InstGen wall time: %8.2f s\n", ggh_seconds(t_gen)); t = ggh_walltime(0); fmpz_t p; fmpz_init(p); fmpz_poly_oz_ideal_norm(p, self->g, self->params->n, 0); fmpz_t a[5]; for(long k=0; k<5; k++) fmpz_init(a[k]); fmpz_t acc; fmpz_init(acc); fmpz_set_ui(acc, 1); // reducing these elements to something small mod g is expensive, for benchmarketing purposes we // hence avoid this costly step most of the time by doing it only twice and by then computing the // remaining elements from those two elements using cheap operations. The reported times still // refer to the expensive step for fairness. fmpz_randm_aes(a[0], randstate, p); fmpz_mul(acc, acc, a[0]); fmpz_mod(acc, acc, p); fmpz_randm_aes(a[1], randstate, p); fmpz_mul(acc, acc, a[1]); fmpz_mod(acc, acc, p); fmpz_set(a[3], a[0]); fmpz_set(a[4], a[1]); for(long k=2; k<cmdline_params->kappa; k++) { fmpz_mul(a[2], a[0], a[1]); fmpz_add_ui(a[2], a[2], k); fmpz_mod(a[2], a[2], p); fmpz_mul(acc, acc, a[2]); fmpz_mod(acc, acc, p); fmpz_set(a[1], a[0]); fmpz_set(a[0], a[2]); } printf("2. Sampling from U(Z_p) wall time: %8.2f s\n", ggh_seconds(ggh_walltime(t))); gghlite_clr_t e[3]; gghlite_clr_init(e[0]); gghlite_clr_init(e[1]); gghlite_clr_init(e[2]); gghlite_enc_t u_k; gghlite_enc_init(u_k, self->params); gghlite_enc_t left; gghlite_enc_init(left, self->params); gghlite_enc_set_ui0(left, 1, self->params); fmpz_poly_set_coeff_fmpz(e[0], 0, a[3]); int GAMMA = 20; uint64_t t_enc = ggh_walltime(0); int group0[GAMMA]; memset(group0, 0, GAMMA * sizeof(int)); group0[0] = 1; gghlite_enc_set_gghlite_clr(u_k, self, e[0], 1, group0, 1, randstate); t_enc = ggh_walltime(t_enc); printf("3. Encoding wall time: %8.2f s (per elem)\n", ggh_seconds(t_enc)); fflush(0); uint64_t t_mul = 0; t = ggh_walltime(0); gghlite_enc_mul(left, self->params, left, u_k); t_mul += ggh_walltime(t); fmpz_poly_set_coeff_fmpz(e[1], 0, a[4]); int group1[GAMMA]; memset(group1, 0, GAMMA * sizeof(int)); group1[1] = 1; gghlite_enc_set_gghlite_clr(u_k, self, e[1], 1, group1, 1, randstate); t = ggh_walltime(0); gghlite_enc_mul(left, self->params, left, u_k); t_mul += ggh_walltime(t); const mp_bitcnt_t prec = (self->params->n/4 < 8192) ? 8192 : self->params->n/4; const oz_flag_t flags = (self->params->flags & GGHLITE_FLAGS_VERBOSE) ? OZ_VERBOSE : 0; _fmpz_poly_oz_rem_small_iter(e[0], e[0], self->g, self->params->n, self->g_inv, prec, flags); _fmpz_poly_oz_rem_small_iter(e[1], e[1], self->g, self->params->n, self->g_inv, prec, flags); for(long k=2; k<cmdline_params->kappa; k++) { fmpz_poly_oz_mul(e[2], e[0], e[1], self->params->n); assert(fmpz_poly_degree(e[2])>=0); fmpz_add_ui(e[2]->coeffs, e[2]->coeffs, k); _fmpz_poly_oz_rem_small_iter(e[2], e[2], self->g, self->params->n, self->g_inv, prec, flags); int groupk[GAMMA]; memset(groupk, 0, GAMMA * sizeof(int)); groupk[k] = 1; gghlite_enc_set_gghlite_clr(u_k, self, e[2], 1, groupk, 1, randstate); t = ggh_walltime(0); gghlite_enc_mul(left, self->params, left, u_k); t_mul += ggh_walltime(t); fmpz_poly_set(e[1], e[0]); fmpz_poly_set(e[0], e[2]); } printf("4. Multiplication wall time: %8.4f s\n", ggh_seconds(t_mul)); fflush(0); t = ggh_walltime(0); gghlite_enc_t rght; gghlite_enc_init(rght, self->params); gghlite_enc_set_ui0(rght, 1, self->params); fmpz_poly_t tmp; fmpz_poly_init(tmp); fmpz_poly_set_coeff_fmpz(tmp, 0, acc); gghlite_enc_set_gghlite_clr0(rght, self, tmp, randstate); for(long k=0; k<cmdline_params->kappa; k++) { gghlite_enc_mul(rght, self->params, rght, self->z_inv[k]); } printf("5. RHS generation wall time: %8.2f s\n", ggh_seconds(ggh_walltime(t))); t = ggh_walltime(0); gghlite_enc_sub(rght, self->params, rght, left); int status = 1 - gghlite_enc_is_zero(self->params, rght); gghlite_clr_t clr; gghlite_clr_init(clr); gghlite_enc_extract(clr, self->params, rght); double size = fmpz_poly_2norm_log2(clr); gghlite_clr_clear(clr); printf("6. Checking correctness wall time: %8.2f s\n", ggh_seconds(ggh_walltime(t))); printf(" Correct: %8s (%8.2f)\n\n", (status == 0) ? "TRUE" : "FALSE", size); for(long i=0; i<5; i++) { fmpz_clear(a[i]); } gghlite_clr_clear(e[0]); gghlite_clr_clear(e[1]); gghlite_clr_clear(e[2]); gghlite_enc_clear(u_k); fmpz_clear(acc); gghlite_enc_clear(left); gghlite_enc_clear(rght); gghlite_clr_clear(tmp); fmpz_clear(p); gghlite_sk_clear(self, 1); t_total = ggh_walltime(t_total); printf("λ: %3ld, κ: %2ld, n: %6ld, seed: 0x%08lx, success: %d, gen: %10.2fs, enc: %8.2fs, mul: %8.4fs, time: %10.2fs\n", cmdline_params->lambda, cmdline_params->kappa, self->params->n, cmdline_params->seed, status==0, ggh_seconds(t_gen), ggh_seconds(t_enc), ggh_seconds(t_mul), ggh_seconds(t_total)); aes_randclear(randstate); mpfr_free_cache(); flint_cleanup(); return status; }
int main(void) { int i; FLINT_TEST_INIT(state); flint_printf("taylor_shift_divconquer...."); fflush(stdout); /* Check aliasing */ for (i = 0; i < 100 * flint_test_multiplier(); i++) { fmpz_poly_t f, g; fmpz_t c; fmpz_poly_init(f); fmpz_poly_init(g); fmpz_init(c); fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), 1 + n_randint(state, 200)); fmpz_randtest(c, state, n_randint(state, 200)); fmpz_poly_taylor_shift_divconquer(g, f, c); fmpz_poly_taylor_shift_divconquer(f, f, c); if (!fmpz_poly_equal(g, f)) { flint_printf("FAIL\n"); fmpz_poly_print(f); flint_printf("\n"); fmpz_poly_print(g); flint_printf("\n"); abort(); } fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_clear(c); } /* Compare with composition */ for (i = 0; i < 100 * flint_test_multiplier(); i++) { fmpz_poly_t f, g, h1, h2; fmpz_t c; fmpz_poly_init(f); fmpz_poly_init(g); fmpz_poly_init(h1); fmpz_poly_init(h2); fmpz_init(c); fmpz_poly_randtest(f, state, 1 + n_randint(state, 20), 1 + n_randint(state, 200)); fmpz_randtest(c, state, n_randint(state, 200)); fmpz_poly_set_coeff_ui(g, 1, 1); fmpz_poly_set_coeff_fmpz(g, 0, c); fmpz_poly_taylor_shift_divconquer(h1, f, c); fmpz_poly_compose(h2, f, g); if (!fmpz_poly_equal(h1, h2)) { flint_printf("FAIL\n"); fmpz_poly_print(f); flint_printf("\n"); fmpz_poly_print(g); flint_printf("\n"); fmpz_poly_print(h1); flint_printf("\n"); fmpz_poly_print(h2); flint_printf("\n"); abort(); } fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_poly_clear(h1); fmpz_poly_clear(h2); fmpz_clear(c); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
int main(int argc, char *argv[]) { fmpz_poly_t f, g; fmpz_poly_factor_t fac; fmpz_t t; slong compd, printd, i, j; if (argc < 2) { flint_printf("poly_roots [-refine d] [-print d] <poly>\n\n"); flint_printf("Isolates all the complex roots of a polynomial with integer coefficients.\n\n"); flint_printf("If -refine d is passed, the roots are refined to an absolute tolerance\n"); flint_printf("better than 10^(-d). By default, the roots are only computed to sufficient\n"); flint_printf("accuracy to isolate them. The refinement is not currently done efficiently.\n\n"); flint_printf("If -print d is passed, the computed roots are printed to d decimals.\n"); flint_printf("By default, the roots are not printed.\n\n"); flint_printf("The polynomial can be specified by passing the following as <poly>:\n\n"); flint_printf("a <n> Easy polynomial 1 + 2x + ... + (n+1)x^n\n"); flint_printf("t <n> Chebyshev polynomial T_n\n"); flint_printf("u <n> Chebyshev polynomial U_n\n"); flint_printf("p <n> Legendre polynomial P_n\n"); flint_printf("c <n> Cyclotomic polynomial Phi_n\n"); flint_printf("s <n> Swinnerton-Dyer polynomial S_n\n"); flint_printf("b <n> Bernoulli polynomial B_n\n"); flint_printf("w <n> Wilkinson polynomial W_n\n"); flint_printf("e <n> Taylor series of exp(x) truncated to degree n\n"); flint_printf("m <n> <m> The Mignotte-like polynomial x^n + (100x+1)^m, n > m\n"); flint_printf("coeffs <c0 c1 ... cn> c0 + c1 x + ... + cn x^n\n\n"); flint_printf("Concatenate to multiply polynomials, e.g.: p 5 t 6 coeffs 1 2 3\n"); flint_printf("for P_5(x)*T_6(x)*(1+2x+3x^2)\n\n"); return 1; } compd = 0; printd = 0; fmpz_poly_init(f); fmpz_poly_init(g); fmpz_init(t); fmpz_poly_one(f); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-refine")) { compd = atol(argv[i+1]); i++; } else if (!strcmp(argv[i], "-print")) { printd = atol(argv[i+1]); i++; } else if (!strcmp(argv[i], "a")) { slong n = atol(argv[i+1]); fmpz_poly_zero(g); for (j = 0; j <= n; j++) fmpz_poly_set_coeff_ui(g, j, j+1); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "t")) { arith_chebyshev_t_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "u")) { arith_chebyshev_u_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "p")) { fmpq_poly_t h; fmpq_poly_init(h); arith_legendre_polynomial(h, atol(argv[i+1])); fmpq_poly_get_numerator(g, h); fmpz_poly_mul(f, f, g); fmpq_poly_clear(h); i++; } else if (!strcmp(argv[i], "c")) { arith_cyclotomic_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "s")) { arith_swinnerton_dyer_polynomial(g, atol(argv[i+1])); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "b")) { fmpq_poly_t h; fmpq_poly_init(h); arith_bernoulli_polynomial(h, atol(argv[i+1])); fmpq_poly_get_numerator(g, h); fmpz_poly_mul(f, f, g); fmpq_poly_clear(h); i++; } else if (!strcmp(argv[i], "w")) { slong n = atol(argv[i+1]); fmpz_poly_zero(g); fmpz_poly_fit_length(g, n+2); arith_stirling_number_1_vec(g->coeffs, n+1, n+2); _fmpz_poly_set_length(g, n+2); fmpz_poly_shift_right(g, g, 1); fmpz_poly_mul(f, f, g); i++; } else if (!strcmp(argv[i], "e")) { fmpq_poly_t h; fmpq_poly_init(h); fmpq_poly_set_coeff_si(h, 0, 0); fmpq_poly_set_coeff_si(h, 1, 1); fmpq_poly_exp_series(h, h, atol(argv[i+1]) + 1); fmpq_poly_get_numerator(g, h); fmpz_poly_mul(f, f, g); fmpq_poly_clear(h); i++; } else if (!strcmp(argv[i], "m")) { fmpz_poly_zero(g); fmpz_poly_set_coeff_ui(g, 0, 1); fmpz_poly_set_coeff_ui(g, 1, 100); fmpz_poly_pow(g, g, atol(argv[i+2])); fmpz_poly_set_coeff_ui(g, atol(argv[i+1]), 1); fmpz_poly_mul(f, f, g); i += 2; } else if (!strcmp(argv[i], "coeffs")) { fmpz_poly_zero(g); i++; j = 0; while (i < argc) { if (fmpz_set_str(t, argv[i], 10) != 0) { i--; break; } fmpz_poly_set_coeff_fmpz(g, j, t); i++; j++; } fmpz_poly_mul(f, f, g); } } fmpz_poly_factor_init(fac); flint_printf("computing squarefree factorization...\n"); TIMEIT_ONCE_START fmpz_poly_factor_squarefree(fac, f); TIMEIT_ONCE_STOP TIMEIT_ONCE_START for (i = 0; i < fac->num; i++) { flint_printf("roots with multiplicity %wd\n", fac->exp[i]); fmpz_poly_complex_roots_squarefree(fac->p + i, 32, compd * 3.32193 + 2, printd); } TIMEIT_ONCE_STOP fmpz_poly_factor_clear(fac); fmpz_poly_clear(f); fmpz_poly_clear(g); fmpz_clear(t); flint_cleanup(); return EXIT_SUCCESS; }