FourthMoment.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 Fourth Central Moment. Specifically,
  26.  * what is computed is the sum of
  27.  * <p>
  28.  * (x_i - xbar) ^ 4,
  29.  * <p>
  30.  * where the x_i are the
  31.  * sample observations and xbar is the sample mean.
  32.  * <p>
  33.  * The following recursive updating formula is used:
  34.  * <p>
  35.  * Let <ul>
  36.  * <li> dev = (current obs - previous mean) </li>
  37.  * <li> m2 = previous value of {@link SecondMoment} </li>
  38.  * <li> m2 = previous value of {@link ThirdMoment} </li>
  39.  * <li> n = number of observations (including current obs) </li>
  40.  * </ul>
  41.  * Then
  42.  * <p>
  43.  * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 + <br>
  44.  * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3
  45.  * <p>
  46.  * Returns <code>Double.NaN</code> if no data values have been added and
  47.  * returns <code>0</code> if there is just one value in the data set. Note that
  48.  * Double.NaN may also be returned if the input includes NaN and / or infinite
  49.  * values.
  50.  * <p>
  51.  * <strong>Note that this implementation is not synchronized.</strong> If
  52.  * multiple threads access an instance of this class concurrently, and at least
  53.  * one of the threads invokes the <code>increment()</code> or
  54.  * <code>clear()</code> method, it must be synchronized externally.
  55.  */
  56. class FourthMoment extends ThirdMoment implements Serializable{

  57.     /** Serializable version identifier */
  58.     private static final long serialVersionUID = 20150412L;

  59.     /** fourth moment of values that have been added */
  60.     private double m4;

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

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

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

  88.         double prevM3 = m3;
  89.         double prevM2 = m2;

  90.         super.increment(d);

  91.         double n0 = n;

  92.         m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 +
  93.             ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0);
  94.     }

  95.     /** {@inheritDoc} */
  96.     @Override
  97.     public double getResult() {
  98.         return m4;
  99.     }

  100.     /** {@inheritDoc} */
  101.     @Override
  102.     public void clear() {
  103.         super.clear();
  104.         m4 = Double.NaN;
  105.     }

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

  113.     /** {@inheritDoc} */
  114.     @Override
  115.     public FourthMoment copy() {
  116.         return new FourthMoment(this);
  117.     }

  118. }