Another way to sample the distribution is to select a random point (evenly) in the area and range of the PDF. If the point falls below the PDF curve, return it. Otherwise, discard it and try again.
This will be slower than evaluating the reverse CDF, as you have to select multiple times. The expected number of samples is 2 / (D ยท R), where D is the domain and R is the PDF range.
abstract class Distribution { public abstract double PDF(double value); public abstract double getDomainMin(); public abstract double getDomainMax(); public abstract double getRangeMax(); protected Random rnd; public Distribution() { rnd = new Random(); } public double sample() { double left = getDomainMin(); double right = getDomainMin(); double top = getRangeMax(); double x, y1, y2; while (true) { x = left + (right - left) * rnd.nextDouble(); y1 = top * rnd.nextDouble(); y2 = PDF(x); if (y1 <= y2) return x; } return Double.NaN; } }
source share