1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.stat;
18
19
20 import org.apache.commons.math4.legacy.TestUtils;
21 import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
22 import org.apache.commons.math4.legacy.exception.NullArgumentException;
23 import org.apache.commons.math4.legacy.stat.descriptive.DescriptiveStatistics;
24 import org.apache.commons.math4.core.jdkmath.JdkMath;
25 import org.apache.commons.numbers.core.Precision;
26 import org.junit.Assert;
27 import org.junit.Test;
28
29
30
31
32
33 public final class StatUtilsTest {
34
35 private static final double ONE = 1;
36 private static final float TWO = 2;
37 private static final int THREE = 3;
38 private static final double MEAN = 2;
39 private static final double SUMSQ = 18;
40 private static final double SUM = 8;
41 private static final double VAR = 0.666666666666666666667;
42 private static final double MIN = 1;
43 private static final double MAX = 3;
44 private static final double TOLERANCE = 10E-15;
45 private static final double NAN = Double.NaN;
46
47
48 @Test
49 public void testStats() {
50 double[] values = new double[] { ONE, TWO, TWO, THREE };
51 Assert.assertEquals("sum", SUM, StatUtils.sum(values), TOLERANCE);
52 Assert.assertEquals("sumsq", SUMSQ, StatUtils.sumSq(values), TOLERANCE);
53 Assert.assertEquals("var", VAR, StatUtils.variance(values), TOLERANCE);
54 Assert.assertEquals("var with mean", VAR, StatUtils.variance(values, MEAN), TOLERANCE);
55 Assert.assertEquals("mean", MEAN, StatUtils.mean(values), TOLERANCE);
56 Assert.assertEquals("min", MIN, StatUtils.min(values), TOLERANCE);
57 Assert.assertEquals("max", MAX, StatUtils.max(values), TOLERANCE);
58 }
59
60 @Test
61 public void testN0andN1Conditions() {
62 double[] values = new double[0];
63
64 Assert.assertTrue(
65 "Mean of n = 0 set should be NaN",
66 Double.isNaN(StatUtils.mean(values)));
67 Assert.assertTrue(
68 "Variance of n = 0 set should be NaN",
69 Double.isNaN(StatUtils.variance(values)));
70
71 values = new double[] { ONE };
72
73 Assert.assertEquals("Mean of n = 1 set should be value of single item n1", ONE, StatUtils.mean(values), 0.0);
74 Assert.assertEquals("Variance of n = 1 set should be zero", 0, StatUtils.variance(values), 0.0);
75 }
76
77 @Test
78 public void testArrayIndexConditions() {
79 double[] values = { 1.0, 2.0, 3.0, 4.0 };
80
81 Assert.assertEquals(
82 "Sum not expected",
83 5.0,
84 StatUtils.sum(values, 1, 2),
85 Double.MIN_VALUE);
86 Assert.assertEquals(
87 "Sum not expected",
88 3.0,
89 StatUtils.sum(values, 0, 2),
90 Double.MIN_VALUE);
91 Assert.assertEquals(
92 "Sum not expected",
93 7.0,
94 StatUtils.sum(values, 2, 2),
95 Double.MIN_VALUE);
96
97 try {
98 StatUtils.sum(values, 2, 3);
99 Assert.fail("Expected RuntimeException");
100 } catch (RuntimeException e) {
101
102 }
103
104 try {
105 StatUtils.sum(values, -1, 2);
106 Assert.fail("Expected RuntimeException");
107 } catch (RuntimeException e) {
108
109 }
110 }
111
112 @Test
113 public void testSumSq() {
114 double[] x = null;
115
116
117 try {
118 StatUtils.sumSq(x);
119 Assert.fail("null is not a valid data array.");
120 } catch (NullArgumentException ex) {
121
122 }
123
124 try {
125 StatUtils.sumSq(x, 0, 4);
126 Assert.fail("null is not a valid data array.");
127 } catch (NullArgumentException ex) {
128
129 }
130
131
132 x = new double[] {};
133 TestUtils.assertEquals(0, StatUtils.sumSq(x), TOLERANCE);
134 TestUtils.assertEquals(0, StatUtils.sumSq(x, 0, 0), TOLERANCE);
135
136
137 x = new double[] {TWO};
138 TestUtils.assertEquals(4, StatUtils.sumSq(x), TOLERANCE);
139 TestUtils.assertEquals(4, StatUtils.sumSq(x, 0, 1), TOLERANCE);
140
141
142 x = new double[] {ONE, TWO, TWO, THREE};
143 TestUtils.assertEquals(18, StatUtils.sumSq(x), TOLERANCE);
144 TestUtils.assertEquals(8, StatUtils.sumSq(x, 1, 2), TOLERANCE);
145 }
146
147 @Test
148 public void testProduct() {
149 double[] x = null;
150
151
152 try {
153 StatUtils.product(x);
154 Assert.fail("null is not a valid data array.");
155 } catch (NullArgumentException ex) {
156
157 }
158
159 try {
160 StatUtils.product(x, 0, 4);
161 Assert.fail("null is not a valid data array.");
162 } catch (NullArgumentException ex) {
163
164 }
165
166
167 x = new double[] {};
168 TestUtils.assertEquals(1, StatUtils.product(x), TOLERANCE);
169 TestUtils.assertEquals(1, StatUtils.product(x, 0, 0), TOLERANCE);
170
171
172 x = new double[] {TWO};
173 TestUtils.assertEquals(TWO, StatUtils.product(x), TOLERANCE);
174 TestUtils.assertEquals(TWO, StatUtils.product(x, 0, 1), TOLERANCE);
175
176
177 x = new double[] {ONE, TWO, TWO, THREE};
178 TestUtils.assertEquals(12, StatUtils.product(x), TOLERANCE);
179 TestUtils.assertEquals(4, StatUtils.product(x, 1, 2), TOLERANCE);
180 }
181
182 @Test
183 public void testSumLog() {
184 double[] x = null;
185
186
187 try {
188 StatUtils.sumLog(x);
189 Assert.fail("null is not a valid data array.");
190 } catch (NullArgumentException ex) {
191
192 }
193
194 try {
195 StatUtils.sumLog(x, 0, 4);
196 Assert.fail("null is not a valid data array.");
197 } catch (NullArgumentException ex) {
198
199 }
200
201
202 x = new double[] {};
203 TestUtils.assertEquals(0, StatUtils.sumLog(x), TOLERANCE);
204 TestUtils.assertEquals(0, StatUtils.sumLog(x, 0, 0), TOLERANCE);
205
206
207 x = new double[] {TWO};
208 TestUtils.assertEquals(JdkMath.log(TWO), StatUtils.sumLog(x), TOLERANCE);
209 TestUtils.assertEquals(JdkMath.log(TWO), StatUtils.sumLog(x, 0, 1), TOLERANCE);
210
211
212 x = new double[] {ONE, TWO, TWO, THREE};
213 TestUtils.assertEquals(JdkMath.log(ONE) + 2.0 * JdkMath.log(TWO) + JdkMath.log(THREE), StatUtils.sumLog(x), TOLERANCE);
214 TestUtils.assertEquals(2.0 * JdkMath.log(TWO), StatUtils.sumLog(x, 1, 2), TOLERANCE);
215 }
216
217 @Test
218 public void testMean() {
219 double[] x = null;
220
221 try {
222 StatUtils.mean(x, 0, 4);
223 Assert.fail("null is not a valid data array.");
224 } catch (NullArgumentException ex) {
225
226 }
227
228
229 x = new double[] {};
230 TestUtils.assertEquals(Double.NaN, StatUtils.mean(x, 0, 0), TOLERANCE);
231
232
233 x = new double[] {TWO};
234 TestUtils.assertEquals(TWO, StatUtils.mean(x, 0, 1), TOLERANCE);
235
236
237 x = new double[] {ONE, TWO, TWO, THREE};
238 TestUtils.assertEquals(2.5, StatUtils.mean(x, 2, 2), TOLERANCE);
239 }
240
241 @Test
242 public void testVariance() {
243 double[] x = null;
244
245 try {
246 StatUtils.variance(x, 0, 4);
247 Assert.fail("null is not a valid data array.");
248 } catch (NullArgumentException ex) {
249
250 }
251
252
253 x = new double[] {};
254 TestUtils.assertEquals(Double.NaN, StatUtils.variance(x, 0, 0), TOLERANCE);
255
256
257 x = new double[] {TWO};
258 TestUtils.assertEquals(0.0, StatUtils.variance(x, 0, 1), TOLERANCE);
259
260
261 x = new double[] {ONE, TWO, TWO, THREE};
262 TestUtils.assertEquals(0.5, StatUtils.variance(x, 2, 2), TOLERANCE);
263
264
265 x = new double[] {ONE, TWO, TWO, THREE};
266 TestUtils.assertEquals(0.5, StatUtils.variance(x,2.5, 2, 2), TOLERANCE);
267 }
268
269 @Test
270 public void testPopulationVariance() {
271 double[] x = null;
272
273 try {
274 StatUtils.variance(x, 0, 4);
275 Assert.fail("null is not a valid data array.");
276 } catch (NullArgumentException ex) {
277
278 }
279
280
281 x = new double[] {};
282 TestUtils.assertEquals(Double.NaN, StatUtils.populationVariance(x, 0, 0), TOLERANCE);
283
284
285 x = new double[] {TWO};
286 TestUtils.assertEquals(0.0, StatUtils.populationVariance(x, 0, 1), TOLERANCE);
287
288
289 x = new double[] {ONE, TWO, TWO, THREE};
290 TestUtils.assertEquals(0.25, StatUtils.populationVariance(x, 0, 2), TOLERANCE);
291
292
293 x = new double[] {ONE, TWO, TWO, THREE};
294 TestUtils.assertEquals(0.25, StatUtils.populationVariance(x, 2.5, 2, 2), TOLERANCE);
295 }
296
297
298 @Test
299 public void testMax() {
300 double[] x = null;
301
302 try {
303 StatUtils.max(x, 0, 4);
304 Assert.fail("null is not a valid data array.");
305 } catch (NullArgumentException ex) {
306
307 }
308
309
310 x = new double[] {};
311 TestUtils.assertEquals(Double.NaN, StatUtils.max(x, 0, 0), TOLERANCE);
312
313
314 x = new double[] {TWO};
315 TestUtils.assertEquals(TWO, StatUtils.max(x, 0, 1), TOLERANCE);
316
317
318 x = new double[] {ONE, TWO, TWO, THREE};
319 TestUtils.assertEquals(THREE, StatUtils.max(x, 1, 3), TOLERANCE);
320
321
322 x = new double[] {NAN, TWO, THREE};
323 TestUtils.assertEquals(THREE, StatUtils.max(x), TOLERANCE);
324
325
326 x = new double[] {ONE, NAN, THREE};
327 TestUtils.assertEquals(THREE, StatUtils.max(x), TOLERANCE);
328
329
330 x = new double[] {ONE, TWO, NAN};
331 TestUtils.assertEquals(TWO, StatUtils.max(x), TOLERANCE);
332
333
334 x = new double[] {NAN, NAN, NAN};
335 TestUtils.assertEquals(NAN, StatUtils.max(x), TOLERANCE);
336 }
337
338 @Test
339 public void testMin() {
340 double[] x = null;
341
342 try {
343 StatUtils.min(x, 0, 4);
344 Assert.fail("null is not a valid data array.");
345 } catch (NullArgumentException ex) {
346
347 }
348
349
350 x = new double[] {};
351 TestUtils.assertEquals(Double.NaN, StatUtils.min(x, 0, 0), TOLERANCE);
352
353
354 x = new double[] {TWO};
355 TestUtils.assertEquals(TWO, StatUtils.min(x, 0, 1), TOLERANCE);
356
357
358 x = new double[] {ONE, TWO, TWO, THREE};
359 TestUtils.assertEquals(TWO, StatUtils.min(x, 1, 3), TOLERANCE);
360
361
362 x = new double[] {NAN, TWO, THREE};
363 TestUtils.assertEquals(TWO, StatUtils.min(x), TOLERANCE);
364
365
366 x = new double[] {ONE, NAN, THREE};
367 TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
368
369
370 x = new double[] {ONE, TWO, NAN};
371 TestUtils.assertEquals(ONE, StatUtils.min(x), TOLERANCE);
372
373
374 x = new double[] {NAN, NAN, NAN};
375 TestUtils.assertEquals(NAN, StatUtils.min(x), TOLERANCE);
376 }
377
378 @Test
379 public void testPercentile() {
380 double[] x = null;
381
382
383 try {
384 StatUtils.percentile(x, .25);
385 Assert.fail("null is not a valid data array.");
386 } catch (NullArgumentException ex) {
387
388 }
389
390 try {
391 StatUtils.percentile(x, 0, 4, 0.25);
392 Assert.fail("null is not a valid data array.");
393 } catch (NullArgumentException ex) {
394
395 }
396
397
398 x = new double[] {};
399 TestUtils.assertEquals(Double.NaN, StatUtils.percentile(x, 25), TOLERANCE);
400 TestUtils.assertEquals(Double.NaN, StatUtils.percentile(x, 0, 0, 25), TOLERANCE);
401
402
403 x = new double[] {TWO};
404 TestUtils.assertEquals(TWO, StatUtils.percentile(x, 25), TOLERANCE);
405 TestUtils.assertEquals(TWO, StatUtils.percentile(x, 0, 1, 25), TOLERANCE);
406
407
408 x = new double[] {ONE, TWO, TWO, THREE};
409 TestUtils.assertEquals(2.5, StatUtils.percentile(x, 70), TOLERANCE);
410 TestUtils.assertEquals(2.5, StatUtils.percentile(x, 1, 3, 62.5), TOLERANCE);
411 }
412
413 @Test
414 public void testDifferenceStats() {
415 double sample1[] = {1d, 2d, 3d, 4d};
416 double sample2[] = {1d, 3d, 4d, 2d};
417 double diff[] = {0d, -1d, -1d, 2d};
418 double small[] = {1d, 4d};
419 double meanDifference = StatUtils.meanDifference(sample1, sample2);
420 Assert.assertEquals(StatUtils.sumDifference(sample1, sample2), StatUtils.sum(diff), TOLERANCE);
421 Assert.assertEquals(meanDifference, StatUtils.mean(diff), TOLERANCE);
422 Assert.assertEquals(StatUtils.varianceDifference(sample1, sample2, meanDifference),
423 StatUtils.variance(diff), TOLERANCE);
424 try {
425 StatUtils.meanDifference(sample1, small);
426 Assert.fail("Expecting MathIllegalArgumentException");
427 } catch (MathIllegalArgumentException ex) {
428
429 }
430 try {
431 StatUtils.varianceDifference(sample1, small, meanDifference);
432 Assert.fail("Expecting MathIllegalArgumentException");
433 } catch (MathIllegalArgumentException ex) {
434
435 }
436 try {
437 double[] single = {1.0};
438 StatUtils.varianceDifference(single, single, meanDifference);
439 Assert.fail("Expecting MathIllegalArgumentException");
440 } catch (MathIllegalArgumentException ex) {
441
442 }
443 }
444
445 @Test
446 public void testGeometricMean() {
447 double[] test = null;
448 try {
449 StatUtils.geometricMean(test);
450 Assert.fail("Expecting NullArgumentException");
451 } catch (NullArgumentException ex) {
452
453 }
454 test = new double[] {2, 4, 6, 8};
455 Assert.assertEquals(JdkMath.exp(0.25d * StatUtils.sumLog(test)),
456 StatUtils.geometricMean(test), Double.MIN_VALUE);
457 Assert.assertEquals(JdkMath.exp(0.5 * StatUtils.sumLog(test, 0, 2)),
458 StatUtils.geometricMean(test, 0, 2), Double.MIN_VALUE);
459 }
460
461
462
463
464
465
466 @Test
467 public void testNormalize1() {
468 double sample[] = { 50, 100 };
469 double expectedSample[] = { -25 / JdkMath.sqrt(1250), 25 / JdkMath.sqrt(1250) };
470 double[] out = StatUtils.normalize(sample);
471 for (int i = 0; i < out.length; i++) {
472 Assert.assertTrue(Precision.equals(out[i], expectedSample[i], 1));
473 }
474 }
475
476
477
478
479
480
481 @Test
482 public void testNormalize2() {
483
484 int length = 77;
485 double sample[] = new double[length];
486 for (int i = 0; i < length; i++) {
487 sample[i] = JdkMath.random();
488 }
489
490 double standardizedSample[] = StatUtils.normalize(sample);
491
492 DescriptiveStatistics stats = new DescriptiveStatistics();
493
494 for (int i = 0; i < length; i++) {
495 stats.addValue(standardizedSample[i]);
496 }
497
498 double distance = 1E-10;
499
500 Assert.assertEquals(0.0, stats.getMean(), distance);
501 Assert.assertEquals(1.0, stats.getStandardDeviation(), distance);
502 }
503
504 @Test
505 public void testMode() {
506 final double[] singleMode = {0, 1, 0, 2, 7, 11, 12};
507 final double[] modeSingle = StatUtils.mode(singleMode);
508 Assert.assertEquals(0, modeSingle[0], Double.MIN_VALUE);
509 Assert.assertEquals(1, modeSingle.length);
510
511 final double[] twoMode = {0, 1, 2, 0, 2, 3, 7, 11};
512 final double[] modeDouble = StatUtils.mode(twoMode);
513 Assert.assertEquals(0, modeDouble[0], Double.MIN_VALUE);
514 Assert.assertEquals(2, modeDouble[1], Double.MIN_VALUE);
515 Assert.assertEquals(2, modeDouble.length);
516
517 final double[] nanInfested = {0, 0, 0, Double.NaN, Double.NaN, Double.NaN, Double.NaN, 2, 2, 2, 3, 5};
518 final double[] modeNan = StatUtils.mode(nanInfested);
519 Assert.assertEquals(0, modeNan[0], Double.MIN_VALUE);
520 Assert.assertEquals(2, modeNan[1], Double.MIN_VALUE);
521 Assert.assertEquals(2, modeNan.length);
522
523 final double[] infInfested = {0, 0, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY,
524 Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, 2, 2, 3, 5};
525 final double[] modeInf = StatUtils.mode(infInfested);
526 Assert.assertEquals(Double.NEGATIVE_INFINITY, modeInf[0], Double.MIN_VALUE);
527 Assert.assertEquals(0, modeInf[1], Double.MIN_VALUE);
528 Assert.assertEquals(2, modeInf[2], Double.MIN_VALUE);
529 Assert.assertEquals(Double.POSITIVE_INFINITY, modeInf[3], Double.MIN_VALUE);
530 Assert.assertEquals(4, modeInf.length);
531
532 final double[] noData = {};
533 final double[] modeNodata = StatUtils.mode(noData);
534 Assert.assertEquals(0, modeNodata.length);
535
536 final double[] nansOnly = {Double.NaN, Double.NaN};
537 final double[] modeNansOnly = StatUtils.mode(nansOnly);
538 Assert.assertEquals(0, modeNansOnly.length);
539
540 final double[] nullArray = null;
541 try {
542 StatUtils.mode(nullArray);
543 Assert.fail("Expecting NullArgumentException");
544 } catch (NullArgumentException ex) {
545
546 }
547 }
548 }