2
* Copyright (C) 2012 10gen Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU Affero General Public License, version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Affero General Public License for more details.
13
* You should have received a copy of the GNU Affero General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
* Tests for mongo/util/descriptive_stats.h
26
#include "mongo/unittest/unittest.h"
27
#include "mongo/util/descriptive_stats.h"
33
const size_t NumQuantiles = 99;
35
TEST(DistributionEstimators, TestNominalResults) {
36
mongo::DistributionEstimators<NumQuantiles> d;
38
for (int i = 0; i < 100000; i++) {
39
d << double(i) / 100000;
41
ASSERT_TRUE(d.quantilesReady());
42
for (size_t quant = 1; quant <= NumQuantiles; ++quant) {
43
ASSERT_EQUALS(d.probability(quant), double(quant) / 100);
44
ASSERT_APPROX_EQUAL(d.quantile(quant), double(quant) / 100, 0.05);
45
double prob = double(quant) / 100;
46
ASSERT_APPROX_EQUAL(d.icdf(prob), prob, 0.05);
48
ASSERT_APPROX_EQUAL(d.min(), 0.0, 0.05);
49
ASSERT_APPROX_EQUAL(d.max(), 1.0, 0.05);
50
ASSERT_APPROX_EQUAL(d.median(), 0.5, 0.05);
53
TEST(DistributionEstimators, TestAppendQuantilesToBSONArrayBuilder) {
54
mongo::DistributionEstimators<NumQuantiles> d;
56
for (int i = 0; i < 10000; i++) {
57
d << static_cast<double>(i) / 10000;
60
mongo::BSONArrayBuilder arrayBuilder;
61
d.appendQuantilesToBSONArrayBuilder(arrayBuilder);
62
mongo::BSONArray arr = arrayBuilder.arr();
64
for (size_t i = 0; i <= NumQuantiles + 1; i++) {
65
ASSERT_EQUALS(arr[i].Number(), d.quantile(i));
69
TEST(BasicEstimators, TestNominalResults) {
70
mongo::BasicEstimators<unsigned int> d;
72
unsigned int count = 0;
73
// [50, 51, 52, ..., 99949, 99950]
74
for (int i = 50; i <= 100000 - 50; i++) {
78
ASSERT_EQUALS(d.min(), 50u);
79
ASSERT_EQUALS(d.max(), 100000u - 50u);
80
ASSERT_APPROX_EQUAL(d.mean(), 100000 / 2, 1e-15);
81
ASSERT_APPROX_EQUAL(d.stddev(), sqrt((static_cast<double>(count) * count - 1) / 12), 1e-15);
84
TEST(BasicEstimators, TestAppendBasicToBSONObjBuilder) {
85
mongo::BasicEstimators<unsigned int> b;
87
for (int i = 0; i < 10000; i++) {
91
mongo::BSONObjBuilder builder;
92
b.appendBasicToBSONObjBuilder(builder);
93
mongo::BSONObj obj = builder.obj();
95
ASSERT_EQUALS(obj["count"].Number(), b.count());
96
ASSERT_EQUALS(obj["mean"].Number(), b.mean());
97
ASSERT_EQUALS(obj["stddev"].Number(), b.stddev());
98
ASSERT_EQUALS(obj["min"].Number(), b.min());
99
ASSERT_EQUALS(obj["max"].Number(), b.max());
102
TEST(SummaryEstimators, TestNominalResults) {
103
mongo::SummaryEstimators<int, NumQuantiles> d;
105
for (int a = -200; a <= 200; a++) {
108
ASSERT_TRUE(d.quantilesReady());
109
for (size_t i = 0; i < d.numberOfQuantiles; i++) {
110
ASSERT_APPROX_EQUAL(d.quantile(i), -200 + static_cast<int>(i) * 4, 1);
112
ASSERT_EQUALS(d.min(), -200);
113
ASSERT_EQUALS(d.max(), 200);
114
ASSERT_APPROX_EQUAL(d.mean(), 0, 1e-15);
115
ASSERT_APPROX_EQUAL(d.icdf(.25), -100, 1e-15);
118
TEST(SummaryEstimators, TestStatisticSummaryToBSONObj) {
119
mongo::SummaryEstimators<double, NumQuantiles> e;
121
for (int i = 0; i < 10000; i++) {
122
e << static_cast<double>(i) / 100;
124
verify(e.quantilesReady());
126
mongo::BSONObj obj = e.statisticSummaryToBSONObj();
128
ASSERT_EQUALS(obj["count"].Number(), e.count());
129
ASSERT_EQUALS(obj["mean"].Number(), e.mean());
130
ASSERT_EQUALS(obj["stddev"].Number(), e.stddev());
131
ASSERT_EQUALS(obj["min"].Number(), e.min());
132
ASSERT_EQUALS(obj["max"].Number(), e.max());
134
mongo::BSONObj quantiles = obj["quantiles"].Obj();
135
ASSERT_EQUALS(static_cast<size_t>(quantiles.nFields()), NumQuantiles);
136
for (mongo::BSONObjIterator it = quantiles.begin(); it.more(); ++it) {
137
ASSERT_EQUALS((*it).Number(), e.icdf(atof((*it).fieldName())));