如何从C#指数拟合函数中返回最优A和b值?
修正MathNet.Numerics非线性回归代码以获取指数拟合的A和b参数
现有基于MathNet.Numerics的C#非线性回归指数拟合代码,当前FitCurve函数返回的MinimizingPoint被误当作x轴起始点,实际需要获取指数公式y = A * exp(-x * b)中的最优A和b值,以下是修改方案:
核心问题分析
- 原模型公式与目标公式不符:原代码模型为
y = parameters[0] * Math.Exp(parameters[1] * x[i]),但目标是y = A * exp(-x * b),需调整指数项符号。 - 返回值结构混乱:原函数返回的元组包含x数据、拟合y值、参数列表,导致调用方误将参数当作坐标点处理。
result.MinimizingPoint本身就是拟合得到的最优参数数组,其中对应目标公式的A和b,无需额外处理。
修改后的拟合函数代码
using System; using System.Collections.Generic; using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.Optimization; namespace NonLinearRegressionExample { public class NonlinearRegressionCurveFitting { // 修改返回类型为具名元组,直接返回x数据、拟合y值、A和b参数,语义更清晰 public static (List<double> xData, List<double> fittedY, double A, double b) FitCurve(List<double> xData, List<double> yData) { var xDataDense = new DenseVector(xData.ToArray()); var yDataDense = new DenseVector(yData.ToArray()); // 修正模型公式,完全匹配目标y = A * exp(-x * b) Vector<double> Model(Vector<double> parameters, Vector<double> x) { var y = CreateVector.Dense<double>(x.Count); // parameters[0]对应A,parameters[1]对应b,指数项添加负号 for (int i = 0; i < x.Count; i++) { y[i] = parameters[0] * Math.Exp(-parameters[1] * x[i]); } return y; } // 初始参数猜测值,可根据实际数据范围调整 var start = new DenseVector(new double[] { 1.0, 0.1 }); var objective = ObjectiveFunction.NonlinearModel(Model, xDataDense, yDataDense); var solver = new LevenbergMarquardtMinimizer(maximumIterations: 10000); var result = solver.FindMinimum(objective, start); // result.MinimizedValues是拟合得到的y值数组 var fittedY = new List<double>(result.MinimizedValues.ToArray()); // result.MinimizingPoint就是最优参数:[0]对应A,[1]对应b double optimalA = result.MinimizingPoint[0]; double optimalB = result.MinimizingPoint[1]; return (xData, fittedY, optimalA, optimalB); } } }
修改后的驱动程序代码
var fittingResult = NonlinearRegressionCurveFitting.FitCurve(xData, yData); List<double> originalX = fittingResult.xData; List<double> originalY = yData; List<double> fittedY = fittingResult.fittedY; double A = fittingResult.A; double b = fittingResult.b; // 输出拟合得到的参数 Console.WriteLine($"拟合得到的指数公式:y = {A:F4} * exp(-x * {b:F4})"); // 绘图展示 DataPlotter plotter = new DataPlotter(); plotter.AddCurve("原始数据", originalX, originalY, IsSymbolVisible: false, color: Color.Red); plotter.AddCurve("拟合曲线", originalX, fittedY, IsSymbolVisible: false, color: Color.Green); plotter.ShowDialog();
关键修改说明
- 模型公式修正:在
Model方法中,将指数项从parameters[1] * x[i]改为-parameters[1] * x[i],完全匹配目标公式y = A * exp(-x * b)。 - 返回类型优化:使用具名元组直接返回
xData、fittedY、A、b,避免调用方混淆返回值含义。 - 参数提取:直接从
result.MinimizingPoint提取最优A和b,无需将其当作坐标点处理。
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

