如何重新创build一个在C#中调用TREND()的Excel公式?

我正在构build一个.net页面来模拟电子表格。 该表包含此公式

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

有人可以提供相当于TREND()的C#吗? 或者,如果任何人都可以提供一个快捷方式,也可以; 我对那里的math不够熟悉,不知道有没有更简单的方法。

这里有一些示例编号,如果有帮助。

AA7:AE7 6 8 10 12 14

10.2 13.6 17.5 20.4 23.8

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

AF $ 4 650

编辑:这是我想出来的,它似乎与我的电子表格产生相同的数字。

 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 } } } 

考虑TREND基于Excel函数LINEST。 如果您按照此链接https://support.office.com/en-us/article/LINEST-function-84d7d0d9-6e50-4101-977a-fa7abf772b6d ,它将解释LINEST背后的function。

另外,你会发现它使用的基本公式。

第一个公式

第二个公式

这篇文章非常有帮助,因为我们需要在C#中重新创build它。 感谢杰夫的回答上面我已经使用以下重新创build公式:

 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); } } 

由于Point使用整数来定义它的值我select使用PointF,因为在我们的应用程序中,可以有很多小数位。 请原谅,因为我花更多的时间来编写代码,而不是像开发这样的algorithm,但是如果我在某个地方弄糊涂了一个词,我会爱任何人纠正我的。

这肯定比等待Excel Interop加载到后台以使用工作簿的趋势方法更快。