0

i try to coding this Function using C#: Function that i try to code

and I'm not sure of my code is correct to solve this Function

this is code i try to write as a method:

 public double PDF()
    {
        // output variable
        double result = 0.0;
        // inputs
        double Segma = 0.35;
        double M = 14.45;
        double x = 0.0;
        Random rnd = new Random();
        x = rnd.NextDouble();
        double LeftBase = 1/(Math.Sqrt(2*Math.PI)*Segma*x);
        double RightEx = (-1 * Math.Pow((Math.Log(x) - M), 2)) / (2 * (Math.Pow(Segma, 2)));
        result= LeftBase * Math.Exp(RightEx);
        return result;
    }

and i try to test this method in for loop but it always return 0 value , i think the return value is Less than accommodate double variable
anyone help me to solve this problem and get the return value

3
  • 1
    Without looking at this too closely my first advice would be to replace all integer constants with double constants (e.g. 1 with 1D). You may be getting conversions to integer where you don't expect. Commented Mar 17, 2014 at 9:04
  • I would output/view in the debugger the values of LeftBase and RightEx to see if they are what you expect - one, or both, of your calculations may be going wrong. You can also split these calculations into multiple steps to see where your code is malforming your math. Commented Mar 17, 2014 at 9:06
  • Usually, the normal function is called with arguments in range Mu +/- 6 Sigma or so. Even after taking the Log, you may be far from this range. Commented Mar 17, 2014 at 9:18

5 Answers 5

1

The problem is occurring here:

Math.Exp(RightEx);

At this point, RightEx has the value -966.1 (approx)

Using double, e^-966.1 will return 0.

Note that if you substitute the values for sigma (1.37) and mu (8.35) from the specified formula, you will get a return value from PDF() of ~0.00000000000000013088463858575497 (still very small, but at least it is non-zero).

Sign up to request clarification or add additional context in comments.

Comments

0

In the picture, sigma is defined as 1.37, whereas in the implementaion it is defined as 0.35. Furthermore, mu (called M in the implementation) is defined as 14.45, whereas in the picture it is defined as 8.35.

Comments

0

This is a very common problem while dealing with exponential pdf's. Generally speaking magnitude of the value inside exp(.) is too high. If you're trying to compute Gaussian density the formulation is wrong by the way, you should remove ln() from the formulation.

However if this is a special case (or another pdf) and the formulation is correct then i will ask the reason of this computation. If you don't need the exact value of the result and will only use the returned variable for comparison (for example finding the peak index of the pdf etc.), then you can do this mathematical trick:

If you encapsulate whole formula inside 'ln()' the formulation will become;

ln(LeftBase*Math.Exp(RightEx)) -> ln(LeftBase)+ln(Math.Exp(RightEx)) -- ln & exp cancels each other --> ln(LeftBase) + RightEx

By doing this you will now have numbers different than zeros and you can compare returning results as you like.

2 Comments

This is a log-normal distribution.
ops i remembered now, thx for the info, but the answer is still valid, it's independent of the distribution and can be generalized for computing any pdf from the exponential family (if you don't need the exact value)
0

This is not a solution but just a suggestion for cleaner and more efficient coding:

double Normal(double X, double Mu, double Sigma)
{
    Sigma= 1. / Sigma;
    X= (X - Mu) * Sigma;
    return Math::Exp(- 0.5 * X * X) * 0.398942280401432678 * Sigma;
}

double LogNormal(double X, double Mu, double Sigma)
{
    return X == 0 ? 0 : Normal(Math::Log(X), Mu, Sigma) / X;
}

Comments

0

Is this supposed to be the normal distribution (aka "bell curve")? If yes, your formula and coding are incorrect. There's no Log function required.

I'd wonder why you would hard code those two constants for mean and standard deviation. This would be a much more generally useful function if you passed those in so you can use it in many different situations.

I'd recommend that you write x*x instead of Math.Pow(x, 2).

public double LogNormal(double x, double mu, double sigma) {
    // check to see if x is less than zero and do something - throw exception, etc.
    double denom = 1.0/Math.Sqrt(2*Math.PI)*sigma*x);
    double expon = (Math.Log(x)-mu)/Math.Sqrt(2.0)/sigma;
    return Math.Exp(-expon*expon)/denom;
}

Instead of embedding that call to Random inside the function I'd pass it in.

3 Comments

Actually, this is Normal(Ln(x), Mu, Sigma) / x.
Didn't know if the OP had just made a mistake; thought it was worth the question.
With the hardcoded numbers chosen, the random double (between 0 and 1) will be so many standard deviations away from the mean, it may as well be 0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.