/// https://numerics.mathdotnet.com/Regression.html#Evaluating-the-model-at-specific-data-points /// Linear: y = (a * x) + b private void ApplyLinearFitting() { double[] xdata = Points.Select(p => p.X).ToArray(); double[] ydata = Points.Select(p => p.Y).ToArray(); Tuple <double, double> p = Fit.Line(xdata, ydata); double a = p.Item1; // == 10; intercept double b = p.Item2; // == 0.5; slope A = a; B = b; //Func<double, double> f = Fit.LineFunc(xdata, ydata); Func <double, double> f = Fit.LinearCombinationFunc( xdata, ydata, x => a * x, x => b); List <DataPoint> fittedPoints = new List <DataPoint>(); foreach (var item in Points) { fittedPoints.Add(new DataPoint(item.X, f(item.X))); } FittedPoints = fittedPoints; }
private void PowerFitting() { var points = dataSource.GetPoints; var xPoints = points.Select(p => p.X).ToList(); var yPoints = points.Select(p => p.Y).ToList(); var fitFunc = Fit.LinearCombinationFunc(xPoints.ToArray(), yPoints.ToArray(), x => 1.0, x => Math.Exp(x)); PopulateFittingPoints(fitFunc); }
/******************************************************************************************** * Constructors ********************************************************************************************/ public PolynomApproximationThroughOrigin( double[] x, double[] y, int order ) { Func <double, double>[] functions = new Func <double, double> [order]; for (int i = 0; i < functions.Length; i++) { int power = i + 1; functions[i] = value => Math.Pow(value, power); } GetValue = Fit.LinearCombinationFunc(x, y, functions); }
public void FitsToTrigonometricLinearCombination() { // Mathematica: Fit[{{1,4.986},{2,2.347},{3,2.061},{4,-2.995},{5,-2.352},{6,-5.782}}, {1, sin(x), cos(x)}, x] // -> 4.02159 sin(x) - 1.46962 cos(x) - 0.287476 var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 }; var resp = Fit.LinearCombination(x, y, z => 1.0, Math.Sin, Math.Cos); Assert.AreEqual(3, resp.Length); Assert.AreEqual(-0.287476, resp[0], 1e-4); Assert.AreEqual(4.02159, resp[1], 1e-4); Assert.AreEqual(-1.46962, resp[2], 1e-4); var resf = Fit.LinearCombinationFunc(x, y, z => 1.0, Math.Sin, Math.Cos); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(4.02159 * Math.Sin(z) - 1.46962 * Math.Cos(z) - 0.287476, resf(z), 1e-4); } }
/// 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; }
/// https://numerics.mathdotnet.com/Regression.html#Evaluating-the-model-at-specific-data-points /// https://numerics.mathdotnet.com/Regression.html#Linearizing-non-linear-models-by-transformation /// https://discuss.mathdotnet.com/t/exponential-fit/131/2 /// Exponential: y = a * exp(b * x) private void ApplyExponentialFitting() { double[] x = Points.Select(p => p.X).ToArray(); double[] y = Points.Select(p => p.Y).ToArray(); double[] p = Exponential(x, y); // a=1.017, r=0.687 A = p[0]; B = p[1]; Func <double, double> f = Fit.LinearCombinationFunc( Points.Select(p => p.X).ToArray(), Points.Select(p => p.Y).ToArray(), x => p[0] * Math.Exp(p[1] * x)); List <DataPoint> fittedPoints = new List <DataPoint>(); foreach (var item in Points) { fittedPoints.Add(new DataPoint(item.X, f(item.X))); } FittedPoints = fittedPoints; }
private void UpdateErgChartData() { splitContainer2.Panel2.Controls.Clear(); splitContainer2.Panel2.Controls.Add(chart); chart.ChartAreas.Clear(); chart.Series.Clear(); ChartArea area = new ChartArea("1"); //area.AxisX.Interval = 5; //area.AxisX.IntervalType = DateTimeIntervalType.Number; //area.AxisX.LabelStyle.Format = "{0.0}"; chart.ChartAreas.Add(area); UpdateErgList(); CheckBox cbC2 = (CheckBox)splitContainer2.Panel1.Controls[0]; CheckBox cbEcho = (CheckBox)splitContainer2.Panel1.Controls[4]; TextBox tbMonths = (TextBox)splitContainer2.Panel1.Controls[2]; TrackBar tb = (TrackBar)splitContainer2.Panel1.Controls[3]; Series ser = new Series(); ser.ChartType = SeriesChartType.Point; double months = Double.Parse(tbMonths.Text); TimeSpan span = new TimeSpan((int)(months * 30), 0, 0, 0, 0); DateTime minDate = GetMinDate(); DateTime maxDate = GetMaxDate(); int totDays = GetTotDays(); DateTime endTime = minDate.AddDays(tb.Value); DateTime startTime = endTime.Subtract(span); List <double> x = new List <double>(); List <double> y = new List <double>(); foreach (Erg m in ErgList) { bool include = false; Activity a = m.Activity; if (cbC2.Checked) { if (m.Type == ErgType.Row) { include = true; } } if (cbEcho.Checked) { if (m.Type == ErgType.Bike) { include = true; } } if ((a.Date < startTime) | (a.Date > endTime.AddDays(1))) { include = false; } if (include) { double mins = (double)m.RndTime / 60; DataPoint dp = new DataPoint(); dp.ToolTip = mins.ToString("0.##") + " mins," + m.calPerMin.ToString("0.##") + " cal/min\n" + a.Date.ToString("MM/dd/yyyy") + '\n' + a.Workout + '\n' + a.Description + "\n\n" + a.Notes; dp.MarkerSize = 6; if (m.Type == ErgType.Row) { dp.Color = Color.Red; } if (m.Type == ErgType.Bike) { dp.Color = Color.Black; } dp.SetValueXY(mins, m.calPerMin); ser.Points.Add(dp); x.Add(mins); y.Add(m.calPerMin); } } if (x.Count > 0) { area.AxisY.Minimum = ((int)(y.Min() / 5)) * 5; area.AxisY.Maximum = ((int)(y.Max() / 5) + 1) * 5; area.AxisX.Minimum = 0; area.AxisX.Maximum = ((int)(x.Max() / 5) + 1) * 5; } area.AxisY.Title = "cal/min"; area.AxisX.Interval = 5; area.AxisX.MajorGrid.Enabled = true; area.AxisX.MinorGrid.Enabled = true; area.AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dash; area.AxisX.MinorGrid.LineWidth = 1; area.AxisX.MinorGrid.LineColor = Color.Gray; area.AxisX.MajorGrid.Interval = 5; area.AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid; area.AxisX.MajorGrid.LineWidth = 2; area.AxisX.MajorGrid.LineColor = Color.Black; area.AxisY.Interval = 5; area.AxisY.MajorGrid.Enabled = true; area.AxisY.MinorGrid.Enabled = true; area.AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dash; area.AxisY.MinorGrid.LineWidth = 1; area.AxisY.MinorGrid.LineColor = Color.Gray; area.AxisY.MajorGrid.Interval = 5; area.AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid; area.AxisY.MajorGrid.LineWidth = 2; area.AxisY.MajorGrid.LineColor = Color.Black; if (x.Count > 3) { //Func<double, double> f = Fit.LineFunc(x.ToArray(), y.ToArray()); //Func<double, double> f = Fit.LinearCombinationFunc(x.ToArray(), y.ToArray(), x => 1.0, x => Math.Log(x)); Func <double, double> f = Fit.LinearCombinationFunc(x.ToArray(), y.ToArray(), dx => 1.0, dx => Math.Log(dx)); int num = 100; Series serFit = new Series(); serFit.ChartType = SeriesChartType.Line; double minV = x.Min(); double maxV = x.Max(); double d = maxV - minV; for (int i = 0; i < num; i++) { double t = ((i) * (d / 100)) + minV; serFit.Points.AddXY(t, f(t)); //Debug.WriteLine(f(t).ToString()); } chart.Series.Add(serFit); } chart.Series.Add(ser); chart.ChartAreas[0].AxisX.Title = "Work Duration"; chart.ChartAreas[0].AxisY.Title = "Cal/min"; }
private void UpdatePowerChartData() { splitContainer2.Panel2.Controls.Clear(); splitContainer2.Panel2.Controls.Add(chart); chart.ChartAreas.Clear(); chart.Series.Clear(); ChartArea area = new ChartArea("1"); area.AxisX.Interval = 5; area.AxisX.IntervalType = DateTimeIntervalType.Number; area.AxisX.LabelStyle.Format = "{0.0}"; chart.ChartAreas.Add(area); double maxPower = 0; double maxDuration = 0; foreach (Activity a in Data) { if (a.WorkPerformed > 0 && a.WorkTime > 0) { int duration = a.WorkTime / 1000; //time in secs double mins = duration / 60.0f; int power = a.WorkPerformed / duration; if (power > maxPower) { maxPower = power; } if (mins > maxDuration) { maxDuration = mins; } } } area.AxisY.Minimum = 0; area.AxisY.Maximum = maxPower; area.AxisX.Minimum = 0; area.AxisX.Maximum = maxDuration; area.AxisY.Title = "ft-lbs/sec"; CheckBox cbRunning = (CheckBox)splitContainer2.Panel1.Controls[0]; TextBox tbMonths = (TextBox)splitContainer2.Panel1.Controls[2]; TrackBar tb = (TrackBar)splitContainer2.Panel1.Controls[3]; Series ser = new Series(); ser.ChartType = SeriesChartType.Point; double months = Double.Parse(tbMonths.Text); TimeSpan span = new TimeSpan((int)(months * 30), 0, 0, 0, 0); DateTime minDate = GetMinDate(); DateTime maxDate = GetMaxDate(); int totDays = GetTotDays(); DateTime endTime = minDate.AddDays(tb.Value); DateTime startTime = endTime.Subtract(span); List <double> x = new List <double>(); List <double> y = new List <double>(); foreach (Activity a in Data) { if (a.WorkPerformed > 0 && a.WorkTime > 0) { bool include = true; if (cbRunning.Checked) { if (a.IncludesRunning()) { include = false; } } if ((a.Date < startTime) | (a.Date > endTime)) { include = false; } if (include) { int duration = a.WorkTime / 1000; //time in secs double mins = duration / 60.0f; int power = a.WorkPerformed / duration; DataPoint dp = new DataPoint(); dp.ToolTip = a.Date.ToString("MM/dd/yyyy") + '\n' + a.Description; dp.MarkerSize = 6; dp.SetValueXY(mins, power); ser.Points.Add(dp); x.Add(mins); y.Add(power); } } } if (x.Count > 3) { //Func<double, double> f = Fit.LineFunc(x.ToArray(), y.ToArray()); //Func<double, double> f = Fit.LinearCombinationFunc(x.ToArray(), y.ToArray(), x => 1.0, x => Math.Log(x)); Func <double, double> f = Fit.LinearCombinationFunc(x.ToArray(), y.ToArray(), dx => 1.0, dx => Math.Log(dx)); int num = 100; Series serFit = new Series(); serFit.ChartType = SeriesChartType.Line; double minV = x.Min(); double maxV = x.Max(); double d = maxV - minV; for (int i = 0; i < num; i++) { double t = ((i) * (d / 100)) + minV; serFit.Points.AddXY(t, f(t)); //Debug.WriteLine(f(t).ToString()); } chart.Series.Add(serFit); } chart.Series.Add(ser); chart.ChartAreas[0].AxisX.Title = "Work Duration"; chart.ChartAreas[0].AxisY.Title = "Total work (ft-lbs/sec)"; }