Beispiel #1
0
//
//        ( n )    ( n ) (n+1)-k
// return (   ) == (   ) -------
//        ( k )    (k-1)    k
//
  void binomialCoefficient(mpz_t b, long n, long k)
  {
    mpz_set_ui(b,0);
    if(k>n || k<0) return;
    mpz_set_si(b,n);
    mpz_bin_ui(b,b,k);
  }
Beispiel #2
0
/* Function finds binomial coefficient for all (N,m) between Nini, 
   Nend and mini mend. Wrties to mpz variables.        */
void tabulate_bins_z(mpz_t bcs[], int Nini, int Nend, int mini, int mend)
{
 int N;
 int m;
 int done=mend-mini+1;
 mpz_t bc;
 mpz_init(bc);
 mpz_t Nz;
 mpz_init(Nz);

 for(N=Nini;N<=Nend;N++)
 {
  mpz_set_ui(Nz,N);
  for(m=mini;m<=mend;m++)
  {
   if(N<1)
   {
    mpz_set_ui(bcs[(N-Nini)*done+(m-mini)],0);
   }
   else
   {
    mpz_bin_ui(bc,Nz,m);
    mpz_set(bcs[(N-Nini)*done+(m-mini)],bc);
   } 
  }
 }
 mpz_clear(bc);
 mpz_clear(Nz);
}      
Beispiel #3
0
// Binomial Coefficient
RCP<const Integer> binomial(const Integer &n, unsigned long k)
{
    mpz_class f;

    mpz_bin_ui(f.get_mpz_t(), n.as_mpz().get_mpz_t(), k);

    return integer(f);
}
//------------------------------------------------------------------------------
// Name: bin
//------------------------------------------------------------------------------
knumber_base *knumber_integer::bin(knumber_base *rhs) {


	if(knumber_integer *const p = dynamic_cast<knumber_integer *>(rhs)) {
		mpz_bin_ui(mpz_, mpz_, mpz_get_ui(p->mpz_));
		return this;

	} else if(knumber_float *const p = dynamic_cast<knumber_float *>(rhs)) {
		delete this;
		return new knumber_error(knumber_error::ERROR_UNDEFINED);
	} else if(knumber_fraction *const p = dynamic_cast<knumber_fraction *>(rhs)) {
		delete this;
		return new knumber_error(knumber_error::ERROR_UNDEFINED);
	} else if(knumber_error *const p = dynamic_cast<knumber_error *>(rhs)) {
		delete this;
		return new knumber_error(knumber_error::ERROR_UNDEFINED);
	}

	Q_ASSERT(0);
	return 0;
}
Beispiel #5
0
/*Function to precompute all binomial coefficients     
   
 inpdf:
 mpz_bin_ui(bcnum,n,i);

 hypergeometricpdf:
 mpz_bin_ui(bc_beta_active_inputs,beta,ai_cnt);
 mpz_bin_ui(bc_sub,mu_sub_beta,di-ai_cnt);
 mpz_bin_ui(bc_mu_d,mu,di);

 uniquecodes:
 mpz_bin_ui(bcnum,n,i);

 scjoint:
 mpz_bin_ui(bc_gamma_sy,gamp,(unsigned long int)sy);

 1) mu,sx;
 2) gamma,sy;

 3) mu,d; 				   (always subset of 1)
 4) mu_sub_beta,di-ai_cnt; (for all mu, find all coeffs for 
                            less than or equal to d draws)
 5) beta,ai_cnt;		   (always a subset of 2)       
 
 Function finds binomial coefficient for all (N,m) between Nini, 
 Nend and mini mend. Wrties to mpfr variables.            */
