Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
Skewness |
|
| 2.142857142857143;2.143 |
1 | /* |
|
2 | * Copyright 2003-2004 The Apache Software Foundation. |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | package org.apache.commons.math.stat.descriptive.moment; |
|
17 | ||
18 | import java.io.Serializable; |
|
19 | ||
20 | import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic; |
|
21 | ||
22 | /** |
|
23 | * Computes the skewness of the available values. |
|
24 | * <p> |
|
25 | * We use the following (unbiased) formula to define skewness: |
|
26 | * <p> |
|
27 | * skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3 |
|
28 | * <p> |
|
29 | * where n is the number of values, mean is the {@link Mean} and std is the |
|
30 | * {@link StandardDeviation} |
|
31 | * <p> |
|
32 | * <strong>Note that this implementation is not synchronized.</strong> If |
|
33 | * multiple threads access an instance of this class concurrently, and at least |
|
34 | * one of the threads invokes the <code>increment()</code> or |
|
35 | * <code>clear()</code> method, it must be synchronized externally. |
|
36 | * |
|
37 | * @version $Revision$ $Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) $ |
|
38 | */ |
|
39 | public class Skewness extends AbstractStorelessUnivariateStatistic implements Serializable { |
|
40 | ||
41 | /** Serializable version identifier */ |
|
42 | static final long serialVersionUID = 7101857578996691352L; |
|
43 | ||
44 | /** Third moment on which this statistic is based */ |
|
45 | 34 | protected ThirdMoment moment = null; |
46 | ||
47 | /** |
|
48 | * Determines whether or not this statistic can be incremented or cleared. |
|
49 | * <p> |
|
50 | * Statistics based on (constructed from) external moments cannot |
|
51 | * be incremented or cleared. |
|
52 | */ |
|
53 | protected boolean incMoment; |
|
54 | ||
55 | /** |
|
56 | * Constructs a Skewness |
|
57 | */ |
|
58 | 32 | public Skewness() { |
59 | 32 | incMoment = true; |
60 | 32 | moment = new ThirdMoment(); |
61 | 32 | } |
62 | ||
63 | /** |
|
64 | * Constructs a Skewness with an external moment |
|
65 | * @param m3 external moment |
|
66 | */ |
|
67 | 2 | public Skewness(final ThirdMoment m3) { |
68 | 2 | incMoment = false; |
69 | 2 | this.moment = m3; |
70 | 2 | } |
71 | ||
72 | /** |
|
73 | * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double) |
|
74 | */ |
|
75 | public void increment(final double d) { |
|
76 | 166 | if (incMoment) { |
77 | 166 | moment.increment(d); |
78 | } |
|
79 | 166 | } |
80 | ||
81 | /** |
|
82 | * Returns the value of the statistic based on the values that have been added. |
|
83 | * <p> |
|
84 | * See {@link Skewness} for the definition used in the computation. |
|
85 | * |
|
86 | * @return the skewness of the available values. |
|
87 | */ |
|
88 | public double getResult() { |
|
89 | ||
90 | 96 | if (moment.n < 3) { |
91 | 74 | return Double.NaN; |
92 | } |
|
93 | 22 | double variance = moment.m2 / (double) (moment.n - 1); |
94 | 22 | double skewness = Double.NaN; |
95 | 22 | if (variance < 10E-20) { |
96 | 2 | skewness = 0.0; |
97 | } else { |
|
98 | 20 | double n0 = (double) moment.getN(); |
99 | 20 | skewness = (n0 * moment.m3) / |
100 | ((n0 - 1) * (n0 -2) * Math.sqrt(variance) * variance); |
|
101 | } |
|
102 | 22 | return skewness; |
103 | } |
|
104 | ||
105 | /** |
|
106 | * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN() |
|
107 | */ |
|
108 | public long getN() { |
|
109 | 70 | return moment.getN(); |
110 | } |
|
111 | ||
112 | /** |
|
113 | * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear() |
|
114 | */ |
|
115 | public void clear() { |
|
116 | 22 | if (incMoment) { |
117 | 22 | moment.clear(); |
118 | } |
|
119 | 22 | } |
120 | ||
121 | /** |
|
122 | * Returns the Skewness of the entries in the specifed portion of the |
|
123 | * input array. |
|
124 | * <p> |
|
125 | * See {@link Skewness} for the definition used in the computation. |
|
126 | * <p> |
|
127 | * Throws <code>IllegalArgumentException</code> if the array is null. |
|
128 | * |
|
129 | * @param values the input array |
|
130 | * @param begin the index of the first array element to include |
|
131 | * @param length the number of elements to include |
|
132 | * @return the skewness of the values or Double.NaN if length is less than |
|
133 | * 3 |
|
134 | * @throws IllegalArgumentException if the array is null or the array index |
|
135 | * parameters are not valid |
|
136 | */ |
|
137 | public double evaluate(final double[] values,final int begin, |
|
138 | final int length) { |
|
139 | ||
140 | // Initialize the skewness |
|
141 | 30 | double skew = Double.NaN; |
142 | ||
143 | 30 | if (test(values, begin, length) && length > 2 ){ |
144 | 20 | Mean mean = new Mean(); |
145 | // Get the mean and the standard deviation |
|
146 | 20 | double m = mean.evaluate(values, begin, length); |
147 | ||
148 | // Calc the std, this is implemented here instead |
|
149 | // of using the standardDeviation method eliminate |
|
150 | // a duplicate pass to get the mean |
|
151 | 20 | double accum = 0.0; |
152 | 20 | double accum2 = 0.0; |
153 | 386 | for (int i = begin; i < begin + length; i++) { |
154 | 366 | accum += Math.pow((values[i] - m), 2.0); |
155 | 366 | accum2 += (values[i] - m); |
156 | } |
|
157 | 20 | double stdDev = Math.sqrt((accum - (Math.pow(accum2, 2) / ((double) length))) / |
158 | (double) (length - 1)); |
|
159 | ||
160 | 20 | double accum3 = 0.0; |
161 | 386 | for (int i = begin; i < begin + length; i++) { |
162 | 366 | accum3 += Math.pow(values[i] - m, 3.0d); |
163 | } |
|
164 | 20 | accum3 /= Math.pow(stdDev, 3.0d); |
165 | ||
166 | // Get N |
|
167 | 20 | double n0 = length; |
168 | ||
169 | // Calculate skewness |
|
170 | 20 | skew = (n0 / ((n0 - 1) * (n0 - 2))) * accum3; |
171 | } |
|
172 | 30 | return skew; |
173 | } |
|
174 | } |