C# 中超过 5 个参数的曲线拟合

问题描述 投票:0回答:1

我想使用 C# 拟合一条具有 6 个参数的曲线。为此,我使用

MathNet.Numerics.Fit.Curve
。但由于它最多只支持 5 个参数,所以我尝试将函数的一个参数设置为猜测值并拟合其他参数。

为了拟合之前固定的值,我设置了另一个已拟合的值作为固定值并再次拟合。这个概念对于大多数数据都适用,但有时仍然会失败。

我想知道是否有人知道如何实现 6 个参数的

MathNet.Numerics.Fit.Curve
,因为我认为这可以解决我的问题。

谢谢

c# curve-fitting function-fitting
1个回答
0
投票

如果您想测试

MathNet.Fit
的五个以上参数 模型,我们可以创建
Fit.Curve
的版本 它采用具有动态数量参数的函数。这意味着 该模型将是类型的函数
Func<Vector<double>, double, double>
- 第一个 参数,是参数向量,第二个参数是
x
坐标的当前值。

我们可以先看一下

Fit.Curve
实现的源代码; 它们基于
FindMinimum.OfFunction
的相应版本; 幸运的是,虽然没有动态参数数量版本
Fit.Curve
中,有 有一个 对于
FindMinimum.OfFunctions
。使用此版本和一般方法 现有的
Fit.Curve
版本我们的函数可以写成 简单如:

static Vector<double> FitCurve2(double[] x, double[] y, Func<Vector<double>, double, double> f, Vector<double> initialGuess, double tolerance = 1e-8, int maxIterations = 1000) {
    return FindMinimum.OfFunction((p) => Distance.Euclidean(Generate.Map(x, t => f(p, t)), y), initialGuess, tolerance, maxIterations);
}

用于测试您的特定案例的示例模型和数据将是最有帮助的,并且仍然可以帮助改进问题和答案。

不过,现在这里有一个使用此函数来拟合 6 参数曲线的示例。这里的模型函数是

F1
,一个带参数的有理函数
q0, ..., q5
。我从这些参数的一组已知值开始
q0 = 1.596, q1 = -1.277, .....
(所有这些都来自我的应用程序, 出于本次测试的目的,将它们视为随机的)并生成 与这些参数匹配的一组
x
y0
数组。然后添加一些 随机噪声到
y0
并拟合所得的
x
y
模型 功能。如果一切顺利,我们将检索一些参数
q0
...
q5
接近原始的,我们通常这样做。

using MathNet.Numerics;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;

const int n = 200;
const double q0 = 1.596, q1 = -1.277, q2 = -4.33, q3 = 0.5, q4 = 1, q5 = 1.4; // "clear" parameters

var x = Generate.LinearSpaced(n, -3, 3);
var rnd = new double[n];
Normal.Samples(rnd, 0.0, 1.0);
var y0 = Generate.Map(x, xi=>F1(q0, q1, q2, q3, q4, q5, xi));
var y = Generate.Map2(y0, rnd, (yi, ri) => yi + ri * 0.2); // y0 + noise
Vector<double> initialGuess = DenseVector.OfArray([1.0, 1.0, 1.0, 1.0, 1.0, 1.0]);
var q = FitCurve2(x, y, (q, x) => F1(q[0], q[1], q[2], q[3], q[4], q[5], x),
    initialGuess, 1e-9, 10000);
Console.WriteLine($"q0 = {q[0]}  q1 = {q[1]}  q2 = {q[2]}  q3 = {q[3]}  q4 = {q[4]}  q5 = {q[5]}");
// parameters impacted by noise, still close the "clear" ones.

double F1(double q0, double q1, double q2, double q3, double q4, double q5, double x)
{
    return (q0 + q1 * x + q2 * Math.Pow(x, 2) + q3  * Math.Pow(x, 3) +  q4 * Math.Pow(x, 4))/(x*x + q5);
}

static Vector<double> FitCurve2(double[] x, double[] y, Func<Vector<double>, double, double> f, Vector<double> initialGuess, double tolerance = 1e-8, int maxIterations = 1000) {
    return FindMinimum.OfFunction((p) => Distance.Euclidean(Generate.Map(x, t => f(p, t)), y), initialGuess, tolerance, maxIterations);
}

这是此拟合的图表图像。 enter image description here

注意,可以验证如果使用少于6个参数 计算结果与计算结果相同

Fit.Curve
的静态参数数量版本(当然,如果 所有其他参数,例如初始猜测、容差或最大迭代次数 平等)。

话虽这么说,但应该注意的是

MathNet
并不是唯一的 可以在 C# 和 dotNet 中进行非线性曲线拟合的库。的 当然,stackoverflow不允许 寻求图书馆的建议, 我也没有资格给予一些。只考虑可能发生的情况 如果曲线拟合没有按预期结果,问题就来了 可能并不总是你的模型,但它也可以是算法 由库使用,在这种情况下,也可以测试其他库。

© www.soinside.com 2019 - 2024. All rights reserved.