Exemple #1
0
mpf_class printGrowthConstant(Motzkin& motzkinInfo, int precision = 15, int maximumIteration = -1) {
    cout << setprecision(precision);
    int i = 1;
    IterationVector old_vector(motzkinInfo, precision);
    while (1) {
        i++;
        IterationVector new_vector = old_vector.iterate();
        mpf_class temp(new_vector.cell_value(1) / old_vector.cell_value(1), precision);
        mpf_class min = temp;
        mpf_class max = temp;
        for (mpz_class j=2; j< new_vector.get_size(); j++) {
            temp = new_vector.cell_value(j) / old_vector.cell_value(j);
            if (min > temp) {
                min = temp;
            }
            if (max < temp) {
                max = temp;
            }
        }
// 		cout << "n="<<i<<endl<<"min = "<< min << endl << "max = " << max <<endl;
        if (mpf_eq(min.get_mpf_t(), max.get_mpf_t(), temp.get_prec()) || (maximumIteration > 0 && i > maximumIteration))
            return min;
        old_vector = new_vector;
    }
}
Exemple #2
0
/* 
 * Evaluate the series 1/0! + 1/1! + 1/2! + 1/3! + 1/4! ...
 * On input, 'bits' is the desired precision in bits.
 * On output, e' contains the calculated value.
 */
static void calculateE(
	unsigned bits,
	mpf_t e)
{
	mpf_t lastE;
	mpf_t invFact;					/* 1/2!, 1/3!, 1/4!, etc. */
	unsigned term;					/* 2, 3, 4... */
	
	/* initial conditions, including the first two terms */
	mpf_init_set_ui(lastE, 0);
	mpf_set_ui(e, 2);				
	mpf_init_set_ui(invFact, 1);	/* 1/1! */
	term = 2;
	
	for(;;) {
		/* invFact /= (term) */
		mpf_div_ui(invFact, invFact, term);
		/* e += 1 / (term!) */
		mpf_add(e, e, invFact);
		
		/* if e == lastE, within the requested precision, we're done */
		if(mpf_eq(e, lastE, bits)) {
			break;
		}
		mpf_set(lastE, e);
		term++;
	}
	/* free memory associated with mpf_t's we allocated */
	mpf_clear(lastE);
	mpf_clear(invFact);
}
//
// The core Gauss - Legendre routine.
// On input, 'bits' is the desired precision in bits.
// On output, 'pi' contains the calculated value.
//
static void calculatePi( unsigned bits, mpf_class & pi )
{
    mpf_class lastPi( 0.0 );
    mpf_class scratch;

    // variables per the formal Gauss - Legendre formulae
    mpf_class a;
    mpf_class b;
    mpf_class t;
    mpf_class x;
    mpf_class y;
    unsigned p = 1;

    // initial conditions
    a = 1;
    // b := 1 / sqrt( 2 )
    mpf_sqrt_ui( b.get_mpf_t( ), 2 );
    b = 1.0 / b;
    t = 0.25;

    for( ;; ) {
        x = ( a + b )/2;

        // y := sqrt( ab )
        y = a * b;
        mpf_sqrt( y.get_mpf_t( ), y.get_mpf_t( ) );

        // t := t - p * ( a - x )**2
        scratch =  a - x;
        scratch *= scratch;
        scratch *= p;
        t -= scratch;

        a = x;
        b = y;
        p <<= 1;

        // pi := ( ( a + b )**2 ) / 4t
        pi = a + b;
        pi *= pi;
        pi /= ( 4 * t );

        // if pi == lastPi, within the requested precision, we're done
        if ( mpf_eq( pi.get_mpf_t( ), lastPi.get_mpf_t( ), bits ) ) {
            break;
        }
        lastPi =  pi;
    }
}
/* 
 * Evaluate the series 1/0! + 1/1! + 1/2! + 1/3! + 1/4! ...
 * On input, 'bits' is the desired precision in bits.
 * On output, e' contains the calculated value.
 */
