The Fit
class is just a facade that is good enough in most scenarios, but you can always use the algorithms directly to get exactly what you need.
Fit.Polynomial:
Polynomial curve fitting with high orders is a bit problematic numerically, so specialized algorithms and routines to tune/refine parameters at the end have been developed. However, Math.NET Numerics just uses a QR decomposition for now (although it is planned to replace the implementation at some point):
public static double[] Polynomial(double[] x, double[] y, int order)
{
var design = Matrix<double>.Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j));
return MultipleRegression.QR(design, Vector<double>.Build.Dense(y)).ToArray();
}
Fit.MultiDim
on the other hand uses normal equations by default, which is much faster but less numerically robust than the QR decomposition. That's why you've seen reduced accuracy with this method.
public static double[] MultiDim(double[][] x, double[] y)
{
return MultipleRegression.NormalEquations(x, y);
}
In your case I'd try to use the MultipleRegression
class directly, with either QR
(if good enough) or Svd
(if even more robustness is needed; much slower (consider to use native provider if too slow)):
var x1 = new double[] { ... };
var x2 = new double[] { ... };
var y = new double[] { ... };
var design = Matrix<double>.Build.DenseOfRowArrays(
Generate.Map2(x1,x2,(x1, x2) => new double[] { x1*x1, x1, x2*x2, x2, 1d }));
double[] p = MultipleRegression.QR(design, Vector<double>.Build.Dense(y)).ToArray();
(Using Math.NET Numerics v3.0.0-alpha7)
f(x1, x2) = a*x1*x1 + b*x1 + c*x2*x2 + d*x2 + e
– Rachellerachisx1*x1
andx2*x2
as separate parameters. However I am afraid this will produce results less accurate than using Fit.Polynomial (it was the case when I tried to do Cubic Function Fitting using your trick to leverage Linear Regression). Do you see any better method? – Rachellerachis