tudocomp
– The TU Dortmund Compression Framework
MonotoneSubsequences.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 
6 namespace tdc {namespace esp {
7  using Sindex = size_t;
8  using Link = size_t;
9 
10  template<typename View>
11  inline std::vector<Sindex> sorted_indices(const View& input) {
12  std::vector<Sindex> sorted_indices;
13  sorted_indices.reserve(input.size());
14  for(size_t i = 0; i < input.size(); i++) {
15  sorted_indices.push_back(i);
16  }
17  DCHECK_EQ(sorted_indices.capacity(), input.size());
18 
19  // TODO: Measure memory, might try to check unstable sort here
20  std::stable_sort(sorted_indices.begin(), sorted_indices.end(), [&](const size_t& a, const size_t& b) {
21  return input[a] < input[b];
22  });
23 
24  return sorted_indices;
25  }
26 
27  struct Point {
28  size_t x;
29  size_t y;
30  };
31 
32  inline bool operator==(const Point& a, const Point& b) {
33  return a.x == b.x && a.y == b.y;
34  }
35 
36  inline std::ostream& operator<<(std::ostream& o, const Point& a) {
37  return o << "(" << a.x << ", " << a.y << ")";
38  }
39 
40  inline Point point_coord_if_at_index(Sindex self, size_t index) {
41  return Point {
42  index,
43  self
44  };
45  }
46 
47  class L;
48 
50  // yields addresses in descending order in normal mode,
51  // and in ascending order if in reverse mode.
52  bool m_reverse;
53  size_t m_front;
54  size_t m_back;
55  L* m_l;
56  bool m_has_next;
57 
58  inline void debug();
59  public:
60  inline LayersIterator(L& l, bool reverse);
61  inline bool has_next();
62  inline Link advance();
63  };
64 
65  inline size_t layers_A_search(ConstGenericView<size_t> searchA, size_t piy) {
66  size_t start = 0;
67  size_t end = searchA.size();
68 
69  do {
70  size_t mid = (end - start) / 2 + start;
71 
72  if (searchA[mid] > piy) {
73  start = mid;
74  } else {
75  end = mid;
76  }
77  } while ((end - start) > 1);
78 
79  return start;
80  }
81 
82  inline Point point_coord_for_link(ConstGenericView<Sindex> sindices, Link link, bool reverse) {
83  size_t inverted_link;
84  if (!reverse) {
85  inverted_link = link;
86  } else {
87  inverted_link = sindices.size() - link - 1;
88  }
89 
90  return point_coord_if_at_index(sindices[link], inverted_link);
91  }
92 
93  class L {
94  ConstGenericView<Sindex> m_sindices;
95  std::vector<Link> m_linked_list;
96  std::vector<Link> m_layers;
97  bool m_reverse = false;
98  std::vector<size_t> m_rebuild_A; // allocation cache
99  size_t m_removed_counter = 0;
100  size_t m_remaining_size = 0;
101  std::vector<Link> m_free_list;
102  size_t m_free_start = 0;
103  size_t m_free_end = 0;
104 
105  friend class LayersIterator;
106  public:
107  inline L(ConstGenericView<Sindex> sindices) {
108  m_linked_list.reserve(sindices.size());
109  m_linked_list.resize(sindices.size());
110  m_sindices = sindices;
111  m_remaining_size = sindices.size();
112  m_free_list.reserve(sindices.size());
113  m_free_list.resize(sindices.size());
114 
115  DCHECK_GT(sindices.size(), 0);
116 
117  for(size_t i = 1; i < m_linked_list.size(); i++) {
118  m_linked_list[i] = i - 1;
119  }
120  m_linked_list[0] = 0;
121 
122  for(size_t i = 0; i < m_free_list.size() - 1; i++) {
123  m_free_list[i] = i + 1;
124  }
125  m_free_list[m_free_list.size() - 1] = m_free_list.size() - 1;
126 
127  m_free_start = 0;
128  m_free_end = m_linked_list.size() - 1;
129  }
130 
131  void rebuild(bool reverse) {
132  m_layers.clear();
133  m_reverse = reverse;
134  auto& A = m_rebuild_A;
135  A.clear();
136  A.push_back(size_t(-1));
137  size_t l = 0;
138 
139  auto layers_iter = LayersIterator(*this, m_reverse);
140 
141  while (layers_iter.has_next()) {
142  auto link = layers_iter.advance();
143  auto pi = point_coord_for_link(m_sindices, link, m_reverse);
144  auto j = layers_A_search(ConstGenericView<size_t>(A).slice(0, l + 1), pi.y);
145  auto is_new_layer = (j == l);
146  if (is_new_layer) {
147  m_layers.push_back(Link());
148  l += 1;
149  }
150 
151  auto& Lj_plus = m_layers[j];
152 
153  // set next pointer in linked list to null
154  m_linked_list[link] = link;
155  if (is_new_layer) {
156  // Just make the layer point to the first element of the linked list
157  Lj_plus = link;
158  } else {
159  // Append link before the first element of the linked list
160  auto old_head = Lj_plus;
161  m_linked_list[link] = old_head;
162  Lj_plus = link;
163  }
164 
165  // Grow A as needed
166  if (A.size() == (j + 1)) {
167  A.push_back(pi.y);
168  } else {
169  A[j + 1] = pi.y;
170  }
171  }
172  }
173 
174  inline bool dominates(Link lhs, Link rhs) {
175  auto lhsp = point_coord_for_link(m_sindices, lhs, m_reverse);
176  auto rhsp = point_coord_for_link(m_sindices, rhs, m_reverse);
177 
178  return (lhsp.x > rhsp.x) && (lhsp.y > rhsp.y);
179  }
180 
181  // return false if error
182  // q is a out parameter
183  inline bool lis(size_t k, std::vector<size_t>& q) {
184  if (k > m_layers.size()) { return false; }
185  q.clear();
186  q.reserve(k);
187  q.resize(k);
188  if (k == 0) { return true; }
189 
190  size_t l = k - 1;
191 
192  q[l] = m_layers[l];
193 
194  while (true) {
195  if (l == 0) {
196  break;
197  } else {
198  l -= 1;
199  }
200 
201  Link search_link = m_layers[l];
202 
203  while (true) {
204  if (dominates(search_link, q[l + 1])) {
205  q[l] = search_link;
206  break;
207  } else {
208  DCHECK_NE(m_linked_list[search_link], search_link)
209  << "should always break out before this happens";
210  search_link = m_linked_list[search_link];
211  }
212  }
213  }
214 
215  // TODO: test if it gets faster by not reversing unneeded
216  std::reverse(q.begin(), q.end());
217 
218  return true;
219  }
220 
222 
223  // Mark the links as deleted
224  for(auto link : links) {
225  m_linked_list[link] = m_removed_counter;
226  }
227 
228  // Update the free list
229  {
230  Link free_link = m_free_start;
231  Link prev_free_link = free_link;
232  Link next_free_link = m_free_list[free_link];
233 
234  auto has_prev = [&](){ return prev_free_link != free_link; };
235  auto has_next = [&](){ return free_link != next_free_link; };
236 
237  auto update_free_list = [&](Link remove_link) {
238  while (free_link != remove_link) {
239  DCHECK(has_next());
240  prev_free_link = free_link;
241  free_link = next_free_link;
242  next_free_link = m_free_list[free_link];
243  }
244 
245  DCHECK_EQ(free_link, remove_link);
246 
247  if (has_prev() && has_next()) {
248  m_free_list[prev_free_link] = next_free_link;
249  free_link = next_free_link;
250  next_free_link = m_free_list[free_link];
251  } else if (has_prev() && !has_next()) {
252  DCHECK_EQ(m_free_end, free_link);
253 
254  m_free_list[prev_free_link] = prev_free_link;
255  m_free_end = prev_free_link;
256  free_link = next_free_link;
257  next_free_link = m_free_list[free_link];
258  } else if (!has_prev() && has_next()) {
259  DCHECK_EQ(m_free_start, free_link);
260 
261  m_free_start = next_free_link;
262  prev_free_link = next_free_link;
263  free_link = next_free_link;
264  next_free_link = m_free_list[free_link];
265  } else {
266  DCHECK_EQ(m_free_start, prev_free_link);
267  DCHECK_EQ(prev_free_link, free_link);
268  DCHECK_EQ(free_link, next_free_link);
269  DCHECK_EQ(next_free_link, m_free_end);
270  // NB: Can not fix free start and free end,
271  // but iteration ends after this, so its fine.
272  }
273  };
274 
275  if (links.size() < 2 || links[0] < links[1]) {
276  // forward
277  for (size_t i = 0; i < links.size(); i++) {
278  update_free_list(links[i]);
279  }
280  } else {
281  // reverse
282  for (size_t i = 0; i < links.size(); i++) {
283  update_free_list(links[links.size() - i - 1]);
284  }
285  }
286 
287  }
288 
289  m_removed_counter++;
290  m_layers.clear();
291  m_remaining_size -= links.size();
292 
293  // update the free list in the linked list
294  if (m_remaining_size > 0) {
295  Link link = m_free_start;
296  Link prev_link = link;
297  while(true) {
298  m_linked_list[link] = prev_link;
299  Link next = m_free_list[link];
300  if (link == next) {
301  break;
302  } else {
303  prev_link = link;
304  link = next;
305  }
306  }
307  }
308 
309  // DEBUG
310  /*
311  std::vector<size_t> fwd_addrs;
312  std::vector<size_t> bwd_addrs;
313  if (m_remaining_size > 0) {
314  Link link = m_free_start;
315  for (size_t i = 0; i < m_linked_list.size(); i++) {
316  if (i == link) {
317  fwd_addrs.push_back(link);
318  link = m_free_list[link];
319  } else {
320  }
321  }
322  } else {
323  DCHECK_EQ(m_free_start, m_free_end);
324  }
325  if (m_remaining_size > 0) {
326  Link link = m_free_end;
327  for (size_t i = 0; i < m_linked_list.size(); i++) {
328  if (m_linked_list.size() - i - 1 == link) {
329  bwd_addrs.push_back(link);
330  link = m_linked_list[link];
331  } else {
332  }
333  }
334  } else {
335  DCHECK_EQ(m_free_start, m_free_end);
336  }
337  std::reverse(bwd_addrs.begin(), bwd_addrs.end());
338  DCHECK(fwd_addrs == bwd_addrs)
339  << "\n" << vec_to_debug_string(m_linked_list) << "\n"
340  << "\n" << vec_to_debug_string(m_free_list) << "\n"
341  << "\n" << vec_to_debug_string(fwd_addrs) << "\n"
342  << "\n" << vec_to_debug_string(bwd_addrs) << "\n"
343  ;
344  */
345  /*
346  std::vector<size_t> fbv;
347  for (size_t i = 0; i < m_removed.size(); i++) {
348  if (m_removed[i] == uint_t<1>(0)) {
349  fbv.push_back(i);
350  }
351  }
352  DCHECK(fwd_addrs == fbv)
353  << "\n" << vec_to_debug_string(m_linked_list) << "\n"
354  << "\n" << vec_to_debug_string(m_free_list) << "\n"
355  << "\n" << vec_to_debug_string(fwd_addrs) << "\n"
356  << "\n" << vec_to_debug_string(fbv) << "\n"
357  << "\n"
358  ;
359  */
360  }
361 
362  inline std::vector<std::vector<Point>> to_debug_layer_points() {
363  std::vector<std::vector<Point>> r;
364  for (auto link : m_layers) {
365  std::vector<Point> list;
366 
367  while (true) {
368  list.push_back(point_coord_for_link(m_sindices, link, m_reverse));
369  if (m_linked_list[link] == link) {
370  break;
371  } else {
372  link = m_linked_list[link];
373  }
374  }
375 
376  r.push_back(std::move(list));
377  }
378  return r;
379  }
380 
381  inline size_t layers_size() {
382  return m_layers.size();
383  }
384 
385  inline Sindex sindex_for_link(Link link) {
386  return m_sindices[link];
387  }
388 
389  inline size_t sindices_size() {
390  return m_remaining_size;
391  }
392 
393  // Extract the linked list vector
394  inline std::vector<size_t> extract() && {
395  return std::move(m_linked_list);
396  }
397  };
398 
399  inline LayersIterator::LayersIterator(L& l, bool reverse):
400  m_reverse(reverse),
401  m_front(l.m_free_start),
402  m_back(l.m_free_end),
403  m_l(&l),
404  m_has_next(l.m_remaining_size > 0)
405  {}
406  inline void LayersIterator::debug() {
407  std::cout << "front: " << m_front << ", back: " << m_back << ", bits: ";
408  }
409  inline bool LayersIterator::has_next() {
410  return m_has_next;
411  }
413  if (m_front == m_back) {
414  m_has_next = false;
415  }
416 
417  //std::cout << "av: "; debug();
418  size_t r;
419  if (!m_reverse) {
420  r = m_back;
421  m_back = m_l->m_linked_list[m_back];
422  } else {
423  r = m_front;
424  m_front = m_l->m_free_list[m_front];
425  }
426 
427  //std::cout << "\n";
428  return r;
429  }
430 
431  struct Dpi_and_b {
432  std::vector<size_t> Dpi;
434  };
435 
436  template<typename SortedIndices, size_t tie_to_decreasing = false>
438  std::vector<size_t> Dpi;
439  auto b = IntVector<uint_t<1>> {};
440  {
441  auto l = esp::L(sorted_indices);
442  std::vector<esp::Link> links;
443  while (l.sindices_size() > 0) {
444  //auto phase = StatPhase("Iteration");
445  l.rebuild(false);
446  l.lis(l.layers_size(), links);
447 
448  l.rebuild(true);
449  if (!tie_to_decreasing && (links.size() == l.layers_size())) {
450  b.push_back(uint_t<1>(0));
451  } else if (tie_to_decreasing && (links.size() == l.layers_size())) {
452  l.lis(l.layers_size(), links);
453  b.push_back(uint_t<1>(1));
454  } else if (links.size() > l.layers_size()) {
455  b.push_back(uint_t<1>(0));
456  } else {
457  l.lis(l.layers_size(), links);
458  b.push_back(uint_t<1>(1));
459  }
460 
461  // links now contains the longer sequence
462  l.remove_all_and_slice(links);
463  }
464  Dpi = std::move(l).extract();
465  }
466 
467  return Dpi_and_b { std::move(Dpi), std::move(b) };
468  }
469 
470  template<typename SortedIndices, typename Dpi_t>
471  inline std::vector<size_t> create_dsigma_from_dpi_and_sorted_indices(
472  const SortedIndices& sorted_indices,
473  const Dpi_t& Dpi
474  ) {
475  auto Dsi = std::vector<size_t> {};
476  Dsi.reserve(sorted_indices.size());
477  Dsi.resize(sorted_indices.size());
478  for (size_t i = 0; i < sorted_indices.size(); i++) {
479  Dsi[sorted_indices[i]] = Dpi[i];
480  }
481  return Dsi;
482  }
483 
484  template<typename Dxx_t>
485  auto make_wt(const Dxx_t& v, size_t max_char) -> std::vector<IntVector<uint_t<1>>> {
486  auto rev = [](uint64_t x) -> uint64_t {
487  x = ((x & 0x5555555555555555ULL) << 1) | ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1);
488  x = ((x & 0x3333333333333333ULL) << 2) | ((x & 0xCCCCCCCCCCCCCCCCULL) >> 2);
489  x = ((x & 0x0F0F0F0F0F0F0F0FULL) << 4) | ((x & 0xF0F0F0F0F0F0F0F0ULL) >> 4);
490  x = ((x & 0x00FF00FF00FF00FFULL) << 8) | ((x & 0xFF00FF00FF00FF00ULL) >> 8);
491  x = ((x & 0x0000FFFF0000FFFFULL) <<16) | ((x & 0xFFFF0000FFFF0000ULL) >>16);
492  x = ((x & 0x00000000FFFFFFFFULL) <<32) | ((x & 0xFFFFFFFF00000000ULL) >>32);
493  return x;
494  };
495  auto wt_bvs = std::vector<IntVector<uint_t<1>>>();
496 
497  //std::cout << "v: " << vec_to_debug_string(v) << "\n";
498  //std::cout << "max_char: " << max_char << "\n";
499 
500  size_t wt_depth = 0;
501  while (max_char) {
502  max_char >>= 1;
503  ++wt_depth;
504  }
505  size_t alloc_size = (v.size() + 63ULL) >> 6;
506 
507  //std::cout << "alloc_size: " << alloc_size << "\n";
508  //std::cout << "wt_depth: " << wt_depth << "\n";
509 
510  if (wt_depth == 0) {
511  return wt_bvs;
512  }
513 
514  auto wt = wt_pc<size_t, size_t>(v, v.size(), wt_depth).get_bv();
515 
516  for (size_t i = 0; i < wt.size(); i++) {
517  IntVector<uint_t<1>> tmp;
518  tmp.reserve(v.size());
519  tmp.resize(v.size());
520  auto start = tmp.data();
521  auto end = start + alloc_size;
522  auto start2 = wt[i];
523  while (start != end) {
524  *start = rev(*start2);
525  start++;
526  start2++;
527  }
528 
529  //std::cout << vec_to_debug_string(tmp, 1) << "\n";
530  wt_bvs.push_back(std::move(tmp));
531  delete[] wt[i];
532 
533  }
534 
535  return wt_bvs;
536  }
537 
538  struct WTIter {
539  size_t m_start;
540  size_t m_end;
542  size_t m_depth;
543  size_t m_min_value;
544  size_t m_max_value;
547 
548  inline bool has_next() {
549  return m_start != m_end;
550  }
551 
552  inline size_t next() {
553  DCHECK(has_next());
554 
555  //std::cout << "next @ depth: " << m_depth << ", pos: " << m_start << "\n";
556 
557  size_t bit = (*m_bv)[m_start++];
558  if (m_next0 != nullptr) {
559  //std::cout << bit << "->";
560  if (bit == 0) {
561  return m_next0->next();
562  } else {
563  return m_next1->next();
564  }
565  } else {
566  DCHECK_EQ(m_max_value - m_min_value, 2)
567  << "\nmin: " << m_min_value << ", "
568  << "\nmax: " << m_max_value << ", "
569  << "\nstart: " << m_start << ", "
570  << "\nend: " << m_end << ", "
571  << "\nbs: " << vec_to_debug_string(*m_bv) << "\n";
572  if (bit == 0) {
573  return m_min_value;
574  } else {
575  return m_max_value - 1;
576  }
577  }
578  }
579  };
580 
581  auto extract_from_wt(const std::vector<std::vector<size_t>>& node_sizes,
582  const std::vector<IntVector<uint_t<1>>>& bvs,
583  size_t size) -> std::vector<size_t>
584  {
585  size_t count = 0;
586  for(size_t depth = 0; depth < bvs.size(); depth++) {
587  count = count * 2 + 1;
588  }
589 
590  std::vector<size_t> ret;
591 
592  if (count > 0) {
593  DCHECK_GT(count, 0);
594  size_t max_value = node_sizes.back().size() * 2;
595  //std::cout << "max value: " << max_value << "\n";
596 
597  auto iters = std::vector<WTIter>();
598  iters.reserve(count);
599  iters.resize(count);
600 
601  iters[0].m_min_value = 0;
602  iters[0].m_max_value = max_value;
603 
604  size_t iters_i = 0;
605  for(size_t depth = 0; depth < bvs.size(); depth++) {
606  auto& layer = node_sizes.at(depth);
607 
608  size_t layer_bv_offset = 0;
609  for(size_t node_i = 0; node_i < layer.size(); node_i++) {
610  size_t node_size = layer.at(node_i);
611  auto& iter = iters.at(iters_i);
612 
613  iter.m_start = layer_bv_offset;
614  iter.m_end = iter.m_start + node_size;
615  iter.m_bv = &bvs.at(depth);
616  iter.m_depth = depth;
617  iter.m_next0 = nullptr;
618  iter.m_next1 = nullptr;
619 
620  if (depth < (bvs.size() - 1)) {
621  auto& child0 = iters[iters_i * 2 + 1];
622  auto& child1 = iters[iters_i * 2 + 2];
623 
624  iter.m_next0 = &child0;
625  iter.m_next1 = &child1;
626 
627  size_t min = iter.m_min_value;
628  size_t max = iter.m_max_value;
629 
630  size_t mid = (max - min) / 2 + min;
631 
632  child0.m_min_value = min;
633  child0.m_max_value = mid;
634  child1.m_min_value = mid;
635  child1.m_max_value = max;
636  }
637 
638  iters_i++;
639  layer_bv_offset += node_size;
640  }
641  }
642 
643  ret.reserve(size);
644  while(iters[0].has_next()) {
645  ret.push_back(iters[0].next());
646  //std::cout << "\n";
647  }
648  } else {
649  ret.reserve(size);
650  ret.resize(size);
651  }
652 
653  //std::cout << "!!!:\n" << vec_to_debug_string(ret) << "\n";
654  return ret;
655  }
656 
657  auto recover_Dxx(const std::vector<IntVector<uint_t<1>>>& bvs,
658  size_t size) -> std::vector<size_t>
659  {
660  auto wt_sizes = std::vector<std::vector<size_t>> { { size } };
661  size_t wt_sizes_i = 0;
662  size_t sizes_sizes = 1;
663 
664  for (size_t bvs_i = 0; (bvs_i + 1) < bvs.size(); bvs_i++) {
665  auto& layer = bvs[bvs_i];
666  sizes_sizes *= 2;
667  auto wt_sizes_next = std::vector<size_t> {};
668  wt_sizes_next.reserve(sizes_sizes);
669  wt_sizes_next.resize(sizes_sizes);
670  size_t wt_sizes_next_i = 0;
671 
672  size_t start = 0;
673 
674  for(size_t w : wt_sizes[wt_sizes_i]) {
675  for(size_t i = start; i < (start + w); i++) {
676  size_t bit = layer[i];
677 
678  wt_sizes_next[wt_sizes_next_i * 2 + bit] += 1;
679  }
680  start += w;
681  wt_sizes_next_i++;
682  }
683 
684  wt_sizes.push_back(std::move(wt_sizes_next));
685  wt_sizes_i++;
686  }
687 
688  /*for(auto& e : wt_sizes) {
689  std::cout << "e: " << vec_to_debug_string(e) << "\n";
690  }*/
691 
692  //std::cout << "ok " << __LINE__ << "\n";
693 
694  return extract_from_wt(wt_sizes, bvs, size);
695  }
696 
697  template<typename Dxx_t, typename b_t, typename Bde_t, typename D_t>
698  auto recover_D_from_encoding(const Dxx_t& Dpi,
699  const Dxx_t& Dsi,
700  const b_t& b,
701  const Bde_t& Bde,
702  D_t* out)
703  {
704  std::vector<size_t> ss_ll;
705  ss_ll.reserve(Dpi.size());
706  ss_ll.resize(Dpi.size());
707 
708  std::vector<size_t> ss_ll_front;
709  ss_ll_front.reserve(b.size());
710  ss_ll_front.resize(b.size(), size_t(-1)); // NB: ensure there is n+1 bits space in real impl
711 
712  // based in Bdecoded and Dpi we know the sorted sequence.
713  // by mapping the Dsi sequence to it we get the original D
714 
715  for (size_t i = 0; i < Dpi.size(); i++) {
716  size_t list_i = Dpi[i];
717  if (ss_ll_front[list_i] == size_t(-1)) {
718  ss_ll_front[list_i] = i;
719  ss_ll[i] = i;
720  } else {
721  size_t root_node = ss_ll_front[list_i];
722  size_t root_node_next = ss_ll[root_node];
723 
724  ss_ll[root_node] = i;
725  ss_ll[i] = root_node_next;
726 
727  if (b[list_i] == uint_t<1>(1)) {
728  ss_ll_front[list_i] = i;
729  }
730  }
731  }
732 
733  for (size_t& link : ss_ll_front) {
734  link = ss_ll[link];
735  }
736 
737  auto& D = *out;
738  DCHECK_EQ(D.size(), Dpi.size());
739  for (size_t i = 0; i < Dsi.size(); i++) {
740  size_t j = Dsi.size() - i - 1;
741 
742  size_t list_i = Dsi[j];
743 
744  auto front = ss_ll_front[list_i];
745  ss_ll_front[list_i] = ss_ll[front];
746 
747  D[j] = Bde[front];
748  }
749  }
750 
751 }}
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
std::vector< size_t > extract() &&
std::vector< Sindex > sorted_indices(const View &input)
A vector over arbitrary unsigned integer types.
Definition: IntVector.hpp:175
std::string vec_to_debug_string(const T &s, size_t indent=0)
Builds the string representation of a vector of byte values, sorrounded by square brackets ([ and ])...
A const view into a slice of memory.
auto make_wt(const Dxx_t &v, size_t max_char) -> std::vector< IntVector< uint_t< 1 >>>
std::vector< size_t > Dpi
auto recover_D_from_encoding(const Dxx_t &Dpi, const Dxx_t &Dsi, const b_t &b, const Bde_t &Bde, D_t *out)
size_type size() const
Returns size of the View.
Point point_coord_for_link(ConstGenericView< Sindex > sindices, Link link, bool reverse)
void rebuild(bool reverse)
void remove_all_and_slice(ConstGenericView< size_t > links)
auto recover_Dxx(const std::vector< IntVector< uint_t< 1 >>> &bvs, size_t size) -> std::vector< size_t >
bool operator==(const Array< N, T > &lhs, const Array< N, T > &rhs)
Definition: HashArray.hpp:35
L(ConstGenericView< Sindex > sindices)
typename uint_dispatch_t< N >::type uint_t
Definition: uint_t.hpp:165
std::ostream & operator<<(std::ostream &o, const Point &a)
void resize(size_type n)
Definition: IntVector.hpp:327
LayersIterator(L &l, bool reverse)
std::vector< std::vector< Point > > to_debug_layer_points()
internal_data_type * data() noexcept
Definition: IntVector.hpp:405
std::vector< size_t > create_dsigma_from_dpi_and_sorted_indices(const SortedIndices &sorted_indices, const Dpi_t &Dpi)
IntVector< uint_t< 1 > > b
bool lis(size_t k, std::vector< size_t > &q)
Sindex sindex_for_link(Link link)
Point point_coord_if_at_index(Sindex self, size_t index)
const IntVector< uint_t< 1 > > * m_bv
bool dominates(Link lhs, Link rhs)
void reserve(size_type n)
Definition: IntVector.hpp:357
size_t layers_A_search(ConstGenericView< size_t > searchA, size_t piy)
auto extract_from_wt(const std::vector< std::vector< size_t >> &node_sizes, const std::vector< IntVector< uint_t< 1 >>> &bvs, size_t size) -> std::vector< size_t >
Dpi_and_b create_dpi_and_b_from_sorted_indices(const SortedIndices &sorted_indices)