void tabulate_bins_fr(mpfr_t *bcs, int Nini, int Nend, int mini, int mend, mpfr_prec_t prec)
{
 int N;
 int m;
 int done=mend-mini+1;
 mpz_t bc;
 mpz_init(bc);
 mpz_t Nz;
 mpz_init(Nz);

 for(N=Nini;N<=Nend;N++)
 {
  mpz_set_ui(Nz,N);
  for(m=mini;m<=mend;m++)
  {
   mpz_bin_ui(bc,Nz,m);
   mpfr_set_z(*(bcs+(N-Nini)*done+(m-mini)),bc,MPFR_RNDN);
  }
 }
 mpz_clear(bc);
 mpz_clear(Nz);
}   
Beispiel #6
0
static PyObject *
GMPy_MPZ_Function_Bincoef(PyObject *self, PyObject *args)
{
    MPZ_Object *result = NULL, *tempx;
    unsigned long n, k;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("bincoef() requires two integer arguments");
        return NULL;
    }

    if (!(result = GMPy_MPZ_New(NULL))) {
        /* LCOV_EXCL_START */
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    k = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1));
    if (k == (unsigned long)(-1) && PyErr_Occurred()) {
        Py_DECREF((PyObject*)result);
        return NULL;
    }

    n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0));
    if (!(n == (unsigned long)(-1) && PyErr_Occurred())) {
        /* Use mpz_bin_uiui which should be faster. */
        mpz_bin_uiui(result->z, n, k);
        return (PyObject*)result;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
        Py_DECREF((PyObject*)result);
        return NULL;
    }

    mpz_bin_ui(result->z, tempx->z, k);
    Py_DECREF((PyObject*)tempx);
    return (PyObject*)result;
}
Beispiel #7
0
  void 
PaillierAdapter::dec( paillier_pubkey* pub,
    paillier_prvkey* prv,
    mpz_t c, 
    unsigned int s,
    mpz_t res)
{
	int i,j,k;
	mpz_t cprime, temp, tempDivisor, i_jCur, i_jPrev;

	mpz_init(cprime);
	
	//cprime = c^key mod n^{s+1}
	mpz_powm(cprime,c,prv->d,*pub->getnj(s+1));
	
	
	
	//the algorithm from extracting i from (1+n)^i described in the paper.
	
	//the algorithm iteratively extracts i mod n, i mod n^2, etc. i mod n starts us off, and is just input - 1 / n.
	mpz_init(temp);
	mpz_init(tempDivisor);
	mpz_init(i_jCur);
	mpz_init_set(i_jPrev,cprime);
	mpz_sub_ui(i_jPrev,i_jPrev,1);
	mpz_divexact(i_jPrev,i_jPrev,*pub->getnj(1));
	mpz_mod(i_jPrev,i_jPrev,*pub->getnj(2));
	
	//just in case s=1; in that case we need this line to actually set i_jcur
	if(s==1)
		mpz_set(i_jCur,i_jPrev);
	
	//extract i_j = i mod n^j given i_{j-1}. this is done by taking (input - 1 mod n^{j+1}) / n , and subtracting
	//from that: ((  (i_{j-1} choose 2)*n  + (i_{j-1} choose 3)*n^2  + ... +  (i_{j-1} choose j)*n^{j-1}  ))   mod n^j
	for(j=2;j<=s;j++)
	{
		//L((1+n)^i) as they call it 
		mpz_mod(i_jCur,cprime,*pub->getnj(j+1));
		mpz_sub_ui(i_jCur,i_jCur,1);
		mpz_divexact(i_jCur,i_jCur,*pub->getnj(1));
		
		mpz_mod(i_jCur,i_jCur,*pub->getnj(j));
		
		//subtract each of the binomial things
		for(k=2;k<=j;k++)
		{
			mpz_bin_ui(temp,i_jPrev,k);
			mpz_mul(temp,temp,*pub->getnj(k-1));
			mpz_mod(temp,temp,*pub->getnj(j));
			mpz_sub(i_jCur,i_jCur,temp);
			mpz_mod(i_jCur,i_jCur,*pub->getnj(j));
		}
		mpz_set(i_jPrev,i_jCur);
	}
	
	//i_jCur is currently the message times the private key.
	mpz_invert(temp, prv->d, *pub->getnj(s));
	mpz_mul(res, i_jCur, temp);
	mpz_mod(res, res, *pub->getnj(s));
	
	//cleanup and return
	mpz_clear(cprime);
	mpz_clear(i_jPrev);
	mpz_clear(i_jCur);
	mpz_clear(temp);
	mpz_clear(tempDivisor);
	

  //  unsigned int kfac, k;
//  mpz_t t1, t2, t3, a, id ;
//  std::cout << "dec called with s="<<s<<std::endl;
//  mpz_inits(t1, t2, t3, a, NULL);
//  mpz_init_set_ui(id,  0);
//
//  mpz_powm(a, c, prv->d, *pub->getnj(s+1));
//
//  for(unsigned int j = 1 ; j <= s; j++)
//  {
//    mpz_set(t1, a);
//    mpz_mod(t1, t1, *pub->getnj(j+1));
//    mpz_sub_ui(t1, t1, 1);
//    mpz_div(t1, t1, *pub->getnj(1));
//    mpz_set(t2, id);
//    kfac = 1;
//
//    for (k = 2; k <= j; k++)
//    {
//      kfac *= k;
//      mpz_sub_ui(id, id, 1);
//      mpz_mul(t2, t2, id);
//      mpz_mod(t2, t2, *pub->getnj(j));
//      mpz_set_ui(t3, kfac);
//
//      mpz_invert(t3, t3, *pub->getnj(j));
//
//      mpz_mul(t3, t3, t2);
//      mpz_mod(t3, t3, *pub->getnj(j));
//      mpz_mul(t3, t3, *pub->getnj(k-1));
//      mpz_mod(t3, t3, *pub->getnj(j));
//      mpz_sub(t1, t1, t3);
//      mpz_mod(t1, t1, *pub->getnj(j));
//    }
//    mpz_set(id, t1);
//  }
//
//  mpz_mul(rop, id, prv->inv_d);
//
//  mpz_mod(rop, rop, *pub->getnj(s));
//
//  mpz_clears(t1, t2, t3, a, id, NULL);
}
Beispiel #8
0
/* Evaluate the expression E and put the result in R.  */
void
mpz_eval_expr (mpz_ptr r, expr_t e)
{
  mpz_t lhs, rhs;

  switch (e->op)
    {
    case LIT:
      mpz_set (r, e->operands.val);
      return;
    case PLUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_add (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MINUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_sub (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MULT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_mul (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case DIV:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_q (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MOD:
      mpz_init (rhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_abs (rhs, rhs);
      mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
      mpz_clear (rhs);
      return;
    case REM:
      /* Check if lhs operand is POW expression and optimize for that case.  */
      if (e->operands.ops.lhs->op == POW)
	{
	  mpz_t powlhs, powrhs;
	  mpz_init (powlhs);
	  mpz_init (powrhs);
	  mpz_init (rhs);
	  mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
	  mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
	  mpz_eval_expr (rhs, e->operands.ops.rhs);
	  mpz_powm (r, powlhs, powrhs, rhs);
	  if (mpz_cmp_si (rhs, 0L) < 0)
	    mpz_neg (r, r);
	  mpz_clear (powlhs);
	  mpz_clear (powrhs);
	  mpz_clear (rhs);
	  return;
	}

      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_r (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION >= 2
    case INVMOD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_invert (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case POW:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmpabs_ui (lhs, 1) <= 0)
	{
	  /* For 0^rhs and 1^rhs, we just need to verify that
	     rhs is well-defined.  For (-1)^rhs we need to
	     determine (rhs mod 2).  For simplicity, compute
	     (rhs mod 2) for all three cases.  */
	  expr_t two, et;
	  two = malloc (sizeof (struct expr));
	  two -> op = LIT;
	  mpz_init_set_ui (two->operands.val, 2L);
	  makeexp (&et, MOD, e->operands.ops.rhs, two);
	  e->operands.ops.rhs = et;
	}

      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_cmp_si (rhs, 0L) == 0)
	/* x^0 is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, 0L) == 0)
	/* 0^y (where y != 0) is 0 */
	mpz_set_ui (r, 0L);
      else if (mpz_cmp_ui (lhs, 1L) == 0)
	/* 1^y is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, -1L) == 0)
	/* (-1)^y just depends on whether y is even or odd */
	mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
      else if (mpz_cmp_si (rhs, 0L) < 0)
	/* x^(-n) is 0 */
	mpz_set_ui (r, 0L);
      else
	{
	  unsigned long int cnt;
	  unsigned long int y;
	  /* error if exponent does not fit into an unsigned long int.  */
	  if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	    goto pow_err;

	  y = mpz_get_ui (rhs);
	  /* x^y == (x/(2^c))^y * 2^(c*y) */
#if __GNU_MP_VERSION >= 2
	  cnt = mpz_scan1 (lhs, 0);
#else
	  cnt = 0;
#endif
	  if (cnt != 0)
	    {
	      if (y * cnt / cnt != y)
		goto pow_err;
	      mpz_tdiv_q_2exp (lhs, lhs, cnt);
	      mpz_pow_ui (r, lhs, y);
	      mpz_mul_2exp (r, r, y * cnt);
	    }
	  else
	    mpz_pow_ui (r, lhs, y);
	}
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    pow_err:
      error = "result of `pow' operator too large";
      mpz_clear (lhs); mpz_clear (rhs);
      longjmp (errjmpbuf, 1);
    case GCD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_gcd (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case LCM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_lcm (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case AND:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_and (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case IOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_ior (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case XOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_xor (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case NEG:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_neg (r, r);
      return;
    case NOT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_com (r, r);
      return;
    case SQRT:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_sgn (lhs) < 0)
	{
	  error = "cannot take square root of negative numbers";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_sqrt (r, lhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case ROOT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_sgn (rhs) <= 0)
	{
	  error = "cannot take non-positive root orders";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}
      if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
	{
	  error = "cannot take even root orders of negative numbers";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}

      {
	unsigned long int nth = mpz_get_ui (rhs);
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    /* If we are asked to take an awfully large root order, cheat and
	       ask for the largest order we can pass to mpz_root.  This saves
	       some error prone special cases.  */
	    nth = ~(unsigned long int) 0;
	  }
	mpz_root (r, lhs, nth);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case FAC:
      mpz_eval_expr (r, e->operands.ops.lhs);
      if (mpz_size (r) > 1)
	{
	  error = "result of `!' operator too large";
	  longjmp (errjmpbuf, 1);
	}
      mpz_fac_ui (r, mpz_get_ui (r));
      return;
#if __GNU_MP_VERSION >= 2
    case POPCNT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { long int cnt;
	cnt = mpz_popcount (r);
	mpz_set_si (r, cnt);
      }
      return;
    case HAMDIST:
      { long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	cnt = mpz_hamdist (lhs, rhs);
	mpz_clear (lhs); mpz_clear (rhs);
	mpz_set_si (r, cnt);
      }
      return;
#endif
    case LOG2:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { unsigned long int cnt;
	if (mpz_sgn (r) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (r, 2);
	mpz_set_ui (r, cnt - 1);
      }
      return;
    case LOG:
      { unsigned long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	if (mpz_sgn (lhs) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	if (mpz_cmp_ui (rhs, 256) >= 0)
	  {
	    error = "logarithm base too large";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
	mpz_set_ui (r, cnt - 1);
	mpz_clear (lhs); mpz_clear (rhs);
      }
      return;
    case FERMAT:
      {
	unsigned long int t;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	t = (unsigned long int) 1 << mpz_get_ui (lhs);
	if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
	  {
	    error = "too large Mersenne number index";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	mpz_set_ui (r, 1);
	mpz_mul_2exp (r, r, t);
	mpz_add_ui (r, r, 1);
	mpz_clear (lhs);
      }
      return;
    case MERSENNE:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
	{
	  error = "too large Mersenne number index";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_set_ui (r, 1);
      mpz_mul_2exp (r, r, mpz_get_ui (lhs));
      mpz_sub_ui (r, r, 1);
      mpz_clear (lhs);
      return;
    case FIBONACCI:
      { mpz_t t;
	unsigned long int n, i;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "Fibonacci index out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);

#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
	mpz_fib_ui (r, n);
#else
	mpz_init_set_ui (t, 1);
	mpz_set_ui (r, 1);

	if (n <= 2)
	  mpz_set_ui (r, 1);
	else
	  {
	    for (i = 3; i <= n; i++)
	      {
		mpz_add (t, t, r);
		mpz_swap (t, r);
	      }
	  }
	mpz_clear (t);
#endif
      }
      return;
    case RANDOM:
      {
	unsigned long int n;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "random number size out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);
	mpz_urandomb (r, rstate, n);
      }
      return;
    case NEXTPRIME:
      {
	mpz_eval_expr (r, e->operands.ops.lhs);
	mpz_nextprime (r, r);
      }
      return;
    case BINOM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      {
	unsigned long int k;
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    error = "k too large in (n over k) expression";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	k = mpz_get_ui (rhs);
	mpz_bin_ui (r, lhs, k);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case TIMING:
      {
	int t0;
	t0 = cputime ();
	mpz_eval_expr (r, e->operands.ops.lhs);
	printf ("time: %d\n", cputime () - t0);
      }
      return;
    default:
      abort ();
    }
}
Beispiel #9
0
/* Function to calculate the expected number of unique codes 
   within each input success class                      */
void uniquecodes(mpfr_t *ucodes, int psiz, mpz_t n, unsigned long int mu, mpz_t ncodes ,mpfr_t *pdf,mpfr_prec_t prec)
{
//200 bits precision gives log[2^200] around 60 digits decimal precision
 mpfr_t unity;
 mpfr_init2(unity,prec);
 mpfr_set_ui(unity,(unsigned long int) 1,MPFR_RNDN);
 mpfr_t nunity;
 mpfr_init2(nunity,prec);
 mpfr_set_si(nunity,(signed long int) -1,MPFR_RNDN);
 mpz_t bcnum;
 mpz_init(bcnum);
 mpfr_t bcnumf;
 mpfr_init2(bcnumf,prec);
 mpq_t cfrac;
 mpq_init(cfrac);
 mpfr_t cfracf;
 mpfr_init2(cfracf,prec);
 mpfr_t expargr;
 mpfr_init2(expargr,prec); 			
 mpfr_t r1;
 mpfr_init2(r1,prec);
 mpfr_t r2;
 mpfr_init2(r2,prec);
// mpfr_t pdf[mu];
 unsigned long int i;
 int pdex;
 int addr;
// for(i=0;i<=mu;i++)
//  mpfr_init2(pdf[i],prec);
 
// inpdf(pdf,n,pin,mu,bcs,prec);

for(pdex=0;pdex<=psiz-1;pdex++)
{
 for(i=0;i<=mu;i++)
 {
  addr=pdex*(mu+1)+i;
  mpz_bin_ui(bcnum,n,i);
  mpq_set_num(cfrac,ncodes);
  mpq_set_den(cfrac,bcnum);
  mpq_canonicalize(cfrac);
  mpfr_set_q(cfracf,cfrac,MPFR_RNDN);
  mpfr_mul(expargr,cfracf,*(pdf+addr),MPFR_RNDN);   
  mpfr_mul(expargr,expargr,nunity,MPFR_RNDN);
  mpfr_exp(r1,expargr,MPFR_RNDN);      
  mpfr_sub(r1,unity,r1,MPFR_RNDN);
  mpfr_set_z(bcnumf,bcnum,MPFR_RNDN); 			
  mpfr_mul(r2,bcnumf,r1,MPFR_RNDN);
  mpfr_set((*ucodes+addr),r2,MPFR_RNDN);          
  mpfr_round((*ucodes+addr),(*ucodes+addr));
 } 
} 
 mpfr_clear(unity);
 mpfr_clear(nunity);
 mpz_clear(bcnum);
 mpfr_clear(bcnumf);
 mpq_clear(cfrac);
 mpfr_clear(cfracf);
 mpfr_clear(expargr);
 mpfr_clear(r1);
 mpfr_clear(r2);
// for(i=0;i<=mu;i++)
//  mpfr_clear(pdf[i]);
} 
Beispiel #10
0
/************************************************************
* We used the GMP library's unsigned long long binomial
* coefficient function whose data will be used in the aks.cpp
* file. This is where most of the program's optimizations will
* be needed as we could use dynamic programming for this 
* portion of our program's tasks. This would greatly speed
* up our program and is really the bottleneck that makes
* our program take so long for large numbers. However, we 
* must marvel at the fact that while it takes a long time,
* our program can handle transcendentally large numbers and
* determine whether they are prime or composite in  puesdo-
* polynomial time! The dynamic programming optimization will
* have to wait for another day! But we hope to make time
* for it in the near future!
*************************************************************/
void binomial (mpz_t retVal, mpz_t topNum, mpz_t bottomNum)
{
  unsigned long long temp = mpz_get_ull(bottomNum);
  mpz_bin_ui(retVal, topNum, temp);  
}
Beispiel #11
0
/*------------------------------------------------------------------------*/
int my_mpfr_beta (mpfr_t R, mpfr_t a, mpfr_t b, mpfr_rnd_t RND)
{
    mpfr_prec_t p_a = mpfr_get_prec(a), p_b = mpfr_get_prec(b);
    if(p_a < p_b) p_a = p_b;// p_a := max(p_a, p_b)
    if(mpfr_get_prec(R) < p_a)
	mpfr_prec_round(R, p_a, RND);// so prec(R) = max( prec(a), prec(b) )
    int ans;
    mpfr_t s; mpfr_init2(s, p_a);
#ifdef DEBUG_Rmpfr
    R_CheckUserInterrupt();
    int cc = 0;
#endif

    /* "FIXME": check each 'ans' below, and return when not ok ... */
    ans = mpfr_add(s, a, b, RND);

    if(mpfr_integer_p(s) && mpfr_sgn(s) <= 0) { // (a + b) is integer <= 0
	if(!mpfr_integer_p(a) && !mpfr_integer_p(b)) {
	    // but a,b not integer ==> R =  finite / +-Inf  = 0 :
	    mpfr_set_zero (R, +1);
	    mpfr_clear (s);
	    return ans;
	}// else: sum is integer; at least one {a,b} integer ==> both integer

	int sX = mpfr_sgn(a), sY = mpfr_sgn(b);
	if(sX * sY < 0) { // one negative, one positive integer
	    // ==> special treatment here :
	    if(sY < 0) // ==> sX > 0; swap the two
		mpfr_swap(a, b);
	    // now have --- a < 0 < b <= |a|  integer ------------------
	    /*              ================  and in this case:
	       B(a,b) = (-1)^b  B(1-a-b, b) = (-1)^b B(1-s, b)

		      = (1*2*..*b) / (-s-1)*(-s-2)*...*(-s-b)
	    */
	    /* where in the 2nd form, both numerator and denominator have exactly
	     * b integer factors. This is attractive {numerically & speed wise}
	     * for 'small' b */
#define b_large 100
#ifdef DEBUG_Rmpfr
	    Rprintf(" my_mpfr_beta(<neg int>): s = a+b= "); R_PRT(s);
	    Rprintf("\n   a = "); R_PRT(a);
	    Rprintf("\n   b = "); R_PRT(b); Rprintf("\n");
	    if(cc++ > 999) { mpfr_set_zero (R, +1); mpfr_clear (s); return ans; }
#endif
	    unsigned long b_ = 0;// -Wall
	    Rboolean
		b_fits_ulong = mpfr_fits_ulong_p(b, RND),
		small_b = b_fits_ulong &&  (b_ = mpfr_get_ui(b, RND)) < b_large;
	    if(small_b) {
#ifdef DEBUG_Rmpfr
		Rprintf("   b <= b_large = %d...\n", b_large);
#endif
		//----------------- small b ------------------
		// use GMP big integer arithmetic:
		mpz_t S; mpz_init(S); mpfr_get_z(S, s, RND); // S := s
		mpz_sub_ui (S, S, (unsigned long) 1); // S = s - 1 = (a+b-1)
		/* binomial coefficient choose(N, k) requires k a 'long int';
		 * here, b must fit into a long: */
		mpz_bin_ui (S, S, b_); // S = choose(S, b) = choose(a+b-1, b)
		mpz_mul_ui (S, S, b_); // S = S*b =  b * choose(a+b-1, b)
		// back to mpfr: R = 1 / S  = 1 / (b * choose(a+b-1, b))
		mpfr_set_ui(s, (unsigned long) 1, RND);
		mpfr_div_z(R, s, S, RND);
		mpz_clear(S);
	    }
	    else { // b is "large", use direct B(.,.) formula
#ifdef DEBUG_Rmpfr
		Rprintf("   b > b_large = %d...\n", b_large);
#endif
		// a := (-1)^b :
		// there is no  mpfr_si_pow(a, -1, b, RND);
		int neg; // := 1 ("TRUE") if (-1)^b = -1, i.e. iff  b is odd
		if(b_fits_ulong) { // (i.e. not very large)
		    neg = (b_ % 2); // 1 iff b_ is odd,  0 otherwise
		} else { // really large b; as we know it is integer, can still..
		    // b2 := b / 2
		    mpfr_t b2; mpfr_init2(b2, p_a);
		    mpfr_div_2ui(b2, b, 1, RND);
		    neg = !mpfr_integer_p(b2); // b is odd, if b/2 is *not* integer
#ifdef DEBUG_Rmpfr
		    Rprintf("   really large b; neg = ('b is odd') = %d\n", neg);
#endif
		}
		// s' := 1-s = 1-a-b
		mpfr_ui_sub(s, 1, s, RND);
#ifdef DEBUG_Rmpfr
		Rprintf("  neg = %d\n", neg);
		Rprintf("  s' = 1-a-b = "); R_PRT(s);
		Rprintf("\n  -> calling B(s',b)\n");
#endif
		// R := B(1-a-b, b) = B(s', b)
		if(small_b) {
		    my_mpfr_beta (R, s, b, RND);
		} else {
		    my_mpfr_lbeta (R, s, b, RND);
		    mpfr_exp(R, R, RND); // correct *if* beta() >= 0
		}
#ifdef DEBUG_Rmpfr
		Rprintf("  R' = beta(s',b) = "); R_PRT(R); Rprintf("\n");
#endif
		// Result = (-1)^b  B(1-a-b, b) = +/- s'
		if(neg) mpfr_neg(R, R, RND);
	    }
	    mpfr_clear(s);
	    return ans;
	}
   }

    ans = mpfr_gamma(s, s, RND);  /* s = gamma(a + b) */
#ifdef DEBUG_Rmpfr
    Rprintf("my_mpfr_beta(): s = gamma(a+b)= "); R_PRT(s);
    Rprintf("\n   a = "); R_PRT(a);
    Rprintf("\n   b = "); R_PRT(b);
#endif

    ans = mpfr_gamma(a, a, RND);
    ans = mpfr_gamma(b, b, RND);
    ans = mpfr_mul(b, b, a, RND); /* b' = gamma(a) * gamma(b) */

#ifdef DEBUG_Rmpfr
    Rprintf("\n    G(a) * G(b) = "); R_PRT(b); Rprintf("\n");
#endif

    ans = mpfr_div(R, b, s, RND);
    mpfr_clear (s);
    /* mpfr_free_cache() must be called in the caller !*/
    return ans;
}
Beispiel #12
0
int my_mpfr_lbeta(mpfr_t R, mpfr_t a, mpfr_t b, mpfr_rnd_t RND)
{
    mpfr_prec_t p_a = mpfr_get_prec(a), p_b = mpfr_get_prec(b);
    if(p_a < p_b) p_a = p_b;// p_a := max(p_a, p_b)
    if(mpfr_get_prec(R) < p_a)
	mpfr_prec_round(R, p_a, RND);// so prec(R) = max( prec(a), prec(b) )
    int ans;
    mpfr_t s;
    mpfr_init2(s, p_a);

    /* "FIXME": check each 'ans' below, and return when not ok ... */
    ans = mpfr_add(s, a, b, RND);

    if(mpfr_integer_p(s) && mpfr_sgn(s) <= 0) { // (a + b) is integer <= 0
	if(!mpfr_integer_p(a) && !mpfr_integer_p(b)) {
	    // but a,b not integer ==> R = ln(finite / +-Inf) = ln(0) = -Inf :
	    mpfr_set_inf (R, -1);
	    mpfr_clear (s);
	    return ans;
	}// else: sum is integer; at least one integer ==> both integer

	int sX = mpfr_sgn(a), sY = mpfr_sgn(b);
	if(sX * sY < 0) { // one negative, one positive integer
	    // ==> special treatment here :
	    if(sY < 0) // ==> sX > 0; swap the two
		mpfr_swap(a, b);
	    /* now have --- a < 0 < b <= |a|  integer ------------------
	     *              ================
	     * --> see my_mpfr_beta() above */
	    unsigned long b_ = 0;// -Wall
	    Rboolean
		b_fits_ulong = mpfr_fits_ulong_p(b, RND),
		small_b = b_fits_ulong &&  (b_ = mpfr_get_ui(b, RND)) < b_large;
	    if(small_b) {
		//----------------- small b ------------------
		// use GMP big integer arithmetic:
		mpz_t S; mpz_init(S); mpfr_get_z(S, s, RND); // S := s
		mpz_sub_ui (S, S, (unsigned long) 1); // S = s - 1 = (a+b-1)
		/* binomial coefficient choose(N, k) requires k a 'long int';
		 * here, b must fit into a long: */
		mpz_bin_ui (S, S, b_); // S = choose(S, b) = choose(a+b-1, b)
		mpz_mul_ui (S, S, b_); // S = S*b =  b * choose(a+b-1, b)

		// back to mpfr: R = log(|1 / S|) =  - log(|S|)
		mpz_abs(S, S);
		mpfr_set_z(s, S, RND); // <mpfr> s :=  |S|
		mpfr_log(R, s, RND);   // R := log(s) = log(|S|)
		mpfr_neg(R, R, RND);   // R = -R = -log(|S|)
		mpz_clear(S);
	    }
	    else { // b is "large", use direct B(.,.) formula
		// a := (-1)^b -- not needed here, neither 'neg': want log( |.| )
		// s' := 1-s = 1-a-b
		mpfr_ui_sub(s, 1, s, RND);
		// R := log(|B(1-a-b, b)|) = log(|B(s', b)|)
		my_mpfr_lbeta (R, s, b, RND);
	    }
	    mpfr_clear(s);
	    return ans;
	}
    }

    ans = mpfr_lngamma(s, s, RND); // s = lngamma(a + b)
    ans = mpfr_lngamma(a, a, RND);
    ans = mpfr_lngamma(b, b, RND);
    ans = mpfr_add (b, b, a, RND); // b' = lngamma(a) + lngamma(b)
    ans = mpfr_sub (R, b, s, RND);

    mpfr_clear (s);
    return ans;
}