2 #include <Engine/Node/SimpleApi.hpp>
4 #include <ossia/detail/hash_map.hpp>
5 #include <ossia/detail/math.hpp>
6 #include <ossia/detail/ssize.hpp>
10 #include <rnd/random.hpp>
11 #if !defined(NDEBUG) && !defined(_MSC_VER) && !defined(__clang__)
12 #include <debug/vector>
13 #define debug_vector_t __gnu_debug::vector
15 #define debug_vector_t std::vector
17 namespace Nodes::FactorOracle
20 template <
typename T, T default_value>
24 debug_vector_t<T> impl;
26 T& operator[](
int i_) {
return (*
this)[
static_cast<std::size_t
>(i_)]; }
27 T& operator[](std::size_t i_)
29 auto i =
static_cast<std::size_t
>(i_);
30 if(i < impl.size() && impl.size() != 0)
34 impl.resize((i + 1) * 2, default_value);
38 const T& operator[](
int i_)
const {
return (*
this)[
static_cast<std::size_t
>(i_)]; }
39 const T& operator[](std::size_t i_)
const
41 auto i =
static_cast<std::size_t
>(i_);
42 if(i < impl.size() && impl.size() != 0)
46 static constexpr
auto dval = default_value;
54 debug_vector_t<T> impl;
56 T& operator[](
int i_) {
return (*
this)[
static_cast<std::size_t
>(i_)]; }
57 T& operator[](std::size_t i_)
59 auto i =
static_cast<std::size_t
>(i_);
60 if(i < impl.size() && impl.size() != 0)
64 impl.resize((i + 1) * 2);
72 int cur_alphabet_size = 0;
73 debug_vector_t<std::pair<int, ossia::value>> value_map;
75 : m_forwardLink(sz + 1, debug_vector_t<int>{-1})
78 m_sp.impl.resize(1000);
79 m_lrs.impl.resize(1000);
85 int LCS(
int p1,
int p2)
90 while(m_sp[p2] != m_sp[p1])
93 return std::min(m_lrs[p1], m_lrs[p2]);
96 void add_char(ossia::value c)
98 if(n < std::ssize(m_forwardLink) - 1)
100 m_sequence.push_back(std::move(c));
101 auto it = ossia::find_if(
102 value_map, [&](
const auto& pair) {
return pair.second == c; });
103 if(it != value_map.end())
105 add_state(it->first);
109 value_map.push_back({cur_alphabet_size, m_sequence.back()});
110 add_state(cur_alphabet_size);
116 void add_state(
int c)
118 m_trans[n][c] = n + 1;
122 while(j != -1 && m_trans[j][c] == -1)
124 int& m_trans_j_c = m_trans[j][c];
126 if(m_forwardLink[j][0] == -1)
128 m_forwardLink[j][0] = m_trans_j_c;
132 m_forwardLink[j].push_back(m_trans_j_c);
137 int& m_sp_n = m_sp[n];
138 m_sp_n = (j == -1 ? 0 : m_trans[j][c]);
139 m_lrs[n] = (m_sp_n == 0 ? 0 :
LCS(p1, m_sp_n - 1) + 1);
142 debug_vector_t<ossia::value> make_rand_sequence(
float continuity,
int seqSize)
const
144 auto start = std::uniform_int_distribution<std::size_t>{0, m_sequence.size()}(
146 return make_sequence(continuity, start, seqSize);
149 debug_vector_t<ossia::value>
150 make_sequence(
float continuity, std::size_t curState, std::size_t seqSize)
const
152 if(curState > m_sequence.size())
154 qDebug() <<
"Le point initial de l'improvisation doit être comprise "
159 debug_vector_t<ossia::value> v;
161 for(std::size_t i = 0; i < seqSize; i++)
163 auto f = std::uniform_real_distribution<float>{}(m_rand_engine);
164 if(f <= continuity && curState < m_sequence.size() - 1)
167 v.push_back(m_sequence[curState]);
173 int links = (curState == 0 ? 0 : 1);
174 if(m_forwardLink[curState][0] != -1)
176 links += m_forwardLink[curState].size();
180 = std::uniform_int_distribution<int>{0, links - 1}(m_rand_engine);
181 if(linkToFollow == links - 1)
185 curState = m_sp[curState];
190 curState = m_forwardLink[curState][linkToFollow];
192 }
while(curState >= m_sequence.size());
194 v.push_back(m_sequence[curState]);
202 safe_vector<int, 0> m_sp;
203 safe_vector<int, 0> m_lrs;
204 safe_vector_simple<safe_vector<int, -1>> m_trans;
205 debug_vector_t<ossia::value> m_sequence;
206 debug_vector_t<debug_vector_t<int>> m_forwardLink;
208 mutable rnd::pcg m_rand_engine;
215 static const constexpr
auto prettyName =
"Factor Oracle";
216 static const constexpr
auto objectKey =
"Factor Oracle";
217 static const constexpr
auto category =
"Control/Impro";
218 static const constexpr
auto author
219 =
"Shlomo Dubnov, Ge Wang, Éric Meaux, Jean-Michaël Celerier";
220 static const constexpr
auto kind = Process::ProcessCategory::Mapping;
221 static const constexpr
auto description =
"Factor Oracle algorithm .";
222 static const constexpr
auto tags = std::array<const char*, 0>{};
223 static const uuid_constexpr
auto uuid
224 = make_uuid(
"d90284c0-4196-47e0-802d-7e07342029ec");
226 static const constexpr
auto controls
229 static const constexpr value_in value_ins[]{
"in",
"regen",
"bang"};
230 static const constexpr value_out value_outs[]{
"out"};
236 debug_vector_t<ossia::value> sequence;
237 std::size_t sequence_idx{};
240 using control_policy = ossia::safe_nodes::last_tick;
242 run(
const ossia::value_port& in,
const ossia::value_port& regen,
243 const ossia::value_port& bangs,
int seq_len, ossia::value_port& out,
244 ossia::token_request, ossia::exec_state_facade,
State&
self)
247 for(
auto val : in.get_data())
249 self.oracle.add_char(val.value);
252 if(!regen.get_data().empty())
254 self.sequence =
self.oracle.make_rand_sequence(0.4, seq_len);
257 if(!
self.sequence.empty())
259 for(
auto& bang : bangs.get_data())
261 self.sequence_idx = ossia::clamp<int64_t>(
262 (int64_t)
self.sequence_idx, 0, (int64_t)
self.sequence.size() - 1);
263 out.write_value(
self.sequence[
self.sequence_idx], bang.timestamp);
264 self.sequence_idx = (
self.sequence_idx + 1) %
self.sequence.size();
269 #undef debug_vector_t
Definition: FactorOracle.hpp:70
int LCS(int p1, int p2)
Function LCS (longest common suffix)
Definition: FactorOracle.hpp:85
Utilities for OSSIA data structures.
Definition: DeviceInterface.hpp:33
Definition: score-lib-process/Control/Widgets.hpp:178
Definition: FactorOracle.hpp:212
Definition: FactorOracle.hpp:52
Definition: FactorOracle.hpp:22