Last active
November 15, 2022 19:09
-
-
Save S1r-Lanzelot/1d93acf9033c56d2f7954ae0dae19d26 to your computer and use it in GitHub Desktop.
Excel TREND Function in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class StatisticalCalculation | |
{ | |
public static double Trend(IEnumerable<double> knownYValues, IEnumerable<double> knownXValues, double newX) | |
{ | |
var line = LineByLeastSquares(knownYValues, knownXValues); | |
return line.slope * newX + line.intercept; | |
} | |
private static (double slope, double intercept) LineByLeastSquares(IEnumerable<double> knownYValues, IEnumerable<double> knownXValues) | |
{ | |
(double xAvg, List<double> xValues) = NormalizeAndFindAvg(knownXValues); | |
(double yAvg, List<double> yValues) = NormalizeAndFindAvg(knownYValues); | |
if (xValues.Count != yValues.Count) | |
throw new ArgumentException($"{nameof(yValues)} must match {nameof(xValues)} [{yValues.Count}, {xValues.Count}]."); | |
double dividendSum = 0d; | |
double divisorSum = 0d; | |
for (int i = 0; i < yValues.Count; ++i) | |
{ | |
double xValue = xValues[i]; | |
double yValue = yValues[i]; | |
double xDiff = xValue - xAvg; | |
dividendSum += xDiff * (yValue - yAvg); | |
divisorSum += Math.Pow(xDiff, 2); | |
} | |
double slope = dividendSum / divisorSum; | |
return (slope, yAvg - (slope * xAvg)); | |
} | |
private static (double avg, List<double> valueList) NormalizeAndFindAvg(IEnumerable<double> values) | |
{ | |
double sum = 0d; | |
var listValues = new List<double>(); | |
foreach (var value in values) | |
{ | |
listValues.Add(value); | |
sum += value; | |
} | |
return (sum / listValues.Count, listValues); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment