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 /* 19 * This is not the original file distributed by the Apache Software Foundation 20 * It has been modified by the Hipparchus project 21 */ 22 package org.hipparchus.stat.descriptive.moment; 23 24 import java.io.Serializable; 25 26 import org.hipparchus.exception.NullArgumentException; 27 28 /** 29 * Computes a statistic related to the Fourth Central Moment. Specifically, 30 * what is computed is the sum of 31 * <p> 32 * (x_i - xbar) ^ 4, 33 * <p> 34 * where the x_i are the 35 * sample observations and xbar is the sample mean. 36 * <p> 37 * The following recursive updating formula is used: 38 * <p> 39 * Let <ul> 40 * <li> dev = (current obs - previous mean) </li> 41 * <li> m2 = previous value of {@link SecondMoment} </li> 42 * <li> m2 = previous value of {@link ThirdMoment} </li> 43 * <li> n = number of observations (including current obs) </li> 44 * </ul> 45 * Then 46 * <p> 47 * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 + <br> 48 * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3 49 * <p> 50 * Returns <code>Double.NaN</code> if no data values have been added and 51 * returns <code>0</code> if there is just one value in the data set. Note that 52 * Double.NaN may also be returned if the input includes NaN and / or infinite 53 * values. 54 * <p> 55 * <strong>Note that this implementation is not synchronized.</strong> If 56 * multiple threads access an instance of this class concurrently, and at least 57 * one of the threads invokes the <code>increment()</code> or 58 * <code>clear()</code> method, it must be synchronized externally. 59 */ 60 class FourthMoment extends ThirdMoment implements Serializable{ 61 62 /** Serializable version identifier */ 63 private static final long serialVersionUID = 20150412L; 64 65 /** fourth moment of values that have been added */ 66 private double m4; 67 68 /** 69 * Create a FourthMoment instance. 70 */ 71 FourthMoment() { 72 super(); 73 m4 = Double.NaN; 74 } 75 76 /** 77 * Copy constructor, creates a new {@code FourthMoment} identical 78 * to the {@code original}. 79 * 80 * @param original the {@code FourthMoment} instance to copy 81 * @throws NullArgumentException if original is null 82 */ 83 FourthMoment(FourthMoment original) throws NullArgumentException { 84 super(original); 85 this.m4 = original.m4; 86 } 87 88 /** {@inheritDoc} */ 89 @Override 90 public void increment(final double d) { 91 if (n < 1) { 92 m4 = 0.0; 93 m3 = 0.0; 94 m2 = 0.0; 95 m1 = 0.0; 96 } 97 98 double prevM3 = m3; 99 double prevM2 = m2; 100 101 super.increment(d); 102 103 double n0 = n; 104 105 m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 + 106 ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0); 107 } 108 109 /** {@inheritDoc} */ 110 @Override 111 public double getResult() { 112 return m4; 113 } 114 115 /** {@inheritDoc} */ 116 @Override 117 public void clear() { 118 super.clear(); 119 m4 = Double.NaN; 120 } 121 122 /** 123 * Throws {@link UnsupportedOperationException}. 124 */ 125 @Override 126 public void aggregate(SecondMoment other) { 127 throw new UnsupportedOperationException(); 128 } 129 130 /** {@inheritDoc} */ 131 @Override 132 public FourthMoment copy() { 133 return new FourthMoment(this); 134 } 135 136 }