Random Number Generation
| Introduction | Methods |
| Random Generation Functions | Statistical Distributions |
| Seeding and Localization | References |
Block[{trials = 10 ^ 5, count, rn},
Table[
count = 0;
rn = Range[n];
Do[If[RandomSample[rn] == rn, count++], {trials}];
{n, N[count / trials]},
{n, 2, 8}]]Table[{i, N[1 / i!]}, {i, 2, 8}]Mean[RandomVariate[NormalDistribution[0, 2], 10 ^ 6] ^ 6]Expectation[x ^ 6, xNormalDistribution[0, 2]]ListLinePlot[Join[{0.}, Accumulate[RandomReal[{-1, 1}, {100}]]]]Max[Abs[Sqrt[x ^ 2] - Abs[x] /. x -> RandomReal[{-10, 10}, 10000]]]Max[Abs[Sqrt[x ^ 2] - Abs[x] /. x -> RandomComplex[{-10 + 10I, 10 + 10I}, 10000]]]ListPlot[Tally[RandomPrime[50, 10 ^ 5]], Filling -> Axis, PlotRange -> {0, Automatic}]Random Numbers
| RandomReal[] | give a pseudorandom real number in the range 0 to 1 |
| RandomReal[{xmin,xmax}] | give a pseudorandom real number in the range xmin to xmax |
| RandomReal[xmax] | give a pseudorandom real number in the range 0 to xmax |
| RandomReal[domain,n] | give a list of n pseudorandom reals |
| RandomReal[domain,{n1,n2,…}] | give an n1×n2×… array of pseudorandom reals |
| RandomInteger[{imin,imax}] | give a pseudorandom integer in the range {imin,…,imax} |
| RandomInteger[imax] | give a pseudorandom integer in the range {0,…,imax} |
| RandomInteger[] | pseudorandomly give 0 or 1 with probability |
| RandomInteger[domain,n] | give a list of n pseudorandom integers |
| RandomInteger[domain,{n1,n2,…}] | give an n1×n2×… array of pseudorandom integers |
| RandomComplex[] | give a pseudorandom complex number in the unit square |
| RandomComplex[{zmin,zmax}] | give a pseudorandom complex number in the rectangle bounded by zmin and zmax |
| RandomComplex[zmax] | give a pseudorandom complex number in the rectangle bounded by 0 and zmax |
| RandomComplex[domain,n] | give a list of n pseudorandom complex numbers |
| RandomComplex[domain,{n1,n2,…}] | give an n1×n2×… array of pseudorandom complex numbers |
| RandomVariate[dist] | give a pseudorandom value from the distribution dist |
| RandomVariate[dist,n] | give a list of n pseudorandom values from dist |
| RandomVariate[dist,{n1,n2,…}] | give an n1×n2×… array of pseudorandom values from dist |
| RandomPrime[{imin,imax}] | give a pseudorandom prime in the range {imin,…,imax} |
| RandomPrime[imax] | give a pseudorandom prime in the range 2 to imax |
| RandomPrime[domain,n] | give a list of n pseudorandom primes |
| RandomPrime[domain,{n1,n2,…}] | give an n1×n2×… array of pseudorandom primes |
Timing[RandomReal[1, 10 ^ 7];]Timing[Table[RandomReal[1], {10 ^ 7}];]Timing[RandomInteger[100, {100, 100, 100, 10}];]Timing[RandomInteger[100, 10 ^ 7];]Timing[Table[RandomInteger[100, {10}], {100}, {100}, {100}];]Timing[RandomVariate[WeibullDistribution[2, 1], 10 ^ 5]//Length]Timing[Table[RandomVariate[WeibullDistribution[2, 1]], {10 ^ 5}]//Length]digits = Apply[StringJoin, Map[ToString, RandomInteger[9, 5]]]pistring = StringJoin[Map[ToString, RealDigits[N[Pi, 10 ^ 6]][[1]]]];StringPosition[pistring, digits]Block[{count = 0, ev},
Do[ev = Eigenvalues[RandomReal[{0, 1}, {5, 5}]];
If[Re[ev] == ev, count++], {10 ^ 5}];
N[count / 10 ^ 5]]Block[{count = 0, ev},
Do[ev = Eigenvalues[RandomVariate[NormalDistribution[0, 1], {5, 5}]];
If[Re[ev] == ev, count++], {10 ^ 5}];
N[count / 10 ^ 5]]sampler[len_] := Block[{y0, dist1, dist2, x0},
y0 = .5;
dist1[y_] := RandomVariate[BinomialDistribution[16, y]];dist2[x_] := RandomVariate[BetaDistribution[x + 2, 16 - x + 4]];
Do[{x0 = dist1[y0], y0 = dist2[x0]}, {1000}];
Table[{x0 = dist1[y0], y0 = dist2[x0]}, {len}]]data = sampler[10 ^ 4];frqs = Sort[Tally[data[[All, 1]]]];
BarChart[frqs[[All, 2]] / 10 ^ 4, ChartLabels -> frqs[[All, 1]]]Histogram[data[[All, -1]], Automatic, "ProbabilityDensity"]Block[{y = .3, bcounts, probs, cdata},
cdata = Select[data, y <= #[[2]] < y + .05&][[All, 1]];
bcounts = BinCounts[cdata, {0, 17}] / Length[cdata];
probs = Table[{x - .025, PDF[BinomialDistribution[16, y], x]}, {x, 0, 16}];
ListPlot[{Transpose[{Range[0, 16], bcounts}], probs}, Filling -> Axis]]Block[{x = 1, bcounts, probs, cdata},
cdata = Select[data, #[[1]] == x&][[All, -1]];
bcounts = BinCounts[cdata, {0, 1, .05}] / Length[cdata];
probs = Table[{y - .025, CDF[BetaDistribution[x + 2, 16 - x + 4], y] - CDF[BetaDistribution[x + 2, 16 - x + 4], y - .05]}, {y, 0, 1, .05}];
ListPlot[{Transpose[{Range[.025, .975, .05], bcounts}], probs}, Filling -> Axis, PlotRange -> All]]Arbitrary-Precision Reals and Complexes
option name | default value | |
| WorkingPrecision | MachinePrecision | precision of the arithmetic to use in calculations |
RandomReal[{5, 50}, WorkingPrecision -> 25]RandomVariate[StudentTDistribution[10], WorkingPrecision -> 50]100 - Precision[BesselJ[1, RandomReal[{0, 1000}, 1000, WorkingPrecision -> 100]]]RandomComplex[7.5 + I, WorkingPrecision -> 50]RandomInteger[10, WorkingPrecision -> 50]Random Elements
| RandomChoice[{e1,e2,…}] | give a pseudorandom choice of one of the ei |
| RandomChoice[list,n] | give a list of n pseudorandom choices from list |
| RandomChoice[list,{n1,n2,…}] | give n1×n2×… pseudorandom choices from list |
| RandomChoice[{w1,w2,…}->{e1,e2,…}] | |
give a pseudorandom choice weighted by the wi | |
| RandomChoice[wlist->elist,n] | give a list of n weighted choices |
| RandomChoice[wlist->elist,{n1,n2,…}] | |
give an array of n1×n2×… array of weighted choices | |
| RandomSample[{e1,e2,…},n] | give a pseudorandom sample of n of the ei |
| RandomSample[{w1,w2,…}->{e1,e2,…},n] | |
give a pseudorandom sample of n of the ei chosen using weights wi | |
| RandomSample[{e1,e2,…}] | give a pseudorandom permutation of the ei |
| RandomSample[wlist->elist] | give a pseudorandom permutation of elist using initial weights wlist |
RandomChoice[{"heads", "tails"}, 15]RandomChoice[{.15, .1, .15, .15, .3, .15} -> Range[6], 20]RandomChoice[{1, 3, 5, 3, 1} -> Range[4, 8]]frqs = Tally[RandomChoice[{1, 3, 5, 3, 1} -> Range[4, 8], 1000]];
BarChart[frqs[[All, 2]] / 100, ChartLabels -> frqs[[All, 1]]]RandomSample[Join[Table["blue", {80}], Table["red", {45}]], 7]RandomSample[Range[10]]RandomSample[Range[10] ^ 2 -> Range[10]]data = Range[10];tallies = Tally[Table[RandomSample[data ^ 2 -> data, 1], {10 ^ 5}]]Sort[tallies][[All, 2]] / 10 ^ 5.Sort[Tally[RandomChoice[data ^ 2 -> data, 10 ^ 5]]][[All, 2]] / 10 ^ 5.N[data ^ 2 / Total[data ^ 2]]Partition[RandomSample[Range[20]], 5]| BlockRandom[expr] | evaluate expr with all pseudorandom generators localized |
| SeedRandom[n] | reset the pseudorandom generator using n as a seed |
| SeedRandom[] | reset the generator using as a seed the time of day and certain attributes of the current Wolfram Language session |
{SeedRandom[1];RandomReal[], SeedRandom[1];RandomReal[]}{BlockRandom[SeedRandom[1];RandomReal[]], BlockRandom[SeedRandom[1]];RandomReal[]}BlockRandom[SeedRandom[1];
SeedRandom[Method -> "Rule30CA"];
RandomReal[]]BlockRandom[SeedRandom[1, Method -> "Rule30CA"];
RandomReal[]]SeedRandom and BlockRandom in Parallel Computations
command | serial | parallel |
| SeedRandom[seed] | seed all current serial random generators with seed and the parallel generators with with seed + i, where i is the index for the parallel thread | seed only the random generator for the current thread with seed |
| SeedRandom[seed,Method->"ParallelGenerator"] | seed the parallel generators with seed + i, where i is the index for the parallel thread | no effect |
| SeedRandom[Method->method] | change the method for the serial random generator to method | change the method for only the random generator for the current thread to method |
| BlockRandom[expr] | evaluate expr with all pseudorandom generators localized | evaluate expr with only the pseudorandom generator for the current thread localized |
cf = Compile[{{n, _Integer}}, Total[Map[If[Norm[#] > 1., 0., 1.]&, RandomReal[1, {n, 2}]]] / n, RuntimeAttributes -> Listable, Parallelization -> True];SeedRandom[1234]; t1 = cf[ConstantArray[10 ^ 4, 20]]SeedRandom[1234]; t2 = BlockRandom[cf[ConstantArray[10 ^ 4, 20]]]Intersection[t1, t2]t3 = BlockRandom[cf[ConstantArray[10 ^ 4, 20]]];
Intersection[t1, t2, t3]cfws = Compile[{{n, _Integer}}, SeedRandom[1234];Total[Map[If[Norm[#] > 1., 0., 1.]&, RandomReal[1, {n, 2}]]] / n, RuntimeAttributes -> Listable, Parallelization -> True];t4 = cfws[ConstantArray[10 ^ 4, 20]]
Union[t4]cfwb = Compile[{{n, _Integer}}, BlockRandom[Total[Map[If[Norm[#] > 1., 0., 1.]&, RandomReal[1, {n, 2}]]] / n], RuntimeAttributes -> Listable, Parallelization -> True];t5 = cfwb[ConstantArray[10 ^ 4, 20]]
Union[t5]cfg = Compile[{{s, _Integer}}, SeedRandom[s, Method -> "ExtendedCA"], RuntimeAttributes -> Listable, Parallelization -> True];seeds = RandomInteger[{1, 2 ^ 16}, $ProcessorCount];cfg[seeds]
t6 = BlockRandom[cf[ConstantArray[10 ^ 4, $ProcessorCount]]]t7 = Map[BlockRandom[SeedRandom[#, Method -> "ExtendedCA"]; cf[10 ^ 4]]&, seeds]Sort[t6] === Sort[t7]| "Congruential" |
linear congruential generator (low
‐
quality randomness)
|
| "ExtendedCA" |
extended cellular automaton generator (default)
|
| "Legacy" | default generators prior to version 6.0 |
| "MersenneTwister" | Mersenne Twister shift register generator |
| "MKL" |
Intel MKL generator (Intel
‐
based systems)
|
| "ParallelGenerator" | used for initializing and seeding generators for parallel computations. |
| "ParallelMersenneTwister" | set of 1024 Mersenne Twister generators of period |
| "Rule30CA" | Wolfram rule 30 generator |
Map[BlockRandom[SeedRandom[2020, Method -> #];RandomInteger[10 ^ 20]]&, {"Congruential", "ExtendedCA", "Legacy", "MersenneTwister", "MKL", "Rule30CA"}]Map[BlockRandom[SeedRandom[2020, Method -> #];RandomReal[]]&, {"Congruential", "ExtendedCA", "Legacy", "MersenneTwister", "MKL", "Rule30CA"}]Congruential
option name | default value | |
| "Bits" | Automatic | specify range of bits to use for numbers constructed from bits |
| "Multiplier" | 1283839219676404755 | multiplier value |
| "Increment" | 0 | increment value |
| "Modulus" | 2305843009213693951 | modulus value |
| "ConvertToRealsDirectly" | True | whether reals should be constructed directly from the congruence relation |
lcdata = BlockRandom[SeedRandom[1, Method -> {"Congruential", "Multiplier" -> 11, "Increment" -> 0, "Modulus" -> 63}];RandomReal[1, 40]];EulerPhi[63]First[Select[Range[36], (Mod[11 ^ #, 63] === 1&)]]Partition[lcdata, 6]ListPlot[BlockRandom[SeedRandom[1, Method -> {"Congruential", "Multiplier" -> 11, "Increment" -> 0, "Modulus" -> 63}];RandomReal[1, 1000]]]ExtendedCA
option name | default value | |
| "Size" | 80 | state vector size as a multiplier of 64 |
| "Skip" | 4 | number of cells to skip |
| "Start" | 0 | which cell to start from |
BlockRandom[SeedRandom[1];RandomReal[1, 5]]BlockRandom[SeedRandom[1, Method -> "ExtendedCA"];RandomReal[1, 5]]Legacy
BlockRandom[SeedRandom[31, Method -> "Legacy"];{RandomReal[], RandomInteger[50]}]BlockRandom[SeedRandom[31];{Random[], Random[Integer, {0, 50}]}]MersenneTwister
BlockRandom[SeedRandom[1, Method -> "MersenneTwister"];RandomReal[1, 5]]Reference implementation
genrand64_int64 ()
#include <stdio.h>
#include "mt64.h"
int main(void) {
int i;
unsigned long long init[1], length=1;
init[0]=1ULL; /*SeedRandom[1, Method -> "MersenneTwister"];*/
init_by_array64(init, length);
for (i=0; i<5; i++) {
printf("%20llu\n", genrand64_int64());
}
return 0;
}
/*Output*/
7259937129391483703
7973299316636211948
16865006314979686608
5442441613857606270
14480929463982189498
Wolfram Language
BlockRandom [
SeedRandom[1, Method -> "MersenneTwister"];
RandomInteger[2 ^ 64 - 1, 5]//Column
]Reals
genrand64_real1()
#include <stdio.h>
#include "mt64.h"
int main(void) {
int i;
unsigned long long init[1], length=1;
init[0]=1ULL; /*SeedRandom[1, Method -> "MersenneTwister"];*/
init_by_array64(init, length);
for (i=0; i<3; i++) {
printf("%16.15f\n", genrand64_real1());
}
return 0;
}
/*Output*/
0.393561980389721
0.432233422048709
0.914253824284137
Wolfram Language
BlockRandom [
SeedRandom[1, Method -> "MersenneTwister"];
RandomReal[1, 3]//Column
]SeedRandom[1, Method -> "MersenneTwister"];
Column[RandomInteger[{0, 2 ^ 64 - 1}, 3] * (1. / (2 ^ 53 - 1) / 2 ^ 11), 15]MKL
| "MCG31" | 31-bit multiplicative congruential generator |
| "MCG59" | 59-bit multiplicative congruential generator |
| "MRG32K3A" | combined multiple recursive generators with two components of order 3 |
| "MersenneTwister" | Mersenne Twister shift register generator |
| "R250" | generalized feedback shift register generator |
| "WichmannHill" | Wichmann–Hill combined multiplicative congruential generators |
| "Niederreiter" | Niederreiter low-discrepancy sequence |
| "Sobol" | Sobol low-discrepancy sequence |
ListPlot[BlockRandom[
SeedRandom[Method -> {"MKL", Method -> {"Niederreiter", "Dimension" -> 2}}];RandomReal[1, {1000, 2}]],
AspectRatio -> 1, PlotStyle -> PointSize[Medium]]ListPlot[BlockRandom[
SeedRandom[Method -> {"MKL", Method -> {"Sobol", "Dimension" -> 2}}];RandomReal[1, {1000, 2}]],
AspectRatio -> 1, PlotStyle -> PointSize[Medium]]Rule30CA
BlockRandom[SeedRandom[1, Method -> "Rule30CA"];RandomInteger[10 ^ 5, {2, 3, 4}]]ParallelMersenneTwister
data = Table[BlockRandom[SeedRandom[1, Method -> {"ParallelMersenneTwister", "Index" -> i}]; RandomReal[1, 2500]], {i, 0, 1}];
ListPlot[Transpose[data], AspectRatio -> 1, PlotStyle -> PointSize[Medium]]ParallelGenerator
| "ParallelMersenneTwister" | parallel Mersenne twister generators with period |
| "ExtendedCA" | extended CA generators with different starting positions |
| f | generator f[i] used for the i th thread |
| "Default" | restores the default method |
f = With[{n = $ProcessorCount}, Function[{"ExtendedCA", "Size" -> 80 n, "Skip" -> 4 n, "Start" -> 4 #}]]cf = Compile[{{n, _Integer}}, Total[RandomInteger[1, n]], RuntimeAttributes -> Listable, Parallelization -> True];SeedRandom[1234, Method -> "ParallelGenerator"]cf[ConstantArray[10 ^ 4, $ProcessorCount]]gfun = Function[{index}, Switch[Mod[index, 8],
0, "ExtendedCA",
1, "Rule50025CA",
2, "Rule30CA",
3, "MersenneTwister",
4, "Congruential",
5, {"MKL", Method -> "MCG31"},
6, {"MKL", Method -> "MCG59"},
7, {"MKL", Method -> "MRG32K3A"}]];SeedRandom[1234, Method -> {"ParallelGenerator", Method -> gfun}]t1 = cf[ConstantArray[10 ^ 4, $ProcessorCount]]t2 = Table[BlockRandom[SeedRandom[1234 + index, Method -> gfun[index]]; cf[10 ^ 4]], {index, 0, 7}]Intersection[t1, t2]SeedRandom[Method -> {"ParallelGenerator", Method -> "Default"}]Defining Your Own Generator
| GeneratesBitsQ | set to True if the method generates bits |
| GeneratesIntegersQ | set to True if the method generates integers for a given range |
| GeneratesRealsQ | set to True if the method generates reals for a given range and precision |
Example: Multiplicative Congruential Generator
Options[MultiplicativeCongruential] = {"Multiplier" -> 123456789, "Modulus" -> 2 ^ 35 - 1};MultiplicativeCongruential/:Random`InitializeGenerator[MultiplicativeCongruential, opts___] := Module[{mult, mod, flops = Flatten[{opts, Options[MultiplicativeCongruential]}]},
mult = "Multiplier" /. flops;
If[!(IntegerQ[mult] && Positive[mult]),
Throw[$Failed]
];
mod = "Modulus" /. flops;
If[!(IntegerQ[mod] && Positive[mult]),
Throw[$Failed]
];
MultiplicativeCongruential[mult, mod, 1]];MultiplicativeCongruential[___]["GeneratesRealsQ"] := True;MultiplicativeCongruential[mult_, mod_, ___]["SeedGenerator"[seed_]] :=
MultiplicativeCongruential[mult, mod, Mod[(mult * seed), mod]];MultiplicativeCongruential[mult_, mod_, s_]["GenerateReals"[n_, {a_, b_}, prec_]] :=
Module[{x = s},
{a + (b - a)Table[x = mult * x;Mod[x, mod], {n}] / mod, MultiplicativeCongruential[mult, mod, x]}
]BlockRandom[
SeedRandom[Method -> MultiplicativeCongruential];
RandomReal[{5, 50}, 10]]BlockRandom[
SeedRandom[Method -> MultiplicativeCongruential];
RandomInteger[{5, 50}]]Example: Blum–Blum–Shub Generator
Options[BlumBlumShub] = {"BlumPrimes" -> {1267650600228229401496703981519, 1267650600228229401496704318359}, "BitWidth" -> Automatic};SpecialBlumPrimeQ[x_] := (Positive[x] && (Mod[x, 4] == 3) && PrimeQ[x])BlumBlumShub::bprime = "`1` is not a list of two distinct special Blum primes.";BlumBlumShub::bw = "Warning: the value of the option BitWidth->`1` exceeds the number `2` that has been proved cyptographically secure.";BlumBlumShub::bw1 = "The value of the option BitWidth->`1` should be a positive machine sized integer or Automatic.";BlumBlumShub/:Random`InitializeGenerator[BlumBlumShub, opts___] := Module[{n, abw, bw, flops = Flatten[{opts, Options[BlumBlumShub]}]},
n = "BlumPrimes" /. flops;
If[!And[VectorQ[n, SpecialBlumPrimeQ], Length[n] == 2, Not[Apply[Equal, n]]],
Message[BlumBlumShub::"bprime", n];
Throw[$Failed]
];
n = Apply[Times, n];
abw = Max[1, Floor[Log[2., Log[2., n]]]];
bw = "BitWidth" /. flops;
If[bw === Automatic,
bw = abw,
If[!(IntegerQ[bw] && Positive[bw]),
Message[BlumBlumShub::bwi, bw];
Throw[$Failed]];
If[bw > abw,
Message[BlumBlumShub::bw, bw, abw]];
];
BlumBlumShub[n, bw, 2 ^ bw - 1, 2]];BlumBlumShub[___]["GeneratesBitsQ"] := True;BlumBlumShub[n_, bw_, __]["BitWidth"] := bw;BlumBlumShub[n_, bw_, mask_, ___]["SeedGenerator"[seed_]] :=
Module[{x, i = 0, state = {}},
While[Length[Union[state]] < 10,
x = seed + i;
state = NestList[PowerMod[#, 2, n]&, x, 9];
];
BlumBlumShub[n, bw, mask, Last[state]]]BlumBlumShub[n_, bw_, mask_, s_]["GenerateBits"[bits_]] :=
Module[{x = PowerMod[s, 2, n]},
{BitAnd[x, mask], BlumBlumShub[n, bw, mask, x]}]BlockRandom[
SeedRandom[Method -> BlumBlumShub];
{RandomInteger[{0, 10}, 5], RandomReal[4, 5]}]| RandomVariate[dist] | give a random number from the continuous distribution dist |
| RandomVariate[dist,n] | give a list of n pseudorandom reals from dist |
| RandomVariate[dist,{n1,n2,…}] | give an n1×n2×… array of pseudorandom reals from dist |
{RandomVariate[ChiSquareDistribution[8]], RandomVariate[PoissonDistribution[100]]}RandomVariate[BetaDistribution[3, 7], WorkingPrecision -> 30]RandomVariate[MultinormalDistribution[{1, 2}, {{2, .5}, {.5, 3}}]]RandomVariate[MultinomialDistribution[20, {1 / 3, 1 / 2, 1 / 6}]]dist = ProbabilityDistribution[E ^ -x ^ 3 / Gamma[4 / 3], {x, 0, Infinity}];
RandomVariate[dist]Continuous Distributions
Timing[With[{x1 = RandomVariate[GammaDistribution[7, 1], 10 ^ 6]}, x1 / (x1 + RandomVariate[GammaDistribution[3, 1], 10 ^ 6])];]Timing[RandomVariate[BetaDistribution[7, 3], 10 ^ 6];]Timing[RandomVariate[NormalDistribution[0, 1], 10 ^ 6] / Sqrt[RandomVariate[ChiSquareDistribution[6], 10 ^ 6] / 6];]Timing[RandomVariate[StudentTDistribution[6], 10 ^ 6];]Discrete Distributions
Defining Distributional Generators
| Random`DistributionVector[expr,n,prec] | |
defines rules for generating n observations from expr with precision prec | |
NegativeOfUniform/:
Random`DistributionVector[NegativeOfUniform[a_, b_], n_Integer, prec_ ? Positive] := -RandomReal[{a, b}, n, WorkingPrecision -> prec] /;
VectorQ[{a, b}, NumericQ] && Element[{a, b}, Reals]{RandomReal[NegativeOfUniform[1, 3]], RandomReal[NegativeOfUniform[1, 3], WorkingPrecision -> 20]}RandomReal[NegativeOfUniform[7, 21], {3, 4}]NegativeOfDiscreteUniform/:
Random`DistributionVector[NegativeOfDiscreteUniform[a_Integer, b_Integer], n_Integer, Infinity] := -RandomInteger[{a, b}, n]RandomInteger[NegativeOfDiscreteUniform[1, 3], 10]Example: Normal Distribution by Inversion
Quantile[NormalDistribution[μ, σ], q]NormalByInversion/:
Random`DistributionVector[
NormalByInversion[mu_ ? (NumericQ[#] && Im[#] === 0&), sigma_ ? Positive], n_Integer, prec_ ? Positive] := mu + Sqrt[2] sigma InverseErf[-1 + 2 RandomReal[1, n, WorkingPrecision -> prec]]RandomReal[NormalByInversion[1, 2], 10](ninv = RandomReal[NormalByInversion[1, 2], 10 ^ 4]);//Timing{Mean[ninv], StandardDeviation[ninv]}(ndist = RandomVariate[NormalDistribution[1, 2], 10 ^ 4]);//Timing{Mean[ndist], StandardDeviation[ndist]}Clear[ninv, ndist]Example: Uniform Distribution on a Disk
UniformDisk/:
Random`DistributionVector[UniformDisk[r_ ? Positive], n_Integer, prec_ ? Positive] :=
r * Sqrt[RandomReal[1, n, WorkingPrecision -> prec]] *
Transpose[{Cos[#], Sin[#]}&[RandomReal[2Pi, n, WorkingPrecision -> prec]]]RandomReal[UniformDisk[2]]ListPlot[RandomReal[UniformDisk[2], 1000], AspectRatio -> 1, PlotStyle -> PointSize[Medium]]Example: Gibbs Sampler
BinomialBetaSampler/:Random`DistributionVector[
BinomialBetaSampler[m_Integer, α_ ? Positive], n_Integer, prec_ ? Positive] := Block[{y0, dist1, dist2, x0},
y0 = .5;
dist1[y_] := RandomVariate[BinomialDistribution[m, y]];dist2[x_] := RandomVariate[BetaDistribution[x + α, m - x + 4], WorkingPrecision -> prec];
Do[{x0 = dist1[y0], y0 = dist2[x0]}, {1000}];
Table[{x0 = dist1[y0], y0 = dist2[x0]}, {n}]]RandomReal[BinomialBetaSampler[16, 2], 5][1] Geman, S. and D. Geman. "Stochastic Relaxation, Gibbs Distributions, and the Bayesian Restoration of Images." IEEE Transactions on Pattern Analysis and Machine Intelligence 6, no. 6 (1984): 721–741.
[2] Casella, G. and E. I. George. "Explaining the Gibbs Sampler." The American Statistician 46, no. 3 (1992): 167–174.
[3] Matsumoto, M. and T. Nishimura. "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudorandom Number Generator." ACM Transactions on Modeling and Computer Simulation 8, no. 1 (1998): 3–30.
[4] Nishimura, T. "Tables of 64-Bit Mersenne Twisters." ACM Transactions on Modeling and Computer Simulation 10, no. 4 (2000): 348–357.
[5] Junod, P. "Cryptographic Secure Pseudo-Random Bits Generation: The Blum–Blum–Shub Generator." August 1999. http://crypto.junod.info/bbs.pdf
[6] Gentle, J. E. Random Number Generation and Monte Carlo Methods, 2nd ed. Springer-Verlag, 2003.
[7] Johnson, N. L., S. Kotz, and N. Balakrishnan. Continuous Univariate Distributions, Volume 2, 2nd ed. John Wiley & Sons, 1995.
[8] Smith, W. B. and R. R. Hocking. "Algorithm AS 53: Wishart Variate Generator." Applied Statistics 21, no. 3 (1972): 341–345.
[9] Cheng, R. C. H. and G. M. Feast. "Some Simple Gamma Variate Generators." Applied Statistics 28, no. 3 (1979): 290–295.
[10] Johnson, M. E. Multivariate Statistical Simulation. John Wiley & Sons, 1987.
[11] Jöhnk, M. D. "Erzeugung von Betaverteilten und Gammaverteilten Zufallszahlen." Metrika 8 (1964): 5–15.
[12] Cheng, R. C. H. "Generating Beta Variables with Nonintegral Shape Parameters." Communications of the ACM 21, no. 4 (1978): 317–322.
[13] Atkinson, A. C. "A Family of Switching Algorithms for the Computer Generation of Beta Random Variables." Biometrika 66, no. 1 (1979): 141–145.
[14] Bailey, R. W. "Polar Generation of Random Variates with the t-Distribution." Mathematics of Computation 62, no. 206 (1994): 779–781.
[15] Devroye, L. Non-Uniform Random Variate Generation. Springer-Verlag, 1986.
[16] Kachitvichyanukul, V. and B. W. Schmeiser. "Binomial Random Variate Generation." Communications of the ACM 31, no. 2 (1988): 216–223.
[17] Kachitvichyanukul, V. and B. W. Schmeiser. "Computer Generation of Hypergeometric Random Variates." Journal of Statistical Computation and Simulation 22, no. 2 (1985): 127–145.
[18] Ahrens, J. H. and U. Dieter. "Computer Generation of Poisson Deviates from Modified Normal Distributions." ACM Transactions on Mathematical Software 8, no. 2 (1982): 163–179.
[19] Matsumoto, M. and T. Nishimura. "Dynamic Creation of Pseudorandom Number Generators." In Proceedings of the Third International Conference on Monte Carlo and Quasi-Monte Carlo Methods in Scientific Computing: Monte Carlo and Quasi‐Monte Carlo Methods 1998, 56–69, 2000.