Created
August 26, 2013 16:47
-
-
Save holyketzer/6343677 to your computer and use it in GitHub Desktop.
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
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Windows; | |
namespace Microsoft.SystemCenter.Visualization.Component.Extensions.Library.Controls.Web.Components | |
{ | |
public class MathUtills | |
{ | |
/// <summary> | |
/// Fits a line to a collection of (x,y) points. | |
/// </summary> | |
/// <param name="xVals">The x-axis values.</param> | |
/// <param name="yVals">The y-axis values.</param> | |
/// <param name="inclusiveStart">The inclusive inclusiveStart index.</param> | |
/// <param name="exclusiveEnd">The exclusive exclusiveEnd index.</param> | |
/// <param name="rsquared">The r^2 value of the line.</param> | |
/// <param name="yintercept">The y-intercept value of the line (i.e. y = ax + b, yintercept is b).</param> | |
/// <param name="slope">The slop of the line (i.e. y = ax + b, slope is a).</param> | |
public static void LinearRegression(double[] xVals, double[] yVals, | |
int inclusiveStart, int exclusiveEnd, | |
out double rsquared, out double yintercept, | |
out double slope) | |
{ | |
Debug.Assert(xVals.Length == yVals.Length); | |
double sumOfX = 0; | |
double sumOfY = 0; | |
double sumOfXSq = 0; | |
double sumOfYSq = 0; | |
double ssX = 0; | |
double ssY = 0; | |
double sumCodeviates = 0; | |
double sCo = 0; | |
double count = exclusiveEnd - inclusiveStart; | |
for (int ctr = inclusiveStart; ctr < exclusiveEnd; ctr++) | |
{ | |
double x = xVals[ctr]; | |
double y = yVals[ctr]; | |
sumCodeviates += x * y; | |
sumOfX += x; | |
sumOfY += y; | |
sumOfXSq += x * x; | |
sumOfYSq += y * y; | |
} | |
ssX = sumOfXSq - ((sumOfX * sumOfX) / count); | |
ssY = sumOfYSq - ((sumOfY * sumOfY) / count); | |
double RNumerator = (count * sumCodeviates) - (sumOfX * sumOfY); | |
double RDenom = (count * sumOfXSq - (sumOfX * sumOfX)) | |
* (count * sumOfYSq - (sumOfY * sumOfY)); | |
sCo = sumCodeviates - ((sumOfX * sumOfY) / count); | |
double meanX = sumOfX / count; | |
double meanY = sumOfY / count; | |
double dblR = RNumerator / Math.Sqrt(RDenom); | |
rsquared = dblR * dblR; | |
yintercept = meanY - ((sCo / ssX) * meanX); | |
slope = sCo / ssX; | |
} | |
/// <summary> | |
/// Get slope (a coeff) of a trend line | |
/// </summary> | |
/// <param name="points">The enumerable of points (x- and y-values).</param> | |
/// <returns>The slop of the line (i.e. y = ax + b, slope is a).</returns> | |
public static double? GetSlope(IEnumerable<Point> points) | |
{ | |
double slope; | |
double yintercept; | |
double rsquared; | |
var cachedPoints = points.ToArray(); | |
LinearRegression(cachedPoints.Select(p => p.X).ToArray(), cachedPoints.Select(p => p.Y).ToArray(), 0, cachedPoints.Length, out rsquared, out yintercept, out slope); | |
if (Double.IsNaN(slope)) | |
{ | |
return null; | |
} | |
return slope; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment