Thread: How to get a random number that follows a particular distribution?

  1. #1
    Registered User
    Join Date
    Sep 2001
    Posts
    412

    How to get a random number that follows a particular distribution?

    For many applications, I need a gaussian random variable, or a random variable which follows a non-gaussian distribution (e.g. a t-distribution).

    Now, the rand() command allows you to get a random int, but how can this be used to generate a random float which is sampled from a particular distribution? The rand() command gives you each value with equal probability -- here I want something quite different.

    Now, I know I can, by a trick, get a normal distribution, by using the CLT, like this:
    Code:
    int i;
    double randomNormal = 0;
    
    for (i = 0; i < 50; i++){
    	randomNormal += ((double)1/(double)rand());
    }
    The CLT, BTW, states that if you average over many points from any probablity distribution (here, 1/rand() is that distro), the average itself will always follow a normal distribution.

    But, this, although it gets me a gaussian distribution, does not help for other types of probablity distributions. Is there a general way to generate samples from an arbitrary distribution given a formula for its PDF?
    Last edited by The V.; 10-11-2001 at 08:31 PM.

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    752
    Hmm, not so sure I have the statistics background to help here, although maybe I could, can you explain what a 'PDF' is?

    What I might be able to offer is that if f(x) is a frequency distribution, F(x) is it's integral, and i(F(x)) is the inverse of F(x), then i(F(x)) should be distributed as f(x) if x is distributed with all values from 0 to 1 having equal probability.

    It might be difficult to integrate the frequency distribution, and then find that function's inverse... but I suppose if you have a table then you could just make another table using sums.

    EDIT: I'm not a math major, don't get mad if this turns out to be wrong.
    Last edited by QuestionC; 10-11-2001 at 10:09 PM.

  3. #3
    Registered User
    Join Date
    Sep 2001
    Posts
    412
    OK, a PDF (probability density function) is a function, such that the closed integral from x=a to x=b is equal to the probability that a random variable which follows this distribution will be between a and b.

    One example is the standard normal distribution (gaussian with mean = 0, std deviation =1): x will be between -1.96 and +1.96 95% of the time, because the integral from -1.96 to 1.96 of the PDF is 0.95.

    And I do see what you're saying about i(F(x)) -- F(x) is the cumulative density function (CDF), and can be derived from the PDF by simple integration. I hadn't thought about the inverse of this, but I believe you are correct, if you distribute a value between 0 and 1 uniformly, this variable should have the same properties as the original distribution.

    Thanks! Now, as I think I can integrate and invert the functions by hand, i should be able to use this.

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    412
    Well, after looking at it, I *can't* integrate by hand, as there IS no explicit expression for the CDF of a gaussian distribution.

    However, being as the inverse-CDF of a gaussian distro is highly desirable, there's a very nifty algorithm which I found on the web which approximates the inverse CDF with incredibly low error (something like +- 10^-18 or somesuch).

    With that, I can at least generate gaussian variables easily now, something I couldn't do this morning, and need to do before next week friday.

  5. #5
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284

    Post

    If (X,Y) is a random vector uniformly distributed within the unit circle , ie. it has a density f such that
    f(x,y)=1 if x*x+y*y<1
    =0 otherwise
    and S=X*X+Y*Y then
    r1=X*sqrt(-2*log(S)/S)
    r2=Y*sqrt(-2*log(S)/S)
    then r1 and r2 are independent and normally distributed with mean 0 and variance 1.
    so a possible function could be

    #include <math.h>
    #include <time.h>
    #include <stdlib.h>
    double gennor(void)
    {
    static int i=0;
    double x,y,s;
    static double r1,r2;
    if(i==1)
    {
    i=0;
    return r2;
    }
    do
    {
    x = 2.*((double) rand()/(RAND_MAX+1.0))-1. ;
    y = 2.*((double) rand()/(RAND_MAX+1.0))-1. ;
    s=x*x+y*y;
    } while(s>1.);
    r1=x*sqrt(-2.*log(s)/s);
    r2=y*sqrt(-2.*log(s)/s);
    i=0;
    return r1;
    }

    int main(void)
    {
    double d;
    int i;
    srand( time(0) );
    for(i=0;i<1000;i++)
    printf("%lf\n",gennor());
    return 0;
    }

  6. #6
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    there is a slight mistake above
    the density above is actually
    f(x,y) = 1/pi if x*x+y*y<1
    = 0 ow
    the program is ok

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Random Number Issues
    By sansterre in forum C++ Programming
    Replies: 8
    Last Post: 05-15-2009, 05:59 PM
  2. rapid random number generation problem
    By Newton in forum C Programming
    Replies: 17
    Last Post: 09-19-2008, 02:08 PM
  3. adding a number to a number
    By bigmac(rexdale) in forum C Programming
    Replies: 11
    Last Post: 10-24-2007, 12:56 PM
  4. How do I restart a random number sequence.
    By jeffski in forum C Programming
    Replies: 6
    Last Post: 05-29-2003, 02:40 PM
  5. Ask about generate Random number
    By ooosawaddee3 in forum C Programming
    Replies: 2
    Last Post: 07-01-2002, 04:30 AM