1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.math.stat.descriptive.moment; 18 19 import java.io.Serializable; 20 21 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; 22 import org.apache.commons.math.stat.descriptive.summary.Sum; 23 24 /** 25 * <p>Computes the arithmetic mean of a set of values. Uses the definitional 26 * formula:</p> 27 * <p> 28 * mean = sum(x_i) / n 29 * </p> 30 * <p>where <code>n</code> is the number of observations. 31 * </p> 32 * <p>When {@link #increment(double)} is used to add data incrementally from a 33 * stream of (unstored) values, the value of the statistic that 34 * {@link #getResult()} returns is computed using the following recursive 35 * updating algorithm: </p> 36 * <ol> 37 * <li>Initialize <code>m = </code> the first value</li> 38 * <li>For each additional value, update using <br> 39 * <code>m = m + (new value - m) / (number of observations)</code></li> 40 * </ol> 41 * <p> If {@link #evaluate(double[])} is used to compute the mean of an array 42 * of stored values, a two-pass, corrected algorithm is used, starting with 43 * the definitional formula computed using the array of stored values and then 44 * correcting this by adding the mean deviation of the data values from the 45 * arithmetic mean. See, e.g. "Comparison of Several Algorithms for Computing 46 * Sample Means and Variances," Robert F. Ling, Journal of the American 47 * Statistical Association, Vol. 69, No. 348 (Dec., 1974), pp. 859-866. </p> 48 * <p> 49 * Returns <code>Double.NaN</code> if the dataset is empty. 50 * </p> 51 * <strong>Note that this implementation is not synchronized.</strong> If 52 * multiple threads access an instance of this class concurrently, and at least 53 * one of the threads invokes the <code>increment()</code> or 54 * <code>clear()</code> method, it must be synchronized externally. 55 * 56 * @version $Revision: 617953 $ $Date: 2008-02-02 22:54:00 -0700 (Sat, 02 Feb 2008) $ 57 */ 58 public class Mean extends AbstractStorelessUnivariateStatistic 59 implements Serializable { 60 61 /** Serializable version identifier */ 62 private static final long serialVersionUID = -1296043746617791564L; 63 64 /** First moment on which this statistic is based. */ 65 protected FirstMoment moment; 66 67 /** 68 * Determines whether or not this statistic can be incremented or cleared. 69 * <p> 70 * Statistics based on (constructed from) external moments cannot 71 * be incremented or cleared.</p> 72 */ 73 protected boolean incMoment; 74 75 /** Constructs a Mean. */ 76 public Mean() { 77 incMoment = true; 78 moment = new FirstMoment(); 79 } 80 81 /** 82 * Constructs a Mean with an External Moment. 83 * 84 * @param m1 the moment 85 */ 86 public Mean(final FirstMoment m1) { 87 this.moment = m1; 88 incMoment = false; 89 } 90 91 /** 92 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double) 93 */ 94 public void increment(final double d) { 95 if (incMoment) { 96 moment.increment(d); 97 } 98 } 99 100 /** 101 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear() 102 */ 103 public void clear() { 104 if (incMoment) { 105 moment.clear(); 106 } 107 } 108 109 /** 110 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getResult() 111 */ 112 public double getResult() { 113 return moment.m1; 114 } 115 116 /** 117 * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN() 118 */ 119 public long getN() { 120 return moment.getN(); 121 } 122 123 /** 124 * Returns the arithmetic mean of the entries in the specified portion of 125 * the input array, or <code>Double.NaN</code> if the designated subarray 126 * is empty. 127 * <p> 128 * Throws <code>IllegalArgumentException</code> if the array is null.</p> 129 * <p> 130 * See {@link Mean} for details on the computing algorithm.</p> 131 * 132 * @param values the input array 133 * @param begin index of the first array element to include 134 * @param length the number of elements to include 135 * @return the mean of the values or Double.NaN if length = 0 136 * @throws IllegalArgumentException if the array is null or the array index 137 * parameters are not valid 138 */ 139 public double evaluate(final double[] values,final int begin, final int length) { 140 if (test(values, begin, length)) { 141 Sum sum = new Sum(); 142 double sampleSize = (double) length; 143 144 // Compute initial estimate using definitional formula 145 double xbar = sum.evaluate(values, begin, length) / sampleSize; 146 147 // Compute correction factor in second pass 148 double correction = 0; 149 for (int i = begin; i < begin + length; i++) { 150 correction += (values[i] - xbar); 151 } 152 return xbar + (correction/sampleSize); 153 } 154 return Double.NaN; 155 } 156 }