# Which Distributions can be Compiled using RandomVariate

Recently, Oleksandr kindly showed a list of Mathematica commands that can be compiled. RandomVariate was part of that list. However, whether this can be compiled depends upon the distribution that is being sampled.

Needs["CompiledFunctionTools"]

cf1 = Compile[{{m, _Real}, {s, _Real}},
Module[{v1, v2, v3, v4, v5, v6},
v1 = RandomVariate[NormalDistribution[m, s]];
v2 = RandomVariate[UniformDistribution[{m, s}]];
v4 = RandomVariate[PoissonDistribution[m]];
v5 = RandomVariate[ChiSquareDistribution[m]];
v6 = RandomVariate[ExponentialDistribution[m]];
{v1, v2, v3, v4, v5, v6}
]
]


Using CompilePrint shows that RandomVariate can be compiled for the Normal Distribution or the Uniform Distribution and not with some others.

CompilePrint[cf1]

2 arguments
4 Integer registers
8 Real registers
1 Tensor register
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}

R0 = A1
R1 = A2
Result = T(R1)0

1   R2 = RandomNormal[ R0, R1]]
2   R3 = RandomReal[ R0, R1]]
3   I0 = MainEvaluate[ Function[{m, s},
4   I1 = MainEvaluate[ Function[{m, s},
RandomVariate[PoissonDistribution[m]]][ R0, R1]]
5   I2 = MainEvaluate[ Function[{m, s},
RandomVariate[ChiSquareDistribution[m]]][ R0, R1]]
6   I3 = MainEvaluate[ Function[{m, s},
RandomVariate[ExponentialDistribution[m]]][ R0, R1]]
7   R4 = I0
8   R5 = I1
9   R6 = I2
10  R7 = I3
11  T(R1)0 ={ R2, R3, R4, R5, R6, R7 }
12  Return


Does anyone have a list of all the distributions that can be compiled (including, PDF, CDF and RandomVariate functionality)?

-
Well, you can check each of them, or semi-automate checking. When one is not compiled, and you try to use it, you'll easily find out anyway: see my answer to that post asking about compilable functions. –  Szabolcs Feb 1 '12 at 19:33
@szabolcs There are too many combinations to try out, unfortunately. –  asim Feb 2 '12 at 1:43
Beta distribution can be compiled too.. –  asim Feb 10 '12 at 14:09

To my knowledge UniformDistribution and NormalDistribution are the only distributions that are directly compilable for RandomVariate.

Consider that sampling from a UniformDistribution is what RandomReal was originally designed to do. This code is likely written deep down in C and so compiles without any special effort. In order to hook up RandomVariate for uniforms Compile just needs to recognize that this is really just a call to RandomReal.

Now, sampling from a NormalDistribution is so common that it was considered worth the time investment to make it compilable. Notice that the call to RandomVariate actually produces a call to RandomNormal which was almost certainly written for this purpose.

As for other distributions, special code would need to be written for each one in a similar fashion to RandomNormal for them to be "supported" by Compile. Since there are well over 100 of these, it would be a huge undertaking. An argument could be made for doing this for a few distributions but who is to decide which ones are most important?

There is a sunny side. Most distributions have their own dedicated and highly optimized methods for random number generation. Often Compile is used under the hood when machine precision numbers are requested.

Because of this, even if they were directly compilable you probably wouldn't see much of a speed boost since the code is already optimized.

Fortunately Compile can happily handle arrays of numbers. I typically just rely on the optimized code used by RandomVariate to generate the numbers and subsequently pass them in as an argument to the compiled function.

Incidentally, everything I just said about RandomVariate is also true of distribution functions like PDF, CDF, etc. Obviously these are just pure functions (in the univariate case) and unless they are built with some exotic components they should compile assuming you evaluate them before putting them into your compiled function.

-
Also of note is that Erf[] is in the list of compilable functions in Olek's answer. So yes, I think the normal distribution is pretty well-covered here. –  Ｊ. Ｍ. Feb 2 '12 at 6:29
I just found out that RandomVariate[BetaDistribution[a,b]] can also be compiled. By the way, it is not always that simple to generate the random numbers before passing them to a compiled function, especially, if the number of draws are endogenously determined within the function, as part of some while loop. –  asim Feb 10 '12 at 14:05
@asim this is definitely true. I was unaware the BetaDistribution was compilable, thanks! –  Andy Ross Feb 10 '12 at 16:09
@asim I have had situations like this. Typically I generate far more numbers than I think I will need and pass them in. It is faster to generate a bunch in one go than to repeatedly call RandomVariate. The downside is having to leave Compile` and generate more if I didn't generate enough numbers in the first go. –  Andy Ross Feb 10 '12 at 23:22