FastStatistics.java
package ac.essex.ooechs.imaging.commons.fast;
import ac.essex.ooechs.imaging.commons.StatisticsSolver;
/**
* A much faster way to calculate the standard deviation. There
* is no need to store all the values of x.
*
* Formula taken from this excellent site:
* http://www.sciencebuddies.org/mentoring/project_data_analysis_variance_std_deviation.shtml
*
* @author Olly Oechsle, University of Essex, Date: 06-Mar-2008
* @version 1.0
*/
public class FastStatistics {
private float sumXSquared = 0;
private float totalX = 0;
private int n = 0;
private float max = Float.MIN_VALUE;
private float min = Float.MAX_VALUE;
public static void main(String[] args) {
StatisticsSolver mean1 = new StatisticsSolver();
for (int n = 0; n < 10; n++) {
long start = System.currentTimeMillis();
for (int i = 0; i <100000; i++) {
StatisticsSolver s = new StatisticsSolver();
s.addData(3);
s.addData(4);
s.addData(4);
s.addData(5);
s.addData(6);
s.addData(8);
s.getStandardDeviation();
}
long time = System.currentTimeMillis() - start;
mean1.addData(time);
System.out.println(time + "ms");
}
System.out.println("Original Mean Time: " + mean1.getMean());
StatisticsSolver mean2 = new StatisticsSolver();
for (int n = 0; n < 10; n++) {
long start = System.currentTimeMillis();
for (int i = 0; i <100000; i++) {
FastStatistics s = new FastStatistics();
s.addData(3);
s.addData(4);
s.addData(4);
s.addData(5);
s.addData(6);
s.addData(8);
s.getStandardDeviation();
}
long time = System.currentTimeMillis() - start;
mean2.addData(time);
System.out.println(time + "ms");
}
System.out.println("Efficient Mean Time: " + mean2.getMean());
}
/**
* Allows you to get the statistic by a numeric type instead of calling the right method.
* Useful if you want to choose which method during runtime.
*/
public float getStatistic(int type) {
switch (type) {
case StatisticsSolver.TOTAL:
return getTotal();
case StatisticsSolver.MEAN:
return getMean();
case StatisticsSolver.MAX:
return getMax();
case StatisticsSolver.MIN:
return getMin();
case StatisticsSolver.RANGE:
return getRange();
case StatisticsSolver.VARIANCE:
return getVariance();
case StatisticsSolver.STANDARD_DEVIATION:
return getStandardDeviation();
}
throw new RuntimeException("Invalid statistic type: " + type);
}
public void addData(float x) {
totalX += x;
sumXSquared += (x * x);
if (x > max) max = x;
if (x < min) min = x;
n++;
}
public float getTotal() {
return totalX;
}
public float getMean() {
return totalX / n;
}
public float getVariance() {
float mean = getMean();
return (sumXSquared / n) - (mean * mean);
}
public float getStandardDeviation() {
return (float) Math.sqrt(getVariance());
}
public float getRange() {
return max - min;
}
public float getMax() {
return max;
}
public float getMin() {
return min;
}
public void reset() {
sumXSquared = 0;
totalX = 0;
n = 0;
}
}