在 C# 中使用非线性平方拟合
Using nonlinear square fit in C#
我正在尝试寻找具有以下形式的拟合函数:
f(x) = P / (1 + e^((x + m) / s)
其中 P
是一个 已知常数 。我将此函数拟合到测量双精度列表(20-100 个元素之间),并且所有这些值都有相应的 x 值。我对 C# 比较陌生,对数学也不是很了解,所以我发现很难阅读可用的文档。
我尝试过使用 AlgLib,但不知道从哪里开始或使用什么功能。
编辑:为了准确说明我正在寻找的内容:我想找到一个 C# 方法,我可以在其中传递函数形式以及一些坐标(x 和 y 值)并拥有该方法返回两个未知变量(上面的 s 和 m)。
我每天使用 AlgLib 正是为了这个目的。如果你去 link http://www.alglib.net/docs.php and scroll all the way down, you'll find the documentation with code examples in a number of languages (including C#) that I think will help you immensely: 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 中有很多内置功能,因此您需要在此处调整问题代码以满足您对边界约束、权重、步长、变量缩放等的需求。从第二个 link.
中的示例和文档中应该清楚如何执行所有这些操作
另请注意,Alglib 对 MyFunc 的方法签名非常讲究,因此我会避免移动这些输入或添加更多输入。
或者,如果 Alglib 不能满足您的所有需求,您可以编写自己的 Levenberg-Marquardt 算法。
我正在尝试寻找具有以下形式的拟合函数:
f(x) = P / (1 + e^((x + m) / s)
其中 P
是一个 已知常数 。我将此函数拟合到测量双精度列表(20-100 个元素之间),并且所有这些值都有相应的 x 值。我对 C# 比较陌生,对数学也不是很了解,所以我发现很难阅读可用的文档。
我尝试过使用 AlgLib,但不知道从哪里开始或使用什么功能。
编辑:为了准确说明我正在寻找的内容:我想找到一个 C# 方法,我可以在其中传递函数形式以及一些坐标(x 和 y 值)并拥有该方法返回两个未知变量(上面的 s 和 m)。
我每天使用 AlgLib 正是为了这个目的。如果你去 link http://www.alglib.net/docs.php and scroll all the way down, you'll find the documentation with code examples in a number of languages (including C#) that I think will help you immensely: 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 中有很多内置功能,因此您需要在此处调整问题代码以满足您对边界约束、权重、步长、变量缩放等的需求。从第二个 link.
中的示例和文档中应该清楚如何执行所有这些操作另请注意,Alglib 对 MyFunc 的方法签名非常讲究,因此我会避免移动这些输入或添加更多输入。
或者,如果 Alglib 不能满足您的所有需求,您可以编写自己的 Levenberg-Marquardt 算法。