View Javadoc
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.math4.legacy.stat.descriptive.moment;
18  
19  import org.apache.commons.math4.legacy.exception.NullArgumentException;
20  import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic;
21  
22  /**
23   * Computes the first moment (arithmetic mean).  Uses the definitional formula:
24   * <p>
25   * mean = sum(x_i) / n </p>
26   * <p>
27   * where <code>n</code> is the number of observations. </p>
28   * <p>
29   * To limit numeric errors, the value of the statistic is computed using the
30   * following recursive updating algorithm: </p>
31   * <ol>
32   * <li>Initialize <code>m = </code> the first value</li>
33   * <li>For each additional value, update using <br>
34   *   <code>m = m + (new value - m) / (number of observations)</code></li>
35   * </ol>
36   * <p>
37   *  Returns <code>Double.NaN</code> if the dataset is empty. Note that
38   *  Double.NaN may also be returned if the input includes NaN and / or infinite
39   *  values.</p>
40   * <p>
41   * <strong>Note that this implementation is not synchronized.</strong> If
42   * multiple threads access an instance of this class concurrently, and at least
43   * one of the threads invokes the <code>increment()</code> or
44   * <code>clear()</code> method, it must be synchronized externally.</p>
45   */
46  class FirstMoment extends AbstractStorelessUnivariateStatistic {
47      /** Count of values that have been added. */
48      protected long n;
49  
50      /** First moment of values that have been added. */
51      protected double m1;
52  
53      /**
54       * Deviation of most recently added value from previous first moment.
55       * Retained to prevent repeated computation in higher order moments.
56       */
57      protected double dev;
58  
59      /**
60       * Deviation of most recently added value from previous first moment,
61       * normalized by previous sample size.  Retained to prevent repeated
62       * computation in higher order moments
63       */
64      protected double nDev;
65  
66      /**
67       * Create a FirstMoment instance.
68       */
69      FirstMoment() {
70          n = 0;
71          m1 = Double.NaN;
72          dev = Double.NaN;
73          nDev = Double.NaN;
74      }
75  
76      /**
77       * Copy constructor, creates a new {@code FirstMoment} identical.
78       * to the {@code original}
79       *
80       * @param original the {@code FirstMoment} instance to copy
81       * @throws NullArgumentException if original is null
82       */
83       FirstMoment(FirstMoment original) throws NullArgumentException {
84           super();
85           copy(original, this);
86       }
87  
88      /**
89       * {@inheritDoc}
90       */
91       @Override
92      public void increment(final double d) {
93          if (n == 0) {
94              m1 = 0.0;
95          }
96          n++;
97          double n0 = n;
98          dev = d - m1;
99          nDev = dev / n0;
100         m1 += nDev;
101     }
102 
103     /**
104      * {@inheritDoc}
105      */
106     @Override
107     public void clear() {
108         m1 = Double.NaN;
109         n = 0;
110         dev = Double.NaN;
111         nDev = Double.NaN;
112     }
113 
114     /**
115      * {@inheritDoc}
116      */
117     @Override
118     public double getResult() {
119         return m1;
120     }
121 
122     /**
123      * {@inheritDoc}
124      */
125     @Override
126     public long getN() {
127         return n;
128     }
129 
130     /**
131      * {@inheritDoc}
132      */
133     @Override
134     public FirstMoment copy() {
135         FirstMoment result = new FirstMoment();
136         // No try-catch or advertised exception because args are guaranteed non-null
137         copy(this, result);
138         return result;
139     }
140 
141     /**
142      * Copies source to dest.
143      * <p>Neither source nor dest can be null.</p>
144      *
145      * @param source FirstMoment to copy
146      * @param dest FirstMoment to copy to
147      * @throws NullArgumentException if either source or dest is null
148      */
149     public static void copy(FirstMoment source, FirstMoment dest)
150         throws NullArgumentException {
151         NullArgumentException.check(source);
152         NullArgumentException.check(dest);
153         dest.n = source.n;
154         dest.m1 = source.m1;
155         dest.dev = source.dev;
156         dest.nDev = source.nDev;
157     }
158 }