1
$\begingroup$

I am trying to efficiently sample from a known probability distribution.

If I have the interval $I=[0,m]$, and consider a partition on $I$ consisting of $n$ bins, how do I then uniformly draw a random variable $X$ which has the value $X \in \{1,2,\dots,n\}$ with probability given by the widths of the corresponding bin?

I have been drawing a uniform variate between $0$ and $m$, and then determining which bin it is in, but this quite is slow for large $n$.

$\endgroup$
  • 1
    $\begingroup$ Look up Differences and RandomChoice (with weights). $\endgroup$ – Szabolcs Feb 10 '18 at 15:47
  • $\begingroup$ Ok RandomChoice, I think that will work. $\endgroup$ – Alexander Kartun-Giles Feb 10 '18 at 15:49
  • $\begingroup$ Never use an upper-case letter for a variable as it will conflict with Mathematica's internal names. $\endgroup$ – David G. Stork Feb 10 '18 at 17:29
  • $\begingroup$ You want to "draw a random sample from a random variable $X$" rather than "uniformly draw a random variable $X$" as "uniformly" implies that the bin widths are all equal. $\endgroup$ – JimB Feb 10 '18 at 19:35
3
$\begingroup$
m = 20;
n = 4;
binlims = {0, 2, 9, 14, 20};
binlengths = Differences[binlims];

RandomChoice

SeedRandom[1]
rc = RandomChoice[binlengths -> Range[4], 20]

{4, 2, 4, 2, 2, 1, 3, 2, 2, 4, 2, 4, 2, 2, 4, 4, 4, 3, 2, 2}

WeightedData + EmpiricalDistribution + RandomVariate

SeedRandom[1]
rved = RandomVariate[EmpiricalDistribution[WeightedData[Range[4], binlengths]], 20]

{4, 2, 4, 2, 2, 1, 3, 2, 2, 4, 2, 4, 2, 2, 4, 4, 4, 3, 2, 2}

UniformDistribution + TransformedDistribution + RandomVariate

This mimics the description of the process used to generate the random variable X, but it is much slower than the previous two methods.

ClearAll[pw]
pw[x_] := Piecewise[MapIndexed[{#2[[1]], #} &, #] &@(# <= x < #2 & @@@ 
   Partition[binlims, 2, 1])];

pw[x]

$\begin{cases} 1 & 0\leq x<2 \\ 2 & 2\leq x<9 \\ 3 & 9\leq x<14 \\ 4 & 14\leq x<20 \end{cases}$

SeedRandom[1]
rvtd = RandomVariate[TransformedDistribution[pw[x], 
   Distributed[x, UniformDistribution[{0, m}]]], 20]

{4, 2, 4, 2, 2, 1, 3, 2, 2, 4, 2, 4, 2, 2, 4, 4, 4, 3, 2, 2}

When used with the same RandomSeed all three methods give the same result. The first two are roughly equal in terms of speed.

rc == rved  == rvtd

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.