| 42333 |
ripley |
1 |
% File src/library/base/man/Random-user.Rd
|
|
|
2 |
% Part of the R package, http://www.R-project.org
|
| 59039 |
ripley |
3 |
% Copyright 1995-2009 R Core Team
|
| 42333 |
ripley |
4 |
% Distributed under GPL 2 or later
|
|
|
5 |
|
| 7842 |
ripley |
6 |
\name{Random.user}
|
|
|
7 |
\title{User-supplied Random Number Generation}
|
| 56186 |
murdoch |
8 |
\alias{Random.user}
|
| 7842 |
ripley |
9 |
\description{
|
| 8438 |
ripley |
10 |
Function \code{\link{RNGkind}} allows user-coded uniform and
|
| 11768 |
hornik |
11 |
normal random number generators to be supplied. The details are given
|
|
|
12 |
here.
|
| 7842 |
ripley |
13 |
}
|
|
|
14 |
\details{
|
| 8438 |
ripley |
15 |
A user-specified uniform RNG is called from entry points in
|
| 55555 |
ripley |
16 |
dynamically-loaded compiled code. The user must supply the entry point
|
| 7842 |
ripley |
17 |
\code{user_unif_rand}, which takes no arguments and returns a
|
| 7850 |
ripley |
18 |
\emph{pointer to} a double. The example below will show the general
|
|
|
19 |
pattern.
|
| 7842 |
ripley |
20 |
|
|
|
21 |
Optionally, the user can supply the entry point \code{user_unif_init},
|
|
|
22 |
which is called with an \code{unsigned int} argument when
|
|
|
23 |
\code{\link{RNGkind}} (or \code{set.seed}) is called, and is intended
|
| 55555 |
ripley |
24 |
to be used to initialize the user's RNG code. The argument is intended
|
| 42961 |
ripley |
25 |
to be used to set the \sQuote{seeds}; it is the \code{seed} argument to
|
| 7842 |
ripley |
26 |
\code{set.seed} or an essentially random seed if \code{\link{RNGkind}}
|
|
|
27 |
is called.
|
|
|
28 |
|
|
|
29 |
If only these functions are supplied, no information about the
|
| 49343 |
ripley |
30 |
generator's state is recorded in \code{.Random.seed}. Optionally,
|
| 7842 |
ripley |
31 |
functions \code{user_unif_nseed} and \code{user_unif_seedloc} can be
|
| 7850 |
ripley |
32 |
supplied which are called with no arguments and should return pointers
|
| 49343 |
ripley |
33 |
to the number of seeds and to an integer (specifically, \samp{Int32})
|
|
|
34 |
array of seeds. Calls to \code{GetRNGstate} and \code{PutRNGstate}
|
|
|
35 |
will then copy this array to and from \code{.Random.seed}.
|
| 8438 |
ripley |
36 |
|
|
|
37 |
A user-specified normal RNG is specified by a single entry point
|
|
|
38 |
\code{user_norm_rand}, which takes no arguments and returns a
|
|
|
39 |
\emph{pointer to} a double.
|
| 7842 |
ripley |
40 |
}
|
|
|
41 |
\section{Warning}{As with all compiled code, mis-specifying these
|
| 47259 |
ripley |
42 |
functions can crash \R. Do include the \file{R_ext/Random.h}
|
| 7850 |
ripley |
43 |
header file for type checking.
|
| 7842 |
ripley |
44 |
}
|
|
|
45 |
\examples{\dontrun{
|
| 40615 |
ripley |
46 |
## Marsaglia's congruential PRNG
|
| 7842 |
ripley |
47 |
#include <R_ext/Random.h>
|
|
|
48 |
|
|
|
49 |
static Int32 seed;
|
|
|
50 |
static double res;
|
| 7850 |
ripley |
51 |
static int nseed = 1;
|
| 7842 |
ripley |
52 |
|
|
|
53 |
double * user_unif_rand()
|
|
|
54 |
{
|
|
|
55 |
seed = 69069 * seed + 1;
|
|
|
56 |
res = seed * 2.32830643653869e-10;
|
|
|
57 |
return &res;
|
|
|
58 |
}
|
|
|
59 |
|
|
|
60 |
void user_unif_init(Int32 seed_in) { seed = seed_in; }
|
| 7850 |
ripley |
61 |
int * user_unif_nseed() { return &nseed; }
|
| 7842 |
ripley |
62 |
int * user_unif_seedloc() { return (int *) &seed; }
|
| 8438 |
ripley |
63 |
|
|
|
64 |
/* ratio-of-uniforms for normal */
|
|
|
65 |
#include <math.h>
|
|
|
66 |
static double x;
|
|
|
67 |
|
|
|
68 |
double * user_norm_rand()
|
|
|
69 |
{
|
|
|
70 |
double u, v, z;
|
|
|
71 |
do {
|
|
|
72 |
u = unif_rand();
|
|
|
73 |
v = 0.857764 * (2. * unif_rand() - 1);
|
|
|
74 |
x = v/u; z = 0.25 * x * x;
|
|
|
75 |
if (z < 1. - u) break;
|
|
|
76 |
if (z > 0.259/u + 0.35) continue;
|
|
|
77 |
} while (z > -log(u));
|
|
|
78 |
return &x;
|
|
|
79 |
}
|
|
|
80 |
|
|
|
81 |
## Use under Unix:
|
| 35411 |
ripley |
82 |
R CMD SHLIB urand.c
|
| 8438 |
ripley |
83 |
R
|
|
|
84 |
> dyn.load("urand.so")
|
|
|
85 |
> RNGkind("user")
|
|
|
86 |
> runif(10)
|
|
|
87 |
> .Random.seed
|
|
|
88 |
> RNGkind(, "user")
|
|
|
89 |
> rnorm(10)
|
|
|
90 |
> RNGkind()
|
|
|
91 |
[1] "user-supplied" "user-supplied"
|
| 7887 |
hornik |
92 |
}}
|
| 8438 |
ripley |
93 |
\keyword{distribution}
|
|
|
94 |
\keyword{sysdata}
|