using System;
using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Optimization;
namespace NonLinearRegressionExample
{
public class NonlinearRegressionCurveFitting
{
public static (List<double>, List<double>, List<double>) FitCurve(List<double> xData, List<double> yData)
{
// example data
var xDataDense = new DenseVector(xData.ToArray());
var yDataDense = new DenseVector(yData.ToArray());
Vector<double> Model(Vector<double> parameters, Vector<double> x)
{
var y = CreateVector.Dense<double>(x.Count);
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);
Vector<double> points = result.MinimizedValues;
Vector<double> minimizing = result.MinimizingPoint;
return (xData, new List<double>(points.ToArray()), new List<double>(minimizing.ToArray()));
}
}
}
Driver program:
var fittedCurve = NonlinearRegressionCurveFitting.FitCurve(xData, yData);
List<double> points = fittedCurve.Item2;
List<double> result = fittedCurve.Item3;
///Output the results
if (result.Count == 2)
{
DataPlotter plotter = new DataPlotter();
//plotter.ZoomXaxis(0, 10);
plotter.AddCurve("original",
new List<double>(xData.ToArray()),
new List<double>(yData.ToArray()),
IsSymbolVisible: false, color: Color.Red);
plotter.AddCurve("fitted",
new List<double>(xData.ToArray()),
new List<double>(points.ToArray()),
IsSymbolVisible: false,
color: Color.Green);
plotter.AddPoint("Point", result[0], result[1], Color.BlueViolet);
plotter.ShowDialog();
}
The above source code fits an exponential curve using nonlinear regression.
However, how can I return the best A
and b
values from this C# function for the exponential formula
y = A * exp(-x * b)
?
.
This function is returning MinimizingPoint
which seems to be the starting point of the x-axis.
.
The values returned by MinimizingPoint
are the parameters to the fitted function. In your case of y = A * exp(b * x)
, the first parameter is A = 0.84275567216928349
and the second is b = -0.0071155733183345549
.
If you want to find a value for any given x
, then calculate:
y = A * exp(b * x)
or with the concrete parameters:
y = 0.84275567216928349 * exp(-0.0071155733183345549 * x)
It makes no sense to plot these parameters given as result[0]
and result[1]
in the FitCurve
method with
plotter.AddPoint("Point", result[0], result[1], Color.BlueViolet);
since they do not represent a point in the graph.