¿Cómo recreo una fórmula de Excel que llama a TREND () en C #?

Estoy construyendo una página .net para imitar una spreadsheet. La hoja contiene esta fórmula

=ROUND(TREND(AA7:AE7,AA$4:AE$4,AF$4),1) 

¿Alguien puede proporcionar el equivalente de C # de TREND() ? Alternativamente, si alguien puede proporcionar un atajo alnetworkingedor de eso, está bien también; No estoy lo suficientemente familiarizado con las matemáticas para saber si hay una manera más fácil.

Aquí hay algunos numbers de muestra si esto ayuda.

AA7: AE7 6 8 10 12 14

o 10.2 13.6 17.5 20.4 23.8

AA $ 4: AE $ 4 600 800 1000 1200 1400

AF $ 4 650

editar: esto es lo que se me ocurrió y parece estar produciendo los mismos numbers que mi spreadsheet.

 public static partial class Math2 { public static double[] Trend(double[] known_y, double[] known_x, params double[] new_x) { // return array of new y values double m, b; Math2.LeastSquaresFitLinear(known_y, known_x, out m, out b); List<double> new_y = new List<double>(); for (int j = 0; j < new_x.Length; j++) { double y = (m * new_x[j]) + b; new_y.Add(y); } return new_y.ToArray(); } // found at http://stackoverflow.com/questions/7437660/how-do-i-recreate-an-excel-formula-which-calls-trend-in-c // with a few modifications public static void LeastSquaresFitLinear(double[] known_y, double[] known_x, out double M, out double B) { if (known_y.Length != known_x.Length) { throw new ArgumentException("arrays are unequal lengths"); } int numPoints = known_y.Length; //Gives best fit of data to line Y = MC + B double x1, y1, xy, x2, J; x1 = y1 = xy = x2 = 0.0; for (int i = 0; i < numPoints; i++) { x1 = x1 + known_x[i]; y1 = y1 + known_y[i]; xy = xy + known_x[i] * known_y[i]; x2 = x2 + known_x[i] * known_x[i]; } M = B = 0; J = ((double)numPoints * x2) - (x1 * x1); if (J != 0.0) { M = (((double)numPoints * xy) - (x1 * y1)) / J; //M = Math.Floor(1.0E3 * M + 0.5) / 1.0E3; // TODO this is disabled as it seems to product results different than excel B = ((y1 * x2) - (x1 * xy)) / J; // B = Math.Floor(1.0E3 * B + 0.5) / 1.0E3; // TODO assuming this is the same as above } } } 

Considere que la TENDENCIA se basa en la Función de Excel, ESTIMACION.LINEAL. Si sigue este enlace, https://support.office.com/en-us/article/LINEST-function-84d7d0d9-6e50-4101-977a-fa7abf772b6d , le explicará la funcionalidad detrás de ESTIMACION.LINEAL.

Además, encontrarás la fórmula base que usa.

Primera Fórmula .

Segunda formulación

Esta publicación ha sido muy útil ya que hemos necesitado recrear esto en C #. Gracias a la respuesta de Jeff anterior he recreado esa fórmula usando lo siguiente:

 using System; using System.Collections.Generic; using System.Linq; using System.Drawing; public static class MathHelper { /// <summary> /// Gets the value at a given X using the line of best fit (Least Square Method) to determine the equation /// </summary> /// <param name="points">Points to calculate the value from</param> /// <param name="x">Function input</param> /// <returns>Value at X in the given points</returns> public static float LeastSquaresValueAtX(List<PointF> points, float x) { float slope = SlopeOfPoints(points); float yIntercept = YInterceptOfPoints(points, slope); return (slope * x) + yIntercept; } /// <summary> /// Gets the slope for a set of points using the formula: /// m = ∑ (x-AVG(x)(y-AVG(y)) / ∑ (x-AVG(x))² /// </summary> /// <param name="points">Points to calculate the Slope from</param> /// <returns>SlopeOfPoints</returns> private static float SlopeOfPoints(List<PointF> points) { float xBar = points.Average(p => pX); float yBar = points.Average(p => pY); float dividend = points.Sum(p => (pX - xBar) * (pY - yBar)); float divisor = (float)points.Sum(p => Math.Pow(pX - xBar, 2)); return dividend / divisor; } /// <summary> /// Gets the Y-Intercept for a set of points using the formula: /// b = AVG(y) - m( AVG(x) ) /// </summary> /// <param name="points">Points to calculate the intercept from</param> /// <returns>Y-Intercept</returns> private static float YInterceptOfPoints(List<PointF> points, float slope) { float xBar = points.Average(p => pX); float yBar = points.Average(p => pY); return yBar - (slope * xBar); } } 

Dado que Point usa numbers integers para definir sus valores, he elegido usar PointF ya que en nuestras aplicaciones, puede haber muchos decimales. Disculpe cualquier terminología matemática que esté desactivada ya que dedico más time a escribir código que a desarrollar algorithms como este, aunque me gustaría que cualquiera me corrija si confundiera un término en alguna parte.

Esto es ciertamente más rápido que esperar a que Excel Interop se cargue en segundo plano para usar el método Trend del libro de trabajo.