0
$\begingroup$

This is sort of an odd question, I realize - but it has to do with random number generation. What I'd like to do is generate random numbers with a normal distribution; many functions (in Python) do this already as long as you give the function a mean and standard deviation. Note also that to generate uniform random variables you must specify a range, e.g. a random number between $i$ and $j$.

I'm in the situation where I need to generate both uniform random numbers in the range $[i,j]$ as well as normally distributed numbers in that range (or at least such that 98% of the random numbers fit into that range). Computing the mean of the uniform distribution is not difficult, so now I have a mean and a range - but I need the final parameter, the standard deviation in order to generate all my random numbers.

So my initial thought is that we can use the following to compute the standard deviation: $\sigma = \frac{j - \mu}{3}$ and or $\sigma = \frac{i - \mu}{-3}$. This seems to work fairly well, for a range $[50, 150]$, it gives me $\mu=100$ and $\sigma=16.666667$ which looks like this:

Normal distribution with mean 100 and standard deviation 16.67 seems to be in the range 50-150

Though perhaps even this is still too long of a curve for the distribution? I'd like some advice if this approach is close to correct, or if there is a more official way to compute this - maybe even a way to generalize the computation for various confidence intervals/z-scores (I know I should have probably chosen 2.333 for 98%).

Another generalization that would be very helpful is if I don't have a range but rather a width, (the width was 100 in the previous example) can I generalize the standard deviation for that width given any $\mu$?

$\endgroup$
1
$\begingroup$

You need to find out, which function in Python gives you the inverse of the cumulative distribution function of the normal distribution: https://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function The cummulative distribution function of the normal distribution is often called $\Phi$ and it gives you the percentage of normally distributed random numbers up to a certain z-value. The inverse should give you the z-value to a certain percentage.

See the red curve in the above linked Wikipedia article: https://upload.wikimedia.org/wikipedia/commons/c/ca/Normal_Distribution_CDF.svg

I don't know about Python, but in R you'd use qnorm(). Say you had a mean of 0 and a Standard deviation of 1 and you wanted to find the intervall were 1% of the data is to the left an 1% to the right of the intervall (that is 99% to the left) than you'd call

qnorm(c(0.01, 0.99), mean = 0, sd = 1)

and get

[1] -2.326348  2.326348

So 2.326 is the exact number of what you estimated to 2.333.

Edit: Apparently the corresponding Python function is norm.ppf() in scipy.stats : https://stackoverflow.com/questions/24695174/python-equivalent-of-qnorm-qf-and-qchi2-of-r

$\endgroup$
  • $\begingroup$ This is very helpful, thank you. So your suggestion is to use norm.ppf (or qnorm) to get the denominator for the equation I had in my question? Can you confirm that my computation of the standard deviation with the z value will result in the curve that I expect? $\endgroup$ – bbengfort Jun 27 '16 at 17:02
  • $\begingroup$ @bbengfort Just to see, whether I understood correctly: There is a range $[i,j]$ given and you look for a mean and a standard deviation, so that 98% of the random numbers fall into this range. The mean is easily computed as $mean = (i+j)/2$ You can use the above mentioned functions to calculate a z-value, so that $mean-z*sd = i$ and $mean+z*sd = j$ This allows for easy computation the standard deviation $sd$. Does that answer the question? $\endgroup$ – Bernhard Jun 27 '16 at 19:32
  • $\begingroup$ I think it does indeed answer the question quite clearly - thanks! $\endgroup$ – bbengfort Jun 28 '16 at 0:34
1
$\begingroup$

Normally distributed values range from $-\infty$ to $\infty$, so you obviously want to generate values from truncated normal distribution. This could be achieved using a number of different methods, e.g.

  1. simulating values from normal distribution and dropping those that fall out of the range,

  2. inverse transform, using uniformly distributed variable $U$

    $ x = \Phi^{-1}( \Phi(\alpha) + U \times (\Phi(\beta)-\Phi(\alpha)))\sigma + \mu $,

  3. using specialized algorithms as e.g. the one described by Robert (1995).

If you choose such $\sigma$ that makes $98\%$ of normally distributed values fall into $(\alpha, \beta)$ interval (i.e. $\mu \pm 2.33\sigma$), then since your data would come from truncated normal distribution, this would obviously lead to situation where $100\%$ of generated values fall into the prespecified range.


Robert, C.P. (1995). Simulation of truncated normal variables. Statistics and Computing 5 (2): 121–125.

$\endgroup$
  • $\begingroup$ Truncation is actually not a requirement for this, but if it was, the plan was to use approach #1; unless you thought there might be performance benefits to either 2 or 3. The point here is really that the description of the range of values is given by a width rather than the standard deviation or variance, and we need to get a standard deviation from that width rather than the other way around with some likelihood that most of the values would fall in that range. Is Phi in approach 2 the cumulative distribution function as mentioned in the below answer? $\endgroup$ – bbengfort Jun 27 '16 at 17:00
  • $\begingroup$ 0.99-th quantile for standard normal is 2.33, so 98% values for normal distribution lies in $x \pm 2.33\sigma$. So yes, if you need the middle 98% then this is the way to go. However 2% will be more or less then that up to $\pm \infty$. $\endgroup$ – Tim Jun 27 '16 at 17:55
  • $\begingroup$ And yes, $\Phi$ is standard normal CDF. Approaches 2 and 3 can be more efficient, but since you want the middle 98% approach 1 would be enough. $\endgroup$ – Tim Jun 27 '16 at 18:01
  • $\begingroup$ awesome, thanks for all the help! We'll stick with #1 for now. $\endgroup$ – bbengfort Jun 28 '16 at 0:34

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.