예제 #1
0
파일: sqrt_a.c 프로젝트: coolpraku/msieve
/*-------------------------------------------------------------------*/
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;
}
예제 #2
0
파일: primorial.c 프로젝트: goens/flint2
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;
}
예제 #3
0
파일: big.o.c 프로젝트: hoobaa/mecl
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);
        }
}
예제 #4
0
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);
}
예제 #6
0
파일: convert.c 프로젝트: sageb0t/testsage
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;
}
예제 #7
0
파일: sqrt_a.c 프로젝트: coolpraku/msieve
/*-------------------------------------------------------------------*/
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);
}
예제 #8
0
파일: chplgmp.c 프로젝트: jcazzie/chapel
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);
}
예제 #9
0
파일: poly2ntl.cpp 프로젝트: 2php/cgal
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;
}
예제 #10
0
파일: bit_pack.c 프로젝트: goens/flint2
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);
}
예제 #11
0
파일: get_fmpz.c 프로젝트: isuruf/arb
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);
        }
    }
예제 #12
0
파일: sqrt_a.c 프로젝트: coolpraku/msieve
/*-------------------------------------------------------------------*/
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;
}
예제 #13
0
파일: sqrt_a.c 프로젝트: coolpraku/msieve
/*-------------------------------------------------------------------*/
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;
}
예제 #14
0
파일: poly2ntl.cpp 프로젝트: 2php/cgal
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;
}
예제 #15
0
void BigInt::SetNumLimbs( int numLimbs )
{
    const int prec = numLimbs*GMP_NUMB_BITS;
    mpz_realloc2( mpzInt_, prec );
}
예제 #16
0
void BigInt::SetMinBits( int minBits )
{
    mpz_realloc2( mpzInt_, minBits );
}