9namespace quids::rules::qcgd {
11 inline void hash_combine(std::size_t& seed,
size_t const value_64) {
12 static size_t magic_number = 0xc6a4a7935bd1e995;
13 static auto shift = 47;
16 seed ^= value_64 >> shift;
36 int16_t hmlz_and_element;
37 int16_t right_or_type;
40 sub_node(int16_t element) : right_or_type(element_t), hash(element) {
41 hmlz_and_element = element == 0 ? -1 : element + 1;
43 sub_node(sub_node
const &node, int16_t type) : right_or_type(type) {
44 if (type == dot_l_t && node.hmlz_and_element < 0) {
45 hmlz_and_element = -1;
50 utils::hash_combine(hash, type);
52 sub_node(sub_node
const &left, sub_node
const &right, int16_t right_offset) : right_or_type(right_offset) {
53 if (left.hmlz_and_element < 0 || right.hmlz_and_element < 0) {
54 hmlz_and_element = -1;
59 utils::hash_combine(hash, right.hash);
63 uint16_t
inline &num_nodes(
char *object_begin) {
64 return *((uint16_t*)object_begin);
67 uint16_t
inline const num_nodes(
char const *object_begin) {
68 return *((uint16_t*)object_begin);
71 uint16_t
inline *node_name_begin(
char *object_begin) {
72 uint16_t num_nodes_ = num_nodes(object_begin);
73 auto offset =
sizeof(uint16_t) + 2*num_nodes_;
74 return (uint16_t*)(object_begin + offset);
76 uint16_t
inline const *node_name_begin(
char const *object_begin) {
77 uint16_t num_nodes_ = num_nodes(object_begin);
78 auto offset =
sizeof(uint16_t) + 2*num_nodes_;
79 return (
const uint16_t*)(object_begin + offset);
81 uint16_t
inline &node_name_begin(
char *object_begin,
int node) {
return node_name_begin(object_begin)[node]; }
82 uint16_t
inline const node_name_begin(
char const *object_begin,
int node) {
return node_name_begin(object_begin)[node]; }
85 sub_node
inline *node_name(
char *object_begin) {
86 uint16_t num_nodes_ = num_nodes(object_begin);
87 auto offset = 2*
sizeof(uint16_t) + (2 +
sizeof(uint16_t))*num_nodes_;
88 return (sub_node*)(object_begin + offset);
90 sub_node
inline const *node_name(
char const *object_begin) {
91 uint16_t num_nodes_ = num_nodes(object_begin);
92 auto offset = 2*
sizeof(uint16_t) + (2 +
sizeof(uint16_t))*num_nodes_;
93 return (
const sub_node*)(object_begin + offset);
95 sub_node
inline &node_name(
char *object_begin,
int node) {
return node_name(object_begin)[node]; }
96 sub_node
inline const node_name(
char const *object_begin,
int node) {
return node_name(object_begin)[node]; }
98 bool inline *left(
char *object_begin) {
return (
bool*)(object_begin +
sizeof(uint16_t)); }
99 bool inline const *left(
char const *object_begin) {
return (
const bool*)(object_begin +
sizeof(uint16_t)); }
100 bool inline &left(
char *object_begin,
int node) {
return left(object_begin)[node]; }
101 bool inline const left(
char const *object_begin,
int node) {
return left(object_begin)[node]; }
103 bool inline *right(
char *object_begin) {
104 uint16_t num_nodes_ = num_nodes(object_begin);
105 return (
bool*)(object_begin +
sizeof(uint16_t) + num_nodes_);
107 bool inline const *right(
char const *object_begin) {
108 uint16_t num_nodes_ = num_nodes(object_begin);
109 return (
const bool*)(object_begin +
sizeof(uint16_t) + num_nodes_);
111 bool inline &right(
char *object_begin,
int node) {
return right(object_begin)[node]; }
112 bool inline const right(
char const *object_begin,
int node) {
return right(object_begin)[node]; }
114 void inline randomize(
char *object_begin) {
115 uint16_t num_nodes_ = num_nodes(object_begin);
116 for (
auto i = 0; i < num_nodes_; ++i) {
117 left(object_begin, i) = rand() & 1;
118 right(object_begin, i) = rand() & 1;
122 size_t inline hash_graph(
char const *object_begin) {
123 size_t left_hash = 0;
124 size_t right_hash = 0;
125 size_t name_hash = 0;
127 bool const *left_ = left(object_begin);
128 bool const *right_ = right(object_begin);
129 auto const *node_begin = node_name_begin(object_begin);
130 auto const *node_name_ = node_name(object_begin);
132 uint16_t
const num_nodes_ = num_nodes(object_begin);
133 for (
auto i = 0; i < num_nodes_; ++i) {
135 utils::hash_combine(left_hash, i);
138 utils::hash_combine(right_hash, i);
140 utils::hash_combine(name_hash, node_name_[node_begin[i]].hash);
143 utils::hash_combine(name_hash, left_hash);
144 utils::hash_combine(name_hash, right_hash);
149 namespace operations {
151 bool inline equal(T* begin_1, T* end_1, T* begin_2, T* end_2) {
152 size_t n_bit = std::distance(begin_1, end_1);
153 if (n_bit != std::distance(begin_2, end_2))
156 for (
auto i = 0; i < n_bit; ++i)
157 if(begin_1[i] != begin_2[i])
164 T
inline *copy(T
const *parent_begin, T
const *parent_end, T* child_begin) {
165 for (
auto it = parent_begin; it != parent_end; ++it)
166 *(child_begin++) = *it;
170 bool inline has_most_left_zero(graphs::sub_node *object_begin) {
171 return object_begin->hmlz_and_element < 0;
174 void inline get_operations(
char const *parent_begin, uint16_t node,
bool &split,
bool &merge) {
176 split = graphs::left(parent_begin, node) && graphs::right(parent_begin, node);
177 if (!split && node + 1 < graphs::num_nodes(parent_begin))
178 merge = graphs::left(parent_begin, node) && graphs::right(parent_begin, node + 1) && !graphs::left(parent_begin, node + 1);
181 graphs::sub_node
inline *merge(graphs::sub_node
const *left_begin, graphs::sub_node
const *left_end,
182 graphs::sub_node
const *right_begin, graphs::sub_node
const *right_end,
183 graphs::sub_node *child_begin) {
185 if (left_begin->right_or_type == graphs::dot_l_t && right_begin->right_or_type == graphs::dot_r_t)
186 if ((left_begin + 1)->hash == (right_begin + 1)->hash)
187 return copy(left_begin + 1, left_end, child_begin);
189 *(child_begin++) = graphs::sub_node(*left_begin, *right_begin, std::distance(left_begin, left_end) + 1);
190 child_begin = copy(left_begin, left_end, child_begin);
191 return copy(right_begin, right_end, child_begin);
194 graphs::sub_node
inline *left(graphs::sub_node
const *parent_begin, graphs::sub_node
const *parent_end, graphs::sub_node *child_begin) {
195 if (parent_begin->right_or_type >= 0)
196 return copy(parent_begin + 1, parent_begin + parent_begin->right_or_type, child_begin);
198 *(child_begin++) = graphs::sub_node(*parent_begin, graphs::dot_l_t);
199 return copy(parent_begin, parent_end, child_begin);
202 graphs::sub_node
inline *right(graphs::sub_node
const *parent_begin, graphs::sub_node
const *parent_end, graphs::sub_node *child_begin) {
203 if (parent_begin->right_or_type >= 0)
204 return copy(parent_begin + parent_begin->right_or_type, parent_end, child_begin);
206 *(child_begin++) = graphs::sub_node(*parent_begin, graphs::dot_r_t);
207 return copy(parent_begin, parent_end, child_begin);
212 size_t max_print_num_graphs = -1;
214 void make_graph(
char* &object_begin,
char* &object_end, uint16_t size) {
215 static auto per_node_size = 2 +
sizeof(uint16_t) +
sizeof(graphs::sub_node);
216 auto object_size = 2*
sizeof(uint16_t) + per_node_size*size;
218 object_begin =
new char[object_size];
219 object_end = object_begin + object_size;
221 graphs::num_nodes(object_begin) = size;
223 graphs::node_name_begin(object_begin, 0) = 0;
224 for (
auto i = 0; i < size; ++i) {
225 graphs::left(object_begin, i) = 0;
226 graphs::right(object_begin, i) = 0;
227 graphs::node_name_begin(object_begin, i + 1) = i + 1;
228 graphs::node_name(object_begin, i) = graphs::sub_node(i);
236 for (
auto gid = 0; gid < iter.num_object; ++gid) {;
237 iter.get_object(gid, begin, size, mag_);
238 graphs::randomize(begin);
243 static std::function<void(graphs::sub_node
const*)> print_node_name = [](graphs::sub_node
const *sub_node) {
244 if (sub_node->right_or_type == graphs::element_t) {
245 std::cout << std::abs(sub_node->hmlz_and_element) - 1;
247 }
else if (sub_node->right_or_type == graphs::dot_l_t) {
249 print_node_name(sub_node + 1);
252 }
else if (sub_node->right_or_type == graphs::dot_r_t) {
254 print_node_name(sub_node + 1);
259 print_node_name(sub_node + 1);
261 print_node_name(sub_node + sub_node->right_or_type);
266 size_t *gids =
new size_t[iter.num_object];
267 std::iota(gids, gids + iter.num_object, 0);
268 __gnu_parallel::sort(gids, gids + iter.num_object, [&](
size_t gid1,
size_t gid2) {
273 iter.get_object(gid1, begin_, size_, mag1);
274 iter.get_object(gid2, begin_, size_, mag2);
276 return std::norm(mag1) > std::norm(mag2);
279 size_t num_prints = std::min(iter.num_object, max_print_num_graphs);
280 for (
auto i = 0; i < num_prints; ++i) {
281 size_t gid = gids[i];
286 iter.get_object(gid, begin, size, mag);
288 uint16_t
const num_nodes = graphs::num_nodes(begin);
293 std::cout <<std::fixed<<std::setprecision(5)<<
"\t" << real << (imag <= -1e-5 ?
" - " :
" + ") << std::abs(imag) <<
"i ";
295 for (
auto i = 0; i < num_nodes; ++i) {
296 auto name_begin = graphs::node_name_begin(begin, i);
298 std::cout <<
"-|" << (graphs::left(begin, i) ?
"<" :
" ") <<
"|";
299 print_node_name(graphs::node_name(begin) + name_begin);
300 std::cout <<
"|" << (graphs::right(begin, i) ?
">" :
" ") <<
"|-";
305 if (num_prints < iter.num_object)
306 std::cout <<
"\t...and " << iter.num_object - num_prints <<
" other graphs\n";
310 PROBA_TYPE interference_ratio = 1;
311 PROBA_TYPE deletion_ratio = 1;
312 if (sy_it.num_object > 0) {
313 interference_ratio = ((PROBA_TYPE)sy_it.num_object_after_interferences) / ((PROBA_TYPE)sy_it.num_object);
314 deletion_ratio = ((PROBA_TYPE)iter.num_object) / ((PROBA_TYPE)sy_it.num_object_after_interferences);
317 PROBA_TYPE avg_size = iter.average_value([](
char const *object_begin,
char const *object_end) {
318 return (PROBA_TYPE)graphs::num_nodes(object_begin);
320 PROBA_TYPE avg_squared_size = iter.average_value([](
char const *object_begin,
char const *object_end) {
321 PROBA_TYPE num_nodes = graphs::num_nodes(object_begin);
322 return num_nodes*num_nodes;
324 PROBA_TYPE avg_density = iter.average_value([](
char const *object_begin,
char const *object_end) {
325 PROBA_TYPE num_nodes = graphs::num_nodes(object_begin);
327 PROBA_TYPE density = 0;
328 for (
auto i = 0; i < num_nodes; ++i)
329 density += graphs::left(object_begin, i) + graphs::right(object_begin, i);
330 density /= 2*num_nodes;
334 PROBA_TYPE avg_squared_density = iter.average_value([](
char const *object_begin,
char const *object_end) {
335 PROBA_TYPE num_nodes = graphs::num_nodes(object_begin);
337 PROBA_TYPE density = 0;
338 for (
auto i = 0; i < num_nodes; ++i)
339 density += graphs::left(object_begin, i) + graphs::right(object_begin, i);
340 density /= 2*num_nodes;
342 return density*density;
345 PROBA_TYPE std_dev_size = avg_squared_size - avg_size*avg_size;
346 std_dev_size = std_dev_size <
quids::tolerance ? 0 : std::sqrt(avg_squared_size);
348 PROBA_TYPE std_dev_density = avg_squared_density - avg_density*avg_density;
349 std_dev_density = std_dev_density <
quids::tolerance ? 0 : std::sqrt(std_dev_density);
351 auto const print_indentation = [=]() {
352 for (
auto i = 0; i < indentation; ++i)
357 print_indentation(); std::cout <<
"\t\"total_proba\" : " << iter.total_proba <<
",\n";
358 print_indentation(); std::cout <<
"\t\"num_graphs\" : " << iter.num_object <<
",\n";
359 print_indentation(); std::cout <<
"\t\"avg_size\" : " << avg_size <<
",\n";
360 print_indentation(); std::cout <<
"\t\"std_dev_size\" : " << std_dev_size <<
",\n";
361 print_indentation(); std::cout <<
"\t\"avg_density\" : " << avg_density <<
",\n";
362 print_indentation(); std::cout <<
"\t\"std_dev_density\" : " << std_dev_density <<
",\n";
363 print_indentation(); std::cout <<
"\t\"interference_ratio\" : " << interference_ratio <<
",\n";
364 print_indentation(); std::cout <<
"\t\"deletion_ratio\" : " << deletion_ratio <<
"\n";
365 print_indentation(); std::cout <<
"}";
371 MPI_Comm_rank(communicator, &rank);
373 size_t total_num_object = iter.get_total_num_object(communicator);
375 PROBA_TYPE interference_ratio = 1;
376 PROBA_TYPE deletion_ratio = 1;
378 PROBA_TYPE total_num_object_after_interferences = sy_it.get_total_num_object_after_interferences(communicator);
380 if (total_num_object_after_interferences >= 0) {
381 interference_ratio = total_num_object_after_interferences / (PROBA_TYPE)sy_it.get_total_num_object(communicator);
382 deletion_ratio = (PROBA_TYPE)total_num_object / total_num_object_after_interferences;
385 PROBA_TYPE avg_size = iter.average_value([](
char const *object_begin,
char const *object_end) {
386 return (PROBA_TYPE)graphs::num_nodes(object_begin);
389 PROBA_TYPE avg_squared_size = iter.average_value([](
char const *object_begin,
char const *object_end) {
390 PROBA_TYPE num_nodes = graphs::num_nodes(object_begin);
391 return num_nodes*num_nodes;
394 PROBA_TYPE avg_density = iter.average_value([](
char const *object_begin,
char const *object_end) {
395 PROBA_TYPE num_nodes = graphs::num_nodes(object_begin);
397 PROBA_TYPE density = 0;
398 for (
auto i = 0; i < num_nodes; ++i)
399 density += graphs::left(object_begin, i) + graphs::right(object_begin, i);
400 density /= 2*num_nodes;
405 PROBA_TYPE avg_squared_density = iter.average_value([](
char const *object_begin,
char const *object_end) {
406 PROBA_TYPE num_nodes = graphs::num_nodes(object_begin);
408 PROBA_TYPE density = 0;
409 for (
auto i = 0; i < num_nodes; ++i)
410 density += graphs::left(object_begin, i) + graphs::right(object_begin, i);
411 density /= 2*num_nodes;
413 return density*density;
416 PROBA_TYPE std_dev_size = avg_squared_size - avg_size*avg_size;
417 std_dev_size = std_dev_size <
quids::tolerance ? 0 : std::sqrt(avg_squared_size);
419 PROBA_TYPE std_dev_density = avg_squared_density - avg_density*avg_density;
420 std_dev_density = std_dev_density <
quids::tolerance ? 0 : std::sqrt(std_dev_density);
422 auto const print_indentation = [=]() {
423 for (
auto i = 0; i < indentation; ++i)
429 print_indentation(); std::cout <<
"\t\"total_proba\" : " << iter.total_proba <<
",\n";
430 print_indentation(); std::cout <<
"\t\"num_graphs\" : " << total_num_object <<
",\n";
431 print_indentation(); std::cout <<
"\t\"avg_size\" : " << avg_size <<
",\n";
432 print_indentation(); std::cout <<
"\t\"std_dev_size\" : " << std_dev_size <<
",\n";
433 print_indentation(); std::cout <<
"\t\"avg_density\" : " << avg_density <<
",\n";
434 print_indentation(); std::cout <<
"\t\"std_dev_density\" : " << std_dev_density <<
",\n";
435 print_indentation(); std::cout <<
"\t\"interference_ratio\" : " << interference_ratio <<
",\n";
436 print_indentation(); std::cout <<
"\t\"deletion_ratio\" : " << deletion_ratio <<
"\n";
437 print_indentation(); std::cout <<
"}";
443 void step(
char *parent_begin,
char *parent_end,
mag_t &mag) {
444 uint16_t num_nodes = graphs::num_nodes(parent_begin);
445 auto left_ = graphs::left(parent_begin);
446 auto right_ = graphs::right(parent_begin);
447 std::rotate(left_, left_ + 1, left_ + num_nodes);
448 std::rotate(right_, right_ + num_nodes - 1, right_ + num_nodes);
451 void reversed_step(
char *parent_begin,
char *parent_end,
mag_t &mag) {
452 uint16_t num_nodes = graphs::num_nodes(parent_begin);
453 auto left_ = graphs::left(parent_begin);
454 auto right_ = graphs::right(parent_begin);
455 std::rotate(right_, right_ + 1, right_ + num_nodes);
456 std::rotate(left_, left_ + num_nodes - 1, left_ + num_nodes);
463 mag_t do_not_conj = 0;
466 erase_create(PROBA_TYPE theta, PROBA_TYPE phi = 0, PROBA_TYPE xi = 0) {
467 do_ = std::polar(std::sin(theta), phi);
468 do_not = std::polar(std::cos(theta), xi);
469 do_conj = std::conj(do_);
470 do_not_conj = std::conj(do_not);
472 inline size_t hasher(
char const *parent_begin,
char const *parent_end)
const override {
473 return graphs::hash_graph(parent_begin);
475 inline void get_num_child(
char const *parent_begin,
char const *parent_end, uint &num_child, uint &max_child_size)
const override {
476 max_child_size = std::distance(parent_begin, parent_end);
478 uint16_t num_nodes = graphs::num_nodes(parent_begin);
481 for (
int i = 0; i < num_nodes; ++i) {
482 bool Xor = graphs::left(parent_begin, i) ^ graphs::right(parent_begin, i);
487 inline void populate_child(
char const *parent_begin,
char const *parent_end,
char*
const child_begin, uint
const child_id_, uint &size,
mag_t &mag)
const override {
488 operations::copy(parent_begin, parent_end, child_begin);
489 size = std::distance(parent_begin, parent_end);
491 uint child_id = child_id_;
493 uint16_t num_nodes = graphs::num_nodes(parent_begin);
494 for (
int i = 0; i < num_nodes; ++i) {
495 bool &left = graphs::left(child_begin, i);
496 bool &right = graphs::right(child_begin, i);
498 uint8_t sum = left + right;
499 if ((sum & 1) == 0) {
502 mag *= conj ? do_conj : do_;
506 mag *= conj ? -do_not_conj : do_not;
511 inline void populate_child_simple(
char const *parent_begin,
char const *parent_end,
char*
const child_begin, uint
const child_id_)
const override {
512 operations::copy(parent_begin, parent_end, child_begin);
514 uint child_id = child_id_;
516 uint16_t num_nodes = graphs::num_nodes(parent_begin);
517 for (
int i = 0; i < num_nodes; ++i) {
518 bool &left = graphs::left(child_begin, i);
519 bool &right = graphs::right(child_begin, i);
521 uint8_t sum = left + right;
522 if ((sum & 1) == 0) {
538 mag_t do_not_conj = 0;
541 coin(PROBA_TYPE theta, PROBA_TYPE phi = 0, PROBA_TYPE xi = 0) {
542 do_ = std::polar(std::sin(theta), phi);
543 do_not = std::polar(std::cos(theta), xi);
544 do_conj = std::conj(do_);
545 do_not_conj = std::conj(do_not);
547 inline size_t hasher(
char const *parent_begin,
char const *parent_end)
const override {
548 return graphs::hash_graph(parent_begin);
550 inline void get_num_child(
char const *parent_begin,
char const *parent_end, uint &num_child, uint &max_child_size)
const override {
551 max_child_size = std::distance(parent_begin, parent_end);
553 uint16_t num_nodes = graphs::num_nodes(parent_begin);
556 for (
int i = 0; i < num_nodes; ++i) {
557 bool Xor = graphs::left(parent_begin, i) ^ graphs::right(parent_begin, i);
562 inline void populate_child(
char const *parent_begin,
char const *parent_end,
char*
const child_begin, uint
const child_id_, uint &size,
mag_t &mag)
const override {
563 operations::copy(parent_begin, parent_end, child_begin);
564 size = std::distance(parent_begin, parent_end);
566 uint child_id = child_id_;
568 uint16_t num_nodes = graphs::num_nodes(parent_begin);
569 for (
int i = 0; i < num_nodes; ++i) {
570 bool &left = graphs::left(child_begin, i);
571 bool &right = graphs::right(child_begin, i);
576 mag *= conj ? do_conj : do_;
580 mag *= conj ? -do_not_conj : do_not;
585 inline void populate_child_simple(
char const *parent_begin,
char const *parent_end,
char*
const child_begin, uint
const child_id_)
const override {
586 operations::copy(parent_begin, parent_end, child_begin);
588 uint child_id = child_id_;
590 uint16_t num_nodes = graphs::num_nodes(parent_begin);
591 for (
int i = 0; i < num_nodes; ++i) {
592 bool &left = graphs::left(child_begin, i);
593 bool &right = graphs::right(child_begin, i);
611 mag_t do_not_conj = 0;
614 split_merge(PROBA_TYPE theta, PROBA_TYPE phi = 0, PROBA_TYPE xi = 0) {
615 do_ = std::polar(std::sin(theta), phi);
616 do_not = std::polar(std::cos(theta), xi);
617 do_conj = std::conj(do_);
618 do_not_conj = std::conj(do_not);
620 inline size_t hasher(
char const *parent_begin,
char const *parent_end)
const override {
621 return graphs::hash_graph(parent_begin);
623 inline void get_num_child(
char const *parent_begin,
char const *parent_end, uint &num_child, uint &max_child_size)
const override {
624 max_child_size = 4*std::distance(parent_begin, parent_end);
626 uint16_t num_nodes = graphs::num_nodes(parent_begin);
628 bool last_merge =
false;
629 bool first_split = graphs::left(parent_begin, 0) && graphs::right(parent_begin, 0);
630 if (!first_split && num_nodes > 1)
631 last_merge = graphs::right(parent_begin, 0) && graphs::left(parent_begin, num_nodes - 1) && !graphs::right(parent_begin, num_nodes - 1);
633 num_child = first_split || last_merge ? 2 : 1;
635 for (
int i = first_split; i < num_nodes - last_merge; ++i) {
638 operations::get_operations(parent_begin, i, split, merge);
643 inline void populate_child(
char const *parent_begin,
char const *parent_end,
char*
const child_begin, uint
const child_id_, uint &size,
mag_t &mag)
const override {
644 uint child_id = child_id_;
645 uint16_t num_nodes = graphs::num_nodes(parent_begin);
648 bool last_merge =
false;
649 bool first_split = graphs::left(parent_begin, 0) && graphs::right(parent_begin, 0);
650 if (!first_split && num_nodes > 1)
651 last_merge = graphs::right(parent_begin, 0) && graphs::left(parent_begin, num_nodes - 1) && !graphs::right(parent_begin, num_nodes - 1);
652 bool first_split_overflow =
false;
655 first_split &= child_id;
670 uint16_t &child_num_nodes = graphs::num_nodes(child_begin);
671 child_num_nodes = num_nodes + first_split - last_merge;
674 uint child_id_copy = child_id;
675 for (
int i = first_split + last_merge; i < num_nodes - last_merge; ++i) {
678 operations::get_operations(parent_begin, i, split, merge);
681 if (merge || split) {
682 if (child_id_copy & 1) {
684 child_num_nodes += split - merge;
703 auto parent_node_name_begin = graphs::node_name(parent_begin);
704 auto child_node_name_begin = graphs::node_name(child_begin);
705 graphs::node_name_begin(child_begin, 0) = 0;
709 bool has_most_left_zero =
true;
710 if (parent_node_name_begin->right_or_type >= 0)
711 if ((parent_node_name_begin + 1)->hmlz_and_element > 0)
712 has_most_left_zero =
false;
714 if (has_most_left_zero) {
716 graphs::left(child_begin, 0) =
true;
717 graphs::right(child_begin, 0) =
false;
718 graphs::left(child_begin, 1) =
false;
719 graphs::right(child_begin, 1) =
true;
722 auto node_name_end = operations::left(parent_node_name_begin,
723 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
724 child_node_name_begin);
726 graphs::node_name_begin(child_begin, 1) = std::distance(child_node_name_begin, node_name_end);
728 node_name_end = operations::right(parent_node_name_begin,
729 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
732 graphs::node_name_begin(child_begin, 2) = std::distance(child_node_name_begin, node_name_end);
734 first_split_overflow =
true;
737 graphs::left(child_begin, child_num_nodes - 1) =
true;
738 graphs::right(child_begin, child_num_nodes - 1) =
false;
739 graphs::left(child_begin, 0) =
false;
740 graphs::right(child_begin, 0) =
true;
743 auto node_name_end = operations::right(parent_node_name_begin,
744 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
745 child_node_name_begin);
747 graphs::node_name_begin(child_begin, 1) = std::distance(child_node_name_begin, node_name_end);
753 graphs::left(child_begin, 0) =
true;
754 graphs::right(child_begin, 0) =
true;
757 auto node_name_end = operations::merge(parent_node_name_begin + graphs::node_name_begin(parent_begin, num_nodes - 1),
758 parent_node_name_begin + graphs::node_name_begin(parent_begin, num_nodes),
759 parent_node_name_begin,
760 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
761 child_node_name_begin);
763 graphs::node_name_begin(child_begin, 1) = std::distance(child_node_name_begin, node_name_end);
767 int offset = first_split - first_split_overflow;
768 for (
int i = first_split + last_merge; i < num_nodes - last_merge; ++i) {
772 operations::get_operations(parent_begin, i, split, merge);
776 if (merge || split) {
781 graphs::left(child_begin, i + offset) =
true;
782 graphs::right(child_begin, i + offset) =
false;
783 graphs::left(child_begin, i + offset + 1) =
false;
784 graphs::right(child_begin, i + offset + 1) =
true;
787 auto node_name_end = operations::left(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
788 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
789 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset));
791 graphs::node_name_begin(child_begin, i + 1 + offset) = std::distance(child_node_name_begin, node_name_end);
794 node_name_end = operations::right(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
795 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
796 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset + 1));
798 graphs::node_name_begin(child_begin, i + 1 + offset + 1) = std::distance(child_node_name_begin, node_name_end);
801 graphs::left(child_begin, i + offset) =
true;
802 graphs::right(child_begin, i + offset) =
true;
805 auto node_name_end = operations::merge(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
806 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
807 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
808 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 2),
809 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset));
811 graphs::node_name_begin(child_begin, i + 1 + offset) = std::distance(child_node_name_begin, node_name_end);
815 offset += split - merge;
825 graphs::left(child_begin, i + offset) = graphs::left(parent_begin, i);
826 graphs::right(child_begin, i + offset) = graphs::right(parent_begin, i);
829 auto node_name_end = operations::copy(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
830 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
831 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset));
833 graphs::node_name_begin(child_begin, i + 1 + offset) = std::distance(child_node_name_begin, node_name_end);
838 if (first_split_overflow) {
840 auto node_name_end = operations::left(parent_node_name_begin,
841 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
842 child_node_name_begin + graphs::node_name_begin(child_begin, child_num_nodes - 1));
844 graphs::node_name_begin(child_begin, child_num_nodes) = std::distance(child_node_name_begin, node_name_end);
847 size = std::distance(child_begin, (
char*)(child_node_name_begin + graphs::node_name_begin(child_begin, child_num_nodes)));
850 inline void populate_child_simple(
char const *parent_begin,
char const *parent_end,
char*
const child_begin, uint
const child_id_)
const override {
851 uint child_id = child_id_;
852 uint16_t num_nodes = graphs::num_nodes(parent_begin);
855 bool last_merge =
false;
856 bool first_split = graphs::left(parent_begin, 0) && graphs::right(parent_begin, 0);
857 if (!first_split && num_nodes > 1)
858 last_merge = graphs::right(parent_begin, 0) && graphs::left(parent_begin, num_nodes - 1) && !graphs::right(parent_begin, num_nodes - 1);
859 bool first_split_overflow =
false;
862 first_split &= child_id;
871 uint16_t &child_num_nodes = graphs::num_nodes(child_begin);
872 child_num_nodes = num_nodes + first_split - last_merge;
875 uint child_id_copy = child_id;
876 for (
int i = first_split + last_merge; i < num_nodes - last_merge; ++i) {
879 operations::get_operations(parent_begin, i, split, merge);
882 if (merge || split) {
883 if (child_id_copy & 1)
885 child_num_nodes += split - merge;
892 auto parent_node_name_begin = graphs::node_name(parent_begin);
893 auto child_node_name_begin = graphs::node_name(child_begin);
894 graphs::node_name_begin(child_begin, 0) = 0;
898 bool has_most_left_zero =
true;
899 if (parent_node_name_begin->right_or_type >= 0)
900 if ((parent_node_name_begin + 1)->hmlz_and_element > 0)
901 has_most_left_zero =
false;
903 if (has_most_left_zero) {
905 graphs::left(child_begin, 0) =
true;
906 graphs::right(child_begin, 0) =
false;
907 graphs::left(child_begin, 1) =
false;
908 graphs::right(child_begin, 1) =
true;
911 auto node_name_end = operations::left(parent_node_name_begin,
912 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
913 child_node_name_begin);
915 graphs::node_name_begin(child_begin, 1) = std::distance(child_node_name_begin, node_name_end);
917 node_name_end = operations::right(parent_node_name_begin,
918 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
921 graphs::node_name_begin(child_begin, 2) = std::distance(child_node_name_begin, node_name_end);
923 first_split_overflow =
true;
926 graphs::left(child_begin, child_num_nodes - 1) =
true;
927 graphs::right(child_begin, child_num_nodes - 1) =
false;
928 graphs::left(child_begin, 0) =
false;
929 graphs::right(child_begin, 0) =
true;
932 auto node_name_end = operations::right(parent_node_name_begin,
933 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
934 child_node_name_begin);
936 graphs::node_name_begin(child_begin, 1) = std::distance(child_node_name_begin, node_name_end);
942 graphs::left(child_begin, 0) =
true;
943 graphs::right(child_begin, 0) =
true;
946 auto node_name_end = operations::merge(parent_node_name_begin + graphs::node_name_begin(parent_begin, num_nodes - 1),
947 parent_node_name_begin + graphs::node_name_begin(parent_begin, num_nodes),
948 parent_node_name_begin,
949 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
950 child_node_name_begin);
952 graphs::node_name_begin(child_begin, 1) = std::distance(child_node_name_begin, node_name_end);
956 int offset = first_split - first_split_overflow;
957 for (
int i = first_split + last_merge; i < num_nodes - last_merge; ++i) {
961 operations::get_operations(parent_begin, i, split, merge);
965 if (merge || split) {
970 graphs::left(child_begin, i + offset) =
true;
971 graphs::right(child_begin, i + offset) =
false;
972 graphs::left(child_begin, i + offset + 1) =
false;
973 graphs::right(child_begin, i + offset + 1) =
true;
976 auto node_name_end = operations::left(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
977 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
978 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset));
980 graphs::node_name_begin(child_begin, i + 1 + offset) = std::distance(child_node_name_begin, node_name_end);
983 node_name_end = operations::right(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
984 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
985 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset + 1));
987 graphs::node_name_begin(child_begin, i + 1 + offset + 1) = std::distance(child_node_name_begin, node_name_end);
990 graphs::left(child_begin, i + offset) =
true;
991 graphs::right(child_begin, i + offset) =
true;
994 auto node_name_end = operations::merge(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
995 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
996 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
997 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 2),
998 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset));
1000 graphs::node_name_begin(child_begin, i + 1 + offset) = std::distance(child_node_name_begin, node_name_end);
1004 offset += split - merge;
1014 graphs::left(child_begin, i + offset) = graphs::left(parent_begin, i);
1015 graphs::right(child_begin, i + offset) = graphs::right(parent_begin, i);
1018 auto node_name_end = operations::copy(parent_node_name_begin + graphs::node_name_begin(parent_begin, i),
1019 parent_node_name_begin + graphs::node_name_begin(parent_begin, i + 1),
1020 child_node_name_begin + graphs::node_name_begin(child_begin, i + offset));
1022 graphs::node_name_begin(child_begin, i + 1 + offset) = std::distance(child_node_name_begin, node_name_end);
1027 if (first_split_overflow) {
1029 auto node_name_end = operations::left(parent_node_name_begin,
1030 parent_node_name_begin + graphs::node_name_begin(parent_begin, 1),
1031 child_node_name_begin + graphs::node_name_begin(child_begin, child_num_nodes - 1));
1033 graphs::node_name_begin(child_begin, child_num_nodes) = std::distance(child_node_name_begin, node_name_end);
1039 typedef std::vector<std::tuple<int, bool, quids::modifier_t, quids::rule_t*, quids::modifier_t, quids::rule_t*>> simulator_t;
1042 std::string strip(std::string &input, std::string
const separator) {
1045 size_t end = input.find(separator);
1047 if (end == std::string::npos) {
1051 result = input.substr(0, end);
1052 input.erase(0, end + separator.length());
1058 std::string parse(std::string
const input, std::string
const key, std::string
const separator) {
1059 size_t begin = input.find(key);
1060 if (begin == std::string::npos)
1063 size_t end = input.find(separator);
1064 end = end == std::string::npos ? input.size() : end;
1066 return input.substr(begin + key.length(), end - begin);
1069 int parse_int_with_default(std::string
const input, std::string
const key, std::string
const separator,
int Default) {
1070 std::string string_value = parse(input, key, separator);
1071 if (string_value ==
"")
1074 return std::atoi(string_value.c_str());
1077 float parse_float_with_default(std::string
const input, std::string
const key, std::string
const separator,
float Default) {
1078 std::string string_value = parse(input, key, separator);
1079 if (string_value ==
"")
1082 return std::atof(string_value.c_str());
1086 std::tuple<uint, uint, size_t> read_n_iter(
const char* argv) {
1087 std::string string_arg = argv;
1089 int n_iters = std::atoi(strip(string_arg,
",").c_str());
1091 std::string string_seed = parse(string_arg,
"seed=",
",");
1092 if (string_seed !=
"") {
1093 std::srand(std::atoi(string_seed.c_str()));
1095 std::srand(std::time(0));
1097 int reversed_n_iters = parse_int_with_default(string_arg,
"reversed_n_iter=",
",", 0);
1099 utils::max_print_num_graphs = parse_int_with_default(string_arg,
"max_print_num_graphs=",
",", utils::max_print_num_graphs);
1114 size_t max_num_object = parse_int_with_default(string_arg,
"max_num_object=",
",", 0);
1116 return {n_iters, reversed_n_iters, max_num_object};
1119 void read_state(
const char* argv,
quids::it_t &state) {
1120 std::string string_args = argv;
1122 std::string string_arg;
1123 while ((string_arg = strip(string_args,
";")) !=
"") {
1124 int n_node = std::atoi(strip(string_arg,
",").c_str());
1125 int n_graphs = parse_int_with_default(string_arg,
"n_graphs=",
",", 1);
1126 float real = parse_float_with_default(string_arg,
"real=",
",", 1) / std::sqrt((
float)n_graphs);
1127 float imag = parse_float_with_default(string_arg,
"imag=",
",", 0) / std::sqrt((
float)n_graphs);
1129 for (
auto i = 0; i < n_graphs; ++i) {
1131 utils::make_graph(begin, end, n_node);
1132 state.append(begin, end, {real, imag});
1136 utils::randomize(state);
1139 simulator_t read_rule(
const char* argv,
debug_t mid_step_function=[](
const char*){}) {
1140 std::string string_args = argv;
1142 simulator_t simulator;
1144 std::string string_arg;
1145 while ((string_arg = strip(string_args,
";")) !=
"") {
1146 std::string rule_name = strip(string_arg,
",");
1147 float theta = M_PI*parse_float_with_default(string_arg,
"theta=",
",", 0.25);
1148 float phi = M_PI*parse_float_with_default(string_arg,
"phi=",
",", 0);
1149 float xi = M_PI*parse_float_with_default(string_arg,
"xi=",
",", 0);
1150 int n_iter = parse_int_with_default(string_arg,
"n_iter=",
",", 1);
1152 if (rule_name ==
"split_merge") {
1153 simulator.push_back({n_iter,
true, NULL,
new split_merge(theta, phi, xi), NULL,
new split_merge(theta, phi, -xi)});
1154 }
else if (rule_name ==
"erase_create") {
1155 simulator.push_back({n_iter,
true, NULL,
new erase_create(theta, phi, xi), NULL,
new erase_create(theta, phi, -xi)});
1156 }
else if (rule_name ==
"coin") {
1157 simulator.push_back({n_iter,
true, NULL,
new coin(theta, phi, xi), NULL,
new coin(theta, phi, -xi)});
1158 }
else if (rule_name ==
"step") {
1159 simulator.push_back({n_iter,
false, step, NULL, reversed_step, NULL});
1160 }
else if (rule_name ==
"reversed_step") {
1161 simulator.push_back({n_iter,
false, reversed_step, NULL, step, NULL});
1168 std::tuple<uint, uint, simulator_t, size_t> parse_simulation(
const char* argv,
it_t &state,
debug_t mid_step_function=[](
const char*){}) {
1169 std::string string_args = argv;
1171 auto [n_iter, reversed_n_iters, max_num_object] = read_n_iter(strip(string_args,
"|").c_str());
1172 read_state(strip(string_args,
"|").c_str(), state);
1173 auto simulator = read_rule(string_args.c_str(), mid_step_function);
1175 return {n_iter, reversed_n_iters, simulator, max_num_object};
class represneting a dynamic (or rule).
Definition: quids.hpp:100
size_t min_equalize_size
minimum number of object that should be attained (in at least one node) before equalizing (load-shari...
Definition: quids_mpi.hpp:46
class mpi_iteration mpi_it_t
mpi iteration type
Definition: quids_mpi.hpp:59
class mpi_symbolic_iteration mpi_sy_it_t
mpi symbolic iteration type
Definition: quids_mpi.hpp:61
float equalize_inbalance
maximum imbalance between nodes (max_obj - avg_obj)/max_obj allowed before equalizing.
Definition: quids_mpi.hpp:48
std::complex< PROBA_TYPE > mag_t
complex magnitude type
Definition: quids.hpp:73
class symbolic_iteration sy_it_t
symbolic iteration type
Definition: quids.hpp:77
std::function< void(const char *step)> debug_t
debuging function type
Definition: quids.hpp:85
class iteration it_t
iteration class type
Definition: quids.hpp:75
int load_balancing_bucket_per_thread
number of load balancing buckets per thread
Definition: quids.hpp:63
float safety_margin
memory safety margin (0.2 = 80% memory usage target)
Definition: quids.hpp:61
PROBA_TYPE tolerance
tolerance for objects (remove objects with a smaller probability)
Definition: quids.hpp:59
uint align_byte_length
amount of byte to align objects to
Definition: quids.hpp:57
bool simple_truncation
simple truncation toggle - disable probabilistic truncation, increasing "accuracy" but reducing the r...
Definition: quids.hpp:69