使用C#编码数学函数

时间:2014-03-17 09:01:36

标签: c#

我尝试使用C#编写此函数: Function that i try to code

我不确定我的代码是否正确以解决此问题

这是我尝试编写的方法代码:

 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;
    }

我尝试在for循环中测试此方法,但它总是返回0值,我认为返回值小于容纳 double 变量
任何人都帮我解决这个问题并获得返回值

5 个答案:

答案 0 :(得分:1)

问题出在这里:

Math.Exp(RightEx);

此时,RightEx的值为-966.1(约)

使用doublee^-966.1将返回0.

请注意,如果您从指定的公式替换sigma(1.37)和mu(8.35)的值,您将从PDF()获得〜0.00000000000000013088463858575497的返回值(仍然非常小,但至少它不是零)。

答案 1 :(得分:0)

这应该是normal distribution(又名“钟形曲线”)吗?如果是,您的公式和编码不正确。没有Log功能。

我想知道为什么你会为平均值和标准偏差硬编码这两个常量。如果您传递了这些函数,那么这将是一个更普遍有用的函数,因此您可以在许多不同的情况下使用它。

我建议你写x*x而不是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;
}

不是将对Random的调用嵌入函数中,而是将其传递给它。

答案 2 :(得分:0)

在图片中,sigma定义为1.37,而在实现中,定义为0.35。此外,mu(在实现中称为M)定义为14.45,而在图片中定义为8.35。

答案 3 :(得分:0)

在处理指数pdf时,这是一个非常常见的问题。一般来说,exp(。)内的值的大小太高。如果你试图计算高斯密度,那么配方就是错误的,你应该从配方中删除ln()。

然而,如果这是一个特殊情况(或另一个pdf)并且公式是正确的,那么我将问这个计算的原因。如果你不需要结果的确切值,并且只使用返回的变量进行比较(例如找到pdf的峰值索引等),那么你可以做这个数学技巧:

如果将整个公式封装在' ln()'配方将成为;

  

ln(LeftBase * Math.Exp(RightEx)) - > LN(LeftBase)+ LN(Math.Exp(RightEx))    - ln& exp相互抵消 - > ln(LeftBase)+ RightEx

通过执行此操作,您现在可以使用与零不同的数字,并且可以根据需要比较返回的结果。

答案 4 :(得分:0)

这不是一个解决方案,只是建议更清晰,更有效的编码:

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;
}