Exemple #1
0
inline static VALUE
f_divide(VALUE self, VALUE other,
	 VALUE (*func)(VALUE, VALUE), ID id)
{
    if (k_complex_p(other)) {
	int flo;
	get_dat2(self, other);

	flo = (k_float_p(adat->real) || k_float_p(adat->imag) ||
	       k_float_p(bdat->real) || k_float_p(bdat->imag));

	if (f_gt_p(f_abs(bdat->real), f_abs(bdat->imag))) {
	    VALUE r, n;

	    r = (*func)(bdat->imag, bdat->real);
	    n = f_mul(bdat->real, f_add(ONE, f_mul(r, r)));
	    if (flo)
		return f_complex_new2(CLASS_OF(self),
				      (*func)(self, n),
				      (*func)(f_negate(f_mul(self, r)), n));
	    return f_complex_new2(CLASS_OF(self),
				  (*func)(f_add(adat->real,
						f_mul(adat->imag, r)), n),
				  (*func)(f_sub(adat->imag,
						f_mul(adat->real, r)), n));
	}
	else {
	    VALUE r, n;

	    r = (*func)(bdat->real, bdat->imag);
	    n = f_mul(bdat->imag, f_add(ONE, f_mul(r, r)));
	    if (flo)
		return f_complex_new2(CLASS_OF(self),
				      (*func)(f_mul(self, r), n),
				      (*func)(f_negate(self), n));
	    return f_complex_new2(CLASS_OF(self),
				  (*func)(f_add(f_mul(adat->real, r),
						adat->imag), n),
				  (*func)(f_sub(f_mul(adat->imag, r),
						adat->real), n));
	}
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	get_dat1(self);

	return f_complex_new2(CLASS_OF(self),
			      (*func)(dat->real, other),
			      (*func)(dat->imag, other));
    }
    return rb_num_coerce_bin(self, other, id);
}
Exemple #2
0
inline static VALUE
f_addsub(VALUE self, VALUE anum, VALUE aden, VALUE bnum, VALUE bden, int k)
{
    VALUE num, den;

    if (FIXNUM_P(anum) && FIXNUM_P(aden) &&
	FIXNUM_P(bnum) && FIXNUM_P(bden)) {
	long an = FIX2LONG(anum);
	long ad = FIX2LONG(aden);
	long bn = FIX2LONG(bnum);
	long bd = FIX2LONG(bden);
	long ig = i_gcd(ad, bd);

	VALUE g = LONG2NUM(ig);
	VALUE a = f_imul(an, bd / ig);
	VALUE b = f_imul(bn, ad / ig);
	VALUE c;

	if (k == '+')
	    c = f_add(a, b);
	else
	    c = f_sub(a, b);

	b = f_idiv(aden, g);
	g = f_gcd(c, g);
	num = f_idiv(c, g);
	a = f_idiv(bden, g);
	den = f_mul(a, b);
    }
    else {
	VALUE g = f_gcd(aden, bden);
	VALUE a = f_mul(anum, f_idiv(bden, g));
	VALUE b = f_mul(bnum, f_idiv(aden, g));
	VALUE c;

	if (k == '+')
	    c = f_add(a, b);
	else
	    c = f_sub(a, b);

	b = f_idiv(aden, g);
	g = f_gcd(c, g);
	num = f_idiv(c, g);
	a = f_idiv(bden, g);
	den = f_mul(a, b);
    }
    return f_rational_new_no_reduce2(CLASS_OF(self), num, den);
}
Exemple #3
0
/* evaluate an expression, eval_err will indicate it any expression
   evaluation occurs */
static struct eval_value_t		/* value of the expression */
expr(struct eval_state_t *es)		/* expression evaluator */
{
  enum eval_token_t tok;
  struct eval_value_t val;

  val = term(es);
  if (eval_error)
    return err_value;

  tok = peek_next_token(es);
  switch (tok)
    {
    case tok_plus:
      (void)get_next_token(es);
      val = f_add(val, expr(es));
      if (eval_error)
	return err_value;
      break;

    case tok_minus:
      (void)get_next_token(es);
      val = f_sub(val, expr(es));
      if (eval_error)
	return err_value;
      break;

    default:;
    }

  return val;
}
Exemple #4
0
/*
 * call-seq:
 *    cmp * numeric  ->  complex
 *
 * Performs multiplication.
 *
 *    Complex(2, 3)  * Complex(2, 3)   #=> (-5+12i)
 *    Complex(900)   * Complex(1)      #=> (900+0i)
 *    Complex(-2, 9) * Complex(-9, 2)  #=> (0-85i)
 *    Complex(9, 8)  * 4               #=> (36+32i)
 *    Complex(20, 9) * 9.8             #=> (196.0+88.2i)
 */
