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 /** 23 * Computes a statistic related to the Third Central Moment. Specifically, 24 * what is computed is the sum of cubed deviations from the sample mean. 25 * <p> 26 * The following recursive updating formula is used:</p> 27 * <p> 28 * Let <ul> 29 * <li> dev = (current obs - previous mean) </li> 30 * <li> m2 = previous value of {@link SecondMoment} </li> 31 * <li> n = number of observations (including current obs) </li> 32 * </ul> 33 * Then 34 * <p> 35 * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)</p> 36 * <p> 37 * Returns <code>Double.NaN</code> if no data values have been added and 38 * returns <code>0</code> if there is just one value in the data set. 39 * Note that Double.NaN may also be returned if the input includes NaN 40 * and / or infinite values.</p> 41 * <p> 42 * <strong>Note that this implementation is not synchronized.</strong> If 43 * multiple threads access an instance of this class concurrently, and at least 44 * one of the threads invokes the <code>increment()</code> or 45 * <code>clear()</code> method, it must be synchronized externally.</p> 46 * 47 */ 48 class ThirdMoment extends SecondMoment { 49 /** third moment of values that have been added. */ 50 protected double m3; 51 52 /** 53 * Square of deviation of most recently added value from previous first 54 * moment, normalized by previous sample size. Retained to prevent 55 * repeated computation in higher order moments. nDevSq = nDev * nDev. 56 */ 57 protected double nDevSq; 58 59 /** 60 * Create a FourthMoment instance. 61 */ 62 ThirdMoment() { 63 super(); 64 m3 = Double.NaN; 65 nDevSq = Double.NaN; 66 } 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 copy(original, this); 77 } 78 79 /** 80 * {@inheritDoc} 81 */ 82 @Override 83 public void increment(final double d) { 84 if (n < 1) { 85 m3 = m2 = m1 = 0.0; 86 } 87 88 double prevM2 = m2; 89 super.increment(d); 90 nDevSq = nDev * nDev; 91 double n0 = n; 92 m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev; 93 } 94 95 /** 96 * {@inheritDoc} 97 */ 98 @Override 99 public double getResult() { 100 return m3; 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public void clear() { 108 super.clear(); 109 m3 = Double.NaN; 110 nDevSq = Double.NaN; 111 } 112 113 /** 114 * {@inheritDoc} 115 */ 116 @Override 117 public ThirdMoment copy() { 118 ThirdMoment result = new ThirdMoment(); 119 // No try-catch or advertised exception because args are guaranteed non-null 120 copy(this, result); 121 return result; 122 } 123 124 /** 125 * Copies source to dest. 126 * <p>Neither source nor dest can be null.</p> 127 * 128 * @param source ThirdMoment to copy 129 * @param dest ThirdMoment to copy to 130 * @throws NullArgumentException if either source or dest is null 131 */ 132 public static void copy(ThirdMoment source, ThirdMoment dest) 133 throws NullArgumentException { 134 NullArgumentException.check(source); 135 NullArgumentException.check(dest); 136 SecondMoment.copy(source, dest); 137 dest.m3 = source.m3; 138 dest.nDevSq = source.nDevSq; 139 } 140 }