static void randiset_lc (gmp_randstate_ptr dst, gmp_randstate_srcptr src) { gmp_rand_lc_struct *dstp, *srcp; srcp = (gmp_rand_lc_struct *) RNG_STATE (src); dstp = (*__gmp_allocate_func) (sizeof (gmp_rand_lc_struct)); RNG_STATE (dst) = (void *) dstp; RNG_FNPTR (dst) = (void *) &Linear_Congruential_Generator; /* _mp_seed and _mp_a might be unnormalized (high zero limbs), but mpz_init_set won't worry about that */ mpz_init_set (dstp->_mp_seed, srcp->_mp_seed); mpz_init_set (dstp->_mp_a, srcp->_mp_a); dstp->_cn = srcp->_cn; dstp->_cp[0] = srcp->_cp[0]; if (LIMBS_PER_ULONG > 1) dstp->_cp[1] = srcp->_cp[1]; if (LIMBS_PER_ULONG > 2) /* usually there's only 1 or 2 */ MPN_COPY (dstp->_cp + 2, srcp->_cp + 2, LIMBS_PER_ULONG - 2); dstp->_mp_m2exp = srcp->_mp_m2exp; }
void gmp_randinit_lc_2exp (gmp_randstate_t rstate, mpz_srcptr a, unsigned long int c, mp_bitcnt_t m2exp) { gmp_rand_lc_struct *p; mp_size_t seedn = BITS_TO_LIMBS (m2exp); ASSERT_ALWAYS (m2exp != 0); p = __GMP_ALLOCATE_FUNC_TYPE (1, gmp_rand_lc_struct); RNG_STATE (rstate) = (void *) p; RNG_FNPTR (rstate) = (void *) &Linear_Congruential_Generator; /* allocate m2exp bits of space for p->_mp_seed, and initial seed "1" */ mpz_init2 (p->_mp_seed, m2exp); MPN_ZERO (PTR (p->_mp_seed), seedn); SIZ (p->_mp_seed) = seedn; PTR (p->_mp_seed)[0] = 1; /* "a", forced to 0 to 2^m2exp-1 */ mpz_init (p->_mp_a); mpz_fdiv_r_2exp (p->_mp_a, a, m2exp); /* Avoid SIZ(a) == 0 to avoid checking for special case in lc(). */ if (SIZ (p->_mp_a) == 0) { SIZ (p->_mp_a) = 1; PTR (p->_mp_a)[0] = CNST_LIMB (0); } MPN_SET_UI (p->_cp, p->_cn, c); /* Internally we may discard any bits of c above m2exp. The following code ensures that __GMPN_ADD in lc() will always work. */ if (seedn < p->_cn) p->_cn = (p->_cp[0] != 0); p->_mp_m2exp = m2exp; }
/* Initialize MT-specific data. */ void gmp_randinit_mt (gmp_randstate_t rstate) { __gmp_randinit_mt_noseed (rstate); RNG_FNPTR (rstate) = (void *) &Mersenne_Twister_Generator; }
void gmp_randseed (gmp_randstate_t rstate, mpz_srcptr seed) { (*((gmp_randfnptr_t *) RNG_FNPTR (rstate))->randseed_fn) (rstate, seed); }
void gmp_randclear (gmp_randstate_t rstate) { (*((gmp_randfnptr_t *) RNG_FNPTR (rstate))->randclear_fn) (rstate); }
void gmp_randinit_set (gmp_randstate_ptr dst, gmp_randstate_srcptr src) { (*((gmp_randfnptr_t *) RNG_FNPTR (src))->randiset_fn) (dst, src); }