8

Can you tell me any ways to generate non-uniform random numbers?
I am using Java but the code examples can be in whatever you want.

One way is to create a skewed distribution by adding two uniform random numbers together (i.e. rolling 2 dice).

KM.
  • 101,727
  • 34
  • 178
  • 212
Robert Greiner
  • 29,049
  • 9
  • 65
  • 85

3 Answers3

11

Try generating uniformly distributed random numbers, then applying your inverted non-uniform cumulative distribution function to each of them.

Noldorin
  • 144,213
  • 56
  • 264
  • 302
Paul Sonier
  • 38,903
  • 3
  • 77
  • 117
  • Wrong, you must invert your distribution function. If you want square distribution, you must take square roots of random numbers. – glmxndr Jun 10 '09 at 18:46
  • I'm making the assumption that the distribution function applies the appropriate inversion. I think your issue is more with the terminology of the type of distribution to the funcion used. – Paul Sonier Jun 10 '09 at 18:54
  • Yes, but terminology matters. And you go way against the standards. – glmxndr Jun 10 '09 at 18:56
  • @subtenante: edited to reflect your suggested change. – Paul Sonier Jun 10 '09 at 18:57
  • I just clarified the answer to stress that it's the inverse CDF (not PDF or whatever else) you want to apply. – Noldorin Jun 10 '09 at 19:00
7

What distribution of deviates do you want?

Here is a technique which always works, but isn't always the most efficient. The cumulative distrubtion function P(x) gives the fraction of the time that values fall below x. Thus P(x)=0 at the lowest possible value of x and P(x)=1 at the highest possible value of x. Every distribution has a unique CDF, which encodes all the properties of the distrubtion in the way that P(x) rises from 0 to 1. If y is a uniform deviate on the interval [0,1], then x satisfying P(x)=y will be disributed according to your distribution. To make this work comuptationally, you just need a way computing the inverse of P(x) for your distribution.

The Meta.Numerics library defines a large number of commonly used distrubtions (e.g. normal, lognormal, exponential, chi squared, etc.) and has functions for computing the CDF (Distribution.LeftProbability) and the inverse CDF (Distribution.InverseLeftProbability) of each.

For specialized techniques that are fast for particular distrubtions, e.g. the Box-Muller technique for normaly distributed deviates, see the book Numerical Recipies.

  • it doesn't matter I was just looking for ways to generate numbers across different distributions. I guess I hadn't thought it that far through. It sounds like I need to do some more reading, is this the book you were talking about? Numerical Recipes 3rd Edition: The Art of Scientific Computing – Robert Greiner Jun 10 '09 at 19:01
  • Yes, that's the book. It's the standard introduction to numerical computing, but it's a big investment of money and effort. If you just want the damn deviates, I'd stick with a library. Using the one I mentioned, it's as simple as: Random rng = new Random(1); Distribution dist = new NormalDistribution(1.0,2.0); double x = dist.InverseLeftProbability(rng.NextDouble()); –  Jun 10 '09 at 19:15
  • awesome, this is something i'd like to get much better at for sure. I do plan on checking out the book. Thank you very much. – Robert Greiner Jun 10 '09 at 19:59
1

If you are using Java then my Uncommons Maths library may be of interest. It includes classes for generating random numbers for Uniform, Gaussian, Poisson, Binomial and Exponential distributions. This article shows how you might use these distributions.

Dan Dyer
  • 53,737
  • 19
  • 129
  • 165