0

我正在尝试找到具有以下形式的拟合函数:

f(x) = P / (1 + e^((x + m) / s)

哪里P是一个已知常数。我正在将此函数拟合到测量的双精度列表(20-100 个元素之间),并且所有这些值都有一个相应的 x 值。我对 C# 比较陌生,对数学也不是很了解,所以我发现阅读可用的文档有点困难。

我曾尝试使用 AlgLib,但不知道从哪里开始或使用什么功能。

编辑:所以要准确地说我要找什么:我想找到一个 C# 方法,我可以在其中传递函数形式以及一些坐标(x 和 y 值)并让该方法返回两个未知变量(上面的 s 和 m)。

4

1 回答 1

3

我每天都使用 AlgLib 来达到这个目的。如果您访问链接http://www.alglib.net/docs.php并一直向下滚动,您会发现包含多种语言(包括 C#)的代码示例的文档,我认为这些对您有帮助非常: http ://www.alglib.net/translator/man/manual.csharp.html

对于您的问题,您应该考虑所需的所有约束,但是在给定输入函数和数据的情况下获得非线性最小二乘拟合的简单示例如下所示:

public SomeReturnObject Optimize(SortedDictionary<double, double> dataToFitTo, double p, double initialGuessM, double initialGuessS)
{
   var x = new double[dataToFitTo.Count,1];

   for(int i=0; i < dataToFitTo.Count; i++)
   {
       x[i, 0] = dataToFitTo.Keys.ElementAt(i);
   }

   var y = dataToFitTo.Values.ToArray();
   var c = new[] {initialGuessM, initialGuessS};

   int info;
   alglib.lsfitstate state;
   alglib.lsfitreport rep;

   alglib.lsfitcreatef(x, y, c, 0.0001, out state);
   alglib.lsfitsetcond(state, epsf, 0, 0);
   alglib.lsfitfit(state, MyFunc, null, p);
   alglib.lsfitresults(state, out info, out c, out rep);

   /*  When you get here, the c[] array should have the optimized values 
       for m and s, so you'll want to handle accordingly depending on your
       needs.  I'm not sure if you want out parameters for m and s or an 
       object that has m and s as properties. */

}

private void MyFunc(double[] c, double[] x, ref double func, object obj)
{
    var xPt = x[0];
    var m = c[0];
    var s = c[1];
    var P = (double)obj;
    func = P / (1 + Math.Exp((xPt + m) / s));
}

请注意,这只是一个快速而肮脏的例子。Alglib 中有很多内置功能,因此您需要在此处调整问题代码以满足您对边界约束、权重、步长、可变缩放等的需求。从第二个链接中的示例和文档中应该清楚如何完成所有这些工作。

另请注意,Alglib 对 MyFunc 的方法签名非常特别,因此我会避免移动这些输入或添加任何更多。

或者,如果 Alglib 不能满足您的所有需求,您可以编写自己的 Levenberg-Marquardt 算法。

于 2018-06-08T15:36:01.917 回答