using System;
using System.Collections.Generic;
namespace MathLib
{
///
/// Container class for all statistics values which may be set by the Statistics class
///
public class StatTypes
{
public double? Average { get; set; }
public double? StdDev { get; set; }
}
public static class Statistics
{
///
/// Gets the average and standard deviation of a set in one pass
///
/// The set to be operated on /// A StatTypes object with the Average and StdDev values
/// for the set operated on
public static StatTypes GetAvgAndStdDev(this IEnumerable<double> values)
{
StatTypes avgAndStdDev = new StatTypes();
// ref: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/
double mean = 0.0;
double sum = 0.0;
double stdDev = 0.0;
int count = 0;
foreach (double val in values)
{
count++;
double delta = val - mean;
mean += delta / count;
sum += delta * (val - mean);
}
if (1 < count)
{
stdDev = Math.Sqrt(sum / (count - 1));
}
if (count > 0)
{
avgAndStdDev.Average = mean;
avgAndStdDev.StdDev = stdDev;
}
return avgAndStdDev;
}
///
/// Gets the average and standard deviation of a set in one pass
///
/// The set to be operated on /// A StatTypes object with the Average and StdDev values
/// for the set operated on
public static StatTypes GetAvgAndStdDev(this IEnumerable<int> values)
{
StatTypes avgAndStdDev = new StatTypes();
// ref: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/
double mean = 0.0;
double sum = 0.0;
double stdDev = 0.0;
int count = 0;
foreach (double val in values)
{
count++;
double delta = val - mean;
mean += delta / count;
sum += delta * (val - mean);
}
if (1 < count)
{
stdDev = Math.Sqrt(sum / (count - 1));
}
if (count > 0)
{
avgAndStdDev.Average = mean;
avgAndStdDev.StdDev = stdDev;
}
return avgAndStdDev;
}
}
}
Usage is made simple this way:
string metric = "DaysWorked";
StatTypes avgAndStdDev = (from row in table.AsEnumerable()
where row.Field<double?>(metric) != null
select row.Field<double>(metric)).GetAvgAndStdDev();
calculatedTarget["Mean"] = (object)avgAndStdDev.Average ?? DBNull.Value;
calculatedTarget["StdDev"] = avgAndStdDev.StdDev;
As an aside, I had no idea how to name the class or namespace for any usefulness. However, I learned that I never use the class name, anyway, so perhaps it doesn't matter. *shrug*
No comments:
Post a Comment