VALUE
rb_nucomp_mul(VALUE self, VALUE other)
{
    if (k_complex_p(other)) {
	VALUE real, imag;
	VALUE areal, aimag, breal, bimag;
	int arzero, aizero, brzero, bizero;

	get_dat2(self, other);

	arzero = !!f_zero_p(areal = adat->real);
	aizero = !!f_zero_p(aimag = adat->imag);
	brzero = !!f_zero_p(breal = bdat->real);
	bizero = !!f_zero_p(bimag = bdat->imag);
	real = f_sub(safe_mul(areal, breal, arzero, brzero),
		     safe_mul(aimag, bimag, aizero, bizero));
	imag = f_add(safe_mul(areal, bimag, arzero, bizero),
		     safe_mul(aimag, breal, aizero, brzero));

	return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	get_dat1(self);

	return f_complex_new2(CLASS_OF(self),
			      f_mul(dat->real, other),
			      f_mul(dat->imag, other));
    }
    return rb_num_coerce_bin(self, other, '*');
}
Exemple #5
0
/*
 * call-seq:
 *    rat - numeric  ->  numeric_result
 *
 * Performs subtraction.
 *
 * For example:
 *
 *    Rational(2, 3)  - Rational(2, 3)   #=> (0/1)
 *    Rational(900)   - Rational(1)      #=> (899/1)
 *    Rational(-2, 9) - Rational(-9, 2)  #=> (77/18)
 *    Rational(9, 8)  - 4                #=> (23/8)
 *    Rational(20, 9) - 9.8              #=> -7.577777777777778
 */
static VALUE
nurat_sub(VALUE self, SEL sel, VALUE other)
{
    switch (TYPE(other)) {
      case T_FIXNUM:
      case T_BIGNUM:
	{
	    get_dat1(self);

	    return f_addsub(self,
			    dat->num, dat->den,
			    other, ONE, '-');
	}
      case T_FLOAT:
	return f_sub(f_to_f(self), other);
      case T_RATIONAL:
	{
	    get_dat2(self, other);

	    return f_addsub(self,
			    adat->num, adat->den,
			    bdat->num, bdat->den, '-');
	}
      default:
	return rb_num_coerce_bin(self, other, '-');
    }
}
Exemple #6
0
/*
 * This is the core of secret sharing.  This computes the coefficients
 * used in Lagrange polynomial interpolation, returning the
 * vector of logarithms of b1(xtarget), b2(xtarget), ..., bn(xtarget).
 * Takes values from the "xCoordinate" header element, inserts the
 * results in the "lagrange" header element.
 * The interpolation values come from the headers of the "shares" array,
 * plus one additional value, xInput, which is the value we are going
 * to interpolate to.
 * 
 * Returns kPGPError_OK on success, error if not all x[i] are unique.
 */
	static PGPError
sInterp(PGPByte *shares, PGPSize bodySize, PGPByte xInput, PGPUInt32 nShares)
{
	PGPUInt32		i, j;
	PGPByte			xi, xj;
	PGPUInt32		numer, denom;

#if !PGP_STATIC_SHAMIR_ARRAYS
	s_FSetup();
#endif /* !PGP_STATIC_SHAMIR_ARRAYS */

	/* First, accumulate the numerator, Prod(xInput-x[i],i=0..n) */
	numer = 0;
	for (i = 0; i < nShares; i++)
	{
		xi = HEADER(shares,bodySize,i)->xCoordinate;
		numer += f_log[ f_sub(xi, xInput) ];
	}
	/* Preliminary partial reduction */
	numer = (numer%FIELD_SIZE) + (numer/FIELD_SIZE);

	/* Then, for each coefficient, compute the corresponding denominator */
	for (i = 0; i < nShares; i++) {
		xi = HEADER(shares,bodySize,i)->xCoordinate;
		denom = 0;
		for (j = 0; j < nShares; j++) {
			xj = (i == j) ? xInput : HEADER(shares,bodySize,j)->xCoordinate;
			if (xi == xj)
				return -1;
			denom += f_log[f_sub(xi,xj)];
		}
		denom = (denom%FIELD_SIZE)+(denom/FIELD_SIZE);
		/* 0 <= denom < 2*FIELD_SIZE-1. */

		/* Now find numer/denom.  In log form, that's a subtract. */
		denom = numer + 2*FIELD_SIZE-2 - denom;
		denom = (denom%FIELD_SIZE)+(denom/FIELD_SIZE);
		denom = (denom%FIELD_SIZE)+(denom/FIELD_SIZE);

		HEADER(shares,bodySize,i)->lagrange = (PGPByte)denom;
	}
	return kPGPError_NoErr;	/* Success */
}
Exemple #7
0
static VALUE
nucomp_sub(VALUE self, VALUE other)
{
    if (k_complex_p(other)) {
	VALUE real, imag;

	get_dat2(self, other);

	real = f_sub(adat->real, bdat->real);
	imag = f_sub(adat->imag, bdat->imag);

	return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	get_dat1(self);

	return f_complex_new2(CLASS_OF(self),
			      f_sub(dat->real, other), dat->imag);
    }
    return rb_num_coerce_bin(self, other, '-');
}
Exemple #8
0
inline static VALUE
nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag)
{
#ifdef CANON
#define CL_CANON
#ifdef CL_CANON
    if (k_exact_zero_p(imag) && canonicalization)
	return real;
#else
    if (f_zero_p(imag) && canonicalization)
	return real;
#endif
#endif
    if (f_real_p(real) && f_real_p(imag))
	return nucomp_s_new_internal(klass, real, imag);
    else if (f_real_p(real)) {
	get_dat1(imag);

	return nucomp_s_new_internal(klass,
				     f_sub(real, dat->imag),
				     f_add(ZERO, dat->real));
    }
    else if (f_real_p(imag)) {
	get_dat1(real);

	return nucomp_s_new_internal(klass,
				     dat->real,
				     f_add(dat->imag, imag));
    }
    else {
	get_dat2(real, imag);

	return nucomp_s_new_internal(klass,
				     f_sub(adat->real, bdat->imag),
				     f_add(adat->imag, bdat->real));
    }
}
Exemple #9
0
static VALUE
m_sqrt(VALUE x)
{
    if (f_real_p(x)) {
	if (f_positive_p(x))
	    return m_sqrt_bang(x);
	return f_complex_new2(rb_cComplex, ZERO, m_sqrt_bang(f_negate(x)));
    }
    else {
	get_dat1(x);

	if (f_negative_p(dat->imag))
	    return f_conj(m_sqrt(f_conj(x)));
	else {
	    VALUE a = f_abs(x);
	    return f_complex_new2(rb_cComplex,
				  m_sqrt_bang(f_div(f_add(a, dat->real), TWO)),
				  m_sqrt_bang(f_div(f_sub(a, dat->real), TWO)));
	}
    }
}
Exemple #10
0
static VALUE
nurat_cmp(VALUE self, VALUE other)
{
    switch (TYPE(other)) {
      case T_FIXNUM:
      case T_BIGNUM:
	{
	    get_dat1(self);

	    if (FIXNUM_P(dat->den) && FIX2LONG(dat->den) == 1)
		return f_cmp(dat->num, other);
	    else
		return f_cmp(self, f_rational_new_bang1(CLASS_OF(self), other));
	}
      case T_FLOAT:
	return f_cmp(f_to_f(self), other);
      case T_RATIONAL:
	{
	    VALUE num1, num2;

	    get_dat2(self, other);

	    if (FIXNUM_P(adat->num) && FIXNUM_P(adat->den) &&
		FIXNUM_P(bdat->num) && FIXNUM_P(bdat->den)) {
		num1 = f_imul(FIX2LONG(adat->num), FIX2LONG(bdat->den));
		num2 = f_imul(FIX2LONG(bdat->num), FIX2LONG(adat->den));
	    }
	    else {
		num1 = f_mul(adat->num, bdat->den);
		num2 = f_mul(bdat->num, adat->den);
	    }
	    return f_cmp(f_sub(num1, num2), ZERO);
	}
      default:
	return rb_num_coerce_bin(self, other, id_cmp);
    }
}
Exemple #11
0
/*
 * call-seq:
 *    cmp ** numeric  ->  complex
 *
 * Performs exponentiation.
 *
 *    Complex('i') ** 2              #=> (-1+0i)
 *    Complex(-8) ** Rational(1, 3)  #=> (1.0000000000000002+1.7320508075688772i)
 */
