Пример #1
0
/*
 * call-seq:
 *   GMP::RandState.new()
 *   GMP::RandState.new(:mt) #=> uses gmp_randinit_mt
 *   GMP::RandState.new(:lc_2exp, a, c, m2exp) #=> uses gmp_randinit_lc_2exp
 *   GMP::RandState.new(:lc_2exp_size, size) #=> uses gmp_randinit_lc_2exp_size
 *
 * Initializes a new Random State object. Multiple GMP::RandState objects can
 * be instantiated. They may use different generators and the states
 * are kept separate.
 */
VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
{
  MP_RANDSTATE *rs_val;
  VALUE rs;
  VALUE algorithm, arg2, arg3, arg4;
  ID algorithm_id = rb_intern("default");
  MP_INT *a_val;
  unsigned long c_val, m2exp_val;
  unsigned long size_val;
  int free_a_val = 0;

  ID default_algorithm      = rb_intern("default");
  ID mt_algorithm           = rb_intern("mt");
  ID lc_2exp_algorithm      = rb_intern("lc_2exp");
  ID lc_2exp_size_algorithm = rb_intern("lc_2exp_size");

  (void)klass;

  mprandstate_make_struct(rs, rs_val);
  rb_scan_args(argc, argv, "04", &algorithm, &arg2, &arg3, &arg4);
  if (NIL_P(algorithm))    { algorithm_id = rb_intern("default"); }  /* default value */
  if (SYMBOL_P(algorithm)) { algorithm_id = rb_to_id(algorithm); }
  if (algorithm_id == default_algorithm ||
      algorithm_id == mt_algorithm) {
    if (argc > 1)
      rb_raise(rb_eArgError, "wrong # of arguments (%d for 0 or 1)", argc);
    gmp_randinit_default(rs_val);
  } else if (algorithm_id == lc_2exp_algorithm) {
    if (argc != 4)
      rb_raise(rb_eArgError, "wrong # of arguments (%d for 4)", argc);
    if (GMPZ_P(arg2)) {
      mpz_get_struct(arg2, a_val);
    } else if (FIXNUM_P(arg2)) {
      mpz_temp_alloc(a_val);
      mpz_init_set_ui(a_val, FIX2INT(arg2));
      free_a_val = 1;
    } else if (BIGNUM_P(arg2)) {
      mpz_temp_from_bignum(a_val, arg2);
      free_a_val = 1;
    } else {
      typeerror_as(ZXB, "b");
    }
    c_val     = NUM2LONG(arg3);
    m2exp_val = NUM2LONG(arg4);
    gmp_randinit_lc_2exp(rs_val, a_val, c_val, m2exp_val);
  } else if (algorithm_id == lc_2exp_size_algorithm) {
    if (argc != 2)
      rb_raise(rb_eArgError, "wrong # of arguments (%d for 2)", argc);
    size_val = NUM2LONG(arg2);
    if (size_val > 128)
      rb_raise(rb_eArgError, "size must be within [0..128]");
    if (gmp_randinit_lc_2exp_size (rs_val, size_val) == 0)
      rb_raise(rb_eArgError, "could not gmp_randinit_lc_2exp_size with %lu", size_val);
  }

  if (free_a_val) { mpz_temp_free(a_val); }
  rb_obj_call_init(rs, argc, argv);

  return rs;
}
Пример #2
0
/* Call (*func)() with various random number generators. */
void
call_rand_algs (void (*func) (const char *, gmp_randstate_ptr))
{
  gmp_randstate_t  rstate;
  mpz_t            a;

  mpz_init (a);

  gmp_randinit_default (rstate);
  (*func) ("gmp_randinit_default", rstate);
  gmp_randclear (rstate);

  gmp_randinit_mt (rstate);
  (*func) ("gmp_randinit_mt", rstate);
  gmp_randclear (rstate);

  gmp_randinit_lc_2exp_size (rstate, 8L);
  (*func) ("gmp_randinit_lc_2exp_size 8", rstate);
  gmp_randclear (rstate);

  gmp_randinit_lc_2exp_size (rstate, 16L);
  (*func) ("gmp_randinit_lc_2exp_size 16", rstate);
  gmp_randclear (rstate);

  gmp_randinit_lc_2exp_size (rstate, 128L);
  (*func) ("gmp_randinit_lc_2exp_size 128", rstate);
  gmp_randclear (rstate);

  /* degenerate always zeros */
  mpz_set_ui (a, 0L);
  gmp_randinit_lc_2exp (rstate, a, 0L, 8L);
  (*func) ("gmp_randinit_lc_2exp a=0 c=0 m=8", rstate);
  gmp_randclear (rstate);

  /* degenerate always FFs */
  mpz_set_ui (a, 0L);
  gmp_randinit_lc_2exp (rstate, a, 0xFFL, 8L);
  (*func) ("gmp_randinit_lc_2exp a=0 c=0xFF m=8", rstate);
  gmp_randclear (rstate);

  mpz_clear (a);
}
Пример #3
0
void mpfr_bench(mpfr_prec_t prec_a, mpfr_prec_t prec_b, mpfr_prec_t prec_c, 
		const char *b_str, const char *c_str, unsigned long seed)
{
  mpfr_t a,b,c;
  mpf_t x,y,z;
  mpz_t zz;
  gmp_randstate_t state;

  gmp_randinit_lc_2exp_size (state, 128);
  gmp_randseed_ui (state, seed);

  mpfr_init2(a, prec_a);
  mpfr_init2(b, prec_b);
  mpfr_init2(c, prec_c);

  mpf_init2(x,  prec_a);
  mpf_init2(y,  prec_b);
  mpf_init2(z,  prec_c);

  if (b_str)
    mpf_set_str(y, b_str, 10);
  else
    mpf_urandomb(y, state, prec_b);
  if (c_str)
    mpf_set_str(z, c_str, 10);
  else
    mpf_urandomb(z, state, prec_c);
  mpfr_set_f(b, y, MPFR_RNDN);
  mpfr_set_f(c, z, MPFR_RNDN);
  mpz_init (zz);
  mpz_urandomb (zz, state, 2*prec_b);

  if (verbose)
    {
      printf("B="); mpfr_out_str(stdout, 10, 0, b, MPFR_RNDD);
      printf("\nC="); mpfr_out_str(stdout, 10, 0, c, MPFR_RNDD);
      putchar('\n');
    }
  TIMP_OVERHEAD ();
#undef BENCH
#define BENCH(TEST_STR, TEST) printf(" "TEST_STR": %Lu\n", TIMP_MEASURE(TEST))
  TEST_LIST;

  mpz_clear (zz);
  mpfr_clear (a);
  mpfr_clear (b);
  mpfr_clear (c);
  mpf_clear (x);
  mpf_clear (y);
  mpf_clear (z);
  gmp_randclear (state);
}
Пример #4
0
void mpfr_stats (unsigned long num, mpfr_prec_t prec_a, mpfr_prec_t prec_b, 
		 mpfr_prec_t prec_c, unsigned long seed)
{
  mpf_t xt[num],yt[num],zt[num];
  unsigned long long mc[num][MAX_OP], m;
  mpfr_t a, b, c;
  mpf_t x, y, z;
  mpz_t zz;
  unsigned long long min,max,moy;
  gmp_randstate_t state;
  int i,j=0, op, cont;
  int imin=0, imax=0;

  mpf_init2(x, prec_a);
  mpf_init2(y, prec_b);
  mpf_init2(z, prec_c);

  mpfr_init2(a, prec_a);
  mpfr_init2(b, prec_b);
  mpfr_init2(c, prec_c);

  gmp_randinit_lc_2exp_size (state, 128);
  gmp_randseed_ui (state, seed);

  mpz_init (zz);
  mpz_urandomb (zz, state, 2*prec_b);

  TIMP_OVERHEAD ();

  for(i = 0 ; i < num ; i++)
    {
      mpf_init2(xt[i],  prec_a);
      mpf_init2(yt[i],  prec_b);
      mpf_init2(zt[i],  prec_c);
      mpf_urandomb(yt[i], state, prec_b); 
      yt[i][0]._mp_exp += (rand() % prec_b) / GMP_NUMB_BITS;
      mpf_urandomb(zt[i], state, prec_c);
      /* zt[i][0]._mp_exp += (rand() % prec_c) / GMP_NUMB_BITS; */
      for(op = 0 ; op < MAX_OP ; op++)
	mc[i][op] = 0xFFFFFFFFFFFFFFFLL;
    }

  for(j = 0, cont = 5 ; cont ; j++, cont--)
    {
      printf("Pass %d...\n", j+1);
      for(i = 0 ; i < num ; i++)
	{
	  op = 0;
	  mpf_set(y,yt[i]);
	  mpf_set(z,zt[i]);
	  mpfr_set_f(b, yt[i], MPFR_RNDN);
	  mpfr_set_f(c, zt[i], MPFR_RNDN);
#undef BENCH
#define BENCH(TEST_STR, TEST)                                           \
 m = TIMP_MEASURE(TEST); if (m < mc[i][op]) {mc[i][op] = m; cont = 4;} op++;
	  TEST_LIST;
	}

#undef BENCH
#define BENCH(TEST_STR, TEST)                                       \
  min = 0xFFFFFFFFFFFFFFFLL; max = 0LL; moy = 0LL;                  \
  for(i = 0 ; i < num ; i++) {                                      \
      if (mc[i][op] < min) imin = i, min = mc[i][op];               \
      if (mc[i][op] > max) imax = i, max = mc[i][op];               \
      moy += mc[i][op];                                             \
    }                                                               \
  printf(" %s: %Lu / %Lu.%02Lu / %Lu", TEST_STR, min,               \
	 (unsigned long long) moy/num, (moy*100LL/num)%100LL, max); \
  if (verbose) printf ("\tMIN:%e,%e\tMAX:%e,%e", mpf_get_d(yt[imin]),\
		       mpf_get_d(zt[imin]), mpf_get_d(yt[imax]),    \
		       mpf_get_d(zt[imax]));                        \
  putchar ('\n');                                                   \
  op++;

      op =0;
      TEST_LIST;
     }

  printf("End\n");
  mpz_clear (zz);
  mpfr_clear(a);
  mpfr_clear(b);
  mpfr_clear(c);
  mpf_clear(x);
  mpf_clear(y);
  mpf_clear(z);
  for(i = 0 ; i < num ; i++)
    {
      mpf_clear(xt[i]);
      mpf_clear(yt[i]);
      mpf_clear(zt[i]);
    }
  gmp_randclear(state);
}