/* * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. * */ package gcparser; import java.io.BufferedReader; import java.io.IOException; import java.util.Collection; import java.util.Iterator; public class Stats { public Stats() { initialize(); } public Stats(double data[], int n) { initialize(); add(data, n); } public Stats(String data[], int n) { initialize(); add(data, n); } public Stats(BufferedReader r) throws IOException { initialize(); add(r); } long n() { return _n; } long count() { return _n; } double sum() { return _sum; } // Valid only if count() > 0 (i.e., at least 1 data point required). // The geometric_mean() is valid only if all data points are >= 0. double min() { return _min; } double max() { return _max; } double mean() { return _sum / _n; } double arithmetic_mean() { return mean(); } double geometric_mean() { // Product of all the points to the power 1/n: // // (x1 * x2 * x3 ...) ** (1/n) // // -or- // // e to the power x, where x is the mean of the natural logs of // the data points: // // exp((ln(x1) + ln(x2) + ln(x3) ...) / n). // // This uses the former. return Math.pow(_product, 1.0 / n()); } double sum_of_squares() { return _sum_of_squares; } double sum_of_squared_deviations() { // sum[i=1:n]((x[i] - mean)^2) // sum[i=1:n](x[i]^2 - 2 mean x[i] + mean^2) // sum[i=1:n](x[i]^2) - 2 mean sum[i=1:n](x[i]) + // sum[i=1:n](mean^2) // sum_of_squares() - 2 mean sum() + n mean^2 // sum_of_squares() - 2 (sum() / n) sum() + n mean^2 // sum_of_squares() - 2 sum()^2 / n + n mean^2 // sum_of_squares() - 2 sum()^2 / n + (n mean)^2 / n // sum_of_squares() - 2 sum()^2 / n + sum()^2 / n // sum_of_squares() - sum()^2 / n return sum_of_squares() - sum() * sum() / n(); } double biased_variance() { // Assumes n >= 1. return sum_of_squared_deviations() / n(); } double unbiased_variance() { // Assumes n >= 2. return sum_of_squared_deviations() / (n() - 1.0); } double variance() { // Assumes n >= 2. return unbiased_variance(); } double stddev() { // Assumes n >= 2. return Math.sqrt(variance()); } // Add a data point to the sample. public void add(double value) { if (value < _min) _min = value; if (value > _max) _max = value; _sum += value; _sum_of_squares += value * value; _product *= value; ++_n; } public void add(String value) { add(Double.parseDouble(value)); } // Add multiple data points from an array. public void add(double data[], int n) { for (int i = 0; i < n; ++i) { add(data[i]); } } // Add multiple data points from an array. public void add(String data[], int n) { for (int i = 0; i < n; ++i) { add(data[i]); } } // Add multiple data points from a collection. public void add(Collection<Double> data, int n) { Iterator<Double> iter = data.iterator(); for (int i = 0; iter.hasNext() && i < n; ++i) { add(iter.next()); } } // Add multiple data points from a stream. public void add(BufferedReader r) throws IOException { String s = r.readLine(); while (s != null) { add(s); } } // Remove a data point from the sample. public void remove(double value, Collection<Double> data) { if (value == _min || value == _max) { initialize(); add(data, data.size()); return; } remove(value); } // Remove a single data point, without checking for min/max. protected void remove(double value) { _sum -= value; _sum_of_squares -= value * value; _product /= value; --_n; } protected void initialize() { _min = Double.MAX_VALUE; _max = Double.MIN_VALUE; _sum = 0.0; _sum_of_squares = 0.0; _product = 1.0; _n = 0; } // Member data. private double _min; private double _max; private double _sum; private double _sum_of_squares; private double _product; // Product of all n terms, for geomean. private long _n; }