Java Lognormal cumulative distribution function for JavaScript?

Click For Summary
A user is developing a "Deal or No Deal" calculator to estimate the odds of securing a better deal than the one offered, specifically seeking a JavaScript function to calculate the cumulative distribution function (CDF). The discussion includes a code snippet utilizing the Box-Muller transform to generate random numbers following a log-normal distribution, which is deemed more suitable than a normal distribution for this application. Clarifications are made regarding the output of the provided code, emphasizing that it generates a random number aligned with the log-normal probability distribution rather than directly calculating P(X ≤ x). Additional algorithms for calculating P(X ≤ x) are suggested, including a reference to the Apache Commons library. The conversation also touches on the background of the "Deal or No Deal" game show, providing context for the calculator's purpose.
moonman239
Messages
276
Reaction score
0
Hey everyone!

I'm building a "Deal or No Deal" calculator that estimates the odds of getting a better deal than the one presented. As you can see in the title, I'm looking for a function that will calculate the CDF. For ease's sake, please only post JavaScript code (no C,Perl,BASIC,etc.)
 
Technology news on Phys.org
moonman239 said:
Hey everyone!

I'm building a "Deal or No Deal" calculator that estimates the odds of getting a better deal than the one presented. As you can see in the title, I'm looking for a function that will calculate the CDF. For ease's sake, please only post JavaScript code (no C,Perl,BASIC,etc.)

Here you go.

Assuming you have mu and sigma as parameters of the log normal distribution (see http://en.wikipedia.org/wiki/Lognormal_distribution), the algorithm is:

Code:
// Get a standard normally distributed number using Box-Muller
double z1 = Math.sqrt(-2 * Math.log(1.0 - Math.random())) 
            * Math.sin(2 * Math.PI * Math.random());

// Transform the number to the log normal distribution
double x = Math.exp(mu + sigma * z1);

Does this meet your needs?

[EDIT]Adjusted the code to prevent a domain-violation of Math.log()[/EDIT]
 
I like Serena said:
Code:
// Get a standard normally distributed number using Box-Muller
double z1 = Math.sqrt(-2 * Math.log(1.0 - Math.random())) 
            * Math.sin(2 * Math.PI * Math.random());

// Transform the number to the log normal distribution
double x = Math.exp(mu + sigma * z1);
[EDIT]Adjusted the code to prevent a domain-violation of Math.log()[/EDIT]

Uh, thanks I guess. Just to be certain you aren't missing anything, this outputs P(X <= x), correct?
EDIT: One more thing: Does the lognormal distribution seem more appropriate for my case than the normal distribution? EDIT: Pardon my asking, but do I need to run this algorithm repeatedly? EDIT: I found another one:

Code:
function rnd_bmt() {
    var x = 0, y = 0, rds, c;

    // Get two random numbers from -1 to 1.
    // If the radius is zero or greater than 1, throw them out and pick two new ones
    // Rejection sampling throws away about 20% of the pairs.
    do {
    x = Math.random()*2-1;
    y = Math.random()*2-1;
    rds = x*x + y*y;
    }
    while (rds == 0 || rds > 1)

    // This magic is the Box-Muller Transform
    c = Math.sqrt(-2*Math.log(rds)/rds);

    // It always creates a pair of numbers. I'll return them in an array.
    // This function is quite efficient so don't be afraid to throw one away if you don't need both.
    return [x*c, y*c];
}
 
Last edited:
moonman239 said:
Uh, thanks I guess. Just to be certain you aren't missing anything, this outputs P(X <= x), correct?
EDIT: One more thing: Does the lognormal distribution seem more appropriate for my case than the normal distribution? EDIT: Pardon my asking, but do I need to run this algorithm repeatedly? EDIT: I found another one: function rnd_bmt()

Oops. No sorry, this does not output P(X <= x).
It outputs a random number x in such a way that its chance matches the log-normal probability distribution.

The other algorithm you found does the same thing as my first line of code calculating z1.
That is, it generates a random number matching the standard normal distribution. It's just a bit more convoluted.

And I don't know yet what you want to use it for, so I can't tell you whether it is appropriate for your case.

To calculate P(X <= x) you'll need another algorithm.

For starters there is a version in the apache commons library you could use:
http://commons.apache.org/math/apidocs/org/apache/commons/math/distribution/NormalDistribution.html

If you call it with:
Code:
NormalDistribution.cumulativeProbability((Math.log(x) - mu) / sigma);
you'll get the P(X <= x) for the log-normal distribution.
 
Last edited by a moderator:
Here's a function for the cumulative probability and a second one for the log-normal cumulative probability

Code:
double normalCumulativeProbability(double z) 
{
    double b1 =  0.31938153; 
    double b2 = -0.356563782; 
    double b3 =  1.781477937;
    double b4 = -1.821255978;
    double b5 =  1.330274429; 
    double p  =  0.2316419; 
    double c2 =  0.3989423; 

    if (z >  6.0) { return 1.0; }; // this guards against overflow 
    if (z < -6.0) { return 0.0; };
    double a = Math.abs(z); 
    double t = 1.0/(1.0+a*p); 
    double b = c2*Math.exp((-z)*(z/2.0)); 
    double n = ((((b5*t+b4)*t+b3)*t+b2)*t+b1)*t; 
    n = 1.0-b*n; 
    if ( z < 0.0 ) n = 1.0 - n; 
    return n; 
}

double lognormalCumulativeProbability(double x, double mu, double sigma)
{
    return normalCumulativeProbabilty((Math.log(x) - mu) / sigma);
}

So what's this about "deal-or-no-deal"?
 
Thanks :)
 
I like Serena said:
So what's this about "deal-or-no-deal"?

It's based on a game show.
 

Similar threads

  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 16 ·
Replies
16
Views
6K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
Replies
24
Views
31K
  • · Replies 4 ·
Replies
4
Views
4K
  • · Replies 14 ·
Replies
14
Views
6K
  • · Replies 2 ·
Replies
2
Views
3K