Rev 25118 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
\name{Random.user}\title{User-supplied Random Number Generation}\alias{Random.user}\description{Function \code{\link{RNGkind}} allows user-coded uniform andnormal random number generators to be supplied. The details are givenhere.}\details{A user-specified uniform RNG is called from entry points indynamically-loaded compiled code. The user must supply the entry point\code{user_unif_rand}, which takes no arguments and returns a\emph{pointer to} a double. The example below will show the generalpattern.Optionally, the user can supply the entry point \code{user_unif_init},which is called with an \code{unsigned int} argument when\code{\link{RNGkind}} (or \code{set.seed}) is called, and is intendedto be used to initialize the user's RNG code. The argument is intendedto be used to set the \dQuote{seeds}; it is the \code{seed} argument to\code{set.seed} or an essentially random seed if \code{\link{RNGkind}}is called.If only these functions are supplied, no information about thegenerator's state is recorded in \code{.Random.seed}. Optionally,functions \code{user_unif_nseed} and \code{user_unif_seedloc} can besupplied which are called with no arguments and should return pointersto the number of \dQuote{seeds} and to an integer array of\dQuote{seeds}. Callsto \code{GetRNGstate} and \code{PutRNGstate} will then copy this arrayto and from \code{.Random.seed}.A user-specified normal RNG is specified by a single entry point\code{user_norm_rand}, which takes no arguments and returns a\emph{pointer to} a double.}\section{Warning}{As with all compiled code, mis-specifying thesefunctions can crash \R. Do include the \file{R\_ext/Random.h}header file for type checking.}\examples{\dontrun{## Marsaglia's conguential PRNG#include <R_ext/Random.h>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 <math.h>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 SHLIB urand.cR> dyn.load("urand.so")> RNGkind("user")> runif(10)> .Random.seed> RNGkind(, "user")> rnorm(10)> RNGkind()[1] "user-supplied" "user-supplied"}}\keyword{distribution}\keyword{sysdata}