4

I need a Poisson distribution.

Currently I have the following code:

public static int getPoisson(double lambda) {
    double l = Math.exp(-lambda);
    double p = 1.0;
    int k = 0;

    do {
        k++;
        p *= Math.random();
    } while (p > l);

    return k - 1;
}

I was wondering how I could modify it such that I can generate x number of values all within a defined range i.e., if a = 5, b = 10, and lambda = 6, all values generated will fall within the range of 5 to 10.

Note: I could overload the method, and thus accept range parameters, and call the getPossion method within a loop; discarding anything that doesn't fit this range. However, I would like to check whether there is a mathematically defined means of achieving this and/or whether this approach would be suitable.

EDIT: The means by which I discard 'out of bounds' values:

public static int getPoisson(final double min, final double max, final double lambda) {
    int k = 0;
    do {
        k = getPoisson(lambda);
    } while (k < min || k > max);
    return k;
}
Dan
  • 75
  • 6

1 Answers1

0

If you want only get some integers in very small given range with given probability with fixed (or rarely changed) lambda the easiest way is to keep probability tables for each of number and do biased sampling.

Some pseudocode:

public class BoundedSampler {
  private final int min;
  private final double[] table;

  public BoundedSampler(int min, int max, double lambda) {
    this.min = min;
    this.table = new double[max - min + 1];

    double cumulative = 0;
    for(int x = min; x <= max; ++x) {
      double prob = probability(x, lambda);
      table[x - min] = cumulative + prob;
      cumulative += prob;
    }

    for(int i = 0; i < table.length; ++i) {
      table[i] /= cumulative;
    }
  }

  public int sample() {
    double r = Math.random();
    for(int i = 0; i < table.length; ++i) {
      if(table[i] <= r) {
        return i + min;
      }
    }
    return -1; // impossible: last table value == 1
  }
}

Or use alias method to fast value selection.

Nikolay
  • 1,949
  • 18
  • 26
  • What algorithm is this? – Dan Feb 10 '19 at 14:27
  • Code stub provided for "pseudo-random number sampling from finite discrete distribution by linear search". – Nikolay Feb 10 '19 at 14:42
  • Unfortunately it _must_ be a poisson algorithm. I'll post the current implementation I am rocking so you can check it out. – Dan Feb 10 '19 at 17:26
  • If it must be poisson *distribution* (and min,max,lambda is fixed for a while), `probability` function can be implemented as PDF for poission. Base idea is to replace infinite poission distribution to finite "bounded poisson". I can provide several useful links: http://mathworld.wolfram.com/PoissonDistribution.html -- PDF formulas https://github.com/apache/commons-rng/blob/master/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java -- implementation for very large means. If it must be possion *algorithm* -- your code is good. – Nikolay Feb 10 '19 at 22:37
  • So in order to generate a value from within a poisson _distribution_ I must implement a bounded PDF algorithm? If so, are there any sources for achieving this, or must I implement the formulae from hand? – Dan Feb 12 '19 at 03:26