void * flint_stack_alloc_small(unsigned long length) { if (length + 1L > block_left) // not enough space left, allocate a new block { if (length + 3L > FLINT_SMALL_BLOCK_SIZE) { printf("Error: attempt to allocate %ld limbs in small stack memory manager!\n", length); abort(); } if (block_ptr == NULL) { block_ptr = (mp_limb_t *) flint_heap_alloc(FLINT_SMALL_BLOCK_SIZE); block_left = FLINT_SMALL_BLOCK_SIZE - 2; block_ptr[0] = 0; block_ptr[1] = (unsigned long) NULL; block_ptr += 2; } else { mp_limb_t * temp = (mp_limb_t *) flint_heap_alloc(FLINT_SMALL_BLOCK_SIZE); temp[0] = block_left; temp[1] = (unsigned long) block_ptr; block_ptr = temp + 2; block_left = FLINT_SMALL_BLOCK_SIZE - 2; } } block_ptr[length] = length; block_ptr += (length+1L); block_left -= (length+1L); return (void *) (block_ptr - (length + 1L)); }
void F_mpz_mod_poly_realloc(F_mpz_mod_poly_t poly, const ulong alloc) { if (!alloc) // alloc == 0, clear up { F_mpz_mod_poly_clear(poly); poly->coeffs = NULL; poly->alloc = 0; poly->length = 0; return; } if (poly->alloc) // realloc { F_mpz_mod_poly_truncate(poly, alloc); poly->coeffs = (F_mpz *) flint_heap_realloc(poly->coeffs, alloc); if (alloc > poly->alloc) F_mpn_clear(poly->coeffs + poly->alloc, alloc - poly->alloc); } else // nothing allocated already so do it now { poly->coeffs = (mp_limb_t*) flint_heap_alloc(alloc); F_mpn_clear(poly->coeffs, alloc); } poly->alloc = alloc; }
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_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_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 fmpz_multi_CRT_ui(fmpz_t output, unsigned long * residues, fmpz_comb_t comb, fmpz_t ** comb_temp) { ulong i, j, k; ulong n = comb->n; ulong num; ulong log_res; mp_limb_t * ptr; ulong size; ulong num_primes = comb->num_primes; if (num_primes == 1) // the output is less than a single prime, so just output the result { unsigned long p = comb->primes[0]; if ((p - residues[0]) < residues[0]) fmpz_set_si(output, (long) (residues[0] - p)); else fmpz_set_ui(output, residues[0]); return; } // first layer of reconstruction num = (1L<<n); mp_limb_t temps[3]; mp_limb_t temp2s[3]; for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) { fmpz_set_ui(temps, residues[i]); fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1])); fmpz_sub_ui_inplace(temp2s, residues[i + 1]); temp2s[0] = -temp2s[0]; fmpz_mul(temps, temp2s, comb->res[0][j]); fmpz_set_ui(temp2s, fmpz_mod_ui(temps, comb->primes[i+1])); fmpz_mul_ui(temps, temp2s, comb->primes[i]); fmpz_add_ui(comb_temp[0][j], temps, residues[i]); } if (i < num_primes) fmpz_set_ui(comb_temp[0][j], residues[i]); // compute other layers of reconstruction fmpz_t temp = (fmpz_t) flint_heap_alloc(2*num + 1); fmpz_t temp2 = (fmpz_t) flint_heap_alloc(2*num + 1); num /= 2; log_res = 1; while (log_res < n) { for (i = 0, j = 0; i < num; i += 2, j++) { if (fmpz_is_one(comb->comb[log_res-1][i+1])) { if (!fmpz_is_one(comb->comb[log_res-1][i])) fmpz_set(comb_temp[log_res][j], comb_temp[log_res-1][i]); } else { fmpz_mod(temp2, comb_temp[log_res-1][i], comb->comb[log_res-1][i+1]); fmpz_sub(temp, temp2, comb_temp[log_res-1][i+1]); temp[0] = -temp[0]; fmpz_mul(temp2, temp, comb->res[log_res][j]); fmpz_mod(temp, temp2, comb->comb[log_res-1][i+1]); fmpz_mul(temp2, temp, comb->comb[log_res-1][i]); fmpz_add(comb_temp[log_res][j], temp2, comb_temp[log_res-1][i]); } } log_res++; num /= 2; } // write out the output __fmpz_multi_CRT_sign(comb_temp[log_res - 1][0], comb_temp[log_res - 1][0], comb); fmpz_set(output, comb_temp[log_res - 1][0]); flint_heap_free(temp2); //temp2 flint_heap_free(temp); //temp }
void fmpz_comb_init(fmpz_comb_t comb, ulong * primes, ulong num_primes) { ulong i, j, k; comb->primes = primes; comb->num_primes = num_primes; ulong n = 0L; while (num_primes > (1L<<n)) n++; comb->n = n; ulong num; // create zn_poly modulus information comb->mod = (zn_mod_t *) flint_heap_alloc_bytes(sizeof(zn_mod_t)*num_primes); for (ulong i = 0; i < num_primes; i++) zn_mod_init(comb->mod[i], primes[i]); if (n == 0) return; // nothing to do // allocate space for comb comb->comb = (fmpz_t **) flint_heap_alloc(n); j = (1L<<(n - 1)); ulong size = 2; mp_limb_t * ptr; for (i = 0; i < n; i++) { comb->comb[i] = (fmpz_t *) flint_heap_alloc(j); ptr = (mp_limb_t *) flint_heap_alloc((1L<<n) + j); for (k = 0; k < j; k++, ptr += (size + 1)) { comb->comb[i][k] = ptr; } j/=2; size*=2; } // allocate space for res comb->res = (fmpz_t **) flint_heap_alloc(n); j = (1L<<(n - 1)); size = 2; for (i = 0; i < n; i++) { comb->res[i] = (fmpz_t *) flint_heap_alloc(j); ptr = (mp_limb_t *) flint_heap_alloc((1L<<n) + j); for (k = 0; k < j; k++, ptr += (size + 1)) { comb->res[i][k] = ptr; } j/=2; size*=2; } // compute products of pairs of primes and place in comb for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) { fmpz_set_ui(comb->comb[0][j], primes[i]); fmpz_mul_ui(comb->comb[0][j], comb->comb[0][j], primes[i+1]); } if (i < num_primes) // in case number of primes is odd { fmpz_set_ui(comb->comb[0][j], primes[i]); i+=2; j++; } num = (1L<<n); // set the rest of the entries on that row of the comb to 1 for (; i < num; i += 2, j++) { fmpz_set_ui(comb->comb[0][j], 1L); } // compute rest of comb by multiplying in pairs ulong log_comb = 1; num /= 2; while (num >= 2) { for (i = 0, j = 0; i < num; i += 2, j++) { fmpz_mul(comb->comb[log_comb][j], comb->comb[log_comb-1][i], comb->comb[log_comb-1][i+1]); } log_comb++; num /= 2; } // compute inverses from pairs of primes fmpz_t temp = (fmpz_t) flint_stack_alloc(2); fmpz_t temp2 = (fmpz_t) flint_stack_alloc(2); for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++) { fmpz_set_ui(temp, primes[i]); fmpz_set_ui(temp2, primes[i+1]); fmpz_invert(comb->res[0][j], temp, temp2); } flint_stack_release(); //temp2 flint_stack_release(); //temp ulong log_res = 1; num = (1L<<(n - 1)); // compute remaining inverses, each level combining pairs from the level below while (log_res < n) { for (i = 0, j = 0; i < num; i += 2, j++) { fmpz_invert(comb->res[log_res][j], comb->comb[log_res-1][i], comb->comb[log_res-1][i+1]); } log_res++; num /= 2; } }