static void calculateE(
	unsigned bits,
	mpf_class &e)
{
	/* initial conditions, including the first two terms */
	mpf_class lastE(0.0);
	mpf_class invFact(1.0);			/* 1/2!, 1/3!, 1/4!, etc. */
	unsigned term = 2;				/* 2, 3, 4... */
	e = 2;
	
	for(;;) {
		invFact /= term;
		e += invFact;
		
		/* if e == lastE, within the requested precision, we're done */
		if(mpf_eq(e.get_mpf_t(), lastE.get_mpf_t(), bits)) {
			return;
		}
		lastE = e;
		term++;
	}
	/* NOT REACHED */
}
Exemple #5
0
void
check_random (long reps)
{
  unsigned long test;
  gmp_randstate_ptr rands = RANDS;
  mpf_t a, b, x;
  mpz_t ds;
  int hibits, lshift1, lshift2;
  int xtra;

#define HIBITS 10
#define LSHIFT1 10
#define LSHIFT2 10

  mpf_set_default_prec ((1 << HIBITS) + (1 << LSHIFT1) + (1 << LSHIFT2));

  mpz_init (ds);
  mpf_inits (a, b, x, NULL);

  for (test = 0; test < reps; test++)
    {
      mpz_urandomb (ds, rands, HIBITS);
      hibits = mpz_get_ui (ds) + 1;
      mpz_urandomb (ds, rands, hibits);
      mpz_setbit (ds, hibits  - 1);	/* make sure msb is set */
      mpf_set_z (a, ds);
      mpf_set_z (b, ds);

      mpz_urandomb (ds, rands, LSHIFT1);
      lshift1 = mpz_get_ui (ds);
      mpf_mul_2exp (a, a, lshift1 + 1);
      mpf_mul_2exp (b, b, lshift1 + 1);
      mpf_add_ui (a, a, 1);	/* make a one-bit difference */

      mpz_urandomb (ds, rands, LSHIFT2);
      lshift2 = mpz_get_ui (ds);
      mpf_mul_2exp (a, a, lshift2);
      mpf_mul_2exp (b, b, lshift2);
      mpz_urandomb (ds, rands, lshift2);
      mpf_set_z (x, ds);
      mpf_add (a, a, x);
      mpf_add (b, b, x);

      insert_random_low_zero_limbs (a, rands);
      insert_random_low_zero_limbs (b, rands);

      if (mpf_eq (a, b, lshift1 + hibits) == 0 ||
	  mpf_eq (b, a, lshift1 + hibits) == 0)
	{
	  dump_abort (a, b, lshift1 + hibits, lshift1, lshift2, hibits, 1, test);
	}
      for (xtra = 1; xtra < 100; xtra++)
	if (mpf_eq (a, b, lshift1 + hibits + xtra) != 0 ||
	    mpf_eq (b, a, lshift1 + hibits + xtra) != 0)
	  {
	    dump_abort (a, b, lshift1 + hibits + xtra, lshift1, lshift2, hibits, 0, test);
	  }
    }

  mpf_clears (a, b, x, NULL);
  mpz_clear (ds);
}
Exemple #6
0
void
check_data (void)
{
  static const struct
  {
    struct {
      int        exp, size;
      mp_limb_t  d[10];
    } x, y;
    mp_bitcnt_t bits;
    int want;

  } data[] = {
    { { 0, 0, { 0 } },             { 0, 0, { 0 } },    0, 1 },

    { { 0, 1, { 7 } },             { 0, 1, { 7 } },    0, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 7 } },   17, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 7 } }, 4711, 1 },

    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    0, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    2, 1 },
    { { 0, 1, { 7 } },             { 0, 1, { 6 } },    3, 0 },

    { { 0, 0, { 0 } },             { 0, 1, { 1 } },    0, 0 },
    { { 0, 1, { 1 } },             { 0,-1 ,{ 1 } },    0, 0 },
    { { 1, 1, { 1 } },             { 0, 1, { 1 } },    0, 0 },

    { { 0, 1, { 8 } },             { 0, 1, { 4 } },    0, 0 },

    { { 0, 2, { 0, 3 } },          { 0, 1, { 3 } }, 1000, 1 },
  };

  mpf_t  x, y;
  int got, got_swapped;
  int i;
  mp_trace_base = 16;

  for (i = 0; i < numberof (data); i++)
    {
      PTR(x) = (mp_ptr) data[i].x.d;
      SIZ(x) = data[i].x.size;
      EXP(x) = data[i].x.exp;
      PREC(x) = numberof (data[i].x.d);
      MPF_CHECK_FORMAT (x);

      PTR(y) = (mp_ptr) data[i].y.d;
      SIZ(y) = data[i].y.size;
      EXP(y) = data[i].y.exp;
      PREC(y) = numberof (data[i].y.d);
      MPF_CHECK_FORMAT (y);

      got         = mpf_eq (x, y, data[i].bits);
      got_swapped = mpf_eq (y, x, data[i].bits);

      if (got != got_swapped || got != data[i].want)
	{
	  printf ("check_data() wrong result at data[%d]\n", i);
	  mpf_trace ("x   ", x);
	  mpf_trace ("y   ", y);
	  printf ("got         %d\n", got);
	  printf ("got_swapped %d\n", got_swapped);
	  printf ("want        %d\n", data[i].want);
	  abort ();
        }
    }
}
// 
// The core Gauss-Legendre routine. 
// On input, 'bits' is the desired precision in bits.
// On output, 'pi' contains the calculated value.
//
static void calculatePi( unsigned bits, mpf_t pi)
{
	mpf_t lastPi;
	mpf_t scratch;

	// variables per the formal Gauss-Legendre formulae
	mpf_t a;
	mpf_t b;
	mpf_t t;
	mpf_t x;
	mpf_t y;
	unsigned p = 1;

	mpf_init_set_ui(lastPi, 0);
	mpf_init(x);
	mpf_init(y);
	mpf_init(scratch);
	
	// initial conditions
	mpf_init_set_ui(a, 1);		// a := 1
	mpf_init(b);				// b := 1 / sqrt(2)
	mpf_sqrt_ui(b, 2);
	mpf_ui_div(b, 1, b);
	mpf_init_set_ui(t, 4);		// t := 1/4
	mpf_ui_div(t, 1, t);
	
	for(;;) {
		// x := (a+b)/2
		mpf_add(x, a, b);
		mpf_div_ui(x, x, 2);
		
		// y := sqrt(a*b)
		mpf_mul(y, a, b);
		mpf_sqrt(y, y);
		
		// t := t - p * (a-x)**2
		mpf_sub(scratch, a, x);
		mpf_pow_ui(scratch, scratch, 2);
		mpf_mul_ui(scratch, scratch, p);
		mpf_sub(t, t, scratch);
		
		// a := x
		// b := y 
		// p := 2p 
		mpf_set(a, x);
		mpf_set(b, y);
		p <<= 1;
		
		// pi := ((a + b)**2) / 4t
		mpf_add(pi, a, b);
		mpf_pow_ui(pi, pi, 2);
		mpf_mul_ui(scratch, t, 4);
		mpf_div(pi, pi, scratch);

		// if pi == lastPi, within the requested precision, we're done
		if(mpf_eq(pi, lastPi, bits)) {
			break;
		}
		mpf_set(lastPi, pi);
	}
	// free memory associated with mpf_t's we allocated
	mpf_clear(a);
	mpf_clear(b);
	mpf_clear(t);
	mpf_clear(x);
	mpf_clear(y);
	mpf_clear(lastPi);
	mpf_clear(scratch);
}