void F_mpz_mod_poly_init(F_mpz_mod_poly_t poly, const F_mpz_t P) { poly->coeffs = NULL; F_mpz_init(poly->P); F_mpz_set(poly->P, P); poly->alloc = 0; poly->length = 0; }
void F_mpz_mod_poly_init2(F_mpz_mod_poly_t poly, const F_mpz_t P, const ulong alloc) { if (alloc) // allocate space for alloc small coeffs { poly->coeffs = (F_mpz *) flint_heap_alloc(alloc); F_mpn_clear(poly->coeffs, alloc); } else poly->coeffs = NULL; F_mpz_init(poly->P); F_mpz_set(poly->P, P); poly->alloc = alloc; poly->length = 0; }
void F_mpzmod_mat_init(F_mpzmod_mat_t mat, F_mpz_t p, ulong rows, ulong cols) { mat->entries = (F_mpz *) flint_heap_alloc(rows*cols); mat->rows = (F_mpz **) flint_heap_alloc(rows); // Set up the rows for (ulong i = 0; i < rows; i++) mat->rows[i] = mat->entries + i*cols; for (ulong i = 0; i < rows*cols; i++) F_mpz_init(mat->entries + i); F_mpz_set(mat->p, p); mat->r = rows; mat->c = cols; }
void F_mpzmod_mat_mul_classical(F_mpzmod_mat_t res, F_mpzmod_mat_t mat1, F_mpzmod_mat_t mat2) { ulong c1 = mat1->c; ulong r2 = mat2->r; if ((c1 != r2) || (c1 == 0)) { printf("FLINT exception : invalid matrix multiplication!\n"); abort(); } ulong r1 = mat1->r; ulong c2 = mat2->c; if ((r1 == 0) || (c2 == 0)) return; // no work to do F_mpz * temp = (F_mpz *) flint_heap_alloc(c2); for (ulong i = 0; i < c2; i++) F_mpz_init(temp + i); for (ulong i = 0; i < r1; i++) // for each row of mat1 { F_mpz * c = mat1->rows[i]; for (ulong k = 0; k < c2; k++) // do initial scalar product of row 1 of mat2 by c F_mpz_mul2(temp + k, mat2->rows[0] + k, c); for (ulong j = 1; j < c1; j++) // compute scalar product for rows 1 to c1 of mat2 { for (ulong k = 0; k < c2; k++) // do scalar product of row j of mat2 by c { F_mpz_addmul(temp + k, mat2->rows[j] + k, c + j); } } for (ulong k = 0; k < c2; k++) // do reduction mod p and store in result { F_mpz_mod(res->rows[i] + k, temp + k, mat1->p); } } for (ulong i = 0; i < c2; i++) F_mpz_clear(temp + i); flint_heap_free(temp); }
void F_mpz_mod_poly_make_monic(F_mpz_mod_poly_t output, F_mpz_mod_poly_t pol) { if (!pol->length) { output->length = 0; return; } F_mpz_t *lead_coeff = (F_mpz_t *)&pol->coeffs[pol->length-1]; if (F_mpz_is_one(*lead_coeff)) { F_mpz_mod_poly_set(output, pol); return; } F_mpz_t lead_inv; F_mpz_init(lead_inv); F_mpz_invert(lead_inv, *lead_coeff, pol->P); F_mpz_mod_poly_scalar_mul(output, pol, lead_inv); }
void F_mpz_mod_poly_divrem_basecase(F_mpz_mod_poly_t Q, F_mpz_mod_poly_t R, const F_mpz_mod_poly_t A, const F_mpz_mod_poly_t B) { if (B->length == 0) { printf("Error: Divide by zero\n"); abort(); } if (A->length < B->length) { F_mpz_mod_poly_set(R, A); F_mpz_mod_poly_zero(Q); return; } F_mpz_t lead_inv; F_mpz_init(lead_inv); F_mpz_invert(lead_inv, B->coeffs + B->length - 1, B->P); F_mpz * coeff_Q; F_mpz_mod_poly_t qB; F_mpz_mod_poly_init2(qB, B->P, B->length); F_mpz_mod_poly_t Bm1; _F_mpz_mod_poly_attach_truncate(Bm1, B, B->length - 1); long coeff = A->length - 1; F_mpz_mod_poly_set(R, A); if (A->length >= B->length) { F_mpz_mod_poly_fit_length(Q, A->length - B->length + 1); _F_mpz_mod_poly_set_length(Q, A->length - B->length + 1); } else F_mpz_mod_poly_zero(Q); coeff_Q = Q->coeffs - B->length + 1; while (coeff >= (long) B->length - 1) { while ((coeff >= (long) B->length - 1) && (F_mpz_is_zero(R->coeffs + coeff))) { F_mpz_zero(coeff_Q + coeff); coeff--; } if (coeff >= (long) B->length - 1) { F_mpz_mulmod2(coeff_Q + coeff, R->coeffs + coeff, lead_inv, B->P); F_mpz_mod_poly_scalar_mul(qB, Bm1, coeff_Q + coeff); F_mpz_mod_poly_t R_sub; F_mpz_init(R_sub->P); F_mpz_set(R_sub->P, B->P); R_sub->coeffs = R->coeffs + coeff - B->length + 1; R_sub->length = B->length - 1; _F_mpz_mod_poly_sub(R_sub, R_sub, qB); F_mpz_clear(R_sub->P); coeff--; } } _F_mpz_mod_poly_set_length(R, B->length - 1); _F_mpz_mod_poly_normalise(R); F_mpz_mod_poly_clear(qB); F_mpz_clear(lead_inv); }
int main(int argc, char * argv[]){ long alpha, Xpow, Ypow, i, j; if (argc == 1){ alpha = 3; Xpow = 20; Ypow = 220; } else{ alpha = atoi(argv[1]); Xpow = atoi(argv[2]); Ypow = atoi(argv[3]); } F_mpz_poly_t f; F_mpz_poly_init(f); FILE * inst = fopen("pol_in","r"); F_mpz_poly_fread(f, inst); fclose(inst); F_mpz_t Modulus; F_mpz_init(Modulus); F_mpz_read(Modulus); // F_mpz_print(Modulus); printf(" was modulus\n"); // F_mpz_poly_print(f); printf(" was f\n"); long d = f->length - 1; long ypow = d*(alpha) + 1; long maxlength = ypow*alpha + 1; // printf("ypow = %ld\n", ypow); F_mpz_poly_t temp; F_mpz_poly_init(temp); F_mpz_poly_t P[alpha + 1]; F_mpz_mat_t M; F_mpz_mat_init(M, ((alpha+1)*(alpha+2))/2 , maxlength); long row = 0; F_mpz_poly_t m_arr; //an array of powers of the modulus, m_arr->coeffs + i should be Modulus^i F_mpz_poly_init(m_arr); F_mpz_poly_set_coeff_ui(m_arr, 0, 1); F_mpz_t temp_m; F_mpz_init(temp_m); F_mpz_set_ui(temp_m, 1); for (j = 1; j < alpha + 1; j++) { F_mpz_mul2(temp_m, temp_m, Modulus); F_mpz_poly_set_coeff(m_arr, j, temp_m); } F_mpz_mat_t row_scale; F_mpz_mat_init(row_scale, M->r, M->r); for (j = 0; j < alpha + 1; j++) { if (j == 0){ F_mpz_poly_init(P[0]); F_mpz_poly_set_coeff_ui(P[0], 0, 1); } else if (j == 1){ F_mpz_poly_init(P[1]); F_mpz_poly_set(P[1], f); // printf("i is %ld and j is %ld\n", i, j); F_mpz_poly_set_coeff_si(P[1], ypow, -1); } else if (j > 1){ F_mpz_poly_init(P[j]); F_mpz_poly_mul(P[j], P[j-1], P[1]); } for (i = 0; i < alpha + 1 - j; i++){ F_mpz_poly_left_shift(temp, P[j], i); // F_mpz_poly_print(temp); printf(" was P with i = %ld and j = %ld\n", i, j); long k; for (k = 0; k < maxlength; k++){ if (k < temp->length) F_mpz_set(M->rows[row]+k, temp->coeffs + k); else F_mpz_zero(M->rows[row]+k); } F_mpz_set(row_scale->rows[row] + row, m_arr->coeffs + alpha - j); row++; } } F_mpz_clear(temp_m); F_mpz_poly_clear(m_arr); F_mpz_t X; F_mpz_t Y; F_mpz_init(X); F_mpz_init(Y); F_mpz_set_ui(X, 2); F_mpz_pow_ui(X, X, Xpow); F_mpz_set_ui(Y, 2); F_mpz_pow_ui(Y, Y, Ypow); F_mpz_mat_t col_scale; F_mpz_mat_init(col_scale, maxlength, maxlength); F_mpz_set_ui(col_scale->rows[0], 1); for (i = 1; i < ypow; i++){ F_mpz_mul2(col_scale->rows[i] + i, col_scale->rows[i-1] + i-1, X); } for (j = 1; j < alpha; j++){ for (i = ypow*(j-1); i < j*ypow; i++){ F_mpz_mul2(col_scale->rows[i + ypow] + i + ypow, col_scale->rows[i] + i, Y); } } //using X bounds and Y bounds as powers of 2 but not taking advantage of //that via cheap multiplication (or to save in LLL costs) and we should F_mpz_mul2(col_scale->rows[maxlength-1] + maxlength -1 , col_scale->rows[maxlength - ypow - 1] + maxlength - ypow - 1, Y); // F_mpz_mat_print_pretty(col_scale); F_mpz_mat_mul_classical(M, M, col_scale); F_mpz_mat_mul_classical(M, row_scale, M); FILE * fpre = fopen("pre_LLL","w"); F_mpz_mat_fprint_pretty(M, fpre); fclose(fpre); // LLL(M); // FILE * fpost = fopen("post_LLL","w"); // F_mpz_mat_fprint_pretty(M, fpost); // fclose(fpost); // F_mpz_poly_clear(temp); // F_mpz_poly_init(temp); // for (i = 0; i < maxlength; i++){ // F_mpz_poly_set_coeff(temp, i, M->rows[0]+i); // F_mpz_divexact(temp->coeffs + i, temp->coeffs + i, col_scale->rows[i] + i); //undo col_scale // } // FILE * fpoly1 = fopen("poly1","w"); // F_mpz_poly_fprint(temp, fpoly1); // fclose(fpoly1); // F_mpz_poly_print(temp); printf(" was the first row after LLL as a polynomial\n"); // F_mpz_poly_clear(temp); F_mpz_clear(X); F_mpz_clear(Y); F_mpz_clear(Modulus); for (j = 0; j < alpha + 1; j++){ F_mpz_poly_clear(P[j]); } F_mpz_poly_clear(temp); F_mpz_mat_clear(col_scale); F_mpz_mat_clear(row_scale); F_mpz_mat_clear(M); F_mpz_poly_clear(f); flint_stack_cleanup(); return 0; }
int test_F_mpz_LLL_randsimdioph() { mpz_mat_t m_mat; F_mpz_mat_t F_mat; int result = 1; ulong bits1, bits2; F_mpz_t fzero; F_mpz_init(fzero); ulong count1; for (count1 = 0; (count1 < 10*ITER) && (result == 1) ; count1++) { #if TRACE printf("count1 == %ld\n", count1); #endif ulong r = z_randint(200) + 1; ulong c = r; F_mpz_mat_init(F_mat, r, c); mpz_mat_init(m_mat, r, c); bits1 = z_randint(200) + 1; bits2 = z_randint(5) + 1; mpz_mat_randsimdioph(m_mat, r, c, bits1, bits2); mpz_mat_to_F_mpz_mat(F_mat, m_mat); F_mpz_set_d_2exp(fzero, 2.0, bits2); // good stuff here U_LLL_with_removal(F_mat, 350, fzero); mp_prec_t prec; prec = 20; __mpfr_struct ** Q, ** R; Q = mpfr_mat_init2(r, c, prec); R = mpfr_mat_init2(r, r, prec); F_mpz_mat_RQ_factor(F_mat, R, Q, r, c, prec); // should be that RQ = FM_copy /* long j; if (count1 == 29){ mpfr_printf("%.12Rf was R[i][i] for i = %ld\n", R[0] + 0, 0); for (j = 1; j < r; j++) { mpfr_printf("%.12Rf was R[i][i+1] for i = %ld\n", R[j] + j - 1, j); mpfr_printf("%.12Rf was R[i+1][i+1] for i = %ld\n", R[j] + j, j); } } */ result = mpfr_mat_R_reduced(R, r, (double) DELTA, (double) ETA, prec); mpfr_mat_clear(Q, r, c); mpfr_mat_clear(R, r, r); //result here result = mpz_mat_equal(res1, res2); if (!result) { F_mpz_mat_print_pretty(F_mat); printf("Error: bits1 = %ld, count1 = %ld\n", bits1, count1); } F_mpz_mat_clear(F_mat); mpz_mat_clear(m_mat); } F_mpz_clear(fzero); return result; }
int test_F_mpz_LLL_randajtai() { mpz_mat_t m_mat; F_mpz_mat_t F_mat; int result = 1; ulong bits; F_mpz_t fzero; F_mpz_init(fzero); ulong count1; for (count1 = 0; (count1 < 100*ITER) && (result == 1) ; count1++) { #if TRACE printf("count1 == %ld\n", count1); #endif ulong r = z_randint(10)+1; ulong c = r; F_mpz_mat_init(F_mat, r, c); mpz_mat_init(m_mat, r, c); bits = z_randint(200) + 1; mpz_mat_randajtai(m_mat, r, c, .5); mpz_mat_to_F_mpz_mat(F_mat, m_mat); F_mpz_set_d_2exp(fzero, (double) 2*r, 1); // good stuff here //F_mpz_mat_print_pretty(F_mat); long newd = U_LLL_with_removal(F_mat, 350, fzero); mp_prec_t prec; prec = 50; __mpfr_struct ** Q, ** R; Q = mpfr_mat_init2(r, c, prec); R = mpfr_mat_init2(r, r, prec); F_mpz_mat_RQ_factor(F_mat, R, Q, r, c, prec); // should be that RQ = FM_copy long j; #if TRACE if (count1 == 30){ mpfr_printf("%.12Rf was R[i][i] for i = %ld\n", R[0] + 0, 0); for (j = 1; j < r; j++) { mpfr_printf("%.12Rf was R[i][i+1] for i = %ld\n", R[j] + j - 1, j); mpfr_printf("%.12Rf was R[i+1][i+1] for i = %ld\n", R[j] + j, j); } } #endif result = mpfr_mat_R_reduced(R, r, (double) DELTA-.01, (double) ETA+.01, prec); mpfr_mat_clear(Q, r, c); mpfr_mat_clear(R, r, r); //result here result = mpz_mat_equal(res1, res2); if (!result) { printf("Error: bits = %ld, count1 = %ld, newd = %ld\n", bits, count1, newd); } F_mpz_mat_clear(F_mat); mpz_mat_clear(m_mat); } F_mpz_clear(fzero); return result; }
void F_mpz_mod_poly_gcd_euclidean(F_mpz_mod_poly_t res, F_mpz_mod_poly_t poly1, F_mpz_mod_poly_t poly2) { F_mpz_mod_poly_t R, A, B; F_mpz_poly_t r; int steps = 0; if (poly1->length == 0) { if (poly2->length == 0) F_mpz_mod_poly_zero(res); else F_mpz_mod_poly_make_monic(res, poly2); return; } if (poly2->length == 0) { F_mpz_mod_poly_make_monic(res, poly1); return; } if ((poly1->length == 1) || (poly2->length == 1)) { _F_mpz_poly_attach_F_mpz_mod_poly(r, res); F_mpz_poly_set_coeff_ui(r, 0, 1L); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); _F_mpz_mod_poly_normalise(res); return; } F_mpz_t P; F_mpz_init(P); F_mpz_set(P, poly1->P); F_mpz_mod_poly_init(R, P); if (poly1->length > poly2->length) { _F_mpz_mod_poly_attach(A, poly1); _F_mpz_mod_poly_attach(B, poly2); } else { _F_mpz_mod_poly_attach(A, poly2); _F_mpz_mod_poly_attach(B, poly1); } F_mpz_mod_poly_rem(R, A, B); F_mpz_mod_poly_swap(A, B); F_mpz_mod_poly_swap(B, R); F_mpz_mod_poly_init(R, P); if (B->length > 1) { F_mpz_mod_poly_rem(R, A, B); F_mpz_mod_poly_swap(A, B); F_mpz_mod_poly_swap(B, R); F_mpz_mod_poly_init(R, P); steps = 1; } while (B->length > 1) { F_mpz_mod_poly_rem(A, A, B); F_mpz_mod_poly_swap(A, B); } if (B->length == 1) { _F_mpz_poly_attach_F_mpz_mod_poly(r, res); F_mpz_poly_set_coeff_ui(r, 0, 1L); _F_mpz_mod_poly_attach_F_mpz_poly(res, r); res->length = 1; } else F_mpz_mod_poly_make_monic(res, A); if (steps) { F_mpz_mod_poly_clear(A); } F_mpz_mod_poly_clear(B); F_mpz_mod_poly_clear(R); }