Take the 2-minute tour ×

Thanks in advance for any help.

I need to create random numbers which follow a user defined function in Java. The general way of doing this is through applying an uniform distribution to the integral of the function. The thing is that I need to create the distribution of functions which cannot be integrated or that the integral is seriously complex or messy.

One example would be to generate random numbers that would follow a distribution of the function:

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

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

Thanks a lot!

share|improve this question
Can you numerically approximate the CDF? –  Oli Charlesworth Jul 13 '12 at 18:05
Do you have a bit more info about the function? Do you know the domain of definition of the function? Is it bounded? –  GL770 Jul 13 '12 at 19:30
I was looking for a general way of creating random numbers from user defined funtions, the function I wrote is just one. Anyway, in my general case it could be bounded, in case it helps... –  beethovenj Jul 13 '12 at 20:00
The two requirements you're giving are not compatible: you want to be able to use arbitrary functions that don't necessary have closed-form integrals, AND you don't want to use any kind of approximation. This just isn't possible. I think numerically integrating the PDF is going to be your best bet; if a high level of accuracy is important then just use a really accurate numerical integral. –  bnaul Jul 13 '12 at 21:51
You are right. I'm used to work with scientific libraries (not Java) where you can generate the distributions from any funtion, but that does not mean they don't do approximations for the ones that cannot be integrated, you just don't see it. If I want to do that in Java I'll need to use approximations as you said for each different fuction I need, since I'm really not finding a library which does this automatically for you and that will allow me to work more fluently with many different funtions :( –  beethovenj Jul 14 '12 at 13:17
add comment

2 Answers

Apologies if I'm repeating what you already know:

You need the user to define (or approximate) the inverse CDF. If you can't calculate it, I would suggest sampling from your distribution and then using a well known distribution to approximate it. I don't know of any libraries that will do this for you from a PDF Once you have this, 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 the percentile (for example .5 = 50% -> the mean of the normal distribution ) mapped back via the user's function to the value.

share|improve this answer
Thanks so much guys. The problem is that I'm working with scientific data and I want to avoid approximations as much as possible, that's the problem... anyway both of you would have solved my problem if I could use approximations, so thanks again. –  beethovenj Jul 13 '12 at 18:41
add comment

Another way to sample the distribution would be to pick a random point (uniformly) in the domain 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 inverse CDF, since you have to sample multiple times. Expected number of samples is 2/(D·R), where D is the domain, and R the range of the PDF.

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;
share|improve this answer
mmm... It makes a lot of sense... I'm gonna try, let's see the results... –  beethovenj Jul 14 '12 at 0:33
add comment

Your Answer


