void mpq_mat_init(mpq_mat_t mat, ulong r, ulong c) { if ((r) && (c)) mat->entries = (mpq_t*) flint_heap_alloc_bytes(r*c*sizeof(mpq_t)); else mat->entries = NULL; long i; for (i = 0; i < r*c; i++) { mpq_init(mat->entries[i]); } mat->r = r; mat->c = c; }
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; } }