1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.stat.descriptive;
18
19 import java.util.Locale;
20
21 import org.apache.commons.math4.legacy.TestUtils;
22 import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
23 import org.apache.commons.math4.legacy.stat.descriptive.moment.GeometricMean;
24 import org.apache.commons.math4.legacy.stat.descriptive.moment.Mean;
25 import org.apache.commons.math4.legacy.stat.descriptive.moment.Variance;
26 import org.apache.commons.math4.legacy.stat.descriptive.rank.Max;
27 import org.apache.commons.math4.legacy.stat.descriptive.rank.Min;
28 import org.apache.commons.math4.legacy.stat.descriptive.rank.Percentile;
29 import org.apache.commons.math4.legacy.stat.descriptive.summary.Sum;
30 import org.apache.commons.math4.legacy.stat.descriptive.summary.SumOfSquares;
31 import org.apache.commons.numbers.core.Precision;
32 import org.apache.commons.rng.UniformRandomProvider;
33 import org.apache.commons.rng.simple.RandomSource;
34 import org.junit.Assert;
35 import org.junit.Test;
36
37
38
39
40 public class DescriptiveStatisticsTest {
41 private static UniformRandomProvider random = RandomSource.WELL_1024_A.create(2345789432894L);
42
43 protected DescriptiveStatistics createDescriptiveStatistics() {
44 return new DescriptiveStatistics();
45 }
46
47 @Test
48 public void testSetterInjection() {
49 DescriptiveStatistics stats = createDescriptiveStatistics();
50 stats.addValue(1);
51 stats.addValue(3);
52 Assert.assertEquals(2, stats.getMean(), 1E-10);
53
54 stats.setMeanImpl(new DeepMean());
55 Assert.assertEquals(42, stats.getMean(), 1E-10);
56 }
57
58 @Test
59 public void testCopy() {
60 DescriptiveStatistics stats = createDescriptiveStatistics();
61 stats.addValue(1);
62 stats.addValue(3);
63 DescriptiveStatistics copy = new DescriptiveStatistics(stats);
64 Assert.assertEquals(2, copy.getMean(), 1E-10);
65
66 stats.setMeanImpl(new DeepMean());
67 copy = stats.copy();
68 Assert.assertEquals(42, copy.getMean(), 1E-10);
69 }
70
71 @Test
72 public void testWindowSize() {
73 DescriptiveStatistics stats = createDescriptiveStatistics();
74 stats.setWindowSize(300);
75 for (int i = 0; i < 100; ++i) {
76 stats.addValue(i + 1);
77 }
78 int refSum = (100 * 101) / 2;
79 Assert.assertEquals(refSum / 100.0, stats.getMean(), 1E-10);
80 Assert.assertEquals(300, stats.getWindowSize());
81 try {
82 stats.setWindowSize(-3);
83 Assert.fail("an exception should have been thrown");
84 } catch (MathIllegalArgumentException iae) {
85
86 }
87 Assert.assertEquals(300, stats.getWindowSize());
88 stats.setWindowSize(50);
89 Assert.assertEquals(50, stats.getWindowSize());
90 int refSum2 = refSum - (50 * 51) / 2;
91 Assert.assertEquals(refSum2 / 50.0, stats.getMean(), 1E-10);
92 }
93
94 @Test
95 public void testGetValues() {
96 DescriptiveStatistics stats = createDescriptiveStatistics();
97 for (int i = 100; i > 0; --i) {
98 stats.addValue(i);
99 }
100 int refSum = (100 * 101) / 2;
101 Assert.assertEquals(refSum / 100.0, stats.getMean(), 1E-10);
102 double[] v = stats.getValues();
103 for (int i = 0; i < v.length; ++i) {
104 Assert.assertEquals(100.0 - i, v[i], 1.0e-10);
105 }
106 double[] s = stats.getSortedValues();
107 for (int i = 0; i < s.length; ++i) {
108 Assert.assertEquals(i + 1.0, s[i], 1.0e-10);
109 }
110 Assert.assertEquals(12.0, stats.getElement(88), 1.0e-10);
111 }
112
113 @Test
114 public void testQuadraticMean() {
115 final double[] values = { 1.2, 3.4, 5.6, 7.89 };
116 final DescriptiveStatistics stats = new DescriptiveStatistics(values);
117
118 final int len = values.length;
119 double expected = 0;
120 for (int i = 0; i < len; i++) {
121 final double v = values[i];
122 expected += v * v / len;
123 }
124 expected = Math.sqrt(expected);
125
126 Assert.assertEquals(expected, stats.getQuadraticMean(), Math.ulp(expected));
127 }
128
129 @Test
130 public void testToString() {
131 DescriptiveStatistics stats = createDescriptiveStatistics();
132 stats.addValue(1);
133 stats.addValue(2);
134 stats.addValue(3);
135 Locale d = Locale.getDefault();
136 Locale.setDefault(Locale.US);
137 Assert.assertEquals("DescriptiveStatistics:\n" +
138 "n: 3\n" +
139 "min: 1.0\n" +
140 "max: 3.0\n" +
141 "mean: 2.0\n" +
142 "std dev: 1.0\n" +
143 "median: 2.0\n" +
144 "skewness: 0.0\n" +
145 "kurtosis: NaN\n", stats.toString());
146 Locale.setDefault(d);
147 }
148
149 @Test
150 public void testShuffledStatistics() {
151
152
153
154 DescriptiveStatistics reference = createDescriptiveStatistics();
155 DescriptiveStatistics shuffled = createDescriptiveStatistics();
156
157 UnivariateStatistic tmp = shuffled.getGeometricMeanImpl();
158 shuffled.setGeometricMeanImpl(shuffled.getMeanImpl());
159 shuffled.setMeanImpl(shuffled.getKurtosisImpl());
160 shuffled.setKurtosisImpl(shuffled.getSkewnessImpl());
161 shuffled.setSkewnessImpl(shuffled.getVarianceImpl());
162 shuffled.setVarianceImpl(shuffled.getMaxImpl());
163 shuffled.setMaxImpl(shuffled.getMinImpl());
164 shuffled.setMinImpl(shuffled.getSumImpl());
165 shuffled.setSumImpl(shuffled.getSumsqImpl());
166 shuffled.setSumsqImpl(tmp);
167
168 for (int i = 100; i > 0; --i) {
169 reference.addValue(i);
170 shuffled.addValue(i);
171 }
172
173 Assert.assertEquals(reference.getMean(), shuffled.getGeometricMean(), 1.0e-10);
174 Assert.assertEquals(reference.getKurtosis(), shuffled.getMean(), 1.0e-10);
175 Assert.assertEquals(reference.getSkewness(), shuffled.getKurtosis(), 1.0e-10);
176 Assert.assertEquals(reference.getVariance(), shuffled.getSkewness(), 1.0e-10);
177 Assert.assertEquals(reference.getMax(), shuffled.getVariance(), 1.0e-10);
178 Assert.assertEquals(reference.getMin(), shuffled.getMax(), 1.0e-10);
179 Assert.assertEquals(reference.getSum(), shuffled.getMin(), 1.0e-10);
180 Assert.assertEquals(reference.getSumsq(), shuffled.getSum(), 1.0e-10);
181 Assert.assertEquals(reference.getGeometricMean(), shuffled.getSumsq(), 1.0e-10);
182 }
183
184 @Test
185 public void testPercentileSetter() {
186 DescriptiveStatistics stats = createDescriptiveStatistics();
187 stats.addValue(1);
188 stats.addValue(2);
189 stats.addValue(3);
190 Assert.assertEquals(2, stats.getPercentile(50.0), 1E-10);
191
192
193 stats.setPercentileImpl(new GoodPercentile());
194 Assert.assertEquals(2, stats.getPercentile(50.0), 1E-10);
195
196
197 stats.setPercentileImpl(new SubPercentile());
198 Assert.assertEquals(10.0, stats.getPercentile(10.0), 1E-10);
199
200
201 try {
202 stats.setPercentileImpl(new BadPercentile());
203 Assert.fail("Expecting MathIllegalArgumentException");
204 } catch (MathIllegalArgumentException ex) {
205
206 }
207 }
208
209 @Test
210 public void test20090720() {
211 DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics(100);
212 for (int i = 0; i < 161; i++) {
213 descriptiveStatistics.addValue(1.2);
214 }
215 descriptiveStatistics.clear();
216 descriptiveStatistics.addValue(1.2);
217 Assert.assertEquals(1, descriptiveStatistics.getN());
218 }
219
220 @Test
221 public void testRemoval() {
222
223 final DescriptiveStatistics dstat = createDescriptiveStatistics();
224
225 checkremoval(dstat, 1, 6.0, 0.0, Double.NaN);
226 checkremoval(dstat, 3, 5.0, 3.0, 4.5);
227 checkremoval(dstat, 6, 3.5, 2.5, 3.0);
228 checkremoval(dstat, 9, 3.5, 2.5, 3.0);
229 checkremoval(dstat, DescriptiveStatistics.INFINITE_WINDOW, 3.5, 2.5, 3.0);
230 }
231
232 @Test
233 public void testSummaryConsistency() {
234 final DescriptiveStatistics dstats = new DescriptiveStatistics();
235 final SummaryStatistics sstats = new SummaryStatistics();
236 final int windowSize = 5;
237 dstats.setWindowSize(windowSize);
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 TestUtils.assertEquals(dstats.getMean(), sstats.getMean(), tol);
247 TestUtils.assertEquals(new Mean().evaluate(values), dstats.getMean(), tol);
248 TestUtils.assertEquals(dstats.getMax(), sstats.getMax(), tol);
249 TestUtils.assertEquals(new Max().evaluate(values), dstats.getMax(), tol);
250 TestUtils.assertEquals(dstats.getGeometricMean(), sstats.getGeometricMean(), tol);
251 TestUtils.assertEquals(new GeometricMean().evaluate(values), dstats.getGeometricMean(), tol);
252 TestUtils.assertEquals(dstats.getMin(), sstats.getMin(), tol);
253 TestUtils.assertEquals(new Min().evaluate(values), dstats.getMin(), tol);
254 TestUtils.assertEquals(dstats.getStandardDeviation(), sstats.getStandardDeviation(), tol);
255 TestUtils.assertEquals(dstats.getVariance(), sstats.getVariance(), tol);
256 TestUtils.assertEquals(new Variance().evaluate(values), dstats.getVariance(), tol);
257 TestUtils.assertEquals(dstats.getSum(), sstats.getSum(), tol);
258 TestUtils.assertEquals(new Sum().evaluate(values), dstats.getSum(), tol);
259 TestUtils.assertEquals(dstats.getSumsq(), sstats.getSumsq(), tol);
260 TestUtils.assertEquals(new SumOfSquares().evaluate(values), dstats.getSumsq(), tol);
261 TestUtils.assertEquals(dstats.getPopulationVariance(), sstats.getPopulationVariance(), tol);
262 TestUtils.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
293 Assert.assertTrue(iqr >= 0);
294 }
295
296 @Test
297 public void testInit0() {
298
299 int window = 1 + random.nextInt(Integer.MAX_VALUE-1);
300 DescriptiveStatistics instance = new DescriptiveStatistics(window);
301 Assert.assertEquals(window,
302 instance.getWindowSize());
303 }
304
305 @Test
306 public void testInitDouble() {
307
308 double[] initialDoubleArray = null;
309 new DescriptiveStatistics(initialDoubleArray);
310
311
312 int initialDoubleArraySize = random.nextInt(1024
313
314 );
315
316
317 initialDoubleArray = new double[initialDoubleArraySize];
318 for(int i = 0; i < initialDoubleArraySize; i++) {
319 double value = random.nextDouble();
320 initialDoubleArray[i] = value;
321 }
322 new DescriptiveStatistics(initialDoubleArray);
323 }
324
325 @Test
326 public void testInitDoubleWrapper() {
327
328 Double[] initialDoubleWrapperArray = null;
329 new DescriptiveStatistics(initialDoubleWrapperArray);
330 int initialDoubleWrapperArraySize = random.nextInt(1024
331
332 );
333 initialDoubleWrapperArray = generateInitialDoubleArray(initialDoubleWrapperArraySize);
334 new DescriptiveStatistics(initialDoubleWrapperArray);
335 }
336
337 @Test
338 public void testInitCopy() {
339
340 int initialDoubleArray = random.nextInt(1024
341
342 );
343 DescriptiveStatistics original = new DescriptiveStatistics(initialDoubleArray);
344 DescriptiveStatistics instance = new DescriptiveStatistics(original);
345 Assert.assertEquals(original.getGeometricMean(),
346 instance.getGeometricMean(),
347 0);
348 Assert.assertEquals(original.getKurtosis(),
349 instance.getKurtosis(),
350 0);
351 Assert.assertEquals(original.getMax(),
352 instance.getMax(),
353 0);
354 Assert.assertEquals(original.getMean(),
355 instance.getMean(),
356 0);
357 Assert.assertEquals(original.getMin(),
358 instance.getMin(),
359 0);
360 Assert.assertEquals(original.getN(),
361 instance.getN());
362 Assert.assertEquals(original.getSkewness(),
363 instance.getSkewness(),
364 0);
365 Assert.assertArrayEquals(original.getValues(),
366 instance.getValues(),
367 0);
368 Assert.assertEquals(original.getWindowSize(),
369 instance.getWindowSize());
370
371 }
372
373 public void checkremoval(DescriptiveStatistics dstat, int wsize,
374 double mean1, double mean2, double mean3) {
375
376 dstat.setWindowSize(wsize);
377 dstat.clear();
378
379 for (int i = 1 ; i <= 6 ; ++i) {
380 dstat.addValue(i);
381 }
382
383 Assert.assertTrue(Precision.equalsIncludingNaN(mean1, dstat.getMean()));
384 dstat.replaceMostRecentValue(0);
385 Assert.assertTrue(Precision.equalsIncludingNaN(mean2, dstat.getMean()));
386 dstat.removeMostRecentValue();
387 Assert.assertTrue(Precision.equalsIncludingNaN(mean3, dstat.getMean()));
388 }
389
390 private Double[] generateInitialDoubleArray(int size) {
391 Double[] retValue = new Double[size];
392 for(int i = 0; i < size; i++) {
393 Double value = random.nextDouble();
394 retValue[i] = value;
395 }
396 return retValue;
397 }
398
399
400
401
402
403
404 static class DeepMean implements UnivariateStatistic {
405
406 @Override
407 public double evaluate(double[] values, int begin, int length) {
408 return 42;
409 }
410
411 @Override
412 public double evaluate(double[] values) {
413 return 42;
414 }
415 @Override
416 public UnivariateStatistic copy() {
417 return new DeepMean();
418 }
419 }
420
421
422
423
424 static class GoodPercentile implements UnivariateStatistic {
425 private final Percentile percentile = new Percentile();
426 public void setQuantile(double quantile) {
427 percentile.setQuantile(quantile);
428 }
429 @Override
430 public double evaluate(double[] values, int begin, int length) {
431 return percentile.evaluate(values, begin, length);
432 }
433 @Override
434 public double evaluate(double[] values) {
435 return percentile.evaluate(values);
436 }
437 @Override
438 public UnivariateStatistic copy() {
439 GoodPercentile result = new GoodPercentile();
440 result.setQuantile(percentile.getQuantile());
441 return result;
442 }
443 }
444
445
446
447
448
449 static class SubPercentile extends Percentile {
450 @Override
451 public double evaluate(double[] values, int begin, int length) {
452 return getQuantile();
453 }
454 @Override
455 public double evaluate(double[] values) {
456 return getQuantile();
457 }
458 private static final long serialVersionUID = 8040701391045914979L;
459 @Override
460 public Percentile copy() {
461 SubPercentile result = new SubPercentile();
462 return result;
463 }
464 }
465
466
467
468
469 static class BadPercentile implements UnivariateStatistic {
470 private final Percentile percentile = new Percentile();
471 @Override
472 public double evaluate(double[] values, int begin, int length) {
473 return percentile.evaluate(values, begin, length);
474 }
475 @Override
476 public double evaluate(double[] values) {
477 return percentile.evaluate(values);
478 }
479 @Override
480 public UnivariateStatistic copy() {
481 return new BadPercentile();
482 }
483 }
484 }