001: /*
002: * Copyright 2003-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.math.stat.descriptive;
017:
018: import junit.framework.Test;
019: import junit.framework.TestCase;
020: import junit.framework.TestSuite;
021:
022: import org.apache.commons.math.TestUtils;
023: import org.apache.commons.math.random.RandomData;
024: import org.apache.commons.math.random.RandomDataImpl;
025:
026: /**
027: * Test cases for the {@link Univariate} class.
028: *
029: * @version $Revision: 201916 $ $Date: 2005-06-26 15:25:41 -0700 (Sun, 26 Jun 2005) $
030: */
031:
032: public final class DescriptiveStatisticsTest extends TestCase {
033: private double one = 1;
034: private float two = 2;
035: private int three = 3;
036: private double mean = 2;
037: private double sumSq = 18;
038: private double sum = 8;
039: private double var = 0.666666666666666666667;
040: private double std = Math.sqrt(var);
041: private double n = 4;
042: private double min = 1;
043: private double max = 3;
044: private double skewness = 0;
045: private double kurtosis = 0.5;
046: private double tolerance = 10E-15;
047:
048: public DescriptiveStatisticsTest(String name) {
049: super (name);
050: }
051:
052: public void setUp() {
053: }
054:
055: public static Test suite() {
056: TestSuite suite = new TestSuite(DescriptiveStatisticsTest.class);
057: suite.setName("Descriptive Statistics Tests");
058: return suite;
059: }
060:
061: /** test stats */
062: public void testStats() {
063: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
064: assertEquals("total count", 0, u.getN(), tolerance);
065: u.addValue(one);
066: u.addValue(two);
067: u.addValue(two);
068: u.addValue(three);
069: assertEquals("N", n, u.getN(), tolerance);
070: assertEquals("sum", sum, u.getSum(), tolerance);
071: assertEquals("sumsq", sumSq, u.getSumsq(), tolerance);
072: assertEquals("var", var, u.getVariance(), tolerance);
073: assertEquals("std", std, u.getStandardDeviation(), tolerance);
074: assertEquals("mean", mean, u.getMean(), tolerance);
075: assertEquals("min", min, u.getMin(), tolerance);
076: assertEquals("max", max, u.getMax(), tolerance);
077: u.clear();
078: assertEquals("total count", 0, u.getN(), tolerance);
079: }
080:
081: public void testN0andN1Conditions() throws Exception {
082: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
083:
084: assertTrue("Mean of n = 0 set should be NaN", Double.isNaN(u
085: .getMean()));
086: assertTrue("Standard Deviation of n = 0 set should be NaN",
087: Double.isNaN(u.getStandardDeviation()));
088: assertTrue("Variance of n = 0 set should be NaN", Double
089: .isNaN(u.getVariance()));
090:
091: u.addValue(one);
092:
093: assertTrue(
094: "Mean of n = 1 set should be value of single item n1",
095: u.getMean() == one);
096: assertTrue(
097: "StdDev of n = 1 set should be zero, instead it is: "
098: + u.getStandardDeviation(), u
099: .getStandardDeviation() == 0);
100: assertTrue("Variance of n = 1 set should be zero", u
101: .getVariance() == 0);
102: }
103:
104: public void testSkewAndKurtosis() {
105: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
106:
107: double[] testArray = { 12.5, 12, 11.8, 14.2, 14.9, 14.5, 21,
108: 8.2, 10.3, 11.3, 14.1, 9.9, 12.2, 12, 12.1, 11, 19.8,
109: 11, 10, 8.8, 9, 12.3 };
110: for (int i = 0; i < testArray.length; i++) {
111: u.addValue(testArray[i]);
112: }
113:
114: assertEquals("mean", 12.40455, u.getMean(), 0.0001);
115: assertEquals("variance", 10.00236, u.getVariance(), 0.0001);
116: assertEquals("skewness", 1.437424, u.getSkewness(), 0.0001);
117: assertEquals("kurtosis", 2.37719, u.getKurtosis(), 0.0001);
118: }
119:
120: public void testProductAndGeometricMean() throws Exception {
121: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
122: u.setWindowSize(10);
123:
124: u.addValue(1.0);
125: u.addValue(2.0);
126: u.addValue(3.0);
127: u.addValue(4.0);
128:
129: //assertEquals( "Product not expected",
130: // 24.0, u.getProduct(), Double.MIN_VALUE );
131: assertEquals("Geometric mean not expected", 2.213364, u
132: .getGeometricMean(), 0.00001);
133:
134: // Now test rolling - StorelessDescriptiveStatistics should discount the contribution
135: // of a discarded element
136: for (int i = 0; i < 10; i++) {
137: u.addValue(i + 2);
138: }
139: // Values should be (2,3,4,5,6,7,8,9,10,11)
140:
141: //assertEquals( "Product not expected", 39916800.0,
142: // u.getProduct(), 0.00001 );
143: assertEquals("Geometric mean not expected", 5.755931, u
144: .getGeometricMean(), 0.00001);
145: }
146:
147: public void testAddValue() {
148: double[] test1 = { 5, 4, 3, 2, 1, 0 };
149: double[] test2 = { 5, 2, 1, 0, 4, 3 };
150:
151: DescriptiveStatistics stats = DescriptiveStatistics
152: .newInstance();
153: stats.setWindowSize(12);
154:
155: for (int i = 0; i < test1.length; i++) {
156: stats.addValue(test1[i]);
157: }
158:
159: double[] test3 = stats.getValues();
160:
161: for (int i = 0; i < 6; i++) {
162: assertEquals("Added value [" + i + "] not equal", test3[i],
163: test1[i], 0.0);
164: //System.out.println(test3[i] + " "+test1[i]);
165: }
166:
167: for (int i = 0; i < test2.length; i++) {
168: stats.addValue(test2[i]);
169: }
170:
171: test3 = stats.getValues();
172:
173: for (int i = 6; i < 12; i++) {
174: assertEquals("Added value [" + i + "] not equal", test3[i],
175: test2[i - 6], 0.0);
176: //System.out.println(test3[i] + " "+test2[i-6]);
177: }
178:
179: for (int i = 0; i < test2.length; i++) {
180: stats.addValue(test2[i]);
181: }
182:
183: test3 = stats.getValues();
184:
185: for (int i = 0; i < 6; i++) {
186: assertEquals("Added value [" + i + "] not equal", test3[i],
187: test2[i], 0.0);
188: //System.out.println(test3[i] + " "+test2[i]);
189: }
190:
191: for (int i = 6; i < 12; i++) {
192: assertEquals("Added value [" + i + "] not equal", test3[i],
193: test2[i - 6], 0.0);
194: //System.out.println(test3[i] + " "+test2[i-6]);
195: }
196:
197: }
198:
199: public void testGetSortedValues() {
200: double[] test1 = { 5, 4, 3, 2, 1 };
201: double[] test2 = { 5, 2, 1, 3, 4, 0 };
202: double[] test3 = { 1 };
203: int[] testi = null;
204: double[] test4 = null;
205: RandomData rd = new RandomDataImpl();
206: tstGetSortedValues(test1);
207: tstGetSortedValues(test2);
208: tstGetSortedValues(test3);
209: for (int i = 0; i < 10; i++) {
210: testi = rd.nextPermutation(10, 6);
211: test4 = new double[6];
212: for (int j = 0; j < testi.length; j++) {
213: test4[j] = (double) testi[j];
214: }
215: tstGetSortedValues(test4);
216: }
217: for (int i = 0; i < 10; i++) {
218: testi = rd.nextPermutation(10, 5);
219: test4 = new double[5];
220: for (int j = 0; j < testi.length; j++) {
221: test4[j] = (double) testi[j];
222: }
223: tstGetSortedValues(test4);
224: }
225: }
226:
227: private void tstGetSortedValues(double[] test) {
228: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
229: u.setWindowSize(test.length);
230: for (int i = 0; i < test.length; i++) {
231: u.addValue(test[i]);
232: }
233: double[] sorted = u.getSortedValues();
234: if (sorted.length != test.length) {
235: fail("wrong length for sorted values array");
236: }
237: for (int i = 0; i < sorted.length - 1; i++) {
238: if (sorted[i] > sorted[i + 1]) {
239: fail("sorted values out of sequence");
240: }
241: }
242: }
243:
244: public void testPercentiles() {
245: double[] test = { 5, 4, 3, 2, 1 };
246: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
247: u.setWindowSize(110);
248: for (int i = 0; i < test.length; i++) {
249: u.addValue(test[i]);
250: }
251: assertEquals("expecting min", 1, u.getPercentile(5), 10E-12);
252: assertEquals("expecting max", 5, u.getPercentile(99), 10E-12);
253: assertEquals("expecting middle", 3, u.getPercentile(50), 10E-12);
254: try {
255: double x = u.getPercentile(0);
256: fail("expecting IllegalArgumentException for getPercentile(0)");
257: } catch (IllegalArgumentException ex) {
258: ;
259: }
260: try {
261: double x = u.getPercentile(120);
262: fail("expecting IllegalArgumentException for getPercentile(120)");
263: } catch (IllegalArgumentException ex) {
264: ;
265: }
266:
267: u.clear();
268: double[] test2 = { 1, 2, 3, 4 };
269: for (int i = 0; i < test2.length; i++) {
270: u.addValue(test2[i]);
271: }
272: assertEquals("Q1", 1.25, u.getPercentile(25), 10E-12);
273: assertEquals("Q3", 3.75, u.getPercentile(75), 10E-12);
274: assertEquals("Q2", 2.5, u.getPercentile(50), 10E-12);
275:
276: u.clear();
277: double[] test3 = { 1 };
278: for (int i = 0; i < test3.length; i++) {
279: u.addValue(test3[i]);
280: }
281: assertEquals("Q1", 1, u.getPercentile(25), 10E-12);
282: assertEquals("Q3", 1, u.getPercentile(75), 10E-12);
283: assertEquals("Q2", 1, u.getPercentile(50), 10E-12);
284:
285: u.clear();
286: RandomData rd = new RandomDataImpl();
287: int[] testi = rd.nextPermutation(100, 100); // will contain 0-99
288: for (int j = 0; j < testi.length; j++) {
289: u.addValue((double) testi[j]); //OK, laugh at me for the cast
290: }
291: for (int i = 1; i < 100; i++) {
292: assertEquals("percentile " + i, (double) i - 1 + (double) i
293: * (.01), u.getPercentile(i), 10E-12);
294: }
295:
296: u.clear();
297: double[] test4 = { 1, 2, 3, 4, 100 };
298: for (int i = 0; i < test4.length; i++) {
299: u.addValue(test4[i]);
300: }
301: assertEquals("80th", 80.8, u.getPercentile(80), 10E-12);
302:
303: u.clear();
304: assertTrue("empty value set should return NaN", Double.isNaN(u
305: .getPercentile(50)));
306: }
307:
308: /** test stats */
309: public void testSerialization() {
310: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
311: assertEquals("total count", 0, u.getN(), tolerance);
312: u.addValue(one);
313: u.addValue(two);
314:
315: DescriptiveStatistics u2 = (DescriptiveStatistics) TestUtils
316: .serializeAndRecover(u);
317:
318: u2.addValue(two);
319: u2.addValue(three);
320:
321: assertEquals("N", n, u2.getN(), tolerance);
322: assertEquals("sum", sum, u2.getSum(), tolerance);
323: assertEquals("sumsq", sumSq, u2.getSumsq(), tolerance);
324: assertEquals("var", var, u2.getVariance(), tolerance);
325: assertEquals("std", std, u2.getStandardDeviation(), tolerance);
326: assertEquals("mean", mean, u2.getMean(), tolerance);
327: assertEquals("min", min, u2.getMin(), tolerance);
328: assertEquals("max", max, u2.getMax(), tolerance);
329:
330: u2.clear();
331: assertEquals("total count", 0, u2.getN(), tolerance);
332: }
333:
334: public void testNewInstanceClassNull() {
335: try {
336: DescriptiveStatistics u = DescriptiveStatistics
337: .newInstance((Class) null);
338: fail("null is not a valid descriptive statistics class");
339: } catch (NullPointerException ex) {
340: // success
341: } catch (Exception ex) {
342: fail();
343: }
344:
345: }
346:
347: public void testNewInstanceClassValid() {
348: try {
349: DescriptiveStatistics u = DescriptiveStatistics
350: .newInstance(DescriptiveStatisticsImpl.class);
351: assertNotNull(u);
352: assertTrue(u instanceof DescriptiveStatisticsImpl);
353: } catch (Exception ex) {
354: fail();
355: }
356: }
357:
358: public void testWindowSize() {
359: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
360: u.setWindowSize(1234);
361: assertEquals(1234, u.getWindowSize());
362:
363: u.addValue(1.0);
364: u.addValue(2.0);
365: u.addValue(3.0);
366: u.addValue(4.0);
367: u.addValue(5.0);
368: assertEquals(5, u.getN());
369:
370: u.setWindowSize(DescriptiveStatistics.INFINITE_WINDOW);
371: assertEquals(5, u.getN());
372: }
373:
374: public void testWindowing() {
375: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
376: u.setWindowSize(2);
377:
378: u.addValue(1.0);
379: assertEquals(1.0, u.getMean(), tolerance);
380:
381: u.addValue(2.0);
382: assertEquals(1.5, u.getMean(), tolerance);
383:
384: u.addValue(3.0);
385: assertEquals(2.5, u.getMean(), tolerance);
386:
387: u.setWindowSize(1);
388: assertEquals(3.0, u.getMean(), tolerance);
389: }
390:
391: public void testToString() {
392: DescriptiveStatistics u = DescriptiveStatistics.newInstance();
393: assertTrue(u.toString().indexOf("NaN") > 0);
394: assertTrue(u.toString().startsWith("DescriptiveStatistics"));
395: double[] testArray = { 12.5, 12, 11.8, 14.2, 14.9, 14.5, 21,
396: 8.2, 10.3, 11.3, 14.1, 9.9, 12.2, 12, 12.1, 11, 19.8,
397: 11, 10, 8.8, 9, 12.3 };
398: for (int i = 0; i < testArray.length; i++) {
399: u.addValue(testArray[i]);
400: }
401: assertTrue(u.toString().indexOf("NaN") == -1);
402: assertTrue(u.toString().startsWith("DescriptiveStatistics"));
403: }
404:
405: }
|