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