Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Generating a Poisson Random Variable

1,215 views
Skip to first unread message

David Entwistle

unread,
Dec 26, 2008, 8:38:37 AM12/26/08
to
Hi,

I'm afraid I'm not a professional Java programmer, nor a mathematician,
but I'd like to be able to generate a set of integers with a Poisson
distribution around a starting value (lambda). The application for which
I wish to do this is deriving confidence limits for analysis of radio
meteor observations.

<http://www.radiometeor.plus.com/>

The method I'm using, derived from "Simulation and the Monte Carlo
Method", by Rubinstein and Kroese works well for small starting values.
But, as the text of this book the algorithm becomes slow for large
starting values of lambda. In my case, the algorithm becomes
impractically slow as Lambda increases above about 745. Some radio
meteor observers have hour counts which exceed this value.

Does anyone have code to implement any alternative method to derive a
Poisson random variable?

Many thanks.

/*
* TestPoissonDistribution.java
* A method to test the Poisson distribution generator.
*/

import java.util.Random;

public class TestPoissonDistribution
{
public static void main(String[] args)
{
for(int i = 0; i <= 600; i++)
{
System.out.println();
for(int j = 0; j <= 10; j++)
{
System.out.print(distribute(i) + ", ");
}
}
}

/**
* A method to randomize a value based on a Poisson distribution.
* @param lambda The starting value.
* @return The integer which forms part of the distribution
* See pp 65 of Simulation and the Monte Carlo Method by
* Rubinstein and Kroese
*/
public static int distribute(int lambda)
{
int n = 1;
double a = 1.0;
Random r = new Random();

while(true)
{
a *= r.nextDouble();
if(a < Math.exp((double)-lambda)) break;
n += 1;
}
return n - 1;
}
}
--
David Entwistle

Patricia Shanahan

unread,
Dec 26, 2008, 10:34:59 AM12/26/08
to
David Entwistle wrote:
> Hi,
>
> I'm afraid I'm not a professional Java programmer, nor a mathematician,
> but I'd like to be able to generate a set of integers with a Poisson
> distribution around a starting value (lambda). The application for which
> I wish to do this is deriving confidence limits for analysis of radio
> meteor observations.
>
> <http://www.radiometeor.plus.com/>
>
> The method I'm using, derived from "Simulation and the Monte Carlo
> Method", by Rubinstein and Kroese works well for small starting values.
> But, as the text of this book the algorithm becomes slow for large
> starting values of lambda. In my case, the algorithm becomes
> impractically slow as Lambda increases above about 745. Some radio
> meteor observers have hour counts which exceed this value.
...

The Colt library includes Poisson distribution support. See
http://acs.lbl.gov/~hoschek/colt/api/cern/jet/random/Poisson.html

I have not benchmarked it, so I am merely bringing it to your attention
as an alternative to consider.

Patricia

David Entwistle

unread,
Dec 26, 2008, 10:47:21 AM12/26/08
to
In message <zvKdneS56MU4ZMnU...@earthlink.com>, Patricia
Shanahan <pa...@acm.org> writes

>
>I have not benchmarked it, so I am merely bringing it to your attention
>as an alternative to consider.
>

Patricia,

Thanks very much for bring the Colt library to my attention - it
certainly looks to do what I want. I'll give it a go.

Thanks again and best wishes for the season,
--
David Entwistle

Lew

unread,
Dec 26, 2008, 11:48:02 AM12/26/08
to
Patricia has already addressed your primary question. Here are a couple of
incidental comments.

David Entwistle wrote:
> public static int distribute(int lambda)

Consider making this an instance variable.

> {
> int n = 1;
> double a = 1.0;
> Random r = new Random();

This will restart the pseudorandom sequence every time the method is called.
Make the Random variable an instance variable instead.

> while(true)
> {
> a *= r.nextDouble();
> if(a < Math.exp((double)-lambda)) break;
> n += 1;
> }
> return n - 1;
> }
> }


--
Lew

Patricia Shanahan

