public PowerViewModel(double[] xdata, double[] ydata, Tuple <double, double> xlimit, Tuple <double, double> ylimit) { DirectRegressionMethod method = DirectRegressionMethod.QR; Tuple <double, double> p = Fit.Power(xdata, ydata, method); double a = p.Item1; double b = p.Item2; if (!Double.IsNaN(a) && !Double.IsNaN(b)) { this.FunctionModel = new PlotModel { Title = "Power regresion [ f(x) = " + a + " x ^ " + b + " ]" }; Func <double, double> powerFunction = (x) => a *Math.Pow(x, b); FunctionModel.Series.Add(new FunctionSeries(powerFunction, xlimit.Item1, xlimit.Item2, 0.0001)); // view limits FunctionModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = xlimit.Item1, Maximum = xlimit.Item2 }); FunctionModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = ylimit.Item1, Maximum = ylimit.Item2 }); } else { displayed = false; } }
/// <summary> /// Least-Squares fitting the points (x, y) to a power /// y : x -> a * x^b. /// </summary> public static IModelledFunction PowerFunc(double[] xArray, double[] yArray) { Tuple <double, double> parameters = Fit.Power(xArray, yArray); double a = parameters.Item1; double b = parameters.Item2; Func <double, double> function = t => a *System.Math.Pow(t, b); return(new PowerFunction(function, parameters)); }
public List <DataPoint> CalculatePoints(List <DataPoint> points) { var pointsLine = new List <DataPoint>(); Tuple <double, double> p = Fit.Power(points.Select(x => x.X).ToArray(), points.Select(x => x.Y).ToArray()); double a = p.Item1; double b = p.Item2; foreach (var item in points) { var y = a * Math.Pow(item.X, b); pointsLine.Add(new DataPoint(item.X, y)); } return(pointsLine); }
/// https://numerics.mathdotnet.com/Regression.html#Linearizing-non-linear-models-by-transformation /// https://github.com/mathnet/mathnet-numerics/blob/master/src/Numerics/Fit.cs /// https://discuss.mathdotnet.com/t/exponential-fit/131/2 /// https://discuss.mathdotnet.com/t/curve-fitting-power/605 /// Power function: y = a * (x ^ b) private void ApplyPowerFunctionFitting() { double[] x = Points.Select(p => p.X).ToArray(); double[] y = Points.Select(p => p.Y).ToArray(); Tuple <double, double> p = Fit.Power(x, y); // a=1.017, r=0.687 A = p.Item1; B = p.Item2; Func <double, double> f = Fit.LinearCombinationFunc( Points.Select(p => p.X).ToArray(), Points.Select(p => p.Y).ToArray(), x => p.Item1 * Math.Pow(x, p.Item2)); List <DataPoint> fittedPoints = new List <DataPoint>(); foreach (var item in Points) { fittedPoints.Add(new DataPoint(item.X, f(item.X))); } FittedPoints = fittedPoints; }
public FitData CalcFit(List <DataPoint> points) { FitData result = new FitData("Power function"); var xdata = points.Select(x => x.X).ToArray(); var ydata = points.Select(x => x.Y).ToArray(); Tuple <double, double> p = Fit.Power(xdata, ydata); result.A = p.Item1; result.B = p.Item2; result.Points = DataPoints(points).ToList(); return(result); //local function for return list of regresion Points[need to C# 8] IEnumerable <DataPoint> DataPoints(List <DataPoint> points) { foreach (var point in points) { yield return(new DataPoint(point.X, result.A * Math.Exp(result.B * point.X))); } } }
public void FitsToPowerSameAsExcelTrendLine() { // X Y // 1 0.2 // 2 0.3 // 4 1.3 // 6 4.2 // -> y = 0.1454*x^1.7044 var x = new[] { 1.0, 2.0, 4.0, 6.0 }; var y = new[] { 0.2, 0.3, 1.3, 4.2 }; var resp = Fit.Power(x, y); Assert.AreEqual(0.1454, resp.Item1, 1e-3); Assert.AreEqual(1.7044, resp.Item2, 1e-3); var resf = Fit.PowerFunc(x, y); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(0.1454 * Math.Pow(z, 1.7044), resf(z), 1e-2); } }