Lognormal cumulative distribution function for JavaScript?

Click For Summary

Discussion Overview

The discussion revolves around the implementation of a cumulative distribution function (CDF) for a lognormal distribution in JavaScript, specifically in the context of creating a "Deal or No Deal" calculator. Participants are exploring various algorithms and code snippets to achieve this functionality.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant requests a JavaScript function to calculate the lognormal CDF for their calculator.
  • Another participant provides a Box-Muller transform algorithm to generate a standard normally distributed number and transforms it to a lognormal distribution, questioning if it outputs P(X ≤ x).
  • A later reply clarifies that the provided code does not output P(X ≤ x) but rather generates a random number matching the log-normal probability distribution.
  • Participants discuss whether the lognormal distribution is more appropriate than the normal distribution for the calculator's purpose, with one expressing uncertainty about its suitability without more context.
  • One participant shares a function for calculating the cumulative probability for both normal and lognormal distributions, referencing the Apache Commons library for additional functionality.
  • Another participant expresses curiosity about the context of the "deal-or-no-deal" application.

Areas of Agreement / Disagreement

There is no consensus on the appropriateness of the lognormal distribution for the specific application. Participants have differing views on the output of the provided algorithms and whether additional algorithms are necessary for calculating P(X ≤ x).

Contextual Notes

Some participants mention the need for additional algorithms to calculate P(X ≤ x) and reference external libraries, indicating potential limitations in the provided solutions.

Who May Find This Useful

Readers interested in statistical programming, particularly in JavaScript, and those working on applications involving probability distributions may find this discussion relevant.

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
12K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 24 ·
Replies
24
Views
31K
  • · Replies 4 ·
Replies
4
Views
4K
  • · Replies 14 ·
Replies
14
Views
6K
  • · Replies 2 ·
Replies
2
Views
3K