unread,
Dec 26, 2008, 12:14:41 PM12/26/08
to
Lew wrote:
> Patricia has already addressed your primary question. Here are a couple
> of incidental comments.
>
> David Entwistle wrote:
>> public static int distribute(int lambda)
>
> Consider making this an instance variable.

There are two ways this sort of random number generator can be used:

1. Get a lot of samples from the same distribution. For this, the best
design is to have lambda be an instance variable, use a parameterless
instance method to return the sampled value, and create an instance for
each different value of lambda.

2. Get samples from a lot of different distributions. A static method
with lambda as parameter is better for this. In the calling code it
replaces:

int sample = new Poisson(myLambda).sample();

with the simpler code:

int sample = Poisson.sample(myLambda);

The Colt Poisson class is designed to support both use cases, and so has
both a constructor for an object with lambda bound to a specific value
and a static method.

David will presumably know how his program uses this, and should pick
whichever design fits better.

Patricia

Lew

unread,
Dec 26, 2008, 12:17:36 PM12/26/08
to
David Entwistle wrote:
>> public static int distribute(int lambda)

Lew wrote:
> Consider making this an instance variable.

I meant instance method - oops.

--
Lew

Lew

unread,
Dec 26, 2008, 12:23:27 PM12/26/08
to
David Entwistle wrote:
>>> public static int distribute(int lambda)

Lew wrote:
>> Consider making this an instance variable [sic].

Patricia Shanahan wrote:
> There are two ways this sort of random number generator can be used:
>
> 1. Get a lot of samples from the same distribution. For this, the best
> design is to have lambda be an instance variable, use a parameterless
> instance method to return the sampled value, and create an instance for
> each different value of lambda.
>
> 2. Get samples from a lot of different distributions. A static method
> with lambda as parameter is better for this. In the calling code it
> replaces:
>
> int sample = new Poisson(myLambda).sample();
>
> with the simpler code:
>
> int sample = Poisson.sample(myLambda);
>
> The Colt Poisson class is designed to support both use cases, and so has
> both a constructor for an object with lambda bound to a specific value
> and a static method.
>
> David will presumably know how his program uses this, and should pick
> whichever design fits better.

That is a good explication of what to consider when considering whether to
make something an instance member. I would add that an instance method is
also useful with a parameter if one wants not to repeat the pseudorandom
sequence of the underlying 'Random' variable. One instantiates a 'Poisson'
and repeatedly calls 'sample( lambda )' on it, thus avoiding repetition of
"random" values for successive calls.

Sometimes an object has state that is not explicitly visible to its consumers.
Static variables for such state are an antipattern, particularly harmful in
concurrent applications, so it would be best to instantiate an object even
with the method that takes a parameter.

--
Lew

Patricia Shanahan

unread,
Dec 27, 2008, 3:35:53 AM12/27/08
to
David Entwistle wrote:
> Hi,
>
> I'm afraid I'm not a professional Java programmer, nor a mathematician,
> but I'd like to be able to generate a set of integers with a Poisson
> distribution around a starting value (lambda). The application for which
> I wish to do this is deriving confidence limits for analysis of radio
> meteor observations.
...

A side note. For this type of work, I strongly recommend the following:

1. Design the program so that you can force a seed value for each
sequence of random numbers in the program. (Usually, there should only
be one sequence.)

2. Report the actual seed in the program output.

It can be *very* frustrating if you get an anomalous result and want to
investigate, but cannot reproduce the problem.

Patricia

Roedy Green

unread,
Dec 28, 2008, 5:37:57 PM12/28/08
to
On Fri, 26 Dec 2008 13:38:37 +0000, David Entwistle
<Da...@invalid.com> wrote, quoted or indirectly quoted someone who
said :

> Random r = new Random();

This should be done only once, not once per generation. Put the code
into static init. Otherwise you will keep getting the same numbers
since the same time will be used as a seed.

--
Roedy Green Canadian Mind Products
http://mindprod.com
PM Steven Harper is fixated on the costs of implementing Kyoto, estimated as high as 1% of GDP.
However, he refuses to consider the costs of not implementing Kyoto which the
famous economist Nicholas Stern estimated at 5 to 20% of GDP

0 new messages