FirstMoment.java

  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. import org.apache.commons.math4.legacy.exception.NullArgumentException;
  19. import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic;

  20. /**
  21.  * Computes the first moment (arithmetic mean).  Uses the definitional formula:
  22.  * <p>
  23.  * mean = sum(x_i) / n </p>
  24.  * <p>
  25.  * where <code>n</code> is the number of observations. </p>
  26.  * <p>
  27.  * To limit numeric errors, the value of the statistic is computed using the
  28.  * following recursive updating algorithm: </p>
  29.  * <ol>
  30.  * <li>Initialize <code>m = </code> the first value</li>
  31.  * <li>For each additional value, update using <br>
  32.  *   <code>m = m + (new value - m) / (number of observations)</code></li>
  33.  * </ol>
  34.  * <p>
  35.  *  Returns <code>Double.NaN</code> if the dataset is empty. Note that
  36.  *  Double.NaN may also be returned if the input includes NaN and / or infinite
  37.  *  values.</p>
  38.  * <p>
  39.  * <strong>Note that this implementation is not synchronized.</strong> If
  40.  * multiple threads access an instance of this class concurrently, and at least
  41.  * one of the threads invokes the <code>increment()</code> or
  42.  * <code>clear()</code> method, it must be synchronized externally.</p>
  43.  */
  44. class FirstMoment extends AbstractStorelessUnivariateStatistic {
  45.     /** Count of values that have been added. */
  46.     protected long n;

  47.     /** First moment of values that have been added. */
  48.     protected double m1;

  49.     /**
  50.      * Deviation of most recently added value from previous first moment.
  51.      * Retained to prevent repeated computation in higher order moments.
  52.      */
  53.     protected double dev;

  54.     /**
  55.      * Deviation of most recently added value from previous first moment,
  56.      * normalized by previous sample size.  Retained to prevent repeated
  57.      * computation in higher order moments
  58.      */
  59.     protected double nDev;

  60.     /**
  61.      * Create a FirstMoment instance.
  62.      */
  63.     FirstMoment() {
  64.         n = 0;
  65.         m1 = Double.NaN;
  66.         dev = Double.NaN;
  67.         nDev = Double.NaN;
  68.     }

  69.     /**
  70.      * Copy constructor, creates a new {@code FirstMoment} identical.
  71.      * to the {@code original}
  72.      *
  73.      * @param original the {@code FirstMoment} instance to copy
  74.      * @throws NullArgumentException if original is null
  75.      */
  76.      FirstMoment(FirstMoment original) throws NullArgumentException {
  77.          super();
  78.          copy(original, this);
  79.      }

  80.     /**
  81.      * {@inheritDoc}
  82.      */
  83.      @Override
  84.     public void increment(final double d) {
  85.         if (n == 0) {
  86.             m1 = 0.0;
  87.         }
  88.         n++;
  89.         double n0 = n;
  90.         dev = d - m1;
  91.         nDev = dev / n0;
  92.         m1 += nDev;
  93.     }

  94.     /**
  95.      * {@inheritDoc}
  96.      */
  97.     @Override
  98.     public void clear() {
  99.         m1 = Double.NaN;
  100.         n = 0;
  101.         dev = Double.NaN;
  102.         nDev = Double.NaN;
  103.     }

  104.     /**
  105.      * {@inheritDoc}
  106.      */
  107.     @Override
  108.     public double getResult() {
  109.         return m1;
  110.     }

  111.     /**
  112.      * {@inheritDoc}
  113.      */
  114.     @Override
  115.     public long getN() {
  116.         return n;
  117.     }

  118.     /**
  119.      * {@inheritDoc}
  120.      */
  121.     @Override
  122.     public FirstMoment copy() {
  123.         FirstMoment result = new FirstMoment();
  124.         // No try-catch or advertised exception because args are guaranteed non-null
  125.         copy(this, result);
  126.         return result;
  127.     }

  128.     /**
  129.      * Copies source to dest.
  130.      * <p>Neither source nor dest can be null.</p>
  131.      *
  132.      * @param source FirstMoment to copy
  133.      * @param dest FirstMoment to copy to
  134.      * @throws NullArgumentException if either source or dest is null
  135.      */
  136.     public static void copy(FirstMoment source, FirstMoment dest)
  137.         throws NullArgumentException {
  138.         NullArgumentException.check(source);
  139.         NullArgumentException.check(dest);
  140.         dest.n = source.n;
  141.         dest.m1 = source.m1;
  142.         dest.dev = source.dev;
  143.         dest.nDev = source.nDev;
  144.     }
  145. }