| 95 | } |
| 96 | |
| 97 | void TestRandom(size_t size) { |
| 98 | const std::vector<double> fixed_quantiles = {0, 0.01, 0.1, 0.2, 0.5, 0.8, 0.9, 0.99, 1}; |
| 99 | |
| 100 | // append random quantiles to test |
| 101 | std::vector<double> quantiles; |
| 102 | random_real(50, 0x11223344, 0.0, 1.0, &quantiles); |
| 103 | quantiles.insert(quantiles.end(), fixed_quantiles.cbegin(), fixed_quantiles.cend()); |
| 104 | |
| 105 | // generate random test values |
| 106 | const double min = 1e3, max = 1e10; |
| 107 | std::vector<double> values; |
| 108 | random_real(size, 0x11223344, min, max, &values); |
| 109 | |
| 110 | TDigest td(200); |
| 111 | for (double value : values) { |
| 112 | td.Add(value); |
| 113 | } |
| 114 | ASSERT_OK(td.Validate()); |
| 115 | |
| 116 | const std::vector<double> expected = ExactQuantile(values, quantiles); |
| 117 | std::vector<double> approximated; |
| 118 | for (auto q : quantiles) { |
| 119 | approximated.push_back(td.Quantile(q)); |
| 120 | } |
| 121 | |
| 122 | // r-square of expected and approximated quantiles should be greater than 0.999 |
| 123 | const double expected_mean = |
| 124 | std::accumulate(expected.begin(), expected.end(), 0.0) / expected.size(); |
| 125 | double rss = 0, tss = 0; |
| 126 | for (size_t i = 0; i < quantiles.size(); ++i) { |
| 127 | rss += (expected[i] - approximated[i]) * (expected[i] - approximated[i]); |
| 128 | tss += (expected[i] - expected_mean) * (expected[i] - expected_mean); |
| 129 | } |
| 130 | const double r2 = 1 - rss / tss; |
| 131 | EXPECT_GT(r2, 0.999); |
| 132 | |
| 133 | // make sure no quantile drifts too much from the truth |
| 134 | #ifdef _TDIGEST_STRICT_TEST |
| 135 | const double error_ratio = 0.02; |
| 136 | #else |
| 137 | const double error_ratio = 0.05; |
| 138 | #endif |
| 139 | for (size_t i = 0; i < quantiles.size(); ++i) { |
| 140 | const double tolerance = std::fabs(expected[i]) * error_ratio; |
| 141 | EXPECT_NEAR(approximated[i], expected[i], tolerance) << quantiles[i]; |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | TEST(TDigestTest, RandomValues) { TestRandom(100000); } |
| 146 |
no test coverage detected