/* *
 * Title:        

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ package umontreal.iro.lecuyer.stat; import umontreal.iro.lecuyer.util.PrintfFormat; import umontreal.iro.lecuyer.probdist.StudentDist; import umontreal.iro.lecuyer.probdist.NormalDist; import umontreal.iro.lecuyer.probdist.ChiSquareDist; import java.util.logging.Level; import java.util.logging.Logger; /** * This type of statistical collector takes a sequence of real-valued * observations and can return the average, * the variance, a confidence interval for the theoretical mean, etc. * Each call to {@link #add add} provides a new observation. * When the broadcasting to observers is activated, * the method {@link #add add} will also pass this new information to its * registered observers. * This type of collector does not memorize the individual observations, * but only their number, sum, sum of squares, maximum, and minimum. * The subclass {@link TallyStore} offers a collector that memorizes * the observations. * */ public class Tally extends StatProbe implements Cloneable { private int numObs; private double sumSquares; private final boolean isStable = true; // = true: use a numerically stable // form for the average and the variance. // = false: use the old unstable forms. private double curAverage; // The average of the first numObs observations private double curSum2; // The sum (xi - average)^2 of the first numObs // observations. private Logger log = Logger.getLogger ("umontreal.iro.lecuyer.stat"); private static enum CIType {CI_NONE, CI_NORMAL, CI_STUDENT}; protected CIType confidenceInterval = CIType.CI_NONE; protected double level = 0.95; protected int digits = 3; /** * Constructs a new unnamed Tally statistical probe. * */ public Tally() { super(); init(); } /** * Constructs a new Tally statistical probe with * name name. * * @param name name of the tally * */ public Tally (String name) { super(); this.name = name; init(); } public void init() { maxValue = Double.NEGATIVE_INFINITY; minValue = Double.POSITIVE_INFINITY; sumValue = 0.0; sumSquares = 0.0; curAverage = 0.0; curSum2 = 0.0; numObs = 0; } /** * Gives a new observation x to the statistical collector. * If broadcasting to observers is activated for this object, * this method also transmits the new information to the * registered observers by invoking the method * {@link #notifyListeners notifyListeners}. * * @param x observation being added to this tally * * */ public void add (double x) { if (collect) { if (x < minValue) minValue = x; if (x > maxValue) maxValue = x; numObs++; sumValue += x; sumSquares += x * x; curSum2 += (numObs - 1)*(x - curAverage)*(x - curAverage) / numObs; curAverage += (x - curAverage)/numObs; } notifyListeners (x); } /** * Returns the number of observations given to this probe * since its last initialization. * * */ public int numberObs() { return numObs; } public double average() { if (numObs < 1) { //System.err.println ( // "******* Tally " + name + ": calling average() with " + numObs + // " Observation"); log.logp (Level.WARNING, "Tally", "average", "Tally " + name + ": calling average() with " + numObs + " observation"); return Double.NaN; } if (!isStable) return sumValue / (double) numObs; else return curAverage; } /** * Returns the sample variance of the observations since the last * initialization. * This returns Double.NaN * if the tally contains less than two observations. * * @return the variance of the observations * */ public double variance() { // throws NumberObservationException { // if (numObs < 2) throw NumberObservationException; if (numObs < 2) { //System.err.println ( // "******* Tally " + name + ": calling variance() with " + numObs + // " Observation"); log.logp (Level.WARNING, "Tally", "variance", "Tally " + name + ": calling variance() with " + numObs + " observation"); return Double.NaN; } if (!isStable) { double temp = sumSquares - (sumValue * sumValue)/(double)numObs; temp = temp / (numObs-1); if (temp < 0.0) return 0.0; return temp; } else return curSum2 / (numObs-1); } /** * Returns the sample standard deviation of the observations * since the last initialization. * This returns Double.NaN * if the tally contains less than two observations. * * @return the standard deviation of the observations * */ public double standardDeviation() { return Math.sqrt (variance()); } /** * Computes a confidence interval on the mean. * Returns, in elements 0 and 1 of the array * object centerAndRadius[], the center and half-length (radius) * of a confidence interval on the true mean of the random variable X, * with confidence level level, assuming that the n observations * given to this collector are independent and identically distributed * (i.i.d.) copies of X, and that n is large enough for the central limit * theorem to hold. This confidence interval is computed based on the statistic *

*

*
* Z = bar(X)n-μ/(Sn, x/(n)1/2) *

* where n is the number of observations given to this collector since its * last initialization, * bar(X)n = average() is the average of these * observations, Sn, x = standardDeviation() is the empirical * standard deviation. Under the assumption that the observations * of X are i.i.d. and n is large, * Z has the standard normal distribution. * The confidence interval given by this method is valid only if * this assumption is approximately verified. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @param centerAndRadius array of size 2 in which are returned the center * and radius of the confidence interval, respectively * * */ public void confidenceIntervalNormal (double level, double[] centerAndRadius) { // Must return an array object, cannot return 2 doubles directly double z; if (numObs < 2) throw new RuntimeException ( "Tally " + name + ": Calling confidenceIntervalStudent with < 2 Observations"); centerAndRadius[0] = average(); z = NormalDist.inverseF01 (0.5 * (level + 1.0)); centerAndRadius[1] = z * Math.sqrt (variance() / (double)numObs); } /** * Computes a confidence interval on the mean. * Returns, in elements 0 and 1 of the array * object centerAndRadius[], the center and half-length (radius) * of a confidence interval on the true mean of the random variable X, * with confidence level level, assuming that the observations * given to this collector are independent and identically distributed * (i.i.d.) copies of X, and that X has the normal distribution. * This confidence interval is computed based on the statistic *

*

*
* T = bar(X)n-μ/(Sn, x/(n)1/2) *

* where n is the number of observations given to this collector since its * last initialization, * bar(X)n = average() is the average of these * observations, Sn, x = standardDeviation() is the empirical * standard deviation. Under the assumption that the observations * of X are i.i.d. and normally distributed, * T has the Student distribution with n - 1 degrees of freedom. * The confidence interval given by this method is valid only if * this assumption is approximately verified, or if n is large enough * so that bar(X)n is approximately normally distributed. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @param centerAndRadius array of size 2 in which are returned the center * and radius of the confidence interval, respectively * * */ public void confidenceIntervalStudent (double level, double[] centerAndRadius) { // Must return an array object, cannot return 2 doubles directly double t; if (numObs < 2) throw new RuntimeException ( "Tally " + name + ": Calling confidenceIntervalStudent with < 2 Observations"); centerAndRadius[0] = average(); t = StudentDist.inverseF (numObs - 1, 0.5 * (level + 1.0)); centerAndRadius[1] = t * Math.sqrt (variance() / (double)numObs); } @Deprecated public String formatConfidenceIntervalNormal (double level, int d) { PrintfFormat str = new PrintfFormat(); double ci[] = new double[2]; confidenceIntervalNormal (level, ci); str.append (" " + (100*level) + "%"); str.append (" confidence interval for mean (normal): ("); str.append (7 + d, d, d-1, ci[0] - ci[1]).append (','); str.append (7 + d, d, d-1, ci[0] + ci[1]).append (" )" + PrintfFormat.NEWLINE); return str.toString(); } @Deprecated public String formatConfidenceIntervalNormal (double level) { return formatConfidenceIntervalNormal (level, 3); } /** * . * * Similar to {@link #confidenceIntervalNormal confidenceIntervalNormal}, * but returns the confidence interval in a formatted string of the form *
*
* ``95% confidence interval for mean (normal): (32.431, 32.487)'',
* using d fractional decimal digits. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @param d number of fractional decimal digits * * @return a confidence interval formatted as a string * */ public String formatCINormal (double level, int d) { return formatConfidenceIntervalNormal (level, d); } /** * Equivalent to formatCINormal (level, 3). * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @return a confidence interval formatted as a string * * */ public String formatCINormal (double level) { return formatConfidenceIntervalNormal (level); } @Deprecated public String formatConfidenceIntervalStudent (double level, int d) { PrintfFormat str = new PrintfFormat(); double ci[] = new double[2]; confidenceIntervalStudent (level, ci); str.append (" " + (100*level) + "%"); str.append (" confidence interval for mean (student): ("); str.append (7 + d, d, d-1, ci[0] - ci[1]).append (','); str.append (7 + d, d, d-1, ci[0] + ci[1]).append (" )" + PrintfFormat.NEWLINE); return str.toString(); } @Deprecated public String formatConfidenceIntervalStudent (double level) { return formatConfidenceIntervalStudent (level, 3); } /** * . * * Similar to {@link #confidenceIntervalStudent confidenceIntervalStudent}, * but returns the confidence interval in a formatted string of the form *
* ``95% confidence interval for mean (student): (32.431, 32.487)'',
* using d fractional decimal digits. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @param d number of fractional decimal digits * * @return a confidence interval formatted as a string * */ public String formatCIStudent (double level, int d) { return formatConfidenceIntervalStudent (level, d); } /** * Equivalent to formatCIStudent (level, 3). * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @return a confidence interval formatted as a string * */ public String formatCIStudent (double level) { return formatConfidenceIntervalStudent (level); } /** * Computes a confidence interval on the variance. * Returns, in elements 0 and 1 of array interval, the * left and right boundaries [I1, I2] of a confidence interval on the true * variance σ2 of the random variable X, with confidence level * level, assuming that the observations * given to this collector are independent and identically distributed * (i.i.d.) copies of X, and that X has the normal distribution. * This confidence interval is computed based on the statistic * * χ2n-1 = (n - 1)S2n/σ2 * where n is the number of observations given to this collector since its * last initialization, and S2n = variance() is the empirical * variance of these observations. Under the assumption that the observations * of X are i.i.d. and normally distributed, * * χ2n-1 has the chi-square distribution with n - 1 degrees of freedom. * Given the level * = 1 - α, * one has * P[χ2n-1 < x1] = P[χ2n-1 > x2] = α/2 * and * [I1, I2] = [(n - 1)S2n/x2,  (n - 1)S2n/x1]. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @param interval array of size 2 in which are returned the left * and right boundaries of the confidence interval, respectively * * */ public void confidenceIntervalVarianceChi2 (double level, double[] interval) { // Must return an array object, cannot return 2 doubles directly if (numObs < 2) throw new RuntimeException ( "Tally " + name + ": calling confidenceIntervalVarianceChi2 with < 2 observations"); double w = (numObs - 1)*variance(); double x2 = ChiSquareDist.inverseF (numObs - 1, 0.5 * (1.0 + level)); double x1 = ChiSquareDist.inverseF (numObs - 1, 0.5 * (1.0 - level)); interval[0] = w / x2; interval[1] = w / x1; } /** * . * * Similar to {@link #confidenceIntervalVarianceChi2 confidenceIntervalVarianceChi2}, * but returns the confidence interval in a formatted string of the form *
*
* ``95.0% confidence interval for variance (chi2): * ( 510.642, 519.673 )'',
* using d fractional decimal digits. * * @param level desired probability that the (random) confidence * interval covers the true variance * * @param d number of fractional decimal digits * * @return a confidence interval formatted as a string * */ public String formatCIVarianceChi2 (double level, int d) { PrintfFormat str = new PrintfFormat(); double ci[] = new double[2]; confidenceIntervalVarianceChi2 (level, ci); str.append (" " + (100*level) + "%"); str.append (" confidence interval for variance (chi2): ("); str.append (7 + d, d, d-1, ci[0]).append (','); str.append (7 + d, d, d-1, ci[1]).append (" )" + PrintfFormat.NEWLINE); return str.toString(); } /** * Returns a formatted string that contains a report on this probe. * * @return a statistical report formatted as a string * */ public String report() { return report(level, digits); } /** * Returns a formatted string that contains a report on this probe * with a confidence interval level level using d * fractional decimal digits. * * @param level desired probability that the confidence * interval covers the true mean * * @param d number of fractional decimal digits * * @return a statistical report formatted as a string * */ public String report (double level, int d) { PrintfFormat str = new PrintfFormat(); str.append ("REPORT on Tally stat. collector ==> " + name); str.append (PrintfFormat.NEWLINE + " num. obs. min max average standard dev." + PrintfFormat.NEWLINE); str.append (7 + d, (int)numObs); str.append (9 + d, d, d-1, (double)minValue); str.append (9 + d, d, d-1, (double)maxValue); str.append (9 + d, d, d-1, (double)average()); str.append (9 + d, d, d-1, standardDeviation()); str.append (PrintfFormat.NEWLINE); switch (confidenceInterval) { case CI_NORMAL: str.append (formatConfidenceIntervalNormal (level, d)); break; case CI_STUDENT: str.append (formatConfidenceIntervalStudent (level, d)); break; } return str.toString(); } public String shortReportHeader() { PrintfFormat pf = new PrintfFormat(); if (showNobs) pf.append (-8, "num obs.").append (" "); pf.append (-8, " min").append (" "); pf.append (-8, " max").append (" "); pf.append (-8, " average").append (" "); pf.append (-8, " std. dev."); if (confidenceInterval != CIType.CI_NONE) pf.append (" ").append (-12, "conf. int."); return pf.toString(); } /** * Formats and returns a short * statistical report for this tally. * The returned single-line report contains the minimum value, * the maximum value, * the average, and the standard deviation, in that order, separated * by three spaces. If the number of observations is shown in the short report, * a column containing the * number of observations in this tally is added. * * @return the string containing the report. * * */ public String shortReport() { PrintfFormat pf = new PrintfFormat(); if (showNobs) pf.append (-8, numberObs()); pf.append (9, 3, 2, min()).append (" "); pf.append (9, 3, 2, max()).append (" "); pf.append (10, 3, 2, average()).append (" "); if (numberObs() >= 2) pf.append (11, 3, 2, standardDeviation()); else pf.append (11, "---"); if (confidenceInterval != CIType.CI_NONE) { double[] ci = new double[2]; switch (confidenceInterval) { case CI_NORMAL: confidenceIntervalNormal (level, ci); break; case CI_STUDENT: confidenceIntervalStudent (level, ci); break; } pf.append (" ").append ((100*level) + "% ("); pf.append (9, 3, 2, ci[0] - ci[1]).append (','); pf.append (9, 3, 2, ci[0] + ci[1]).append (")"); } return pf.toString(); } @Deprecated public String reportAndConfidenceIntervalStudent (double level, int d) { CIType oldCIType = confidenceInterval; try { confidenceInterval = CIType.CI_STUDENT; return report(level, d); } finally { confidenceInterval = oldCIType; } } @Deprecated public String reportAndConfidenceIntervalStudent (double level) { return reportAndConfidenceIntervalStudent (level, 3); } /** * Returns a formatted string that contains a report on this probe (as in * {@link #report report}), followed by a confidence interval (as in * {@link #formatCIStudent formatCIStudent}), using d fractional decimal digits. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @param d number of fractional decimal digits * * @return a statistical report with a confidence interval, formatted as a string * */ public String reportAndCIStudent (double level, int d) { return reportAndConfidenceIntervalStudent (level, d); } /** * Same as {@link #reportAndCIStudent reportAndCIStudent} * (level, 3). * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * @return a statistical report with a confidence interval, formatted as a string * */ public String reportAndCIStudent (double level) { return reportAndConfidenceIntervalStudent (level); } /** * Returns the level of confidence for the intervals on the mean displayed in * reports. The default confidence level is 0.95. * * @return desired probability that the (random) confidence * interval covers the true mean (a constant) * */ public double getConfidenceLevel() { return level; } /** * Sets the level of confidence for the intervals on the mean displayed in * reports. * * @param level desired probability that the (random) confidence * interval covers the true mean (a constant) * * */ public void setConfidenceLevel (double level) { if (level < 0.0) throw new IllegalArgumentException("level < 0"); if (level >= 1.0) throw new IllegalArgumentException("level >= 1"); this.level = level; } /** * Indicates that no confidence interval needs to be printed in * reports formatted by {@link #report report}, and {@link #shortReport shortReport}. * This restores the default behavior of the reporting system. * */ public void setConfidenceIntervalNone() { confidenceInterval = CIType.CI_NONE; } /** * Indicates that a confidence interval on the true mean, based on the * central limit theorem, needs to be included in reports formatted by * {@link #report report} and {@link #shortReport shortReport}. The confidence interval is * formatted using {@link #formatCINormal formatCINormal}. * */ public void setConfidenceIntervalNormal() { confidenceInterval = CIType.CI_NORMAL; } /** * Indicates that a confidence interval on the true mean, based on the * normality assumption, needs to be included in * reports formatted by {@link #report report} and {@link #shortReport shortReport}. * The confidence interval is formatted using {@link #formatCIStudent formatCIStudent}. * */ public void setConfidenceIntervalStudent() { confidenceInterval = CIType.CI_STUDENT; } /** * Determines if the number of observations must be displayed in reports. * By default, the number of observations is displayed. * * @param showNumObs the value of the indicator. * * */ public void setShowNumberObs (boolean showNumObs) { showNobs = showNumObs; } /** * Clones this object. * */ public Tally clone() { try { return (Tally)super.clone(); } catch (CloneNotSupportedException e) { throw new IllegalStateException ("Tally can't clone"); } } }

Ads help maintain this website.