001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math.stat.descriptive.moment;
018
019 import java.io.Serializable;
020 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
021
022 /**
023 * Computes the first moment (arithmetic mean). Uses the definitional formula:
024 * <p>
025 * mean = sum(x_i) / n </p>
026 * <p>
027 * where <code>n</code> is the number of observations. </p>
028 * <p>
029 * To limit numeric errors, the value of the statistic is computed using the
030 * following recursive updating algorithm: </p>
031 * <p>
032 * <ol>
033 * <li>Initialize <code>m = </code> the first value</li>
034 * <li>For each additional value, update using <br>
035 * <code>m = m + (new value - m) / (number of observations)</code></li>
036 * </ol></p>
037 * <p>
038 * Returns <code>Double.NaN</code> if the dataset is empty.</p>
039 * <p>
040 * <strong>Note that this implementation is not synchronized.</strong> If
041 * multiple threads access an instance of this class concurrently, and at least
042 * one of the threads invokes the <code>increment()</code> or
043 * <code>clear()</code> method, it must be synchronized externally.</p>
044 *
045 * @version $Revision: 902934 $ $Date: 2010-01-25 14:09:17 -0500 (Mon, 25 Jan 2010) $
046 */
047 public class FirstMoment extends AbstractStorelessUnivariateStatistic
048 implements Serializable {
049
050 /** Serializable version identifier */
051 private static final long serialVersionUID = 6112755307178490473L;
052
053
054 /** Count of values that have been added */
055 protected long n;
056
057 /** First moment of values that have been added */
058 protected double m1;
059
060 /**
061 * Deviation of most recently added value from previous first moment.
062 * Retained to prevent repeated computation in higher order moments.
063 */
064 protected double dev;
065
066 /**
067 * Deviation of most recently added value from previous first moment,
068 * normalized by previous sample size. Retained to prevent repeated
069 * computation in higher order moments
070 */
071 protected double nDev;
072
073 /**
074 * Create a FirstMoment instance
075 */
076 public FirstMoment() {
077 n = 0;
078 m1 = Double.NaN;
079 dev = Double.NaN;
080 nDev = Double.NaN;
081 }
082
083 /**
084 * Copy constructor, creates a new {@code FirstMoment} identical
085 * to the {@code original}
086 *
087 * @param original the {@code FirstMoment} instance to copy
088 */
089 public FirstMoment(FirstMoment original) {
090 super();
091 copy(original, this);
092 }
093
094 /**
095 * {@inheritDoc}
096 */
097 @Override
098 public void increment(final double d) {
099 if (n == 0) {
100 m1 = 0.0;
101 }
102 n++;
103 double n0 = n;
104 dev = d - m1;
105 nDev = dev / n0;
106 m1 += nDev;
107 }
108
109 /**
110 * {@inheritDoc}
111 */
112 @Override
113 public void clear() {
114 m1 = Double.NaN;
115 n = 0;
116 dev = Double.NaN;
117 nDev = Double.NaN;
118 }
119
120 /**
121 * {@inheritDoc}
122 */
123 @Override
124 public double getResult() {
125 return m1;
126 }
127
128 /**
129 * {@inheritDoc}
130 */
131 public long getN() {
132 return n;
133 }
134
135 /**
136 * {@inheritDoc}
137 */
138 @Override
139 public FirstMoment copy() {
140 FirstMoment result = new FirstMoment();
141 copy(this, result);
142 return result;
143 }
144
145 /**
146 * Copies source to dest.
147 * <p>Neither source nor dest can be null.</p>
148 *
149 * @param source FirstMoment to copy
150 * @param dest FirstMoment to copy to
151 * @throws NullPointerException if either source or dest is null
152 */
153 public static void copy(FirstMoment source, FirstMoment dest) {
154 dest.n = source.n;
155 dest.m1 = source.m1;
156 dest.dev = source.dev;
157 dest.nDev = source.nDev;
158 }
159 }