24 using namespace folly;
37 std::vector<double>
values;
38 for (
int i = 1;
i <= 100; ++
i) {
42 digest = digest.
merge(values);
60 std::vector<double>
values;
61 for (
int i = 1;
i <= 100; ++
i) {
64 digest = digest.
merge(values);
67 for (
int i = 101;
i <= 200; ++
i) {
70 digest = digest.
merge(values);
88 std::vector<double>
values;
91 digest = digest.
merge(values);
109 std::vector<double>
values;
110 for (
int i = 1;
i <= 1000; ++
i) {
113 digest = digest.
merge(values);
129 std::vector<TDigest> digests;
132 std::vector<double>
values;
133 for (
int i = 1;
i <= 1000; ++
i) {
138 values.begin(), values.end(), std::mt19937(std::random_device()()));
139 for (
int i = 0;
i < 10; ++
i) {
140 std::vector<double> unsorted_values(
141 values.begin() + (
i * 100), values.begin() + (
i + 1) * 100);
142 digests.push_back(digest.
merge(unsorted_values));
160 std::vector<TDigest> digests;
163 std::vector<double>
values;
164 for (
int i = 1;
i <= 100; ++
i) {
166 values.push_back(-
i);
169 digest = digest.
merge(values);
186 std::vector<TDigest> digests;
189 std::vector<double>
values;
190 std::vector<double> negativeValues;
191 for (
int i = 1;
i <= 100; ++
i) {
193 negativeValues.push_back(-
i);
196 auto digest1 = digest.
merge(values);
197 auto digest2 = digest.
merge(negativeValues);
199 std::array<TDigest, 2>
a{{digest1, digest2}};
218 std::vector<TDigest::Centroid> centroids{};
221 std::vector<double>
values;
222 for (
int i = 1;
i <= 100; ++
i) {
225 auto digest1 = digest.
merge(values);
230 digest1.getCentroids(),
238 EXPECT_EQ(digest1.count(), digest2.count());
241 EXPECT_EQ(digest1.getCentroids().size(), digest2.getCentroids().size());
244 digest1.getCentroids(),
251 EXPECT_EQ(digest1.count(), digest3.count());
254 EXPECT_NE(digest1.getCentroids().size(), digest3.getCentroids().size());
260 std::vector<double>
values;
261 for (
double i = 0;
i < 19; ++
i) {
264 values.push_back(1000000);
266 std::sort(values.begin(), values.end());
267 digest = digest.
merge(values);
269 (
int64_t)digest.estimateQuantile(0.5),
270 (
int64_t)digest.estimateQuantile(0.90));
279 std::vector<double> values1;
280 for (
int i = 1;
i <= 100; ++
i) {
281 values1.push_back(val);
283 digest1 = digest1.
merge(values1);
286 std::vector<double> values2;
287 for (
int i = 1;
i <= 100; ++
i) {
288 values2.push_back(val);
290 digest2 = digest2.
merge(values2);
292 std::array<TDigest, 2>
a{{digest1, digest2}};
296 std::vector<double> values3;
297 for (
int i = 1;
i <= 100; ++
i) {
298 values3.push_back(val);
300 digest3 = digest2.
merge(values3);
301 std::array<TDigest, 2>
b{{digest3, mergeDigest1}};
304 auto centroids = mergeDigest2.getCentroids();
305 EXPECT_EQ(std::is_sorted(centroids.begin(), centroids.end()),
true);
309 :
public ::testing::TestWithParam<
310 std::tuple<std::pair<bool, size_t>, double, bool>> {};
313 std::pair<bool, size_t> underlyingDistribution;
317 double reasonableError = 0;
320 std::tie(underlyingDistribution, quantile, digestMerge) = GetParam();
322 std::tie(logarithmic, modes) = underlyingDistribution;
323 if (quantile == 0.001 || quantile == 0.999) {
324 reasonableError = 0.001;
325 }
else if (quantile == 0.01 || quantile == 0.99) {
326 reasonableError = 0.01;
327 }
else if (quantile == 0.25 || quantile == 0.5 || quantile == 0.75) {
328 reasonableError = 0.04;
331 std::vector<double> errors;
334 generator.seed(
kSeed);
338 std::vector<double>
values;
341 std::lognormal_distribution<double> distribution(0.0, 1.0);
344 auto mode = (int)distribution(generator) % modes;
345 values.push_back(distribution(generator) + 100.0 *
mode);
348 std::uniform_int_distribution<int> distributionPicker(0, modes - 1);
350 std::vector<std::normal_distribution<double>> distributions;
351 for (
size_t i = 0;
i < modes; ++
i) {
352 distributions.emplace_back(100.0 * (
i + 1), 25);
356 auto distributionIdx = distributionPicker(generator);
357 values.push_back(distributions[distributionIdx](generator));
361 std::vector<TDigest> digests;
365 digests.push_back(digest.
merge(r));
367 digest = digest.
merge(r);
371 std::sort(values.begin(), values.end());
378 auto it = std::lower_bound(values.begin(), values.end(), est);
379 int32_t actualRank = std::distance(values.begin(), it);
380 double actualQuantile = ((double)actualRank) /
kNumSamples;
381 errors.push_back(actualQuantile - quantile);
386 for (
auto error : errors) {
392 double numerator = 0.0;
393 for (
auto error : errors) {
394 numerator += pow(
error - mean, 2);
397 double stddev = std::sqrt(numerator / (kNumRandomRuns - 1));
407 std::make_pair(
true, 1),
408 std::make_pair(
true, 3),
409 std::make_pair(
false, 1),
410 std::make_pair(
false, 10)),
411 ::testing::Values(0.001, 0.01, 0.25, 0.50, 0.75, 0.99, 0.999),
std::atomic< int64_t > sum(0)
const int32_t kNumRandomRuns
INSTANTIATE_TEST_CASE_P(ReasonableErrors, DistributionTest,::testing::Combine(::testing::Values(std::make_pair(true, 1), std::make_pair(true, 3), std::make_pair(false, 1), std::make_pair(false, 10)),::testing::Values(0.001, 0.01, 0.25, 0.50, 0.75, 0.99, 0.999),::testing::Bool()))
std::default_random_engine generator
#define EXPECT_EQ(val1, val2)
const std::vector< Centroid > & getCentroids() const
const int32_t kNumSamples
double estimateQuantile(double q) const
—— Concurrent Priority Queue Implementation ——
#define EXPECT_GE(val1, val2)
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
folly::Optional< PskKeyExchangeMode > mode
TEST_P(DistributionTest, ReasonableError)
TDigest merge(presorted_t, Range< const double * > sortedValues) const
#define EXPECT_NE(val1, val2)
#define EXPECT_LT(val1, val2)
TEST(SequencedExecutor, CPUThreadPoolExecutor)
std::vector< int > values(1'000)