#include <ebpps_sample.hpp>
#include <catch2/catch.hpp>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <cmath>
#include <random>
#include <stdexcept>
namespace datasketches {
static constexpr double EPS = 1e-15;
TEST_CASE("ebpps sample: basic initialization", "[ebpps_sketch]") {
ebpps_sample<int> sample = ebpps_sample<int>(0);
REQUIRE(sample.get_c() == 0.0);
REQUIRE(sample.get_num_retained_items() == 0);
REQUIRE(sample.get_sample().size() == 0);
}
TEST_CASE("ebpps sample: pre-initialized", "[ebpps_sketch]") {
double theta = 1.0;
ebpps_sample<int> sample(1);
sample.replace_content(-1, theta);
REQUIRE(sample.get_c() == theta);
REQUIRE(sample.get_num_retained_items() == 1);
REQUIRE(sample.get_sample().size() == 1);
REQUIRE(sample.has_partial_item() == false);
theta = 1e-300;
sample.replace_content(-1, theta);
REQUIRE(sample.get_c() == theta);
REQUIRE(sample.get_num_retained_items() == 1);
REQUIRE(sample.get_sample().size() == 0); REQUIRE(sample.has_partial_item());
}
TEST_CASE("ebpps sample: downsampling", "[ebpps_sketch]") {
ebpps_sample<char> sample(1);
sample.replace_content('a', 1.0);
sample.downsample(2.0); REQUIRE(sample.get_c() == 1.0);
REQUIRE(sample.get_num_retained_items() == 1);
REQUIRE(sample.has_partial_item() == false);
random_utils::override_seed(12);
std::vector<char> items = {'a', 'b'};
optional<char> opt; sample = ebpps_sample<char>(std::move(items), std::move(opt), 1.8);
sample.downsample(0.5);
REQUIRE(sample.get_c() == 0.9);
REQUIRE(sample.get_num_retained_items() == 0);
REQUIRE(sample.has_partial_item() == false);
items = {'a', 'b'};
opt.reset();
sample = ebpps_sample<char>(std::move(items), std::move(opt), 1.5);
sample.downsample(0.5);
REQUIRE(sample.get_c() == 0.75);
REQUIRE(sample.get_num_retained_items() == 1);
REQUIRE(sample.has_partial_item() == true);
for (char c : sample) {
REQUIRE((c == 'a' || c == 'b'));
}
items = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
opt.emplace('h');
auto ref_items = items; ref_items.emplace_back('h'); sample = ebpps_sample<char>(std::move(items), std::move(opt), 7.5);
sample.downsample(0.8);
REQUIRE(sample.get_c() == 6.0);
REQUIRE(sample.get_num_retained_items() == 6);
REQUIRE(sample.has_partial_item() == false);
for (char c : sample) {
REQUIRE(std::find(ref_items.begin(), ref_items.end(), c) != ref_items.end());
}
items = ref_items; opt.emplace('i');
sample = ebpps_sample<char>(std::move(items), std::move(opt), 8.5);
REQUIRE(sample.get_partial_item() == 'i');
sample.downsample(0.8);
REQUIRE(sample.get_c() == Approx(6.8).margin(EPS));
REQUIRE(sample.get_num_retained_items() == 7);
REQUIRE(sample.has_partial_item() == true);
ref_items.emplace_back('i');
for (char c : sample) {
REQUIRE(std::find(ref_items.begin(), ref_items.end(), c) != ref_items.end());
}
random_utils::override_seed(random_utils::rd());
}
TEST_CASE("ebpps sample: merge unit samples", "[ebpps_sketch]") {
uint32_t k = 8;
ebpps_sample<int> sample = ebpps_sample<int>(k);
ebpps_sample<int> s(1);
for (uint32_t i = 1; i <= k; ++i) {
s.replace_content(i, 1.0);
sample.merge(s);
REQUIRE(sample.get_c() == static_cast<double>(i));
REQUIRE(sample.get_num_retained_items() == i);
}
sample.reset();
REQUIRE(sample.get_c() == 0);
REQUIRE(sample.get_num_retained_items() == 0);
REQUIRE(sample.has_partial_item() == false);
}
}