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 org.hipparchus.UnitTestUtils;
25  import org.hipparchus.exception.MathIllegalArgumentException;
26  import org.hipparchus.stat.descriptive.moment.GeometricMean;
27  import org.hipparchus.stat.descriptive.moment.Mean;
28  import org.hipparchus.stat.descriptive.moment.Variance;
29  import org.hipparchus.stat.descriptive.rank.Max;
30  import org.hipparchus.stat.descriptive.rank.Min;
31  import org.hipparchus.stat.descriptive.summary.Sum;
32  import org.hipparchus.stat.descriptive.summary.SumOfSquares;
33  import org.hipparchus.util.FastMath;
34  import org.hipparchus.util.Precision;
35  import org.junit.jupiter.api.Test;
36  
37  import java.util.Arrays;
38  import java.util.Locale;
39  
40  import static org.junit.jupiter.api.Assertions.assertEquals;
41  import static org.junit.jupiter.api.Assertions.assertTrue;
42  import static org.junit.jupiter.api.Assertions.fail;
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      void testStats() {
69          DescriptiveStatistics u = createDescriptiveStatistics();
70          assertEquals(0, u.getN(), tolerance, "total count");
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, u.getN(), tolerance, "N");
80          assertEquals(sum, u.getSum(), tolerance, "sum");
81          assertEquals(sumSq, u.getSumOfSquares(), tolerance, "sumsq");
82          assertEquals(var, u.getVariance(), tolerance, "var");
83          assertEquals(popVar, u.getPopulationVariance(), tolerance, "population var");
84          assertEquals(std, u.getStandardDeviation(), tolerance, "std");
85          assertEquals(mean, u.getMean(), tolerance, "mean");
86          assertEquals(min, u.getMin(), tolerance, "min");
87          assertEquals(max, u.getMax(), tolerance, "max");
88          u.clear();
89          assertEquals(0, u.getN(), tolerance, "total count");
90      }
91  
92      @Test
93      void testConsume() {
94          DescriptiveStatistics u = createDescriptiveStatistics();
95          assertEquals(0, u.getN(), tolerance, "total count");
96  
97          Arrays.stream(testArray)
98                .forEach(u);
99  
100         assertEquals(n, u.getN(), tolerance, "N");
101         assertEquals(sum, u.getSum(), tolerance, "sum");
102         assertEquals(sumSq, u.getSumOfSquares(), tolerance, "sumsq");
103         assertEquals(var, u.getVariance(), tolerance, "var");
104         assertEquals(popVar, u.getPopulationVariance(), tolerance, "population var");
105         assertEquals(std, u.getStandardDeviation(), tolerance, "std");
106         assertEquals(mean, u.getMean(), tolerance, "mean");
107         assertEquals(min, u.getMin(), tolerance, "min");
108         assertEquals(max, u.getMax(), tolerance, "max");
109         u.clear();
110         assertEquals(0, u.getN(), tolerance, "total count");
111     }
112 
113     @Test
114     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     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     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     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     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     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     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     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     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.customAssertEquals(dstats.getMean(), sstats.getMean(), tol);
247             UnitTestUtils.customAssertEquals(new Mean().evaluate(values), dstats.getMean(), tol);
248             UnitTestUtils.customAssertEquals(dstats.getMax(), sstats.getMax(), tol);
249             UnitTestUtils.customAssertEquals(new Max().evaluate(values), dstats.getMax(), tol);
250             UnitTestUtils.customAssertEquals(dstats.getGeometricMean(), sstats.getGeometricMean(), tol);
251             UnitTestUtils.customAssertEquals(new GeometricMean().evaluate(values), dstats.getGeometricMean(), tol);
252             UnitTestUtils.customAssertEquals(dstats.getMin(), sstats.getMin(), tol);
253             UnitTestUtils.customAssertEquals(new Min().evaluate(values), dstats.getMin(), tol);
254             UnitTestUtils.customAssertEquals(dstats.getStandardDeviation(), sstats.getStandardDeviation(), tol);
255             UnitTestUtils.customAssertEquals(dstats.getVariance(), sstats.getVariance(), tol);
256             UnitTestUtils.customAssertEquals(new Variance().evaluate(values), dstats.getVariance(), tol);
257             UnitTestUtils.customAssertEquals(dstats.getSum(), sstats.getSum(), tol);
258             UnitTestUtils.customAssertEquals(new Sum().evaluate(values), dstats.getSum(), tol);
259             UnitTestUtils.customAssertEquals(dstats.getSumOfSquares(), sstats.getSumOfSquares(), tol);
260             UnitTestUtils.customAssertEquals(new SumOfSquares().evaluate(values), dstats.getSumOfSquares(), tol);
261             UnitTestUtils.customAssertEquals(dstats.getPopulationVariance(), sstats.getPopulationVariance(), tol);
262             UnitTestUtils.customAssertEquals(new Variance(false).evaluate(values), dstats.getPopulationVariance(), tol);
263         }
264     }
265 
266     @Test
267     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 }