/* * 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; }
/* 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); }
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); }
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); }