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;
17  
18  import junit.framework.Test;
19  import junit.framework.TestCase;
20  import junit.framework.TestSuite;
21  
22  import org.apache.commons.math.random.RandomData;
23  import org.apache.commons.math.random.RandomDataImpl;
24  
25  /**
26   * Test cases for the {@link Univariate} class.
27   *
28   * @version $Revision: 201916 $ $Date: 2005-06-26 15:25:41 -0700 (Sun, 26 Jun 2005) $
29   */
30  
31  public final class DescriptiveStatisticsImplTest extends TestCase {
32      private double one = 1;
33      private float two = 2;
34      private int three = 3;
35      private double mean = 2;
36      private double sumSq = 18;
37      private double sum = 8;
38      private double var = 0.666666666666666666667;
39      private double std = Math.sqrt(var);
40      private double n = 4;
41      private double min = 1;
42      private double max = 3;
43      private double skewness = 0;
44      private double kurtosis = 0.5;
45      private double tolerance = 10E-15;
46      
47      public DescriptiveStatisticsImplTest(String name) {
48          super(name);
49      }
50      
51      public void setUp() {  
52      }
53      
54      public static Test suite() {
55          TestSuite suite = new TestSuite(DescriptiveStatisticsImplTest.class);
56          suite.setName("DescriptiveStatistics Tests");
57          return suite;
58      }
59      
60      /** test stats */
61      public void testStats() {
62          DescriptiveStatistics u = DescriptiveStatistics.newInstance(); 
63          assertEquals("total count",0,u.getN(),tolerance);
64          u.addValue(one);
65          u.addValue(two);
66          u.addValue(two);
67          u.addValue(three);
68          assertEquals("N",n,u.getN(),tolerance);
69          assertEquals("sum",sum,u.getSum(),tolerance);
70          assertEquals("sumsq",sumSq,u.getSumsq(),tolerance);
71          assertEquals("var",var,u.getVariance(),tolerance);
72          assertEquals("std",std,u.getStandardDeviation(),tolerance);
73          assertEquals("mean",mean,u.getMean(),tolerance);
74          assertEquals("min",min,u.getMin(),tolerance);
75          assertEquals("max",max,u.getMax(),tolerance);
76          u.clear();
77          assertEquals("total count",0,u.getN(),tolerance);    
78      }     
79      
80      public void testN0andN1Conditions() throws Exception {
81          DescriptiveStatistics u = DescriptiveStatistics.newInstance(); 
82                  
83              assertTrue("Mean of n = 0 set should be NaN", 
84                  Double.isNaN( u.getMean() ) );
85              assertTrue("Standard Deviation of n = 0 set should be NaN", 
86                  Double.isNaN( u.getStandardDeviation() ) );
87              assertTrue("Variance of n = 0 set should be NaN",
88                  Double.isNaN(u.getVariance() ) );
89  
90              u.addValue(one);
91  
92              assertTrue( "Mean of n = 1 set should be value of single item n1",
93                  u.getMean() == one);
94              assertTrue( "StdDev of n = 1 set should be zero, instead it is: " 
95                  + u.getStandardDeviation(), u.getStandardDeviation() == 0);
96              assertTrue( "Variance of n = 1 set should be zero", 
97                  u.getVariance() == 0);  
98      }
99      
100     public void testSkewAndKurtosis() {
101         DescriptiveStatistics u = DescriptiveStatistics.newInstance(); 
102         
103         double[] testArray = 
104         { 12.5, 12, 11.8, 14.2, 14.9, 14.5, 21, 8.2, 10.3, 11.3, 14.1,
105           9.9, 12.2, 12, 12.1, 11, 19.8, 11, 10, 8.8, 9, 12.3 };
106         for( int i = 0; i < testArray.length; i++) {
107             u.addValue( testArray[i]);
108         }
109         
110         assertEquals("mean", 12.40455, u.getMean(), 0.0001);
111         assertEquals("variance", 10.00236, u.getVariance(), 0.0001);
112         assertEquals("skewness", 1.437424, u.getSkewness(), 0.0001);
113         assertEquals("kurtosis", 2.37719, u.getKurtosis(), 0.0001);
114     }
115 
116     public void testProductAndGeometricMean() throws Exception {
117         DescriptiveStatistics u = DescriptiveStatistics.newInstance(); 
118         u.setWindowSize(10);
119                 
120         u.addValue( 1.0 );
121         u.addValue( 2.0 );
122         u.addValue( 3.0 );
123         u.addValue( 4.0 );
124 
125         //assertEquals( "Product not expected", 
126         //    24.0, u.getProduct(), Double.MIN_VALUE );
127         assertEquals( "Geometric mean not expected", 
128             2.213364, u.getGeometricMean(), 0.00001 );
129 
130         // Now test rolling - StorelessDescriptiveStatistics should discount the contribution
131         // of a discarded element
132         for( int i = 0; i < 10; i++ ) {
133             u.addValue( i + 2 );
134         }
135         // Values should be (2,3,4,5,6,7,8,9,10,11)
136         
137         //assertEquals( "Product not expected", 39916800.0, 
138         //    u.getProduct(), 0.00001 );
139         assertEquals( "Geometric mean not expected", 5.755931, 
140             u.getGeometricMean(), 0.00001 );
141     }
142     
143     public void testGetSortedValues() {
144         double[] test1 = {5,4,3,2,1};
145         double[] test2 = {5,2,1,3,4,0};
146         double[] test3 = {1};
147         int[] testi = null;
148         double[] test4 = null;
149         RandomData rd = new RandomDataImpl();
150         tstGetSortedValues(test1);
151         tstGetSortedValues(test2);
152         tstGetSortedValues(test3);
153         for (int i = 0; i < 10; i++) {
154             testi = rd.nextPermutation(10,6);
155             test4 = new double[6];
156             for (int j = 0; j < testi.length; j++) {
157                 test4[j] = (double) testi[j];
158             }
159             tstGetSortedValues(test4);
160         }
161         for (int i = 0; i < 10; i++) {
162             testi = rd.nextPermutation(10,5);
163             test4 = new double[5];
164             for (int j = 0; j < testi.length; j++) {
165                 test4[j] = (double) testi[j];
166             }
167             tstGetSortedValues(test4);
168         }        
169     }
170     
171         
172     private void tstGetSortedValues(double[] test) {
173         DescriptiveStatistics u = DescriptiveStatistics.newInstance(); 
174         for (int i = 0; i < test.length; i++) {
175             u.addValue(test[i]);
176         }
177         double[] sorted = u.getSortedValues();
178         if (sorted.length != test.length) {
179             fail("wrong length for sorted values array");
180         }
181         for (int i = 0; i < sorted.length-1; i++) {
182             if (sorted[i] > sorted[i+1]) {
183                 fail("sorted values out of sequence");
184             }
185         }
186     }
187     
188     public void testPercentiles() {
189         double[] test = {5,4,3,2,1};
190         DescriptiveStatistics u = DescriptiveStatistics.newInstance(); 
191         for (int i = 0; i < test.length; i++) {
192             u.addValue(test[i]);
193         }
194         assertEquals("expecting min",1,u.getPercentile(5),10E-12);
195         assertEquals("expecting max",5,u.getPercentile(99),10E-12);
196         assertEquals("expecting middle",3,u.getPercentile(50),10E-12);
197         try {
198             double x = u.getPercentile(0);
199             fail("expecting IllegalArgumentException for getPercentile(0)");
200         } catch (IllegalArgumentException ex) {
201             ;
202         }
203         try {
204             double x = u.getPercentile(120);
205             fail("expecting IllegalArgumentException for getPercentile(120)");
206         } catch (IllegalArgumentException ex) {
207             ;
208         }
209         
210         u.clear();
211         double[] test2 = {1,2,3,4};
212         for (int i = 0; i < test2.length; i++) {
213             u.addValue(test2[i]);
214         }
215         assertEquals("Q1",1.25,u.getPercentile(25),10E-12);
216         assertEquals("Q3",3.75,u.getPercentile(75),10E-12);
217         assertEquals("Q2",2.5,u.getPercentile(50),10E-12);
218         
219         u.clear();
220         double[] test3 = {1};
221         for (int i = 0; i < test3.length; i++) {
222             u.addValue(test3[i]);
223         }
224         assertEquals("Q1",1,u.getPercentile(25),10E-12);
225         assertEquals("Q3",1,u.getPercentile(75),10E-12);
226         assertEquals("Q2",1,u.getPercentile(50),10E-12);
227         
228         u.clear();
229         RandomData rd = new RandomDataImpl();
230         int[] testi = rd.nextPermutation(100,100); // will contain 0-99
231         for (int j = 0; j < testi.length; j++) {
232             u.addValue((double) testi[j]);  //OK, laugh at me for the cast
233         }
234         for (int i = 1; i < 100; i++) {
235             assertEquals("percentile " + i,
236                 (double) i-1 + (double) i*(.01), u.getPercentile(i),10E-12);
237         }
238         
239         u.clear();
240         double[] test4 = {1,2,3,4,100};
241         for (int i = 0; i < test4.length; i++) {
242             u.addValue(test4[i]);
243         }
244         assertEquals("80th",80.8,u.getPercentile(80),10E-12);
245         
246         u.clear();
247         assertTrue("empty value set should return NaN",
248             Double.isNaN(u.getPercentile(50)));
249     }
250                                      
251 }
252