Random.user package:base R Documentation _U_s_e_r-_s_u_p_p_l_i_e_d _R_a_n_d_o_m _N_u_m_b_e_r _G_e_n_e_r_a_t_i_o_n _D_e_s_c_r_i_p_t_i_o_n: Function 'RNGkind' allows user-coded uniform and normal random number generators to be supplied. The details are given here. _D_e_t_a_i_l_s: A user-specified uniform RNG is called from entry points in dynamically-loaded compiled code. The user must supply the entry point 'user_unif_rand', which takes no arguments and returns a _pointer to_ a double. The example below will show the general pattern. Optionally, the user can supply the entry point 'user_unif_init', which is called with an 'unsigned int' argument when 'RNGkind' (or 'set.seed') is called, and is intended to be used to initialize the user's RNG code. The argument is intended to be used to set the 'seeds'; it is the 'seed' argument to 'set.seed' or an essentially random seed if 'RNGkind' is called. If only these functions are supplied, no information about the generator's state is recorded in '.Random.seed'. Optionally, functions 'user_unif_nseed' and 'user_unif_seedloc' can be supplied which are called with no arguments and should return pointers to the number of seeds and to an integer array of seeds. Calls to 'GetRNGstate' and 'PutRNGstate' will then copy this array to and from '.Random.seed'. A user-specified normal RNG is specified by a single entry point 'user_norm_rand', which takes no arguments and returns a _pointer to_ a double. _W_a_r_n_i_n_g: As with all compiled code, mis-specifying these functions can crash R. Do include the 'R_ext/Random.h' header file for type checking. _E_x_a_m_p_l_e_s: ## Not run: ## Marsaglia's congruential PRNG #include static Int32 seed; static double res; static int nseed = 1; double * user_unif_rand() { seed = 69069 * seed + 1; res = seed * 2.32830643653869e-10; return &res; } void user_unif_init(Int32 seed_in) { seed = seed_in; } int * user_unif_nseed() { return &nseed; } int * user_unif_seedloc() { return (int *) &seed; } /* ratio-of-uniforms for normal */ #include static double x; double * user_norm_rand() { double u, v, z; do { u = unif_rand(); v = 0.857764 * (2. * unif_rand() - 1); x = v/u; z = 0.25 * x * x; if (z < 1. - u) break; if (z > 0.259/u + 0.35) continue; } while (z > -log(u)); return &x; } ## Use under Unix: R CMD SHLIB urand.c R > dyn.load("urand.so") > RNGkind("user") > runif(10) > .Random.seed > RNGkind(, "user") > rnorm(10) > RNGkind() [1] "user-supplied" "user-supplied" ## End(Not run)