View Javadoc
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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.stat.descriptive;
23  
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.util.Arrays;
29  import java.util.Locale;
30  
31  import org.hipparchus.UnitTestUtils;
32  import org.hipparchus.exception.MathIllegalArgumentException;
33  import org.hipparchus.stat.descriptive.moment.GeometricMean;
34  import org.hipparchus.stat.descriptive.moment.Mean;
35  import org.hipparchus.stat.descriptive.moment.Variance;
36  import org.hipparchus.stat.descriptive.rank.Max;
37  import org.hipparchus.stat.descriptive.rank.Min;
38  import org.hipparchus.stat.descriptive.summary.Sum;
39  import org.hipparchus.stat.descriptive.summary.SumOfSquares;
40  import org.hipparchus.util.FastMath;
41  import org.hipparchus.util.Precision;
42  import org.junit.Test;
43  
44  /**
45   * Test cases for the {@link DescriptiveStatistics} class.
46   */
47  public class DescriptiveStatisticsTest {
48  
49      private final double[] testArray = new double[] { 1, 2, 2, 3 };
50  
51      private final double mean = 2;
52      private final double sumSq = 18;
53      private final double sum = 8;
54      private final double var = 0.666666666666666666667;
55      private final double popVar = 0.5;
56      private final double std = FastMath.sqrt(var);
57      private final double n = 4;
58      private final double min = 1;
59      private final double max = 3;
60      private final double tolerance = 10E-15;
61  
62      protected DescriptiveStatistics createDescriptiveStatistics() {
63          return new DescriptiveStatistics();
64      }
65  
66      /** test stats */
67      @Test
68      public void testStats() {
69          DescriptiveStatistics u = createDescriptiveStatistics();
70          assertEquals("total count", 0, u.getN(), tolerance);
71          double one = 1;
72          u.addValue(one);
73          float twoF = 2;
74          u.addValue(twoF);
75          long twoL = 2;
76          u.addValue(twoL);
77          int three = 3;
78          u.addValue(three);
79          assertEquals("N", n, u.getN(), tolerance);
80          assertEquals("sum", sum, u.getSum(), tolerance);
81          assertEquals("sumsq", sumSq, u.getSumOfSquares(), tolerance);
82          assertEquals("var", var, u.getVariance(), tolerance);
83          assertEquals("population var", popVar, u.getPopulationVariance(), tolerance);
84          assertEquals("std", std, u.getStandardDeviation(), tolerance);
85          assertEquals("mean", mean, u.getMean(), tolerance);
86          assertEquals("min", min, u.getMin(), tolerance);
87          assertEquals("max", max, u.getMax(), tolerance);
88          u.clear();
89          assertEquals("total count", 0, u.getN(), tolerance);
90      }
91  
92      @Test
93      public void testConsume() {
94          DescriptiveStatistics u = createDescriptiveStatistics();
95          assertEquals("total count", 0, u.getN(), tolerance);
96  
97          Arrays.stream(testArray)
98                .forEach(u);
99  
100         assertEquals("N", n, u.getN(), tolerance);
101         assertEquals("sum", sum, u.getSum(), tolerance);
102         assertEquals("sumsq", sumSq, u.getSumOfSquares(), tolerance);
103         assertEquals("var", var, u.getVariance(), tolerance);
104         assertEquals("population var", popVar, u.getPopulationVariance(), tolerance);
105         assertEquals("std", std, u.getStandardDeviation(), tolerance);
106         assertEquals("mean", mean, u.getMean(), tolerance);
107         assertEquals("min", min, u.getMin(), tolerance);
108         assertEquals("max", max, u.getMax(), tolerance);
109         u.clear();
110         assertEquals("total count", 0, u.getN(), tolerance);
111     }
112 
113     @Test
114     public void testCopy() {
115         DescriptiveStatistics stats = createDescriptiveStatistics();
116         stats.addValue(1);
117         stats.addValue(3);
118         assertEquals(2, stats.getMean(), 1E-10);
119         DescriptiveStatistics copy = stats.copy();
120         assertEquals(2, copy.getMean(), 1E-10);
121     }
122 
123     @Test
124     public void testWindowSize() {
125         DescriptiveStatistics stats = createDescriptiveStatistics();
126         stats.setWindowSize(300);
127         for (int i = 0; i < 100; ++i) {
128             stats.addValue(i + 1);
129         }
130         int refSum = (100 * 101) / 2;
131         assertEquals(refSum / 100.0, stats.getMean(), 1E-10);
132         assertEquals(300, stats.getWindowSize());
133         try {
134             stats.setWindowSize(-3);
135             fail("an exception should have been thrown");
136         } catch (MathIllegalArgumentException iae) {
137             // expected
138         }
139         assertEquals(300, stats.getWindowSize());
140         stats.setWindowSize(50);
141         assertEquals(50, stats.getWindowSize());
142         int refSum2 = refSum - (50 * 51) / 2;
143         assertEquals(refSum2 / 50.0, stats.getMean(), 1E-10);
144     }
145 
146     @Test
147     public void testGetValues() {
148         DescriptiveStatistics stats = createDescriptiveStatistics();
149         for (int i = 100; i > 0; --i) {
150             stats.addValue(i);
151         }
152         int refSum = (100 * 101) / 2;
153         assertEquals(refSum / 100.0, stats.getMean(), 1E-10);
154         double[] v = stats.getValues();
155         for (int i = 0; i < v.length; ++i) {
156             assertEquals(100.0 - i, v[i], 1.0e-10);
157         }
158         double[] s = stats.getSortedValues();
159         for (int i = 0; i < s.length; ++i) {
160             assertEquals(i + 1.0, s[i], 1.0e-10);
161         }
162         assertEquals(12.0, stats.getElement(88), 1.0e-10);
163     }
164 
165     @Test
166     public void testQuadraticMean() {
167         final double[] values = { 1.2, 3.4, 5.6, 7.89 };
168         final DescriptiveStatistics stats = new DescriptiveStatistics(values);
169 
170         final int len = values.length;
171         double expected = 0;
172         for (int i = 0; i < len; i++) {
173             final double v = values[i];
174             expected += v * v / len;
175         }
176         expected = Math.sqrt(expected);
177 
178         assertEquals(expected, stats.getQuadraticMean(), Math.ulp(expected));
179     }
180 
181     @Test
182     public void testToString() {
183         DescriptiveStatistics stats = createDescriptiveStatistics();
184         stats.addValue(1);
185         stats.addValue(2);
186         stats.addValue(3);
187         Locale d = Locale.getDefault();
188         Locale.setDefault(Locale.US);
189         assertEquals("DescriptiveStatistics:\n" +
190                      "n: 3\n" +
191                      "min: 1.0\n" +
192                      "max: 3.0\n" +
193                      "mean: 2.0\n" +
194                      "std dev: 1.0\n" +
195                      "median: 2.0\n" +
196                      "skewness: 0.0\n" +
197                      "kurtosis: NaN\n",  stats.toString());
198         Locale.setDefault(d);
199     }
200 
201     @Test
202     public void testPercentile() {
203         DescriptiveStatistics stats = createDescriptiveStatistics();
204 
205         stats.addValue(1);
206         stats.addValue(2);
207         stats.addValue(3);
208         assertEquals(2, stats.getPercentile(50.0), 1E-10);
209     }
210 
211     @Test
212     public void test20090720() {
213         DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(100);
214         for (int i = 0; i < 161; i++) {
215             descriptiveStatistics.addValue(1.2);
216         }
217         descriptiveStatistics.clear();
218         descriptiveStatistics.addValue(1.2);
219         assertEquals(1, descriptiveStatistics.getN());
220     }
221 
222     @Test
223     public void testRemoval() {
224         final DescriptiveStatistics dstat = createDescriptiveStatistics();
225 
226         checkRemoval(dstat, 1, 6.0, 0.0, Double.NaN);
227         checkRemoval(dstat, 3, 5.0, 3.0, 4.5);
228         checkRemoval(dstat, 6, 3.5, 2.5, 3.0);
229         checkRemoval(dstat, 9, 3.5, 2.5, 3.0);
230         checkRemoval(dstat, DescriptiveStatistics.INFINITE_WINDOW, 3.5, 2.5, 3.0);
231     }
232 
233     @Test
234     public void testSummaryConsistency() {
235         final int windowSize = 5;
236         final DescriptiveStatistics dstats = new DescriptiveStatistics(windowSize);
237         final StreamingStatistics sstats = new StreamingStatistics();
238         final double tol = 1E-12;
239         for (int i = 0; i < 20; i++) {
240             dstats.addValue(i);
241             sstats.clear();
242             double[] values = dstats.getValues();
243             for (int j = 0; j < values.length; j++) {
244                 sstats.addValue(values[j]);
245             }
246             UnitTestUtils.assertEquals(dstats.getMean(), sstats.getMean(), tol);
247             UnitTestUtils.assertEquals(new Mean().evaluate(values), dstats.getMean(), tol);
248             UnitTestUtils.assertEquals(dstats.getMax(), sstats.getMax(), tol);
249             UnitTestUtils.assertEquals(new Max().evaluate(values), dstats.getMax(), tol);
250             UnitTestUtils.assertEquals(dstats.getGeometricMean(), sstats.getGeometricMean(), tol);
251             UnitTestUtils.assertEquals(new GeometricMean().evaluate(values), dstats.getGeometricMean(), tol);
252             UnitTestUtils.assertEquals(dstats.getMin(), sstats.getMin(), tol);
253             UnitTestUtils.assertEquals(new Min().evaluate(values), dstats.getMin(), tol);
254             UnitTestUtils.assertEquals(dstats.getStandardDeviation(), sstats.getStandardDeviation(), tol);
255             UnitTestUtils.assertEquals(dstats.getVariance(), sstats.getVariance(), tol);
256             UnitTestUtils.assertEquals(new Variance().evaluate(values), dstats.getVariance(), tol);
257             UnitTestUtils.assertEquals(dstats.getSum(), sstats.getSum(), tol);
258             UnitTestUtils.assertEquals(new Sum().evaluate(values), dstats.getSum(), tol);
259             UnitTestUtils.assertEquals(dstats.getSumOfSquares(), sstats.getSumOfSquares(), tol);
260             UnitTestUtils.assertEquals(new SumOfSquares().evaluate(values), dstats.getSumOfSquares(), tol);
261             UnitTestUtils.assertEquals(dstats.getPopulationVariance(), sstats.getPopulationVariance(), tol);
262             UnitTestUtils.assertEquals(new Variance(false).evaluate(values), dstats.getPopulationVariance(), tol);
263         }
264     }
265 
266     @Test
267     public void testMath1129(){
268         final double[] data = new double[] {
269             -0.012086732064244697,
270             -0.24975668704012527,
271             0.5706168483164684,
272             -0.322111769955327,
273             0.24166759508327315,
274             Double.NaN,
275             0.16698443218942854,
276             -0.10427763937565114,
277             -0.15595963093172435,
278             -0.028075857595882995,
279             -0.24137994506058857,
280             0.47543170476574426,
281             -0.07495595384947631,
282             0.37445697625436497,
283             -0.09944199541668033
284         };
285 
286         final DescriptiveStatistics ds = new DescriptiveStatistics(data);
287 
288         final double t = ds.getPercentile(75);
289         final double o = ds.getPercentile(25);
290 
291         final double iqr = t - o;
292         // System.out.println(String.format("25th percentile %s 75th percentile %s", o, t));
293         assertTrue(iqr >= 0);
294     }
295 
296     public void checkRemoval(DescriptiveStatistics dstat, int wsize,
297                              double mean1, double mean2, double mean3) {
298 
299         dstat.setWindowSize(wsize);
300         dstat.clear();
301 
302         for (int i = 1 ; i <= 6 ; ++i) {
303             dstat.addValue(i);
304         }
305 
306         assertTrue(Precision.equalsIncludingNaN(mean1, dstat.getMean()));
307         dstat.replaceMostRecentValue(0);
308         assertTrue(Precision.equalsIncludingNaN(mean2, dstat.getMean()));
309         dstat.removeMostRecentValue();
310         assertTrue(Precision.equalsIncludingNaN(mean3, dstat.getMean()));
311     }
312 
313 }