In the Matlab I have the following equation, which gives me a, b, c and d coefficients.
gaussEqn = 'a*exp(-((x-b)/c)^2)+d';
[fittedModel, gof] = fit(sensData(:, 1), sensData(:, 2), gaussEqn, 'Start', startPoints);
a = fittedModel.a;
b = fittedModel.b;
c = fittedModel.c;
d = fittedModel.d;
How can I do the same in C# using math libraries? The equation is not exactly gaussian, but contains an extra d coefficient. But I will be happy even to calculate a, b c only based on gaussian equation.
If you want to use MathNet to estimate the fit parameters in C#, as per Felix Castor's recommendation, you may use
Fit.Curve
functions.
Using your model function, in order to test the fit, I started with some arbitrary parameters a0 = 2.1, b0 = 3.4, c0 = 1.35, d0 = 5.3
. I generated n = 1000
equidistant x
values and computed the function for them. I added some
normally distributed random noise to the y
values and used matlab's
fit
to retrieve the parameters (which are typically close to the
"correct" values, a0, b0, c0, d0
if the initial guess is sufficiently
close).
I ended up with this matlab code:
a0 = 2.1; b0 = 3.4; c0 = 1.35; d0 = 5.3;
n = 1000;
x = linspace(0, 2*b, n);
y = a0 * exp(-((x - b0) / c0).^2) + d0 + randn(1, n)*0.05;
startPoints = [2, 2, 1, 1];
fittedModel = fit(x', y', 'a*exp(-((x-b)/c)^2)+d', 'Start', startPoints);
a = fittedModel.a;
b = fittedModel.b;
c = fittedModel.c;
d = fittedModel.d;
fprintf("a = %f b = %f c = %f d = %f", a, b, c, d);
which I wrote in order to show its C# MathNet "translation":
using MathNet.Numerics;
using MathNet.Numerics.Distributions;
double F0(double a, double b, double c, double d, double x)
{
return a * Math.Exp(-Math.Pow((x - b) / c, 2)) + d;
}
const int n = 1000;
const double a0 = 2.1, b0 = 3.4, c0 = 1.35, d0 = 5.3; // "correct" parameters
var x = Generate.LinearSpaced(n, 0, 2*b0);
var rnd = new double[n];
Normal.Samples(rnd, 0.0, 1.0);
var y0 = Generate.Map(x, xi=>F0(a0, b0, c0, d0, xi));
var y = Generate.Map2(y0, rnd, (yi, ri) => yi + ri * 0.05);
var (a, b, c, d) = Fit.Curve(x, y, F0, 2.0, 2.0, 1.0, 1.0);
Console.WriteLine($"a = {a} b = {b} c = {c} d = {d}");
That being said, you have to be aware that MathNet's algorithms are different from those of matlab, with matlab's versions being more sophisticated and more likely to find the right solution in difficult/edge cases.