public static int poissonRand(double xm){
  double sqrt2xm, logxm, expxm, g;
  double t, y;
  int k;
  if (xm < 12.0) {
    expxm=Math.exp(-xm);
    k=-1;
    t=1.0;
    do {
      k++;
      t*=uniformRand();
    }
 while (t > expxm);
  }
 else {
    sqrt2xm=Math.sqrt(2.0 * xm);
    logxm=Math.log(xm);
    g=xm * logxm - lngamma(xm + 1.0);
    do {
      do {
        y=Math.tan(Math.PI * uniformRand());
        k=(int)Math.floor(sqrt2xm * y + xm);
      }
 while (k < 0);
      t=0.9 * (1.0 + y * y) * Math.exp(k * logxm - lngamma((double)k + 1.0) - g);
    }
 while (uniformRand() > t);
  }
  return (k);
}

public static int poissonRand ( double xm ) { double sqrt2xm , logxm , expxm , g ; double t , y ; int k ; if ( xm < 12.0 ) { expxm = Math . exp ( - xm ) ; k = - 1 ; t = 1.0 ; do { k ++ ; t *= uniformRand ( ) ; } while ( t > expxm ) ; } else { sqrt2xm = Math . sqrt ( 2.0 * xm ) ; logxm = Math . log ( xm ) ; g = xm * logxm - lngamma ( xm + 1.0 ) ; do { do { y = Math . tan ( Math . PI * uniformRand ( ) ) ; k = ( int ) Math . floor ( sqrt2xm * y + xm ) ; } while ( k < 0 ) ; t = 0.9 * ( 1.0 + y * y ) * Math . exp ( k * logxm - lngamma ( ( double ) k + 1.0 ) - g ) ; } while ( uniformRand ( ) > t ) ; } return ( k ) ; }
poisson random generator from numerical recipes
