From de4b97f096e38f78952b5f49de4ab4f141bc6ba5 Mon Sep 17 00:00:00 2001 From: Valentin Ochs Date: Sun, 9 Feb 2020 23:06:14 +0100 Subject: [PATCH] Sort & comment --- markov.hpp | 118 +++++++++++++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/markov.hpp b/markov.hpp index 8f6ad98..aadad13 100644 --- a/markov.hpp +++ b/markov.hpp @@ -63,60 +63,6 @@ public: return false; } - template - 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 - T gen_impl(IT iter, size_t size, Generator &g, - std::bool_constant) const { - auto child = children.find(*iter); - if (child == children.end()) { - return random_child(g); - } - - return child->second.gen(iter + 1, size - 1, g); - } - template - T gen_impl(IT iter, size_t size, Generator &g, - std::bool_constant) 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 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 model, given the previous sequence */ template 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 + 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 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 T random_child(Generator &g) const { std::uniform_int_distribution dist(0u, total - 1); auto val = dist(g); @@ -148,6 +128,31 @@ public: } 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 + T gen_impl(IT iter, size_t size, Generator &g, + std::bool_constant) const { + return random_child(g); + } + + /* Generate an item for longer chains, using the prefix */ + template + T gen_impl(IT iter, size_t size, Generator &g, + std::bool_constant) 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 */ @@ -159,15 +164,12 @@ public: constexpr size_t order() const { return 0; } template void add(IT, size_t) { total++; } - template bool dec(IT, size_t) { total--; return true; } - - template double probability(IT, size_t) const { return 1.; } - template double final_probability(IT, size_t) const { return 1.; } + template double probability(IT, size_t) const { return 1.; } };