Java: generate random numbers after user defined function

Thanks in advance for your help.

I need to create random numbers that follow a custom function in Java. The general way to do this is to apply a uniform distribution to the integral of the function. The fact is that I need to create a distribution of functions that cannot be integrated, or that the integral is seriously complex or messy.

One example would be the generation of random numbers that will follow the distribution of a function:

f(x) = (cos(x))^1.5 

Is there a math library in Java where you can define a function and it returns random numbers? Any recommendations?

Thanks a lot!

+4
source share
2 answers

Sorry if I repeat what you already know:

You need the user to identify (or approach) the reverse CDF . If you cannot figure it out, I would suggest sampling from your distribution, and then using a well-known distribution to get closer to it. I do not know of any libraries that will do this for you from PDF. After that, you can create a mapping from the uniform randomness of your random number generator in your language to the function. When you generate a random number that will serve as a percentile (e.g. .5 = 50% โ†’ average value of the normal distribution), mapped back through the user function to the value.

+1
source

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; } } 
+1
source

All Articles