View Javadoc

1   /*
2    * Copyright 2013 University of Glasgow.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package broadwick.statistics;
17  
18  import java.io.Serializable;
19  import java.text.DecimalFormat;
20  
21  /**
22   * This class collects data values and calculates their mean and variance.
23   */
24  public class Samples implements Serializable {
25  
26      /**
27       * Empty object where the internal values are initialised to 0. Getting any statistics from this object will result
28       * in a divide by zero exceptions since there are zero elements in the accumulator.
29       */
30      public Samples() {
31          sum = 0.0;
32          sumSqr = 0.0;
33          product = 0.0;
34          sumInv = 0.0;
35          total = 0;
36      }
37  
38      /**
39       * Initialise the internal values of the accumulator with the argument given.
40       * @param value the value to initialise the internal variables.
41       */
42      public Samples(final double value) {
43          sum = value;
44          sumSqr = value * value;
45          product = value;
46          sumInv = 1.0 / value;
47          total = 1;
48      }
49  
50      /**
51       * Add an observable (value) to the accumulator.
52       * @param value add the value to the accumulated values.
53       * @return the current accumulator object.
54       */
55      public final Samples add(final double value) {
56          sum += value;
57          sumSqr += (value * value);
58          product = (product == 0) ? value : product * value;
59          sumInv += (1.0 / value);
60          total++;
61          return this;
62      }
63  
64      /**
65       * Add the contents of anther accumulator to this accumulator.
66       * @param value add the value to the accumulated values.
67       * @return the current accumulator object.
68       */
69      public final Samples add(final Samples value) {
70          sum += value.sum;
71          sumSqr += value.sumSqr;
72          product += value.product;
73          sumInv += value.sumInv;
74          total += value.getSize();
75          return this;
76      }
77  
78      /**
79       * Obtain the mean of the set of observables in the accumulator.
80       * @return double the mean in the observed values.
81       */
82      public final double getMean() {
83          final int tot = (total == 0) ? 1 : total;
84          return sum / tot;
85      }
86  
87      /**
88       * Obtain the root mean square of the set of observables in the accumulator.
89       * @return double the root mean square in the observed values.
90       */
91      public final double getRootMeanSquare() {
92          final int tot = (total == 0) ? 1 : total;
93          return Math.sqrt(sumSqr / tot);
94      }
95  
96      /**
97       * Obtain the geometric mean of the set of observables in the accumulator.
98       * @return double the geometric mean in the observed values.
99       */
100     public final double getGeometricMean() {
101         final int tot = (total == 0) ? 1 : total;
102         return Math.pow(product, 1.0 / tot);
103     }
104 
105     /**
106      * Obtain the harmonic mean of the set of observables in the accumulator.
107      * @return double the harmonic mean in the observed values.
108      */
109     public final double getHarmonicMean() {
110         final double inv = (sumInv == 0) ? 1 : sumInv;
111         return total / inv;
112     }
113 
114     /**
115      * Get the sum of the values held in the accumulator.
116      * @return the sum of all the values added to the accumulator.
117      */
118     public final double getSum() {
119         return sum;
120     }
121 
122     /**
123      * Get the number of items added to the Accumulator.
124      * @return the number of items added to the Accumulator.
125      */
126     public final int getSize() {
127         return total;
128     }
129 
130     /**
131      * Default sample variance implementation based on the second moment \f$ M_n^{(2)} \f$ moment<2>, mean and count.
132      * \f[ \sigma_n^2 = M_n^{(2)} - \mu_n^2. \f] where \f[ \mu_n = \frac{1}{n} \sum_{i = 1}^n x_i. \f] is the estimate
133      * of the sample mean and \f$n\f$ is the number of samples.
134      * @return double the variance of the observed values.
135      */
136     public final double getVariance() {
137         final int tot = (total == 0) ? 1 : total;
138         final double mn = sum / tot;
139 
140         return (sumSqr / tot - (mn * mn)) / tot;
141     }
142 
143     /**
144      * Obtain the standard deviation (error in the mean) of the set of observeables in the accumulator.
145      * @return double the standard deviation in the observed values.
146      */
147     public final double getStdDev() {
148         return Math.sqrt(this.getVariance());
149     }
150 
151     /**
152      * Clear the contents of the accumulator. Sets all the internal counts back to zero.
153      */
154     public final void clear() {
155         sum = 0.0;
156         sumSqr = 0.0;
157         product = 0.0;
158         sumInv = 0.0;
159         total = 0;
160     }
161 
162     /**
163      * Get a tab delimited string of the mean and standard deviation of the values in the accumulator.
164      * @return a string in the form "\tmean\tdev"
165      */
166     public final String getSummary() {
167         final StringBuilder sb = new StringBuilder(10);
168         sb.append("\t").append(new DecimalFormat("0.0000E0").format(getMean()));
169         sb.append("\t").append(new DecimalFormat("0.0000E0").format(getStdDev()));
170         return sb.toString();
171     }
172 
173     private double sum = 0.0; // The sum of all values added to the accumulator.
174     private double sumSqr = 0.0; // The sum of all values squared added to the accumulator.
175     private double product = 0.0; // The product of all values added to the accumulator.
176     private double sumInv = 0.0; // The sum of the 1/value.
177     private int total = 0; // The total number of values added to the accumulator.
178 }