Java Generator for Poisson and Uniform Distributions?
Asked Answered
R

4

10

From what I understand, the standard generator is for the Normal Distribution. I have to generate random numbers according to the Normal, Uniform and Poisson Distributions, but I can't seem to find a class for the last 2.

I have to generate them in the range of 0 - 999999.

Rationalize answered 15/4, 2009 at 4:37 Comment(0)
L
12

As David has pointed out, the supplied pseudo-random number generator uses the Uniform distribution.

For the other two, I would use the Cern Colt library functions:

These library functions easily allow you to find a random number taken from each distribution, rather than giving you a probability density function or cumulative density function and expecting you to derive the number yourself (which seems to be the Apache Commons-Math approach):

RandomEngine engine = new DRand();
Poisson poisson = new Poisson(lambda, engine);
int poissonObs = poisson.nextInt();

Normal normal = new Normal(mean, variance, engine);
double normalObs = normal.nextDouble();

Also, bear in mind that the Poisson distribution P(λ) for large λ can be approximated very well by the normal distribution N(λ, sqrt(λ)).

Legist answered 15/4, 2009 at 5:21 Comment(3)
Is there a way to specify the min and max value they use? Doesn't seem like it, from what I saw.Rationalize
That's because Poisson and Normal distributions don't have a maximum or minimum (well, Poisson has a fixed minimum of 0).Legist
Two of your links are now 404. :-(Goffer
W
6

The standard Java RNG (java.util.Random), and its subclasses such as java.security.SecureRandom, already generate uniformly distributed values.

They also have a method, nextGaussian, that returns normally-distributed values. By default, the distribution has mean of zero and standard deviation of 1 but this is trivially tweaked. Just multiply by the required s.d. and add the required mean. So, for example, if you wanted normally-distributed values with a mean of 6 and standard deviation of 2.5, you'd do this:

double value = rng.nextGaussian() * 2.5 + 6;

The Poisson distribution is not explicitly supported, but you can fake it by doing the same as Tom's Python code.

Alternatively, you may be interested in my Uncommons Maths library, which provides utility classes for Normal, Poisson and other distributions.

Whitehall answered 15/4, 2009 at 21:25 Comment(1)
The link to Uncommons is 404.Goffer
O
5

Actually, the standard generator is for the uniform distribution. The basic random number generator in any language/library will always (in all cases I know of) use the uniform distribution because that's what comes out of all the popular pseudorandom number generator algorithms - basically, uniform random numbers are the easiest.

I see Eddie already pointed you to a link for other distributions so I'll skip writing the rest of this...

Orizaba answered 15/4, 2009 at 4:59 Comment(1)
Actually, it looks like that link also points out the "nextGaussian" method to create normal variates too.Megalith
P
4

Let me preface all this by the fact that none of this is truly random, I am talking about pseudo random number generators.

Let me also say that I have never had to do this for production quality code. I have done this for a hw assignment though, in Python. I simulated Poisson random variables.

The way that I did it made use of the following facts:

  1. A Poisson random variable is a sum of exponential random variables.
  2. We can use the inverse transform method to generate exponential random variables. http://en.wikipedia.org/wiki/Inverse_transform_sampling.

In particular, you can use the fact that: if X1, ..., Xn are independent standard exponential random variables, then Z = min(k : X1 + ... + Xk < λ) - 1 is Poisson(λ).

So, with that, I wrote the following code in python to generate Poisson values:

class Poisson:
    """Generate Poisson(lambda) values by using exponential
    random variables."""

    def __init__(self, lam):
        self.__lam = lam

    def nextPoisson(self):
        sum = 0
        n = -1
        while sum < self.__lam:
            n += 1
            sum -= math.log(random.random())
        return n

Example usage of the class is:

# Generates a random value that is Poisson(lambda = 5) distributed
poisson = Poisson(5)
poisson_value = poisson.nextPoisson

I posted this here because it is good to know that these kinds of relationships exist, and this inverse transform method gives you a general way to deal with generating random values following a particular continuous distribution.

Pinsky answered 15/4, 2009 at 5:8 Comment(1)
I fixed the formatting of the numbered list to what I believe you intended. If this is not what you intended, then of course feel free to roll back the change.Downhill

© 2022 - 2024 — McMap. All rights reserved.