Random Numbers – Generate Random Numbers Following a Distribution Within an Interval

MATLABnormal distributionrrandom-generationsimulation

I need to generate random numbers following Normal distribution within the interval $(a,b)$. (I am working in R.)

I know the function rnorm(n,mean,sd) will generate random numbers following normal distribution,but how to set the interval limits within that? Is there any particular R functions available for that?

Best Answer

It sounds like you want to simulate from a truncated distribution, and in your specific example, a truncated normal.

There are a variety of methods for doing so, some simple, some relatively efficient.

I'll illustrate some approaches on your normal example.

  1. Here's one very simple method for generating one at a time (in some kind of pseudocode):

    $\tt{repeat}$ generate $x_i$ from N(mean,sd) $\tt{until}$ lower $\leq x_i\leq$ upper

    enter image description here

    If most of the distribution is within the bounds, this is pretty reasonable but it can get quite slow if you nearly always generate outside the limits.

    In R you could avoid the one-at-a-time loop by computing the area within the bounds and generate enough values that you could be almost certain that after throwing out the values outside the bounds you still had as many values as needed.

  2. You could use accept-reject with some suitable majorizing function over the interval (in some cases uniform will be good enough). If the limits were reasonably narrow relative to the s.d. but you weren't far into the tail, a uniform majorizing would work okay with the normal, for example.

    enter image description here

  3. If you have a reasonably efficient cdf and inverse cdf (such as pnorm and qnorm for the normal distribution in R) you can use the inverse-cdf method described in the first paragraph of the simulating section of the Wikipedia page on the truncated normal. [In effect this is the same as taking a truncated uniform (truncated at the required quantiles, which actually requires no rejections at all, since that's just another uniform) and apply the inverse normal cdf to that. Note that this can fail if you're far into the tail]

    enter image description here

  4. There are other approaches; the same Wikipedia page mentions adapting the ziggurat method, that should work for a variety of distributions.

The same Wikipedia link mentions two specific packages (both on CRAN) with functions for generating truncated normals:

The MSM package in R has a function, rtnorm, that calculates draws from a truncated normal. The truncnorm package in R also has functions to draw from a truncated normal.


Looking around, a lot of this is covered in answers on other questions (but not exactly duplicates since this question is more general than just the truncated normal) ... see additional discussion in

a. This answer

b. Xi'an's answer here, which has a link to his arXiv paper (along with some other worthwhile responses).

Related Question