ThirdMoment.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. /**
  20.  * Computes a statistic related to the Third Central Moment.  Specifically,
  21.  * what is computed is the sum of cubed deviations from the sample mean.
  22.  * <p>
  23.  * The following recursive updating formula is used:</p>
  24.  * <p>
  25.  * Let <ul>
  26.  * <li> dev = (current obs - previous mean) </li>
  27.  * <li> m2 = previous value of {@link SecondMoment} </li>
  28.  * <li> n = number of observations (including current obs) </li>
  29.  * </ul>
  30.  * Then
  31.  * <p>
  32.  * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)</p>
  33.  * <p>
  34.  * Returns <code>Double.NaN</code> if no data values have been added and
  35.  * returns <code>0</code> if there is just one value in the data set.
  36.  * Note that Double.NaN may also be returned if the input includes NaN
  37.  * and / or infinite 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.  */
  45. class ThirdMoment extends SecondMoment {
  46.     /** third moment of values that have been added. */
  47.     protected double m3;

  48.     /**
  49.      * Square of deviation of most recently added value from previous first
  50.      * moment, normalized by previous sample size.  Retained to prevent
  51.      * repeated computation in higher order moments.  nDevSq = nDev * nDev.
  52.      */
  53.     protected double nDevSq;

  54.     /**
  55.      * Create a FourthMoment instance.
  56.      */
  57.     ThirdMoment() {
  58.         super();
  59.         m3 = Double.NaN;
  60.         nDevSq = Double.NaN;
  61.     }

  62.     /**
  63.      * Copy constructor, creates a new {@code ThirdMoment} identical
  64.      * to the {@code original}.
  65.      *
  66.      * @param original the {@code ThirdMoment} instance to copy
  67.      * @throws NullArgumentException if original is null
  68.      */
  69.     ThirdMoment(ThirdMoment original) throws NullArgumentException {
  70.         copy(original, this);
  71.     }

  72.     /**
  73.      * {@inheritDoc}
  74.      */
  75.     @Override
  76.     public void increment(final double d) {
  77.         if (n < 1) {
  78.             m3 = m2 = m1 = 0.0;
  79.         }

  80.         double prevM2 = m2;
  81.         super.increment(d);
  82.         nDevSq = nDev * nDev;
  83.         double n0 = n;
  84.         m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev;
  85.     }

  86.     /**
  87.      * {@inheritDoc}
  88.      */
  89.     @Override
  90.     public double getResult() {
  91.         return m3;
  92.     }

  93.     /**
  94.      * {@inheritDoc}
  95.      */
  96.     @Override
  97.     public void clear() {
  98.         super.clear();
  99.         m3 = Double.NaN;
  100.         nDevSq = Double.NaN;
  101.     }

  102.     /**
  103.      * {@inheritDoc}
  104.      */
  105.     @Override
  106.     public ThirdMoment copy() {
  107.         ThirdMoment result = new ThirdMoment();
  108.         // No try-catch or advertised exception because args are guaranteed non-null
  109.         copy(this, result);
  110.         return result;
  111.     }

  112.     /**
  113.      * Copies source to dest.
  114.      * <p>Neither source nor dest can be null.</p>
  115.      *
  116.      * @param source ThirdMoment to copy
  117.      * @param dest ThirdMoment to copy to
  118.      * @throws NullArgumentException if either source or dest is null
  119.      */
  120.     public static void copy(ThirdMoment source, ThirdMoment dest)
  121.         throws NullArgumentException {
  122.         NullArgumentException.check(source);
  123.         NullArgumentException.check(dest);
  124.         SecondMoment.copy(source, dest);
  125.         dest.m3 = source.m3;
  126.         dest.nDevSq = source.nDevSq;
  127.     }
  128. }