FactorOracle2.hpp
1 #pragma once
2 #include <Engine/Node/SimpleApi.hpp>
3 
4 #include <ossia/detail/hash_map.hpp>
5 #include <ossia/detail/math.hpp>
6 #include <ossia/detail/ssize.hpp>
7 
8 #include <random>
9 //#if !defined(NDEBUG) && !defined(_MSC_VER) && !defined(__clang__)
10 //#include <debug/vector>
11 //#define debug_vector_t __gnu_debug::vector
12 //#else
13 #define debug_vector_t std::vector
14 //#endif
15 
53 namespace Factor
54 {
57 template <class T>
59 {
60 public:
63  T symbol_;
64 };
65 
72 template <class T>
73 class State
74 {
75 public:
76  int state_;
77  std::vector<SingleTransition<T>> transition_;
78  int suffix_transition_;
79  int lrs_ = 0;
80  void singleTransitionResize() { transition_.resize(10); }
81 };
82 
83 template <class T>
85 {
86 public:
87  int phi = 0, k = 0, fo_iter = 0, current_state = 1;
88  std::vector<T> input_values;
89  std::vector<State<T>> states_;
90  std::vector<std::vector<int>>
93  {
94  this->states_.resize(2);
95  this->states_[0].state_ = 0;
96  this->states_[0].lrs_ = 0;
97  this->states_[0].suffix_transition_ = -1;
98  this->RevSuffix.resize(2);
99  }
100  void AddLetter(int i, const std::vector<T> word)
101  {
103 
107  if(i != 0)
108  {
109  this->states_.resize(i + 1);
110  this->RevSuffix.resize(i + 1);
111  T alpha = word[i - 1];
112  this->AddState(i - 1);
113  int state_m_plus_one = i;
114  this->AddTransition(i - 1, i, alpha);
115  k = this->states_[i - 1].suffix_transition_;
116  phi = i - 1;
117  int flag = 0, iter = 0;
124  while(k > -1 && flag == 0)
125  {
126  while(iter < std::ssize(this->states_[k].transition_))
127  {
128  if(this->states_[k].transition_[iter].symbol_ == alpha)
129  {
130  flag = 1;
131  }
132  iter++;
133  }
134  if(flag == 0)
135  {
136  this->AddTransition(k, state_m_plus_one, alpha);
137  phi = k;
138  k = this->states_[k].suffix_transition_;
139  iter = 0;
140  }
141  }
142  if(k == -1)
143  {
144  this->states_[state_m_plus_one].suffix_transition_ = 0;
145  this->states_[state_m_plus_one].lrs_ = 0;
146  }
147  else
148  {
149  flag = 0, iter = 0;
150  if(this->states_[k].transition_[iter].symbol_ == alpha)
151  {
152  flag = 1;
153  this->states_[state_m_plus_one].suffix_transition_
154  = this->states_[k].transition_[iter].last_state_;
155  this->states_[state_m_plus_one].lrs_
156  = this->LengthCommonSuffix(
157  phi, this->states_[state_m_plus_one].suffix_transition_ - 1)
158  + 1;
159  }
160  while(iter < this->states_[k].transition_.size() && flag == 0)
161  {
162  if(this->states_[k].transition_[iter].symbol_ == alpha)
163  {
164 
165  this->states_[state_m_plus_one].suffix_transition_
166  = this->states_[k].transition_[iter].last_state_;
167  this->states_[state_m_plus_one].lrs_
168  = this->LengthCommonSuffix(
169  phi, this->states_[state_m_plus_one].suffix_transition_ - 1)
170  + 1;
171  flag = 1;
172  }
173 
174  iter++;
175  }
176  }
177  T temp_word = word[state_m_plus_one - this->states_[state_m_plus_one].lrs_ - 1];
178  k = this->FindBetter(state_m_plus_one, temp_word, word);
179  if(k != 0)
180  {
181  this->states_[state_m_plus_one].lrs_ = this->states_[state_m_plus_one].lrs_ + 1;
182  this->states_[state_m_plus_one].suffix_transition_ = k;
183  }
184  RevSuffix[this->states_[state_m_plus_one].suffix_transition_].push_back(
185  std::move(state_m_plus_one));
186  }
187  };
188  int LengthCommonSuffix(int phi_one, int phi_two)
189  {
190  if(phi_two == this->states_[phi_one].suffix_transition_)
191  return this->states_[phi_one].lrs_;
192  else
193  {
194  while(this->states_[phi_one].suffix_transition_
195  != this->states_[phi_two].suffix_transition_)
196  phi_two = this->states_[phi_two].suffix_transition_;
197  }
198  if(this->states_[phi_one].lrs_ <= this->states_[phi_two].lrs_)
199  return this->states_[phi_one].lrs_;
200  else
201  return this->states_[phi_two].lrs_;
202  };
203  int FindBetter(int i, T alpha, const std::vector<T> word)
204  {
206 
213  int len_t = this->RevSuffix[this->states_[i].suffix_transition_].size();
214  int state_i = this->states_[i].suffix_transition_;
215  if(len_t == 0)
216  return 0;
217  sort(this->RevSuffix[state_i].begin(), this->RevSuffix[state_i].end());
218  for(int j = 0; j < len_t; j++)
219  {
220  if(this->states_[this->RevSuffix[this->states_[i].suffix_transition_][j]].lrs_
221  == this->states_[i].lrs_
222  && word
223  [this->RevSuffix[this->states_[i].suffix_transition_][j]
224  - this->states_[i].lrs_ - 1]
225  == alpha)
226  {
227  int out = RevSuffix[this->states_[i].suffix_transition_][j];
228  return out;
229  }
230  }
231  return 0;
232  };
233  std::vector<T> FOGenerate(int& i, std::vector<T> v, float q)
234  {
236 
242  std::random_device rd;
243  std::mt19937 gen(rd());
244  std::uniform_real_distribution<> dis(0.0, 1.0);
245  float u = dis(gen);
246 
247  if(this->states_.size() == 2 || this->states_.size() == 1)
248  {
249  v.push_back(this->states_[0].transition_[0].symbol_);
250  }
251  else
252  {
253  if(u < q)
254  {
255  i = i + 1;
256  int len = this->states_.size();
257  if(i >= len)
258  i = len - 1;
259  T w = this->states_[i].transition_[0].symbol_;
260  v.push_back(std::move(w));
261  }
262  else
263  {
264  int lenSuffix
265  = this->states_[this->states_[i].suffix_transition_].transition_.size() - 1;
266  std::random_device rd;
267  std::mt19937 gen(rd());
268  std::uniform_int_distribution<> dis_int(0, lenSuffix);
269  int rand_alpha = dis_int(gen);
270  T alpha = this->states_[this->states_[i].suffix_transition_]
271  .transition_[rand_alpha]
272  .symbol_;
273  i = this->states_[this->states_[i].suffix_transition_]
274  .transition_[rand_alpha]
275  .last_state_;
276  if(i == -1)
277  {
278  i = 0;
279  }
280  v.push_back(std::move(alpha));
281  }
282  }
283  return v;
284  };
285  void FactorOracleStart(const std::vector<T> word)
286  {
288 
291  int len = std::ssize(word);
292  this->states_.resize(2);
293  this->states_[0].state_ = 0;
294  this->states_[0].lrs_ = 0;
295  this->states_[0].suffix_transition_ = -1;
296  this->RevSuffix.resize(2);
297  };
298  void AddState(int first_state) { this->states_[first_state].state_ = first_state; };
299  void AddTransition(int first_state, int last_state, T symbol)
300  {
301  SingleTransition<T> transition_i;
302  transition_i.first_state_ = first_state;
303  transition_i.last_state_ = last_state;
304  transition_i.symbol_ = std::move(symbol);
305  this->states_[first_state].transition_.push_back(std::move(transition_i));
306  };
307  std::vector<T> CallGenerate(int len, float q)
308  {
309 
310  std::vector<T> oracle = {};
311  fo_iter = 1;
312  for(int x = 0; x < len; x++)
313  {
314  oracle = this->FOGenerate(fo_iter, oracle, q);
315  if(fo_iter == len)
316  fo_iter = len - 1;
317  }
318  return oracle;
319  };
320 };
321 }
322 namespace Nodes::FactorOracle2
323 {
324 struct Node
325 {
327  {
328  static const constexpr auto prettyName = "New Factor Oracle";
329  static const constexpr auto objectKey = "New Factor Oracle";
330  static const constexpr auto category = "Control/Impro";
331  static const constexpr auto author = "Maria Paula Carrero Rivas";
332  static const constexpr auto kind = Process::ProcessCategory::Mapping;
333  static const constexpr auto description = "Factor Oracle algorithm ."; // TODO cite
334  static const constexpr auto tags = std::array<const char*, 0>{};
335  static const uuid_constexpr auto uuid
336  = make_uuid("66F1C352-C48F-40A2-9283-35C2CB376258");
337 
338  static const constexpr auto controls
339  = tuplet::make_tuple(Control::IntSlider{"Sequence length", 1, 64, 8});
340  static const constexpr value_in value_ins[]{"in", "regen", "bang"};
341  static const constexpr value_out value_outs[]{"out"};
342  };
343 
344  struct State
345  {
346  int i = 0;
347  std::size_t sequence_idx{};
348  debug_vector_t<ossia::value> sequence;
350  };
351  ossia::value* buffer = nullptr;
352  using control_policy = ossia::safe_nodes::last_tick;
353  static void
354  run(const ossia::value_port& in, const ossia::value_port& regen,
355  const ossia::value_port& bangs, int seq_len, ossia::value_port& out,
356  ossia::token_request, ossia::exec_state_facade, State& self)
357  {
358 
359  // EntrĂ©es sont dans p1
360  for(auto val : in.get_data())
361  {
362  self.oracle.input_values.push_back(val.value);
363  self.oracle.AddLetter(self.oracle.current_state, self.oracle.input_values);
364  self.oracle.current_state = self.oracle.current_state + 1;
365  }
366 
367  if(!regen.get_data().empty())
368  {
369  self.sequence = self.oracle.CallGenerate(seq_len, 0.6);
370  }
371 
372  if(!self.sequence.empty())
373  {
374  for(auto& bang : bangs.get_data())
375  {
376  self.sequence_idx = ossia::clamp<int64_t>(
377  (int64_t)self.sequence_idx, 0, (int64_t)self.sequence.size() - 1);
378  out.write_value(self.sequence[self.sequence_idx], bang.timestamp);
379  self.sequence_idx = (self.sequence_idx + 1) % self.sequence.size();
380  }
381  }
382  }
383 };
384 #undef debug_vector_t
385 }
Definition: FactorOracle2.hpp:85
int FindBetter(int i, T alpha, const std::vector< T > word)
Definition: FactorOracle2.hpp:203
std::vector< std::vector< int > > RevSuffix
Definition: FactorOracle2.hpp:91
FactorOracle()
Definition: FactorOracle2.hpp:92
std::vector< State< T > > states_
Definition: FactorOracle2.hpp:89
std::vector< T > FOGenerate(int &i, std::vector< T > v, float q)
Definition: FactorOracle2.hpp:233
void AddLetter(int i, const std::vector< T > word)
Definition: FactorOracle2.hpp:100
void FactorOracleStart(const std::vector< T > word)
Definition: FactorOracle2.hpp:285
Definition: FactorOracle2.hpp:59
int first_state_
Definition: FactorOracle2.hpp:61
int last_state_
Definition: FactorOracle2.hpp:62
T symbol_
Definition: FactorOracle2.hpp:63
std::vector< SingleTransition< T > > transition_
denotes the number of the state
Definition: FactorOracle2.hpp:77
int state_
denotes the number of the state
Definition: FactorOracle2.hpp:76
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Definition: score-lib-process/Control/Widgets.hpp:178
Definition: SimpleApi.hpp:32
Definition: FactorOracle2.hpp:327
Definition: FactorOracle2.hpp:325