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.math.stat.descriptive.moment;
18
19 import java.io.Serializable;
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</p>
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.</p>
39 * <p>
40 * <strong>Note that this implementation is not synchronized.</strong> If
41 * multiple threads access an instance of this class concurrently, and at least
42 * one of the threads invokes the <code>increment()</code> or
43 * <code>clear()</code> method, it must be synchronized externally.</p>
44 *
45 * @version $Revision: 762116 $ $Date: 2009-04-05 12:48:53 -0400 (Sun, 05 Apr 2009) $
46 */
47 public class ThirdMoment extends SecondMoment implements Serializable {
48
49 /** Serializable version identifier */
50 private static final long serialVersionUID = -7818711964045118679L;
51
52 /** third moment of values that have been added */
53 protected double m3;
54
55 /**
56 * Square of deviation of most recently added value from previous first
57 * moment, normalized by previous sample size. Retained to prevent
58 * repeated computation in higher order moments. nDevSq = nDev * nDev.
59 */
60 protected double nDevSq;
61
62 /**
63 * Create a FourthMoment instance
64 */
65 public ThirdMoment() {
66 super();
67 m3 = Double.NaN;
68 nDevSq = Double.NaN;
69 }
70
71 /**
72 * Copy constructor, creates a new {@code ThirdMoment} identical
73 * to the {@code original}
74 *
75 * @param original the {@code ThirdMoment} instance to copy
76 */
77 public ThirdMoment(ThirdMoment original) {
78 copy(original, this);
79 }
80
81 /**
82 * {@inheritDoc}
83 */
84 @Override
85 public void increment(final double d) {
86 if (n < 1) {
87 m3 = m2 = m1 = 0.0;
88 }
89
90 double prevM2 = m2;
91 super.increment(d);
92 nDevSq = nDev * nDev;
93 double n0 = n;
94 m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev;
95 }
96
97 /**
98 * {@inheritDoc}
99 */
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 }