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 19 import org.apache.commons.math4.legacy.exception.NullArgumentException; 20 21 /** 22 * Computes a statistic related to the Fourth Central Moment. Specifically, 23 * what is computed is the sum of 24 * <p> 25 * (x_i - xbar) ^ 4, </p> 26 * <p> 27 * where the x_i are the 28 * sample observations and xbar is the sample mean. </p> 29 * <p> 30 * The following recursive updating formula is used: </p> 31 * <p> 32 * Let <ul> 33 * <li> dev = (current obs - previous mean) </li> 34 * <li> m2 = previous value of {@link SecondMoment} </li> 35 * <li> m2 = previous value of {@link ThirdMoment} </li> 36 * <li> n = number of observations (including current obs) </li> 37 * </ul> 38 * Then 39 * <p> 40 * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 + <br> 41 * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3 </p> 42 * <p> 43 * Returns <code>Double.NaN</code> if no data values have been added and 44 * returns <code>0</code> if there is just one value in the data set. Note that 45 * Double.NaN may also be returned if the input includes NaN and / or infinite 46 * values. </p> 47 * <p> 48 * <strong>Note that this implementation is not synchronized.</strong> If 49 * multiple threads access an instance of this class concurrently, and at least 50 * one of the threads invokes the <code>increment()</code> or 51 * <code>clear()</code> method, it must be synchronized externally. </p> 52 */ 53 class FourthMoment extends ThirdMoment { 54 /** fourth moment of values that have been added. */ 55 private double m4; 56 57 /** 58 * Create a FourthMoment instance. 59 */ 60 FourthMoment() { 61 super(); 62 m4 = Double.NaN; 63 } 64 65 /** 66 * Copy constructor, creates a new {@code FourthMoment} identical 67 * to the {@code original}. 68 * 69 * @param original the {@code FourthMoment} instance to copy 70 * @throws NullArgumentException if original is null 71 */ 72 FourthMoment(FourthMoment original) throws NullArgumentException { 73 super(); 74 copy(original, this); 75 } 76 77 /** 78 * {@inheritDoc} 79 */ 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 89 double prevM3 = m3; 90 double prevM2 = m2; 91 92 super.increment(d); 93 94 double n0 = n; 95 96 m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 + 97 ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0); 98 } 99 100 /** 101 * {@inheritDoc} 102 */ 103 @Override 104 public double getResult() { 105 return m4; 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 @Override 112 public void clear() { 113 super.clear(); 114 m4 = Double.NaN; 115 } 116 117 /** 118 * {@inheritDoc} 119 */ 120 @Override 121 public FourthMoment copy() { 122 FourthMoment result = new FourthMoment(); 123 // No try-catch or advertised exception because args are guaranteed non-null 124 copy(this, result); 125 return result; 126 } 127 128 /** 129 * Copies source to dest. 130 * <p>Neither source nor dest can be null.</p> 131 * 132 * @param source FourthMoment to copy 133 * @param dest FourthMoment to copy to 134 * @throws NullArgumentException if either source or dest is null 135 */ 136 public static void copy(FourthMoment source, FourthMoment dest) 137 throws NullArgumentException { 138 NullArgumentException.check(source); 139 NullArgumentException.check(dest); 140 ThirdMoment.copy(source, dest); 141 dest.m4 = source.m4; 142 } 143 }