Sort & comment

This commit is contained in:
Lynn Ochs 2020-02-09 23:06:14 +01:00
parent 87b239a53c
commit de4b97f096

View File

@ -63,60 +63,6 @@ public:
return false; return false;
} }
template <typename IT, typename Generator>
T gen(IT iter, size_t size, Generator &g) const {
while (size > order()) {
iter++;
size--;
}
if (size == 0) {
return random_child(g);
}
return gen_impl(iter, size, g, std::bool_constant<(ORDER > 0)>{});
}
protected:
template <typename IT, typename Generator>
T gen_impl(IT iter, size_t size, Generator &g,
std::bool_constant<true>) const {
auto child = children.find(*iter);
if (child == children.end()) {
return random_child(g);
}
return child->second.gen(iter + 1, size - 1, g);
}
template <typename IT, typename Generator>
T gen_impl(IT iter, size_t size, Generator &g,
std::bool_constant<false>) const {
return random_child(g);
}
/* Finds the key or adds it */
typename Children::iterator find(const T &key) {
return children.try_emplace(key).first;
}
public:
/* Probability of finding the first order() items (but at most size) in the
sequence */
template <typename IT> double probability(IT iter, size_t size) const {
if (size == 0) {
return 1.;
}
auto child = children.find(*iter);
if (child != children.cend()) {
auto &val = child->second;
return (double(val.total) / double(total)) *
val.probability(iter + 1, size - 1);
} else {
return 0.5 / double(total);
}
}
/* Probability of finding the last item (but at most the order+1st) in the /* Probability of finding the last item (but at most the order+1st) in the
model, given the previous sequence */ model, given the previous sequence */
template <typename IT> double final_probability(IT iter, size_t size) const { template <typename IT> double final_probability(IT iter, size_t size) const {
@ -136,6 +82,40 @@ public:
} }
} }
/* Generate one single item that can appear after the prefix given by iter and
size, using the RNG g */
template <typename IT, typename Generator>
T gen(IT iter, size_t size, Generator &g) const {
while (size > order()) {
iter++;
size--;
}
if (size == 0) {
return random_child(g);
}
return gen_impl(iter, size, g, std::bool_constant<(ORDER > 0)>{});
}
/* Probability of finding the first order() items (but at most size) in the
sequence */
template <typename IT> double probability(IT iter, size_t size) const {
if (size == 0) {
return 1.;
}
auto child = children.find(*iter);
if (child != children.cend()) {
auto &val = child->second;
return (double(val.total) / double(total)) *
val.probability(iter + 1, size - 1);
} else {
return 0.5 / double(total);
}
}
/* Returns a random item, weighted by the probability of child nodes */
template <typename Generator> T random_child(Generator &g) const { template <typename Generator> T random_child(Generator &g) const {
std::uniform_int_distribution<size_t> dist(0u, total - 1); std::uniform_int_distribution<size_t> dist(0u, total - 1);
auto val = dist(g); auto val = dist(g);
@ -148,6 +128,31 @@ public:
} }
return T{}; return T{};
} }
protected:
/* Finds the key or adds it */
typename Children::iterator find(const T &key) {
return children.try_emplace(key).first;
}
/* Generate an item for Markov chains of order 0 */
template <typename IT, typename Generator>
T gen_impl(IT iter, size_t size, Generator &g,
std::bool_constant<false>) const {
return random_child(g);
}
/* Generate an item for longer chains, using the prefix */
template <typename IT, typename Generator>
T gen_impl(IT iter, size_t size, Generator &g,
std::bool_constant<true>) const {
auto child = children.find(*iter);
if (child == children.end()) {
return random_child(g);
}
return child->second.gen(iter + 1, size - 1, g);
}
}; };
/* Leaf of the recursion with just a count */ /* Leaf of the recursion with just a count */
@ -159,15 +164,12 @@ public:
constexpr size_t order() const { return 0; } constexpr size_t order() const { return 0; }
template <typename IT> void add(IT, size_t) { total++; } template <typename IT> void add(IT, size_t) { total++; }
template <typename IT> bool dec(IT, size_t) { template <typename IT> bool dec(IT, size_t) {
total--; total--;
return true; return true;
} }
template <typename IT> double probability(IT, size_t) const { return 1.; }
template <typename IT> double final_probability(IT, size_t) const { template <typename IT> double final_probability(IT, size_t) const {
return 1.; return 1.;
} }
template <typename IT> double probability(IT, size_t) const { return 1.; }
}; };