1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math.stat.descriptive;
18
19 import java.io.Serializable;
20
21 import org.apache.commons.math.MathRuntimeException;
22 import org.apache.commons.math.stat.descriptive.moment.GeometricMean;
23 import org.apache.commons.math.stat.descriptive.moment.Mean;
24 import org.apache.commons.math.stat.descriptive.moment.SecondMoment;
25 import org.apache.commons.math.stat.descriptive.moment.Variance;
26 import org.apache.commons.math.stat.descriptive.rank.Max;
27 import org.apache.commons.math.stat.descriptive.rank.Min;
28 import org.apache.commons.math.stat.descriptive.summary.Sum;
29 import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
30 import org.apache.commons.math.stat.descriptive.summary.SumOfSquares;
31 import org.apache.commons.math.util.MathUtils;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class SummaryStatistics implements StatisticalSummary, Serializable {
58
59
60 private static final long serialVersionUID = -2021321786743555871L;
61
62
63
64
65 public SummaryStatistics() {
66 }
67
68
69
70
71
72
73 public SummaryStatistics(SummaryStatistics original) {
74 copy(original, this);
75 }
76
77
78 protected long n = 0;
79
80
81 protected SecondMoment secondMoment = new SecondMoment();
82
83
84 protected Sum sum = new Sum();
85
86
87 protected SumOfSquares sumsq = new SumOfSquares();
88
89
90 protected Min min = new Min();
91
92
93 protected Max max = new Max();
94
95
96 protected SumOfLogs sumLog = new SumOfLogs();
97
98
99 protected GeometricMean geoMean = new GeometricMean(sumLog);
100
101
102 protected Mean mean = new Mean();
103
104
105 protected Variance variance = new Variance();
106
107
108 private StorelessUnivariateStatistic sumImpl = sum;
109
110
111 private StorelessUnivariateStatistic sumsqImpl = sumsq;
112
113
114 private StorelessUnivariateStatistic minImpl = min;
115
116
117 private StorelessUnivariateStatistic maxImpl = max;
118
119
120 private StorelessUnivariateStatistic sumLogImpl = sumLog;
121
122
123 private StorelessUnivariateStatistic geoMeanImpl = geoMean;
124
125
126 private StorelessUnivariateStatistic meanImpl = mean;
127
128
129 private StorelessUnivariateStatistic varianceImpl = variance;
130
131
132
133
134
135
136 public StatisticalSummary getSummary() {
137 return new StatisticalSummaryValues(getMean(), getVariance(), getN(),
138 getMax(), getMin(), getSum());
139 }
140
141
142
143
144
145 public void addValue(double value) {
146 sumImpl.increment(value);
147 sumsqImpl.increment(value);
148 minImpl.increment(value);
149 maxImpl.increment(value);
150 sumLogImpl.increment(value);
151 secondMoment.increment(value);
152
153
154 if (!(meanImpl instanceof Mean)) {
155 meanImpl.increment(value);
156 }
157 if (!(varianceImpl instanceof Variance)) {
158 varianceImpl.increment(value);
159 }
160 if (!(geoMeanImpl instanceof GeometricMean)) {
161 geoMeanImpl.increment(value);
162 }
163 n++;
164 }
165
166
167
168
169
170 public long getN() {
171 return n;
172 }
173
174
175
176
177
178 public double getSum() {
179 return sumImpl.getResult();
180 }
181
182
183
184
185
186
187
188
189 public double getSumsq() {
190 return sumsqImpl.getResult();
191 }
192
193
194
195
196
197
198
199
200 public double getMean() {
201 if (mean == meanImpl) {
202 return new Mean(secondMoment).getResult();
203 } else {
204 return meanImpl.getResult();
205 }
206 }
207
208
209
210
211
212
213
214
215 public double getStandardDeviation() {
216 double stdDev = Double.NaN;
217 if (getN() > 0) {
218 if (getN() > 1) {
219 stdDev = Math.sqrt(getVariance());
220 } else {
221 stdDev = 0.0;
222 }
223 }
224 return (stdDev);
225 }
226
227
228
229
230
231
232
233
234 public double getVariance() {
235 if (varianceImpl == variance) {
236 return new Variance(secondMoment).getResult();
237 } else {
238 return varianceImpl.getResult();
239 }
240 }
241
242
243
244
245
246
247
248
249 public double getMax() {
250 return maxImpl.getResult();
251 }
252
253
254
255
256
257
258
259
260 public double getMin() {
261 return minImpl.getResult();
262 }
263
264
265
266
267
268
269
270
271 public double getGeometricMean() {
272 return geoMeanImpl.getResult();
273 }
274
275
276
277
278
279
280
281
282
283 public double getSumOfLogs() {
284 return sumLogImpl.getResult();
285 }
286
287
288
289
290
291
292
293
294
295
296
297
298 public double getSecondMoment() {
299 return secondMoment.getResult();
300 }
301
302
303
304
305
306
307
308 @Override
309 public String toString() {
310 StringBuffer outBuffer = new StringBuffer();
311 String endl = "\n";
312 outBuffer.append("SummaryStatistics:").append(endl);
313 outBuffer.append("n: ").append(getN()).append(endl);
314 outBuffer.append("min: ").append(getMin()).append(endl);
315 outBuffer.append("max: ").append(getMax()).append(endl);
316 outBuffer.append("mean: ").append(getMean()).append(endl);
317 outBuffer.append("geometric mean: ").append(getGeometricMean())
318 .append(endl);
319 outBuffer.append("variance: ").append(getVariance()).append(endl);
320 outBuffer.append("sum of squares: ").append(getSumsq()).append(endl);
321 outBuffer.append("standard deviation: ").append(getStandardDeviation())
322 .append(endl);
323 outBuffer.append("sum of logs: ").append(getSumOfLogs()).append(endl);
324 return outBuffer.toString();
325 }
326
327
328
329
330 public void clear() {
331 this.n = 0;
332 minImpl.clear();
333 maxImpl.clear();
334 sumImpl.clear();
335 sumLogImpl.clear();
336 sumsqImpl.clear();
337 geoMeanImpl.clear();
338 secondMoment.clear();
339 if (meanImpl != mean) {
340 meanImpl.clear();
341 }
342 if (varianceImpl != variance) {
343 varianceImpl.clear();
344 }
345 }
346
347
348
349
350
351
352
353
354 @Override
355 public boolean equals(Object object) {
356 if (object == this) {
357 return true;
358 }
359 if (object instanceof SummaryStatistics == false) {
360 return false;
361 }
362 SummaryStatistics stat = (SummaryStatistics)object;
363 return (MathUtils.equals(stat.getGeometricMean(), this.getGeometricMean()) &&
364 MathUtils.equals(stat.getMax(), this.getMax()) &&
365 MathUtils.equals(stat.getMean(), this.getMean()) &&
366 MathUtils.equals(stat.getMin(), this.getMin()) &&
367 MathUtils.equals(stat.getN(), this.getN()) &&
368 MathUtils.equals(stat.getSum(), this.getSum()) &&
369 MathUtils.equals(stat.getSumsq(), this.getSumsq()) &&
370 MathUtils.equals(stat.getVariance(),
371 this.getVariance()));
372 }
373
374
375
376
377
378 @Override
379 public int hashCode() {
380 int result = 31 + MathUtils.hash(getGeometricMean());
381 result = result * 31 + MathUtils.hash(getGeometricMean());
382 result = result * 31 + MathUtils.hash(getMax());
383 result = result * 31 + MathUtils.hash(getMean());
384 result = result * 31 + MathUtils.hash(getMin());
385 result = result * 31 + MathUtils.hash(getN());
386 result = result * 31 + MathUtils.hash(getSum());
387 result = result * 31 + MathUtils.hash(getSumsq());
388 result = result * 31 + MathUtils.hash(getVariance());
389 return result;
390 }
391
392
393
394
395
396
397
398 public StorelessUnivariateStatistic getSumImpl() {
399 return sumImpl;
400 }
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 public void setSumImpl(StorelessUnivariateStatistic sumImpl) {
418 checkEmpty();
419 this.sumImpl = sumImpl;
420 }
421
422
423
424
425
426
427 public StorelessUnivariateStatistic getSumsqImpl() {
428 return sumsqImpl;
429 }
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446 public void setSumsqImpl(StorelessUnivariateStatistic sumsqImpl) {
447 checkEmpty();
448 this.sumsqImpl = sumsqImpl;
449 }
450
451
452
453
454
455
456 public StorelessUnivariateStatistic getMinImpl() {
457 return minImpl;
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475 public void setMinImpl(StorelessUnivariateStatistic minImpl) {
476 checkEmpty();
477 this.minImpl = minImpl;
478 }
479
480
481
482
483
484
485 public StorelessUnivariateStatistic getMaxImpl() {
486 return maxImpl;
487 }
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504 public void setMaxImpl(StorelessUnivariateStatistic maxImpl) {
505 checkEmpty();
506 this.maxImpl = maxImpl;
507 }
508
509
510
511
512
513
514 public StorelessUnivariateStatistic getSumLogImpl() {
515 return sumLogImpl;
516 }
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533 public void setSumLogImpl(StorelessUnivariateStatistic sumLogImpl) {
534 checkEmpty();
535 this.sumLogImpl = sumLogImpl;
536 geoMean.setSumLogImpl(sumLogImpl);
537 }
538
539
540
541
542
543
544 public StorelessUnivariateStatistic getGeoMeanImpl() {
545 return geoMeanImpl;
546 }
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563 public void setGeoMeanImpl(StorelessUnivariateStatistic geoMeanImpl) {
564 checkEmpty();
565 this.geoMeanImpl = geoMeanImpl;
566 }
567
568
569
570
571
572
573 public StorelessUnivariateStatistic getMeanImpl() {
574 return meanImpl;
575 }
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592 public void setMeanImpl(StorelessUnivariateStatistic meanImpl) {
593 checkEmpty();
594 this.meanImpl = meanImpl;
595 }
596
597
598
599
600
601
602 public StorelessUnivariateStatistic getVarianceImpl() {
603 return varianceImpl;
604 }
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621 public void setVarianceImpl(StorelessUnivariateStatistic varianceImpl) {
622 checkEmpty();
623 this.varianceImpl = varianceImpl;
624 }
625
626
627
628
629 private void checkEmpty() {
630 if (n > 0) {
631 throw MathRuntimeException.createIllegalStateException(
632 "{0} values have been added before statistic is configured",
633 n);
634 }
635 }
636
637
638
639
640
641
642 public SummaryStatistics copy() {
643 SummaryStatistics result = new SummaryStatistics();
644 copy(this, result);
645 return result;
646 }
647
648
649
650
651
652
653
654
655
656 public static void copy(SummaryStatistics source, SummaryStatistics dest) {
657 dest.maxImpl = source.maxImpl.copy();
658 dest.meanImpl = source.meanImpl.copy();
659 dest.minImpl = source.minImpl.copy();
660 dest.sumImpl = source.sumImpl.copy();
661 dest.varianceImpl = source.varianceImpl.copy();
662 dest.sumLogImpl = source.sumLogImpl.copy();
663 dest.sumsqImpl = source.sumsqImpl.copy();
664 if (source.getGeoMeanImpl() instanceof GeometricMean) {
665
666 dest.geoMeanImpl = new GeometricMean((SumOfLogs) dest.sumLogImpl);
667 } else {
668 dest.geoMeanImpl = source.geoMeanImpl.copy();
669 }
670 SecondMoment.copy(source.secondMoment, dest.secondMoment);
671 dest.n = source.n;
672
673
674
675 if (source.geoMean == source.geoMeanImpl) {
676 dest.geoMean = (GeometricMean) dest.geoMeanImpl;
677 } else {
678 GeometricMean.copy(source.geoMean, dest.geoMean);
679 }
680 if (source.max == source.maxImpl) {
681 dest.max = (Max) dest.maxImpl;
682 } else {
683 Max.copy(source.max, dest.max);
684 }
685 if (source.mean == source.meanImpl) {
686 dest.mean = (Mean) dest.meanImpl;
687 } else {
688 Mean.copy(source.mean, dest.mean);
689 }
690 if (source.min == source.minImpl) {
691 dest.min = (Min) dest.minImpl;
692 } else {
693 Min.copy(source.min, dest.min);
694 }
695 if (source.sum == source.sumImpl) {
696 dest.sum = (Sum) dest.sumImpl;
697 } else {
698 Sum.copy(source.sum, dest.sum);
699 }
700 if (source.variance == source.varianceImpl) {
701 dest.variance = (Variance) dest.varianceImpl;
702 } else {
703 Variance.copy(source.variance, dest.variance);
704 }
705 if (source.sumLog == source.sumLogImpl) {
706 dest.sumLog = (SumOfLogs) dest.sumLogImpl;
707 } else {
708 SumOfLogs.copy(source.sumLog, dest.sumLog);
709 }
710 if (source.sumsq == source.sumsqImpl) {
711 dest.sumsq = (SumOfSquares) dest.sumsqImpl;
712 } else {
713 SumOfSquares.copy(source.sumsq, dest.sumsq);
714 }
715 }
716 }