Euphoria
markov.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "base/random.h"
4 #include "assert/assert.h"
5 
6 
7 #include <map>
8 #include <deque>
9 #include <memory>
10 
12 {
13  template <typename T>
14  struct Some
15  {
16  std::deque<T> value;
17  size_t max;
18 
19  explicit Some(size_t m) : max(m) {}
20 
21  void
22  add(T t)
23  {
24  if(value.size() == max)
25  {
26  value.pop_front();
27  }
28  ASSERTX(value.size() < max, max, value.size());
29  value.push_back(t);
30  }
31  };
32 
33  template <typename T>
34  struct Probability
35  {
36  std::map<T, float> data;
37 
38  T
39  get(Random* rnd) const
40  {
41  float value = rnd->get_next_float01();
42  for(auto it: data)
43  {
44  if(value <= it.second)
45  {
46  return it.first;
47  }
48  value -= it.second;
49  }
50 
51  return data.rbegin()->first;
52  }
53  };
54 
55  template <typename T>
57  {
58  int total = 0;
59  std::map<T, int> data;
60 
61  void
62  add(const T& t)
63  {
64  total += 1;
65 
66  auto r = data.find(t);
67  if(r == data.end())
68  {
69  data[t] = 1;
70  }
71  else
72  {
73  data[t] = r->second + 1;
74  }
75  }
76 
78  build() const
79  {
81  for(auto it: data)
82  {
83  r.data[it.first] = it.second / static_cast<float>(total);
84  }
85  return r;
86  }
87  };
88 
89  template <typename T>
90  struct Chain
91  {
92  std::map<std::deque<T>, Probability<std::shared_ptr<T>>> next;
93  size_t order;
94 
95  std::vector<T>
96  generate(Random* rnd) const
97  {
98  std::vector<T> r;
99  Some<T> memory {order};
100  while(true)
101  {
102  auto found = next.find(memory.value);
103  ASSERT(found != next.end());
104  auto n = found->second.get(rnd);
105  if(n == nullptr)
106  {
107  return r;
108  }
109 
110  r.emplace_back(*n);
111  memory.add(*n);
112  }
113  }
114  };
115 
116  template <typename T>
118  {
119  std::map<std::deque<T>, ProbabilityBuilder<std::shared_ptr<T>>> next;
120  size_t order;
121 
122  ChainBuilder(int o) : order(o) {}
123 
124  void
125  add(const std::vector<T>& ts)
126  {
127  ASSERT(!ts.empty());
128  Some<T> memory {order};
129 
130  for(const auto& t: ts)
131  {
132  next[memory.value].add(std::make_shared<T>(t));
133 
134  memory.add(t);
135  }
136 
137  next[memory.value].add(nullptr);
138  }
139 
140  Chain<T>
141  build() const
142  {
143  Chain<T> r;
144  r.order = order;
145  for(auto n: next)
146  {
147  r.next[n.first] = n.second.build();
148  }
149  return r;
150  }
151  };
152 
153 }
#define ASSERTX(x,...)
Definition: assert.h:48
#define ASSERT(x)
Definition: assert.h:29
WEL512 Random Number Generator.
Definition: random.h:21
float get_next_float01()
Definition: random.cc:78
std::map< std::deque< T >, ProbabilityBuilder< std::shared_ptr< T > > > next
Definition: markov.h:119
Chain< T > build() const
Definition: markov.h:141
void add(const std::vector< T > &ts)
Definition: markov.h:125
std::map< std::deque< T >, Probability< std::shared_ptr< T > > > next
Definition: markov.h:92
std::vector< T > generate(Random *rnd) const
Definition: markov.h:96
Probability< T > build() const
Definition: markov.h:78
T get(Random *rnd) const
Definition: markov.h:39
std::map< T, float > data
Definition: markov.h:36
Some(size_t m)
Definition: markov.h:19
std::deque< T > value
Definition: markov.h:16