/*-------------------------------------------------------------------*/ static void gmp_poly_mod_q(gmp_poly_t *p, mpz_t q, gmp_poly_t *res) { uint32 i; uint32 pbits, resbits; /* also trim aggressively the memory use of the computed remainders; the algebraic square root has comparatively few arithmetic operations but the memory use for large problems is a concern */ for (i = 0; i <= p->degree; i++) { pbits = mpz_sizeinbase(p->coeff[i], 2); mpz_fdiv_r(res->coeff[i], p->coeff[i], q); resbits = mpz_sizeinbase(res->coeff[i], 2); if (pbits > resbits + 1000) mpz_realloc2(res->coeff[i], resbits + 500); } /* recalculate the degree */ for (i = p->degree; i; i--) { if (mpz_sgn(res->coeff[i]) != 0) break; } res->degree = i; }
void fmpz_primorial(fmpz_t res, long n) { mp_size_t len, pi; ulong bits; __mpz_struct * mpz_ptr; if (n <= LARGEST_ULONG_PRIMORIAL) { if (n <= 2) fmpz_set_ui(res, 1 + (n==2)); else fmpz_set_ui(res, ULONG_PRIMORIALS[(n-1)/2-1]); return; } pi = n_prime_pi(n); n_compute_primes(pi); bits = FLINT_BIT_COUNT(flint_primes[pi - 1]); mpz_ptr = _fmpz_promote(res); mpz_realloc2(mpz_ptr, pi*bits); len = mpn_prod_limbs(mpz_ptr->_mp_d, flint_primes, pi, bits); mpz_ptr->_mp_size = len; }
void _ecl_big_register_free(cl_object x) { return; /* We only need to free the integer when it gets too large */ if (ECL_BIGNUM_DIM(x) > 3 * ECL_BIG_REGISTER_SIZE) { mpz_realloc2(x->big.big_num, ECL_BIG_REGISTER_SIZE * GMP_LIMB_BITS); } }
void testmain (int argc, char **argv) { unsigned i; mpz_t a, b, res, ref; mpz_init (a); mpz_init (b); mpz_init (res); mpz_init (ref); for (i = 0; i < COUNT; i++) { mini_random_op3 (OP_MUL, MAXBITS, a, b, ref); if (mpz_sgn(ref) == 0) /* my_mpz_mul requires a != 0, b != 0 */ continue; my_mpz_mul (res, a, b); if (mpz_cmp (res, ref)) { fprintf (stderr, "my_mpz_mul failed:\n"); dump ("a", a); dump ("b", b); dump ("r", res); dump ("ref", ref); abort (); } /* The following test exploits a side-effect of my_mpz_mul: res points to a buffer with at least an+bn limbs, and the limbs above the result are zeroed. */ if (mpz_size (b) > 0 && mpz_getlimbn (res, mpz_size(a)) != mpz_limbs_read (res) [mpz_size(a)]) { fprintf (stderr, "getlimbn - limbs_read differ.\n"); abort (); } if ((i % 4 == 0) && mpz_size (res) > 1) { mpz_realloc2 (res, 1); if (mpz_cmp_ui (res, 0)) { fprintf (stderr, "mpz_realloc2 did not clear res.\n"); abort (); } mpz_limbs_finish (ref, 0); if (mpz_cmp_d (ref, 0)) { fprintf (stderr, "mpz_limbs_finish did not clear res.\n"); abort (); } } } mpz_clear (a); mpz_clear (b); mpz_clear (res); mpz_clear (ref); }
void convert_j2mp(JNIEnv* env, jbyteArray jvalue, mpz_t mvalue) { jsize size; jbyte* jbuffer; size = env->GetArrayLength(jvalue); jbuffer = env->GetByteArrayElements(jvalue, NULL); mpz_realloc2(mvalue, sizeof(jbyte) * 8 * size); //preallocate the size mpz_import(mvalue, size, 1, sizeof(jbyte), 1, 0, (void*)jbuffer); env->ReleaseByteArrayElements(jvalue, jbuffer, JNI_ABORT); }
void t_INT_to_ZZ ( mpz_t value, GEN g ) { long limbs = 0; limbs = lgefint(g) - 2; mpz_realloc2( value, limbs ); mpz_import( value, limbs, -1, sizeof(long), 0, 0, int_LSW(g) ); if ( signe(g) == -1 ) mpz_neg( value, value ); return; }
/*-------------------------------------------------------------------*/ static void gmp_poly_monic_derivative(gmp_poly_t *src, gmp_poly_t *dest) { uint32 i; /* compute the coefficients of the derivative of src, assumed to be monic */ for (i = 0; i < src->degree; i++) { mpz_mul_ui(dest->coeff[i], src->coeff[i+1], (unsigned long)(i+1)); } mpz_set_ui(dest->coeff[i], (unsigned long)(i+1)); dest->degree = src->degree; for (i++; i < MAX_POLY_DEGREE; i++) mpz_realloc2(dest->coeff[i], 1); }
void chpl_gmp_get_mpz(mpz_t ret, int64_t src_locale, __mpz_struct from) { // First, resize our destination appropriately. mpz_realloc2(ret, from._mp_alloc * mp_bits_per_limb); // Copy the _alloc and _size fields. ret[0]._mp_alloc = from._mp_alloc; ret[0]._mp_size = from._mp_size; // Next, use GASNET to move the pointer data. chpl_gen_comm_get(ret[0]._mp_d, src_locale, from._mp_d, sizeof(mp_limb_t) * ret[0]._mp_alloc, CHPL_TYPE_uint64_t, CHPL_COMM_UNKNOWN_ID, 0, 0); }
Integer prs_resultant_ufd< Integer >(Poly_1 A, Poly_1 B) { #ifdef CGAL_ACK_BENCHMARK_RES // std::cout << "start res " << "\n"; res_tm.start(); #endif // implemented using the subresultant algorithm for resultant computation // see [Cohen, 1993], algorithm 3.3.7 typedef Integer NT; if (A.is_zero() || B.is_zero()) return NT(0); NTL::ZZX q1, q2; poly2ntl(A, q1); poly2ntl(B, q2); NTL::ZZ zz; NTL::resultant(zz, q1, q2); if(NTL::IsZero(zz)) return Integer(0); Integer res; NTL_bigint_rep *rep = (NTL_bigint_rep *)zz.rep; int sz = rep->size; if(sz < 0) sz = -sz; mpz_ptr tmp = res.get_mp(); mpz_realloc2(tmp, sz * GMP_NUMB_BITS); tmp->_mp_size = rep->size; memcpy(tmp->_mp_d, &rep->data, sz*sizeof(mp_limb_t)); // std::cout << "stop res " << "\n"; #ifdef CGAL_ACK_BENCHMARK_RES // std::cout << "stop res " << "\n"; res_tm.stop(); #endif return res; }
void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly, mp_bitcnt_t bit_size) { long len; __mpz_struct * mpz; long i, d; int negate; len = fmpz_poly_length(poly); if (len == 0 || bit_size == 0) { fmpz_zero(f); return; } mpz = _fmpz_promote(f); mpz_realloc2(mpz, len * bit_size); d = mpz->_mp_alloc; mpn_zero(mpz->_mp_d, d); if (fmpz_sgn(fmpz_poly_lead(poly)) < 0) negate = -1; else negate = 0; _fmpz_poly_bit_pack(mpz->_mp_d, poly->coeffs, len, bit_size, negate); for (i = d - 1; i >= 0; i--) { if (mpz->_mp_d[i] != 0) break; } d = i + 1; mpz->_mp_size = d; _fmpz_demote_val(f); if (negate) fmpz_neg(f, f); }
void arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd) { if (arf_is_special(x)) { if (arf_is_zero(x)) { fmpz_zero(z); } else { flint_printf("arf_get_fmpz: cannot convert infinity or nan to integer\n"); abort(); } } else if (COEFF_IS_MPZ(*ARF_EXPREF(x))) { /* tiny */ if (fmpz_sgn(ARF_EXPREF(x)) < 0) { int negative = ARF_SGNBIT(x); if (rnd == ARF_RND_NEAR || rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } } else { flint_printf("arf_get_fmpz: number too large to convert to integer\n"); abort(); } } else { slong exp; int negative, inexact; mp_size_t xn, zn; mp_srcptr xp; __mpz_struct * zz; /* TBD: implement efficiently */ if (rnd == ARF_RND_NEAR) { fmpr_t t; fmpr_init(t); arf_get_fmpr(t, x); fmpr_get_fmpz(z, t, rnd); fmpr_clear(t); return; } exp = ARF_EXP(x); negative = ARF_SGNBIT(x); /* |x| < 1 */ if (exp <= 0) { if (rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } return; } ARF_GET_MPN_READONLY(xp, xn, x); /* |x| < 2^31 or 2^63 (must save 1 bit for rounding up!) */ if (exp < FLINT_BITS) { mp_limb_t v, v2; v = xp[xn - 1]; v2 = v >> (FLINT_BITS - exp); inexact = (xn > 1) || ((v2 << (FLINT_BITS - exp)) != v); if (inexact && rnd != ARF_RND_DOWN) { if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR)) v2++; if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL)) v2++; } if (negative) fmpz_neg_ui(z, v2); else fmpz_set_ui(z, v2); return; } /* |x| >= 1 */ zn = (exp + FLINT_BITS - 1) / FLINT_BITS; zz = _fmpz_promote(z); if (zz->_mp_alloc < zn) mpz_realloc2(zz, zn * FLINT_BITS); inexact = _arf_get_integer_mpn(zz->_mp_d, xp, xn, exp); zz->_mp_size = negative ? -zn : zn; _fmpz_demote_val(z); if (inexact && rnd != ARF_RND_DOWN) { if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR)) fmpz_sub_ui(z, z, 1); if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL)) fmpz_add_ui(z, z, 1); } }
/*-------------------------------------------------------------------*/ static uint32 get_final_sqrt(msieve_obj *obj, gmp_poly_t *alg_poly, gmp_poly_t *prod, gmp_poly_t *isqrt_mod_q, mpz_t q) { /* the main q-adic Newton iteration. On input, isqrt_mod_q contains the starting value of the reciprocal square root R[0](x) of the polynomial prod(x). The iteration is R[k](x) = R[k-1](x) * (3 - prod(x)*R[k-1](x)^2) / 2 mod (q^(2^k)) and at the end of iteration k, prod(x)*R[k-1](x)^2 mod (q^(2^k)) is 1. We keep iterating until q^(2^k) is larger than the size of the coefficients of the square root (i.e. about half the size of the coefficients of prod(x)). Then the square root to use is R[k](x) * prod(x) mod (q^(2^k)), which is written to isqrt_mod_q */ uint32 i, j; uint32 prod_bits, prod_max_bits; uint32 num_iter; /* initialize */ gmp_poly_bits(prod, &prod_bits, &prod_max_bits); /* since prod(x) only matters mod q^(2^(final_k)), we can cut the memory use in half by changing prod(x) to this. Remember final_k as well */ i = mpz_get_ui(q); for (num_iter = 0; mpz_sizeinbase(q, 2) < prod_max_bits / 2 + 4000; num_iter++) { mpz_mul(q, q, q); } gmp_poly_mod_q(prod, q, prod); mpz_set_ui(q, (unsigned long)i); mpz_realloc2(q, 33); /* do the main iteration */ for (i = 0; i < num_iter; i++) { gmp_poly_t tmp_poly; /* square the previous modulus */ mpz_mul(q, q, q); /* compute prod(x) * (previous R)^2 */ gmp_poly_init(&tmp_poly); gmp_poly_mod_q(prod, q, &tmp_poly); gmp_poly_mul(&tmp_poly, isqrt_mod_q, alg_poly, 0); gmp_poly_mod_q(&tmp_poly, q, &tmp_poly); gmp_poly_mul(&tmp_poly, isqrt_mod_q, alg_poly, 0); gmp_poly_mod_q(&tmp_poly, q, &tmp_poly); /* compute ( (3 - that) / 2 ) mod q */ mpz_sub_ui(tmp_poly.coeff[0], tmp_poly.coeff[0], (unsigned long)3); for (j = 0; j <= tmp_poly.degree; j++) { mpz_t *c = tmp_poly.coeff + j; if (mpz_sgn(*c) != 0) { mpz_neg(*c, *c); if (mpz_tstbit(*c, (unsigned long)0)) mpz_add(*c, *c, q); mpz_tdiv_q_2exp(*c, *c, (unsigned long)1); } } /* finally, compute the new R(x) by multiplying the result above by the old R(x) */ gmp_poly_mul(&tmp_poly, isqrt_mod_q, alg_poly, 1); gmp_poly_mod_q(&tmp_poly, q, isqrt_mod_q); gmp_poly_clear(&tmp_poly); } /* attempt to compute the square root. First multiply R(x) by prod(x), deleting prod(x) since we won't need it beyond this point */ gmp_poly_mul(isqrt_mod_q, prod, alg_poly, 1); gmp_poly_mod_q(isqrt_mod_q, q, isqrt_mod_q); /* this is a little tricky. Up until now we've been working modulo big numbers, but the coef- ficients of the square root are just integers, and may be negative. Negative numbers mod q have a numerical value near that of +q, but we want the square root to have a negative coef- ficient in that case. Hence, if the top few words of any coefficent of the square root match the top few words of q, we assume this coefficient is negative and subtract q from it. Theoretically we could be wrong, and the coefficient really is supposed to be a big positive number near q in size. However, if q is thousands of bits larger than the size we expect for the square root coefficients, this is so unlikely that it's not worth worrying about */ for (i = 0; i <= isqrt_mod_q->degree; i++) { mpz_t *c = isqrt_mod_q->coeff + i; size_t limbs = mpz_size(*c); if (limbs == mpz_size(q) && mpz_getlimbn(*c, (mp_size_t)(limbs-1)) == mpz_getlimbn(q, (mp_size_t)(limbs-1)) && mpz_getlimbn(*c, (mp_size_t)(limbs-2)) == mpz_getlimbn(q, (mp_size_t)(limbs-2)) && mpz_getlimbn(*c, (mp_size_t)(limbs-3)) == mpz_getlimbn(q, (mp_size_t)(limbs-3))) { mpz_sub(*c, *c, q); } } /* another heuristic: we will assume the Newton iteration has converged if, after applying the correction above for negative square root coefficients, the total number of bits in the coefficients of the resulting polynomial is much smaller than we would expect from random polynomials modulo q */ gmp_poly_bits(isqrt_mod_q, &prod_bits, &i); if (prod_bits >= (isqrt_mod_q->degree + 1) * mpz_sizeinbase(q, 2) - 100) { logprintf(obj, "Newton iteration failed to converge\n"); return 0; } return 1; }
/*-------------------------------------------------------------------*/ static void gmp_poly_mul(gmp_poly_t *p1, gmp_poly_t *p2, gmp_poly_t *mod, uint32 free_p2) { /* multiply p1(x) by p2(x) modulo mod(x) (assumed monic) If free_p2 is nonzero the coefficients of p2(x) are freed after being used */ uint32 i, j; uint32 d = mod->degree; uint32 d1 = p1->degree; uint32 d2 = p2->degree; uint32 prod_degree; mpz_t tmp[MAX_POLY_DEGREE + 1]; /* initialize */ for (i = 0; i < MAX_POLY_DEGREE + 1; i++) mpz_init_set_ui(tmp[i], (unsigned long)0); /* multiply p1 by the leading coefficient of p2 */ for (i = 0; i <= d1; i++) { mpz_mul(tmp[i], p1->coeff[i], p2->coeff[d2]); } prod_degree = d1; if (free_p2) { mpz_realloc2(p2->coeff[d2], 1); } /* for each of the other coefficients in p2 */ for (i = d2 - 1; (int32)i >= 0; i--) { /* shift the accumulator up by one, bubbling the highest-order coefficient to the lowest */ for (j = prod_degree; (int32)j >= 0; j--) mpz_swap(tmp[j+1], tmp[j]); /* add in the product of p1(x) and coefficient i of p2 */ for (j = d1; j; j--) { mpz_addmul(tmp[j], p1->coeff[j], p2->coeff[i]); } mpz_mul(tmp[j], p1->coeff[j], p2->coeff[i]); if (free_p2) { mpz_realloc2(p2->coeff[i], 1); } /* recalculate the degree of the result */ prod_degree = d + 1; while (prod_degree && mpz_sgn(tmp[prod_degree]) == 0) prod_degree--; /* if it exceeds the degree of mod(x), subtract mod(x) * (leading accumulator coefficient) */ if (prod_degree <= d) continue; for (j = d; (int32)j >= 0; j--) { mpz_submul(tmp[j], mod->coeff[j], tmp[prod_degree]); } prod_degree--; } /* move the result in the accumulator over to p1 */ for (i = 0; i <= prod_degree; i++) { mpz_swap(p1->coeff[i], tmp[i]); mpz_clear(tmp[i]); } for (; i < MAX_POLY_DEGREE + 1; i++) mpz_clear(tmp[i]); /* recalculate the degree */ i = prod_degree; while (i > 0 && mpz_sgn(p1->coeff[i]) == 0) { mpz_realloc2(p1->coeff[i], 1); i--; } p1->degree = i; }
Poly_1& Poly_1::operator *= (const Poly_1& p2) { Poly_1 p1 = *this; if(p1.is_zero() || p2.is_zero()) { // std::cout << "mul NTL: zero poly\n"; return (*this) = Poly_1(Integer(0)); } // TODO: use this if poly size is small.. if(p1.degree() <= POLY_NTL_MIN_DEGREE && p2.degree() <= POLY_NTL_MIN_DEGREE) { internal::Creation_tag TAG; Poly_1 p(TAG, p1.degree() + p2.degree() + 1); for (int i=0; i <= p1.degree(); ++i) for (int j=0; j <= p2.degree(); ++j) p.coeff(i+j) += (p1[i]*p2[j]); p.reduce(); // std::cout << "mul usual: " << p << "\n\n";; return (*this) = p ; } NTL::ZZX q, q2; poly2ntl(p1, q); poly2ntl(p2, q2); q *= q2; int d = NTL::deg(q); // if(d == -1) { // std::cout << "Fatal: zero poly\n"; // throw -1; // } this->copy_on_write(); // ?? this->coeffs().resize(d + 1); // TODO: use reduce ?? mpz_t tmp; mpz_init(tmp); for(int i = 0; i <= d; i++) { const NTL::ZZ& zz = q.rep[i]; if(NTL::IsZero(zz)) { coeff(i) = Integer(0); continue; } NTL_bigint_rep *rep = (NTL_bigint_rep *)zz.rep; int sz = rep->size; if(sz < 0) sz = -sz; mpz_realloc2(tmp, sz * GMP_NUMB_BITS); tmp->_mp_size = rep->size; memcpy(tmp->_mp_d, &rep->data, sz*sizeof(mp_limb_t)); // coeff(i).makeCopy(); // mpz_ptr mpd = coeff(i).get_mp(); // mpd->_mp_size = rep->size; // mpz_realloc2(mpd, sz * GMP_NUMB_BITS); // memcpy(mpd->_mp_d, &rep->data, sz*sizeof(mp_limb_t)); coeff(i) = Integer(tmp); // mpz_init_set(coeff(i).get_mp(), tmp); } mpz_clear(tmp); // CGALi::Creation_tag TAG; // Poly_1 p(TAG, p1.degree() + p2.degree() + 1); // for (int i=0; i <= p1.degree(); ++i) // for (int j=0; j <= p2.degree(); ++j) // p.coeff(i+j) += (p1[i]*p2[j]); // //p.reduce(); // // std::cout << "mul usual: " << p << "\n\n";; // // if(*this != p) { // // std::cout << "------------ p1: " << p1 << "---------- p2: " << // p2 << "\n"; // std::cout << "FATAL: " << *this << "----------- and " << p << "\n"; // // } // Poly_1 pp(vec.begin(), vec.end()); //p.reduce(); // std::cout << "mul NTL: " << *this << "\n"; return (*this);// = pp; }
void BigInt::SetNumLimbs( int numLimbs ) { const int prec = numLimbs*GMP_NUMB_BITS; mpz_realloc2( mpzInt_, prec ); }
void BigInt::SetMinBits( int minBits ) { mpz_realloc2( mpzInt_, minBits ); }