Just a short one again. This time I will explain the coefficient of variation. And once again give you a full code example of how you can implement it in c#.
The coefficient of variation (CV) is a normalized measure of dispersion. It is a measure of consistency indicating the uniformity in the values of the signal from the mean of the signal. A smaller coefficient of variation indicates a more consistent signal. The values are more uniformly dispersed.
Coefficient of variation is useful when comparing data with different units. For example in the SoapSynergy project I am working on I often have to make comparisons between displacement and angles. Since those signals have different units ((centi)meters versus degrees) it is useful to have a dimensionless number to compare with.
The downside of the coefficient of variation is that it is quite sensitive to changes in the mean. So if your signal moves around the 0 (as a sine wave does) making your mean ~=0, the coefficient of variation can quickly jump to near infinite numbers rendering it useless. For this reason I chose to calculate the coefficient of variation using the absolute values of my signals.
using System;
using System.Collections.Generic;
namespace SampleApp
{
internal static class Program
{
private const float CompareIsZeroTolerance = 0.000000000001f;
private static void Main()
{
List<double> data = new List<double> {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2};
double mean = data.Mean();
double sd = data.StandardDeviation();
double cv = CoefficientOfVariance(sd, mean);
Console.WriteLine("CV: {0}, (mean: {1}, sd: {2})", cv, mean, sd);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private static double CoefficientOfVariance(double sd, double mean)
{
if (Math.Abs(mean - 0) < CompareIsZeroTolerance) return 0;
return sd / mean;
}
}
public static class MyListExtensions
{
public static double Mean(this List<double> values)
{
return values.Count == 0 ? 0 : values.Mean(0, values.Count);
}
private static double Mean(this IList<double> values, int start, int end)
{
double s = 0;
for (int i = start; i < end; i++)
{
s += values[i];
}
return s / (end - start);
}
private static double Variance(this IList<double> values, double mean, int start, int end)
{
double variance = 0;
int i;
for (i = start; i < end; i++)
{
variance += Math.Pow((values[i] - mean), 2);
}
int n = end - start;
if (start > 0) n -= 1;
return variance / (n);
}
public static double StandardDeviation(this List<double> values)
{
return values.Count == 0 ? 0 : values.StandardDeviation(0, values.Count);
}
private static double StandardDeviation(this IList<double> values, int start, int end)
{
double mean = values.Mean(start, end);
double variance = values.Variance(mean, start, end);
return Math.Sqrt(variance);
}
}
}