C# 如何将正态分布的累积分布函数拟合到数据点?

C# 如何将正态分布的累积分布函数拟合到数据点?,c#,normal-distribution,data-fitting,C#,Normal Distribution,Data Fitting,我有数据需要拟合公式 y = a*CDF[NormalDistribution[m, s], x] 我需要在哪里找到a,m和s 我用Mathematica测试了拟合,它发现拟合速度相当快,数据拟合得很好 但是,我需要实现这一点 目前,我已经实现了一种通过下坡来估计参数的方法,但是我的实现非常慢(每次估计大约0.5秒) 最好的方法是什么?John Cook有一个实现: 我将在下面复制它: static double Phi(double x) { // constants dou

我有数据需要拟合公式

y = a*CDF[NormalDistribution[m, s], x]
我需要在哪里找到a,m和s

我用Mathematica测试了拟合,它发现拟合速度相当快,数据拟合得很好

但是,我需要实现这一点

目前,我已经实现了一种通过下坡来估计参数的方法,但是我的实现非常慢(每次估计大约0.5秒)


最好的方法是什么?

John Cook有一个实现:

我将在下面复制它:

static double Phi(double x)
{
    // constants
    double a1 = 0.254829592;
    double a2 = -0.284496736;
    double a3 = 1.421413741;
    double a4 = -1.453152027;
    double a5 = 1.061405429;
    double p = 0.3275911;

    // Save the sign of x
    int sign = 1;
    if (x < 0)
        sign = -1;
    x = Math.Abs(x) / Math.Sqrt(2.0);

    // A&S formula 7.1.26
    double t = 1.0 / (1.0 + p*x);
    double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t * Math.Exp(-x*x);

    return 0.5 * (1.0 + sign*y);
}

static void TestPhi()
{
    // Select a few input values
    double[] x = 
    {
        -3, 
        -1, 
        0.0, 
        0.5, 
        2.1 
    };

    // Output computed by Mathematica
    // y = Phi[x]
    double[] y = 
    { 
        0.00134989803163, 
        0.158655253931, 
        0.5, 
        0.691462461274, 
        0.982135579437 
    };

    double maxError = 0.0;
    for (int i = 0; i < x.Length; ++i)
    {
        double error = Math.Abs(y[i] - Phi(x[i]));
        if (error > maxError)
            maxError = error;
    }

        Console.WriteLine("Maximum error: {0}", maxError);
}
静态双φ(双x)
{
//常数
双a1=0.254829592;
双a2=-0.284496736;
双a3=1.421413741;
双a4=-1.453152027;
双a5=1.061405429;
双p=0.3275911;
//保存x的符号
int符号=1;
if(x<0)
符号=-1;
x=数学Abs(x)/数学Sqrt(2.0);
//A&S公式7.1.26
双t=1.0/(1.0+p*x);
双y=1.0-(((a5*t+a4)*t+a3)*t+a2)*t+a1)*t*数学实验(-x*x);
返回0.5*(1.0+符号*y);
}
静态void TestPhi()
{
//选择几个输入值
双[]x=
{
-3, 
-1, 
0.0, 
0.5, 
2.1
};
//Mathematica计算的输出
//y=φ[x]
双[]y=
{ 
0.00134989803163, 
0.158655253931, 
0.5, 
0.691462461274, 
0.982135579437
};
double maxError=0.0;
对于(int i=0;i最大错误)
maxError=错误;
}
WriteLine(“最大错误:{0}”,maxError);
}

John Cook有一个实现:

我将在下面复制它:

static double Phi(double x)
{
    // constants
    double a1 = 0.254829592;
    double a2 = -0.284496736;
    double a3 = 1.421413741;
    double a4 = -1.453152027;
    double a5 = 1.061405429;
    double p = 0.3275911;

    // Save the sign of x
    int sign = 1;
    if (x < 0)
        sign = -1;
    x = Math.Abs(x) / Math.Sqrt(2.0);

    // A&S formula 7.1.26
    double t = 1.0 / (1.0 + p*x);
    double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t * Math.Exp(-x*x);

    return 0.5 * (1.0 + sign*y);
}

static void TestPhi()
{
    // Select a few input values
    double[] x = 
    {
        -3, 
        -1, 
        0.0, 
        0.5, 
        2.1 
    };

    // Output computed by Mathematica
    // y = Phi[x]
    double[] y = 
    { 
        0.00134989803163, 
        0.158655253931, 
        0.5, 
        0.691462461274, 
        0.982135579437 
    };

    double maxError = 0.0;
    for (int i = 0; i < x.Length; ++i)
    {
        double error = Math.Abs(y[i] - Phi(x[i]));
        if (error > maxError)
            maxError = error;
    }

        Console.WriteLine("Maximum error: {0}", maxError);
}
静态双φ(双x)
{
//常数
双a1=0.254829592;
双a2=-0.284496736;
双a3=1.421413741;
双a4=-1.453152027;
双a5=1.061405429;
双p=0.3275911;
//保存x的符号
int符号=1;
if(x<0)
符号=-1;
x=数学Abs(x)/数学Sqrt(2.0);
//A&S公式7.1.26
双t=1.0/(1.0+p*x);
双y=1.0-(((a5*t+a4)*t+a3)*t+a2)*t+a1)*t*数学实验(-x*x);
返回0.5*(1.0+符号*y);
}
静态void TestPhi()
{
//选择几个输入值
双[]x=
{
-3, 
-1, 
0.0, 
0.5, 
2.1
};
//Mathematica计算的输出
//y=φ[x]
双[]y=
{ 
0.00134989803163, 
0.158655253931, 
0.5, 
0.691462461274, 
0.982135579437
};
double maxError=0.0;
对于(int i=0;i最大错误)
maxError=错误;
}
WriteLine(“最大错误:{0}”,maxError);
}