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.  *      https://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. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.stat.descriptive.moment;

  22. import java.io.Serializable;

  23. import org.hipparchus.exception.NullArgumentException;


  24. /**
  25.  * Computes a statistic related to the Third Central Moment.  Specifically,
  26.  * what is computed is the sum of cubed deviations from the sample mean.
  27.  * <p>
  28.  * The following recursive updating formula is used:
  29.  * <p>
  30.  * Let <ul>
  31.  * <li> dev = (current obs - previous mean) </li>
  32.  * <li> m2 = previous value of {@link SecondMoment} </li>
  33.  * <li> n = number of observations (including current obs) </li>
  34.  * </ul>
  35.  * Then
  36.  * <p>
  37.  * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)
  38.  * <p>
  39.  * Returns <code>Double.NaN</code> if no data values have been added and
  40.  * returns <code>0</code> if there is just one value in the data set.
  41.  * Note that Double.NaN may also be returned if the input includes NaN
  42.  * and / or infinite values.
  43.  * <p>
  44.  * <strong>Note that this implementation is not synchronized.</strong> If
  45.  * multiple threads access an instance of this class concurrently, and at least
  46.  * one of the threads invokes the <code>increment()</code> or
  47.  * <code>clear()</code> method, it must be synchronized externally.
  48.  */
  49. class ThirdMoment extends SecondMoment implements Serializable {

  50.     /** Serializable version identifier */
  51.     private static final long serialVersionUID = 20150412L;

  52.     /** third moment of values that have been added */
  53.     protected double m3;

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

  60.     /**
  61.      * Create a FourthMoment instance.
  62.      */
  63.     ThirdMoment() {
  64.         super();
  65.         m3 = Double.NaN;
  66.         nDevSq = Double.NaN;
  67.     }

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

  80.     /** {@inheritDoc} */
  81.     @Override
  82.     public void increment(final double d) {
  83.         if (n < 1) {
  84.             m3 = m2 = m1 = 0.0;
  85.         }

  86.         double prevM2 = m2;
  87.         super.increment(d);
  88.         nDevSq = nDev * nDev;
  89.         double n0 = n;
  90.         m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev;
  91.     }

  92.     /** {@inheritDoc} */
  93.     @Override
  94.     public double getResult() {
  95.         return m3;
  96.     }

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

  104.     /**
  105.      * Throws {@link UnsupportedOperationException}.
  106.      */
  107.     @Override
  108.     public void aggregate(SecondMoment other) {
  109.         throw new UnsupportedOperationException();
  110.     }

  111.     /** {@inheritDoc} */
  112.     @Override
  113.     public ThirdMoment copy() {
  114.         return new ThirdMoment(this);
  115.     }

  116. }