static VALUE
nucomp_expt(VALUE self, VALUE other)
{
    if (k_numeric_p(other) && k_exact_zero_p(other))
	return f_complex_new_bang1(CLASS_OF(self), ONE);

    if (k_rational_p(other) && f_one_p(f_denominator(other)))
	other = f_numerator(other); /* c14n */

    if (k_complex_p(other)) {
	get_dat1(other);

	if (k_exact_zero_p(dat->imag))
	    other = dat->real; /* c14n */
    }

    if (k_complex_p(other)) {
	VALUE r, theta, nr, ntheta;

	get_dat1(other);

	r = f_abs(self);
	theta = f_arg(self);

	nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)),
			      f_mul(dat->imag, theta)));
	ntheta = f_add(f_mul(theta, dat->real),
		       f_mul(dat->imag, m_log_bang(r)));
	return f_complex_polar(CLASS_OF(self), nr, ntheta);
    }
    if (k_fixnum_p(other)) {
	if (f_gt_p(other, ZERO)) {
	    VALUE x, z;
	    long n;

	    x = self;
	    z = x;
	    n = FIX2LONG(other) - 1;

	    while (n) {
		long q, r;

		while (1) {
		    get_dat1(x);

		    q = n / 2;
		    r = n % 2;

		    if (r)
			break;

		    x = nucomp_s_new_internal(CLASS_OF(self),
				       f_sub(f_mul(dat->real, dat->real),
					     f_mul(dat->imag, dat->imag)),
				       f_mul(f_mul(TWO, dat->real), dat->imag));
		    n = q;
		}
		z = f_mul(z, x);
		n--;
	    }
	    return z;
	}
	return f_expt(f_reciprocal(self), f_negate(other));
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	VALUE r, theta;

	if (k_bignum_p(other))
	    rb_warn("in a**b, b may be too big");

	r = f_abs(self);
	theta = f_arg(self);

	return f_complex_polar(CLASS_OF(self), f_expt(r, other),
			       f_mul(theta, other));
    }
    return rb_num_coerce_bin(self, other, id_expt);
}
Exemple #12
0
int main(int argc, char** argv) {
    double lambda = atof(argv[2]);
 
    int N = atoi(argv[1]);
    double crude_mc,variance;
    crude_mc=0;
    double g_sigma = 0;
    int num_cores = 0;
 #if 0
    double start = clock();
#pragma omp parallel 
    {
        double l_sum = 0;
        double r1,r2,theta1,theta2,phi1,phi2;
        double fx = 0;
        double sum_sigma = 0;
        long idum1,idum2,idum3,idum4,idum5,idum6;
        idum1 = time(0)-123; idum2 = time(0)-383;idum3 = time(0)-73;idum4 = time(0)-239; 
        idum5 = time(0)-830;idum6 = time(0)-955;
#pragma omp for
    for(int i=0;i<N;i++){
        r1 = lambda*ran0(&idum1);
        r2 = lambda*ran0(&idum2);
        theta1 = PI*ran0(&idum3);
        theta2 = PI*ran0(&idum4);
        phi1 = 2*PI*ran0(&idum5);
        phi2 = 2*PI*ran0(&idum6);
       
        fx = r1*r1*r2*r2*f_sub(r1,r2,theta1,theta2,phi1,phi2)*exp(-4*(r1+r2));
        l_sum += fx;
        sum_sigma += fx*fx;
    }
#pragma omp critical
    {crude_mc += l_sum; g_sigma += sum_sigma;num_cores = omp_get_num_threads();}
    }
    double stop = clock();
    double diff = timediff(start,stop)*0.25;
    /*
    double var = ((pow(PI,4)*lambda*lambda*4)/N)*(g_sigma-((pow(PI,4)*lambda*lambda*4)/N)*crude_mc*crude_mc);
    cout<<"test: "<<var<<" sdv: "<<sqrt(var)<<" comparisson: "<<var/sqrt(N)<<endl;*/
    crude_mc /= ((double) N);
    g_sigma /= ((double) N);
    variance = g_sigma - crude_mc*crude_mc;
    crude_mc *= lambda*lambda*4*pow(PI,4);
    cout<<"Monte Carlo simulation with N = "<<N<<" gives "<<crude_mc<<endl;
    cout<<"The variance is "<<variance<<" and standard deviation "<<sqrt(variance)<<endl;
    cout<<"This took "<<diff<<" ms on "<<num_cores<<" cores"<<endl;
#else
    double start = clock();
#pragma omp parallel 
    {
        /*Set up private variables for the paralell execution of this loop*/
        double l_sum = 0;
        double l_sum2 = 0;
        double r1,r2,theta1,theta2,phi1,phi2;
        double fx = 0;
        double sum_sigma = 0;
        double sum_sigma2 = 0;
        long idum1,idum2,idum3,idum4,idum5,idum6;
        idum1 = time(0)-123; idum2 = time(0)-383;idum3 = time(0)-73;idum4 = time(0)-239; 
        idum5 = time(0)-830;idum6 = time(0)-955;
#pragma omp for
    
    for(int i=0;i<N;i++){
        r1 = -log(1-ran0(&idum1));
        r2 = -log(1-ran0(&idum2));
        theta1 = PI*ran0(&idum3);
        theta2 = PI*ran0(&idum4);
        phi1 = 2*PI*ran0(&idum5);
        phi2 = 2*PI*ran0(&idum6);
        fx = (1./1024)*r1*r1*r2*r2*f_sub(r1,r2,theta1,theta2,phi1,phi2);
        if (l_sum > 1e4){
            l_sum2 +=fx;
            sum_sigma2 +=fx*fx;
        }
        else{
                l_sum += fx;
                sum_sigma += fx*fx;
        }
    }
#pragma omp critical
        {
        crude_mc +=l_sum+l_sum2; 
        g_sigma += sum_sigma+sum_sigma2; 
        num_cores = omp_get_num_threads();
        }
    }
    double stop = clock();
    double diff = timediff(start,stop)*0.25;
    crude_mc /= ((double) N);
    g_sigma /= ((double) N);
    variance = g_sigma - crude_mc*crude_mc;
    crude_mc *= 4*pow(PI,4);
    cout<<"Monte Carlo simulation with (importance sampling) N = "<<N<<" gives "<<crude_mc<<endl;
    cout<<"correct result: "<<5*PI*PI/(16*16)<<endl;
    cout<<"The variance is "<<variance<<" and standard deviation "<<pow(4,PI)*sqrt(variance/((double) N))<<endl;
    cout<<"This took "<<diff<<" ms on "<<num_cores<<" cores"<<endl;
#endif
    return 0;
}
Exemple #13
0
static VALUE
nucomp_expt(VALUE self, VALUE other)
{
    if (k_exact_p(other) && f_zero_p(other))
	return f_complex_new_bang1(CLASS_OF(self), ONE);

    if (k_rational_p(other) && f_one_p(f_denominator(other)))
	other = f_numerator(other); /* good? */

    if (k_complex_p(other)) {
	VALUE a, r, theta, ore, oim, nr, ntheta;

	get_dat1(other);

	a = f_polar(self);
	r = RARRAY_PTR(a)[0];
	theta = RARRAY_PTR(a)[1];

	ore = dat->real;
	oim = dat->imag;
	nr = m_exp_bang(f_sub(f_mul(ore, m_log_bang(r)),
			      f_mul(oim, theta)));
	ntheta = f_add(f_mul(theta, ore), f_mul(oim, m_log_bang(r)));
	return f_complex_polar(CLASS_OF(self), nr, ntheta);
    }
    if (k_integer_p(other)) {
	if (f_gt_p(other, ZERO)) {
	    VALUE x, z, n;

	    x = self;
	    z = x;
	    n = f_sub(other, ONE);

	    while (f_nonzero_p(n)) {
		VALUE a;

		while (a = f_divmod(n, TWO),
		       f_zero_p(RARRAY_PTR(a)[1])) {
		    get_dat1(x);

		    x = f_complex_new2(CLASS_OF(self),
				       f_sub(f_mul(dat->real, dat->real),
					     f_mul(dat->imag, dat->imag)),
				       f_mul(f_mul(TWO, dat->real), dat->imag));
		    n = RARRAY_PTR(a)[0];
		}
		z = f_mul(z, x);
		n = f_sub(n, ONE);
	    }
	    return z;
	}
	return f_expt(f_div(f_to_r(ONE), self), f_negate(other));
    }
    if (k_numeric_p(other) && f_real_p(other)) {
	VALUE a, r, theta;

	a = f_polar(self);
	r = RARRAY_PTR(a)[0];
	theta = RARRAY_PTR(a)[1];
	return f_complex_polar(CLASS_OF(self), f_expt(r, other),
			      f_mul(theta, other));
    }
    return rb_num_coerce_bin(self, other, id_expt);
}
Exemple #14
0
/* :nodoc: */
static VALUE
nurat_quotrem(VALUE self, VALUE other)
{
    VALUE val = f_truncate(f_div(self, other));
    return rb_assoc_new(val, f_sub(self, f_mul(other, val)));
}
Exemple #15
0
static VALUE
nurat_rem(VALUE self, VALUE other)
{
    VALUE val = f_truncate(f_div(self, other));
    return f_sub(self, f_mul(other, val));
}
Exemple #16
0
static VALUE
nurat_divmod(VALUE self, VALUE other)
{
    VALUE val = f_floor(f_div(self, other));
    return rb_assoc_new(val, f_sub(self, f_mul(other, val)));
}
Exemple #17
0
static VALUE
nurat_mod(VALUE self, VALUE other)
{
    VALUE val = f_floor(f_div(self, other));
    return f_sub(self, f_mul(other, val));
}