001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math.stat.descriptive.moment; 018 019 import java.io.Serializable; 020 021 022 /** 023 * Computes a statistic related to the Third Central Moment. Specifically, 024 * what is computed is the sum of cubed deviations from the sample mean. 025 * <p> 026 * The following recursive updating formula is used:</p> 027 * <p> 028 * Let <ul> 029 * <li> dev = (current obs - previous mean) </li> 030 * <li> m2 = previous value of {@link SecondMoment} </li> 031 * <li> n = number of observations (including current obs) </li> 032 * </ul> 033 * Then</p> 034 * <p> 035 * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)</p> 036 * <p> 037 * Returns <code>Double.NaN</code> if no data values have been added and 038 * returns <code>0</code> if there is just one value in the data set.</p> 039 * <p> 040 * <strong>Note that this implementation is not synchronized.</strong> If 041 * multiple threads access an instance of this class concurrently, and at least 042 * one of the threads invokes the <code>increment()</code> or 043 * <code>clear()</code> method, it must be synchronized externally.</p> 044 * 045 * @version $Revision: 811685 $ $Date: 2009-09-05 19:36:48 +0200 (sam. 05 sept. 2009) $ 046 */ 047 public class ThirdMoment extends SecondMoment implements Serializable { 048 049 /** Serializable version identifier */ 050 private static final long serialVersionUID = -7818711964045118679L; 051 052 /** third moment of values that have been added */ 053 protected double m3; 054 055 /** 056 * Square of deviation of most recently added value from previous first 057 * moment, normalized by previous sample size. Retained to prevent 058 * repeated computation in higher order moments. nDevSq = nDev * nDev. 059 */ 060 protected double nDevSq; 061 062 /** 063 * Create a FourthMoment instance 064 */ 065 public ThirdMoment() { 066 super(); 067 m3 = Double.NaN; 068 nDevSq = Double.NaN; 069 } 070 071 /** 072 * Copy constructor, creates a new {@code ThirdMoment} identical 073 * to the {@code original} 074 * 075 * @param original the {@code ThirdMoment} instance to copy 076 */ 077 public ThirdMoment(ThirdMoment original) { 078 copy(original, this); 079 } 080 081 /** 082 * {@inheritDoc} 083 */ 084 @Override 085 public void increment(final double d) { 086 if (n < 1) { 087 m3 = m2 = m1 = 0.0; 088 } 089 090 double prevM2 = m2; 091 super.increment(d); 092 nDevSq = nDev * nDev; 093 double n0 = n; 094 m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev; 095 } 096 097 /** 098 * {@inheritDoc} 099 */ 100 @Override 101 public double getResult() { 102 return m3; 103 } 104 105 /** 106 * {@inheritDoc} 107 */ 108 @Override 109 public void clear() { 110 super.clear(); 111 m3 = Double.NaN; 112 nDevSq = Double.NaN; 113 } 114 115 /** 116 * {@inheritDoc} 117 */ 118 @Override 119 public ThirdMoment copy() { 120 ThirdMoment result = new ThirdMoment(); 121 copy(this, result); 122 return result; 123 } 124 125 /** 126 * Copies source to dest. 127 * <p>Neither source nor dest can be null.</p> 128 * 129 * @param source ThirdMoment to copy 130 * @param dest ThirdMoment to copy to 131 * @throws NullPointerException if either source or dest is null 132 */ 133 public static void copy(ThirdMoment source, ThirdMoment dest) { 134 SecondMoment.copy(source, dest); 135 dest.m3 = source.m3; 136 dest.nDevSq = source.nDevSq; 137 } 138 139 }