tudocomp
– The TU Dortmund Compression Framework
DRCoder.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <tudocomp/Algorithm.hpp>
9 
10 namespace tdc {namespace esp {
11  //template<typename coder_t>
12  class DHuffman: public Algorithm {
13  public:
14  inline static Meta meta() {
15  Meta m("d_coding", "huffman");
16  //m.option("coder").templated<coder_t, HuffmanCoder>("coder");
17  return m;
18  };
19 
21 
22  template<typename rhs_t>
23  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
24  HuffmanEncoder encoder { out, rhs };
25 
26  for (size_t i = 0; i < rhs.size(); i++) {
27  encoder.encode(rhs[i]);
28  }
29  }
30  template<typename rhs_t>
31  inline void decode(rhs_t& rhs, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
32  HuffmanDecoder decoder { in };
33 
34  for (size_t i = 0; i < rhs.size(); i++) {
35  rhs[i] = decoder.decode();
36  }
37  }
38  };
39  class DArithmetic: public Algorithm {
40  public:
41  inline static Meta meta() {
42  Meta m("d_coding", "arithmetic");
43  //m.option("coder").templated<coder_t, HuffmanCoder>("coder");
44  return m;
45  };
46 
48 
49  template<typename rhs_t>
50  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
51  ArithmeticEncoder encoder { out, rhs };
52 
53  for (size_t i = 0; i < rhs.size(); i++) {
54  encoder.encode(rhs[i]);
55  }
56  }
57  template<typename rhs_t>
58  inline void decode(rhs_t& rhs, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
59  ArithmeticDecoder decoder { in };
60 
61  for (size_t i = 0; i < rhs.size(); i++) {
62  rhs[i] = decoder.decode();
63  }
64  }
65  };
66  class DPlain: public Algorithm {
67  public:
68  inline static Meta meta() {
69  Meta m("d_coding", "plain");
70  return m;
71  };
72 
74 
75  template<typename rhs_t>
76  inline void encode(const rhs_t& rhs, BitOStream& out, size_t bit_width, size_t max_value) const {
77  for(size_t i = 0; i < rhs.size(); i++) {
78  out.write_int(rhs[i], bit_width);
79  }
80  }
81  template<typename rhs_t>
82  inline void decode(rhs_t& rhs, BitIStream& in, size_t bit_width, size_t max_value) const {
83  for(size_t i = 0; i < rhs.size(); i++) {
84  rhs[i] = in.read_int<size_t>(bit_width);
85  }
86  }
87  template<typename rhs_t>
88  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
89  encode(rhs, *out, bit_width, max_value);
90  }
91  template<typename rhs_t>
92  inline void decode(rhs_t& rhs, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
93  decode(rhs, *in, bit_width, max_value);
94  }
95  };
96  class DWaveletTree: public Algorithm {
97  public:
98  inline static Meta meta() {
99  Meta m("d_coding", "wavelet_tree");
100  return m;
101  };
102 
103  using Algorithm::Algorithm;
104 
105  template<typename rhs_t>
106  inline void encode(const rhs_t& rhs, BitOStream& bout, size_t bit_width, size_t max_value) const {
107  auto bvs = make_wt(rhs, max_value);
108 
109  // write WT depth
110  bout.write_compressed_int(bvs.size());
111 
112  {
113  // write WT
114  for(auto& bv : bvs) {
115  for(uint8_t bit: bv) {
116  bout.write_bit(bit != 0);
117  }
118  }
119  }
120  }
121  template<typename rhs_t>
122  inline void decode(rhs_t& rhs, BitIStream& bin, size_t bit_width, size_t max_value) const {
123  // Read WT dept
124  size_t wt_depth = bin.read_compressed_int<size_t>();
125 
126  auto Dcombined_bvs = std::vector<IntVector<uint_t<1>>>();
127  Dcombined_bvs.reserve(wt_depth);
128  Dcombined_bvs.resize(wt_depth);
129  {
130  for(auto& bv : Dcombined_bvs) {
131  bv.reserve(rhs.size());
132 
133  for(size_t i = 0; i < rhs.size(); i++) {
134  bv.push_back(bin.read_bit());
135  }
136  }
137 
138  auto Dcombined = esp::recover_Dxx(Dcombined_bvs, rhs.size());
139  for (size_t i = 0; i < rhs.size(); i++) {
140  rhs[i] = Dcombined[i];
141  }
142  }
143  }
144  template<typename rhs_t>
145  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
146  encode(rhs, *out, bit_width, max_value);
147  }
148  template<typename rhs_t>
149  inline void decode(rhs_t& rhs, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
150  decode(rhs, *in, bit_width, max_value);
151  }
152  };
153  template<typename subseq_t = SubSeqOptimal, typename d_coding_t = DWaveletTree>
154  class DMonotonSubseq: public Algorithm {
155  public:
156  inline static Meta meta() {
157  Meta m("d_coding", "succinct");
158  m.option("subseq").templated<subseq_t, SubSeqOptimal>("subseq");
159  m.option("dx_coder").templated<d_coding_t, DWaveletTree>("d_coding");
160  return m;
161  };
162 
163  using Algorithm::Algorithm;
164  template<typename rhs_t>
165  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
166  BitOStream& bout = *out;
167 
168  auto phase1 = StatPhase("Sorting D");
169 
170  // Sort rhs and create sorted indice array O(n log n)
171  const auto sis = sorted_indices(rhs);
172 
173  //std::cout << "sis: " << vec_to_debug_string(sis) << "\n";
174 
175  phase1.split("Write out B array");
176 
177  // Write rules rhs in sorted order (B array of encoding)
178  {
179  size_t last = 0;
180  for (size_t i = 0; i < rhs.size(); i++) {
181  auto v = rhs[sis[i]];
182  //TMP_Bde.push_back(v);
183  DCHECK_LE(last, v);
184  size_t diff = v - last;
185  bout.write_unary(diff);
186  last = v;
187  }
188  }
189 
190  phase1.split("Create Dpi and b arrays");
191 
192  // Create Dpi and b
193  std::vector<size_t> Dpi;
194  auto b = IntVector<uint_t<1>> {};
195  {
196  const subseq_t subseq { this->env().env_for_option("subseq") };
197  auto tmp = subseq.create_dpi_and_b_from_sorted_indices(sis);
198  Dpi = std::move(tmp.Dpi);
199  b = std::move(tmp.b);
200  }
201  size_t b_size = b.size();
202  phase1.log_stat("Subsequence count", b_size);
203  //TMP_b = b;
204  //TMP_Dpi = Dpi;
205  DCHECK_GE(b_size, 1);
206 
207  //std::cout << "Dpi: " << vec_to_debug_string(Dpi) << "\n";
208  //std::cout << "b: " << vec_to_debug_string(b) << "\n";
209 
210  phase1.split("Write out b, discard");
211 
212  // Write out b and discard it
213  bout.write_compressed_int(b_size);
214  for(uint8_t e : b) {
215  bout.write_bit(e != 0);
216  }
217  b = IntVector<uint_t<1>> {};
218 
219  phase1.split("Create Dsi from Dpi");
221 
222  // TODO: change the two function to write in same vector
223  phase1.split("Combine Dsi and Dpi arrays");
224 
225  auto Dcombined = std::move(Dpi);
226  Dcombined.reserve(Dcombined.size() * 2);
227  for (auto x : Dsi) {
228  Dcombined.push_back(x);
229  }
230  Dsi = std::vector<size_t>();
231 
232  phase1.split("Encode Dcombined");
233 
234  const d_coding_t coder { this->env().env_for_option("dx_coder") };
235 
236  auto d_max_value = b_size - 1;
237  auto d_bit_width = bits_for(d_max_value);
238 
239  coder.encode(Dcombined, out, d_bit_width, d_max_value);
240  }
241  template<typename rhs_t>
242  inline void decode(rhs_t& D, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
243  BitIStream& bin = *in;
244  auto slp_size = D.size();
245 
246  // TODO: Read later, requires splitting up input a bit
247  // Read rules rhs in sorted order (B array)
248  std::vector<size_t> Bde;
249  Bde.reserve(slp_size);
250  {
251  size_t last = 0;
252  for(size_t i = 0; i < slp_size && !bin.eof(); i++) {
253  // ...
254  auto diff = bin.read_unary<size_t>();
255  last += diff;
256  Bde.push_back(last);
257  }
258  }
259  //std::cout << vec_to_debug_string(Bde) << "\n";
260 
261  // Read b
262  size_t b_size = bin.read_compressed_int<size_t>();
263  auto b = IntVector<uint_t<1>> {};
264  b.reserve(b_size);
265  b.resize(b_size);
266  for(size_t i = 0; i < b_size; i++) {
267  b[i] = bin.read_bit();
268  }
269 
270  // Read Dpi WT
271  // Read Dsi WT
272  auto Dcombined = std::vector<size_t>();
273  Dcombined.reserve(slp_size * 2);
274  Dcombined.resize(slp_size * 2);
275 
276  const d_coding_t coder { this->env().env_for_option("dx_coder") };
277 
278  auto d_max_value = b_size - 1;
279  auto d_bit_width = bits_for(d_max_value);
280 
281  coder.decode(Dcombined, in, d_bit_width, d_max_value);
282 
283  auto Dpi = ConstGenericView<size_t>(Dcombined).slice(0, slp_size);
284  auto Dsi = ConstGenericView<size_t>(Dcombined).slice(slp_size, slp_size * 2);
285 
286  esp::recover_D_from_encoding(Dpi, Dsi, b, Bde, &D);
287  }
288  };
289 
290 
291  template<typename vec_t>
292  inline auto encode_unary_diff(vec_t& vec,
293  BitOStream& out,
294  const size_t bit_width,
295  const size_t diff_bit_width,
296  const bool sign,
297  StatPhase& phase
298  ) -> uint64_t {
299  auto cvec = [&](size_t i) -> size_t {
300  return size_t(typename vec_t::value_type(vec[i]));
301  };
302 
303  uint64_t written_bits = 0;
304 
305  size_t last;
306 
307  uint64_t unary_sep_bit_counter = 0;
308  uint64_t unary_val_bit_counter = 0;
309  uint64_t unary_sign_bit_counter = 0;
310 
311  last = 0;
312  for(size_t i = 0; i < vec.size(); i++) {
313  const size_t current = cvec(i);
314  size_t diff;
315  if (current >= last) {
316  diff = current - last;
317  } else {
318  diff = last - current;
319  }
320 
321  unary_sep_bit_counter += 1;
322  unary_val_bit_counter += diff;
323  if (diff != 0) {
324  unary_sign_bit_counter += 1;
325  }
326  last = current;
327  }
328 
329  uint64_t diff_val_counter = unary_sign_bit_counter;
330  if (vec.size() > 0 && cvec(0) == 0) {
331  diff_val_counter++;
332  }
333 
334  const uint64_t bits_unary
335  = unary_sep_bit_counter + unary_val_bit_counter + unary_sign_bit_counter;
336  const uint64_t bits_binary
337  = (diff_val_counter) * (bit_width + diff_bit_width) // size change entry
338  ;
339 
340  phase.log_stat("predicted unary bits", bits_unary);
341  phase.log_stat("predicted binary bits", bits_binary);
342 
343  const bool use_unary = (bits_unary <= bits_binary);
344  out.write_bit(use_unary);
345  written_bits++;
346 
347  phase.log_stat("use unary", use_unary);
348 
349  /*
350  std::cout
351  << "bits unary: " << bits_unary
352  << ", bits_binary: " << bits_binary
353  << ", use unary: " << (use_unary ? "true" : "false")
354  << "\n";
355  */
356 
357  if (use_unary) {
358  size_t diff_sign_bits = 0;
359  size_t sign_bits = 0;
360 
361  last = 0;
362  for(size_t i = 0; i < vec.size(); i++) {
363  const size_t current = cvec(i);
364  size_t diff;
365  if (current >= last) {
366  diff = current - last;
367  } else {
368  diff = last - current;
369  }
370  out.write_unary(diff);
371  written_bits += (diff + 1);
372  last = current;
373  diff_sign_bits += (diff + 1);
374  }
375  phase.log_stat("diff bits", diff_sign_bits);
376 
377  if (sign) {
378  last = 0;
379  for(size_t i = 0; i < vec.size(); i++) {
380  const size_t current = cvec(i);
381 
382  if (last < current) {
383  out.write_bit(true);
384  sign_bits++;
385  written_bits++;
386  } else if (last > current) {
387  out.write_bit(false);
388  sign_bits++;
389  written_bits++;
390  }
391 
392  last = current;
393  }
394  phase.log_stat("sign bits", sign_bits);
395  }
396 
397  CHECK_EQ(diff_sign_bits + sign_bits, bits_unary);
398  } else {
399  size_t out_counter = 0;
400  size_t last_value = 0;
401  size_t value_counter = 0;
402  size_t binary_bits = 0;
403 
404  for(size_t i = 0; i < vec.size(); i++) {
405  const size_t current = cvec(i);
406 
407  if (current == last_value) {
408  value_counter++;
409  continue;
410  } else {
411  if (value_counter > 0) {
412  out.write_int<size_t>(value_counter, bit_width);
413  out.write_int<size_t>(last_value, diff_bit_width);
414  binary_bits += (bit_width + diff_bit_width);
415  written_bits += (bit_width + diff_bit_width);
416  out_counter++;
417  }
418 
419  last_value = current;
420  value_counter = 1;
421  }
422  }
423  if (value_counter > 0) {
424  out.write_int<size_t>(value_counter, bit_width);
425  out.write_int<size_t>(last_value, diff_bit_width);
426  binary_bits += (bit_width + diff_bit_width);
427  written_bits += (bit_width + diff_bit_width);
428  out_counter++;
429  }
430 
431  phase.log_stat("binary bits", binary_bits);
432 
433  CHECK_EQ(binary_bits, bits_binary);
434  CHECK_EQ(out_counter, diff_val_counter);
435  }
436  return written_bits;
437  }
438 
439  template<typename vec_t>
440  inline void decode_unary_diff(vec_t& vec,
441  BitIStream& in,
442  const size_t bit_width,
443  const size_t diff_bit_width,
444  const bool sign) {
445  auto cvec = [&](size_t i) -> size_t {
446  return size_t(typename vec_t::value_type(vec[i]));
447  };
448 
449  const bool use_unary = in.read_bit();
450 
451  if (use_unary) {
452  for(size_t i = 0; i < vec.size(); i++) {
453  vec[i] = in.read_unary<size_t>();
454  }
455 
456  size_t last = 0;
457  for(size_t i = 0; i < vec.size(); i++) {
458  const size_t diff = cvec(i);
459  if (diff != 0) {
460  if (sign) {
461  if (in.read_bit()) {
462  last += diff;
463  } else {
464  last -= diff;
465  }
466  } else {
467  last += diff;
468  }
469  }
470  vec[i] = last;
471  }
472  } else {
473  size_t vec_i = 0;
474  while(vec_i < vec.size()) {
475  const size_t repeats = in.read_int<size_t>(bit_width);
476  const size_t val = in.read_int<size_t>(diff_bit_width);
477  const size_t vec_i_end = vec_i + repeats;
478  for (; vec_i < vec_i_end; vec_i++) {
479  vec[vec_i] = val;
480  }
481  }
482  }
483  }
484 
485  class DDiff: public Algorithm {
486  public:
487  inline static Meta meta() {
488  Meta m("d_coding", "diff");
489  return m;
490  };
491 
492  using Algorithm::Algorithm;
493 
494  template<typename rhs_t>
495  inline void encode(const rhs_t& rhs, BitOStream& out, size_t bit_width, size_t max_value) const {
496  auto phase = StatPhase("RangeFit");
497  encode_unary_diff(rhs, out, bit_width, bit_width, true, phase);
498  }
499  template<typename rhs_t>
500  inline void decode(rhs_t& rhs, BitIStream& in, size_t bit_width, size_t max_value) const {
501  decode_unary_diff(rhs, in, bit_width, bit_width, true);
502  }
503  template<typename rhs_t>
504  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
505  encode(rhs, *out, bit_width, max_value);
506  }
507  template<typename rhs_t>
508  inline void decode(rhs_t& rhs, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
509  decode(rhs, *in, bit_width, max_value);
510  }
511  };
512 
513  class DRangeFit: public Algorithm {
514  inline static bool perc_diff(double a, double b, double diff) {
515  auto r = std::abs((a - b) / ((a + b) / 2.0)) <= diff;
516  /*
517  if (r && (a != b)) {
518  std::cout << a << " too close to " << b << "\n";
519  }
520  */
521  return r;
522  }
523  public:
524  inline static Meta meta() {
525  Meta m("d_coding", "range_fit");
526  m.option("threshold").dynamic("none"); // "none"
527  m.option("wt").dynamic(false); // false
528  m.option("zero_min").dynamic(false); // false
529  return m;
530  };
531 
532  using Algorithm::Algorithm;
533 
534  template<typename rhs_t>
535  inline void encode(const rhs_t& rhs, BitOStream& out, size_t bit_width, size_t max_value) const {
536  auto phase = StatPhase("RangeFit");
537  const size_t size = rhs.size();
538 
539  const bool has_threshold = env().option("threshold").as_string() != "none";
540  double threshold = 0.0;
541  if (has_threshold) {
542  threshold = double(env().option("threshold").as_integer()) / 100.0;
543  }
544  const bool use_wt = env().option("wt").as_bool();
545  const bool use_zero_min = env().option("zero_min").as_bool();
546 
547  std::vector<size_t> mins;
548  mins.reserve(size);
549  mins.resize(size);
550 
551  size_t min = size_t(-1);
552  for(size_t i = 0; i < size; i++) {
553  const size_t j = size - i - 1;
554  const size_t current = rhs[j];
555 
556  if (current < min) {
557  min = current;
558  }
559  mins[j] = min;
560  }
561 
562  if (has_threshold) {
563  size_t last = 0;
564  for(size_t i = 0; i < size; i++) {
565  if (perc_diff(mins[i], last, threshold)) {
566  DCHECK_GE(mins[i], last);
567  mins[i] = last;
568  }
569  last = mins[i];
570  }
571  }
572 
573  if (!use_wt) {
574  // TODO: Potential bug if bit width == 64 ?
575  IntVector<uint_t<6>> bit_ranges;
576  bit_ranges.reserve(size);
577 
578  size_t max = 0;
579  size_t last_min_flush = 0;
580  for(size_t i = 0; i < size; i++) {
581  const size_t current = rhs[i];
582  if (current > max) {
583  max = current;
584  }
585 
586  // Insert check here
587  if (use_zero_min) {
588  const size_t min = mins[i];
589  const size_t min_max_bits = bits_for(max - min);
590  const size_t max_bits = bits_for(max - 0);
591  if (max_bits == min_max_bits && last_min_flush == 0) {
592  mins[i] = 0;
593  }
594  last_min_flush = mins[i];
595  }
596 
597  const size_t min = mins[i];
598  const size_t range = max - min;
599  bit_ranges.push_back(bits_for(range));
600  }
601 
602  uint64_t writte_bits_mins =
603  encode_unary_diff(mins, out, bit_width, bit_width, false, phase);
604  uint64_t written_bits_bit_range =
605  encode_unary_diff(bit_ranges, out, bit_width, 64, true, phase);
606 
607  uint64_t written_bits_values = 0;
608  for(size_t i = 0; i < size; i++) {
609  const size_t current = rhs[i];
610  const size_t min = mins[i];
611  const size_t compact_value = current - min;
612  const size_t bits = size_t(uint_t<6>(bit_ranges[i]));
613  written_bits_values += bits;
614 
615  out.write_int<size_t>(compact_value, bits);
616  }
617 
618  phase.log_stat("writte_bits_mins", writte_bits_mins);
619  phase.log_stat("written_bits_bit_range", written_bits_bit_range);
620  phase.log_stat("written_bits_values", written_bits_values);
621  phase.log_stat("written_bits_all",
622  writte_bits_mins + written_bits_bit_range + written_bits_values
623  );
624  phase.log_stat("written_bits_all_plain", rhs.size() * bit_width);
625  phase.log_stat("elements", rhs.size());
626  phase.log_stat("max_bit_width", bit_width);
627  } else {
628  std::vector<size_t> maxs;
629  maxs.reserve(size);
630  maxs.resize(size);
631 
632  size_t max = 0;
633  for(size_t i = 0; i < size; i++) {
634  const size_t current = rhs[i];
635 
636  if (current > max) {
637  max = current;
638  }
639  maxs[i] = max;
640  }
641 
642  if (has_threshold) {
643  size_t last = size_t(-1);
644  for(size_t i = 0; i < size; i++) {
645  const size_t j = size - i - 1;
646 
647  if (perc_diff(maxs[j], last, threshold)) {
648  DCHECK_LE(maxs[j], last);
649  maxs[j] = last;
650  }
651  last = maxs[j];
652  }
653  }
654 
655  std::vector<size_t> ranges;
656  ranges.reserve(size);
657  ranges.resize(size);
658 
659  size_t last_min_flush = 0;
660  for(size_t i = 0; i < size; i++) {
661  if (use_zero_min) {
662  const size_t bits_min_max = bits_for(maxs[i] - mins[i]);
663  const size_t bits_max = bits_for(maxs[i] - 0);
664  if (bits_min_max == bits_max && last_min_flush == 0) {
665  mins[i] = 0;
666  }
667  last_min_flush = mins[i];
668  }
669 
670  ranges[i] = maxs[i] - mins[i];
671  }
672 
673  if (has_threshold) {
674  size_t last = 0;
675  for(size_t i = 0; i < size; i++) {
676  const size_t j = size - i - 1;
677 
678  if (ranges[j] < last) {
679  if (perc_diff(ranges[j], last, threshold)) {
680  DCHECK_LE(ranges[j], last);
681  ranges[j] = last;
682  }
683  }
684  last = ranges[j];
685  }
686  }
687  if (has_threshold) {
688  size_t last = 0;
689  for(size_t i = 0; i < size; i++) {
690  if (ranges[i] < last) {
691  if (perc_diff(ranges[i], last, threshold)) {
692  DCHECK_LE(ranges[i], last);
693  ranges[i] = last;
694  }
695  }
696  last = ranges[i];
697  }
698  }
699 
700  encode_unary_diff(mins, out, bit_width, bit_width, false, phase);
701  encode_unary_diff(ranges, out, bit_width, bit_width, true, phase);
702 
703  size_t range_chunk_i = 0;
704  while (range_chunk_i < ranges.size()) {
705  size_t range_chunk_j = range_chunk_i;
706  while(range_chunk_j < ranges.size()
707  && (ranges[range_chunk_j] == ranges[range_chunk_i])) {
708  range_chunk_j++;
709  }
710 
711  {
712  const auto range = ranges[range_chunk_i];
713 
714  struct ChunkView {
715  const std::vector<size_t>* mins;
716  const rhs_t* vals;
717  size_t i;
718  size_t j;
719 
720  inline size_t operator[](size_t x) const {
721  return (*vals)[x + i] - (*mins)[x + i];
722  }
723 
724  inline size_t size() const {
725  return j - i;
726  }
727  };
728 
729  auto cv = ChunkView {
730  &mins,
731  &rhs,
732  range_chunk_i,
733  range_chunk_j,
734  };
735 
736  auto bvs = esp::make_wt(cv, range);
737 
738  if (range == 0) {
739  DCHECK_EQ(bvs.size(), bits_for(range) - 1);
740  } else {
741  DCHECK_EQ(bvs.size(), bits_for(range));
742  }
743 
744  for(const auto& bv : bvs) {
745  size_t tnull = 0;
746 
747  for(size_t i = 0; i < cv.size(); i++) {
748  size_t j = cv.size() - i - 1;
749  if (bv[j] == 0u) {
750  tnull++;
751  } else {
752  break;
753  }
754  }
755 
756  out.write_int<size_t>(tnull, bits_for(cv.size()));
757 
758  for(size_t i = 0; i < cv.size() - tnull; i++) {
759  out.write_bit(bv[i]);
760  }
761  }
762  }
763 
764  range_chunk_i = range_chunk_j;
765  }
766  }
767  }
768  template<typename rhs_t>
769  inline void decode(rhs_t& rhs, BitIStream& in, size_t bit_width, size_t max_value) const {
770  const size_t size = rhs.size();
771  const bool use_wt = env().option("wt").as_bool();
772 
773  std::vector<size_t> mins;
774  mins.reserve(size);
775  mins.resize(size);
776  decode_unary_diff(mins, in, bit_width, bit_width, false);
777 
778 
779  if (!use_wt) {
780  IntVector<uint_t<6>> bit_ranges;
781  bit_ranges.reserve(size);
782  bit_ranges.resize(size);
783 
784  decode_unary_diff(bit_ranges, in, bit_width, 64, true);
785 
786  for(size_t i = 0; i < size; i++) {
787  rhs[i] = in.read_int<size_t>(size_t(uint_t<6>(bit_ranges[i]))) + mins[i];
788  }
789  } else {
790  std::vector<size_t> ranges;
791  ranges.reserve(size);
792  ranges.resize(size);
793 
794  decode_unary_diff(ranges, in, bit_width, bit_width, true);
795 
796  size_t range_chunk_i = 0;
797  while (range_chunk_i < ranges.size()) {
798  size_t range_chunk_j = range_chunk_i;
799  while(range_chunk_j < ranges.size()
800  && (ranges[range_chunk_j] == ranges[range_chunk_i])) {
801  range_chunk_j++;
802  }
803 
804  {
805  const auto range = ranges[range_chunk_i];
806  size_t cv_size = range_chunk_j - range_chunk_i;
807 
808  size_t bv_c = 0;
809  if (range == 0) {
810  bv_c = bits_for(range) - 1;
811  } else {
812  bv_c = bits_for(range);
813  }
814 
815 
816  std::vector<IntVector<uint_t<1>>> bvs(bv_c);
817  for(size_t bv_i = 0; bv_i < bv_c; bv_i++) {
818  auto& bv = bvs[bv_i];
819  size_t tnull = in.read_int<size_t>(bits_for(cv_size));
820 
821  bv = IntVector<uint_t<1>>(cv_size);
822  for(size_t i = 0; i < cv_size - tnull; i++) {
823  bv[i] = in.read_bit();
824  }
825  for(size_t i = cv_size - tnull; i < cv_size; i++) {
826  bv[i] = 0;
827  }
828  }
829 
830  auto vec = recover_Dxx(bvs, cv_size);
831 
832  for(size_t i = range_chunk_i; i < range_chunk_j; i++) {
833  rhs[i] = vec[i - range_chunk_i] + mins[i];
834  }
835  }
836 
837  range_chunk_i = range_chunk_j;
838  }
839  }
840  }
841  template<typename rhs_t>
842  inline void encode(const rhs_t& rhs, std::shared_ptr<BitOStream>& out, size_t bit_width, size_t max_value) const {
843  encode(rhs, *out, bit_width, max_value);
844  }
845  template<typename rhs_t>
846  inline void decode(rhs_t& rhs, std::shared_ptr<BitIStream>& in, size_t bit_width, size_t max_value) const {
847  decode(rhs, *in, bit_width, max_value);
848  }
849  };
850 }}
T read_compressed_int(size_t b=7)
Reads a compressed integer from the input.
Definition: BitIStream.hpp:175
Contains the text compression and encoding framework.
Definition: namespaces.hpp:11
void decode(rhs_t &rhs, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:149
constexpr uint_fast8_t bits_for(size_t n)
Computes the number of bits required to store the given integer value.
Encodes data to an ASCII character stream.
Provides meta information about an Algorithm.
Definition: Meta.hpp:34
std::vector< Sindex > sorted_indices(const View &input)
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:504
A vector over arbitrary unsigned integer types.
Definition: IntVector.hpp:175
static Meta meta()
Definition: DRCoder.hpp:68
void write_bit(bool set)
Writes a single bit to the output.
Definition: BitOStream.hpp:79
Env env_for_option(const std::string &option) const
Create the environment for a sub algorithm option.
Definition: Env.hpp:34
const std::string & as_string() const
A const view into a slice of memory.
void decode(rhs_t &rhs, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:846
const OptionValue & option(const std::string &option) const
Get an option of this algorithm.
Definition: Env.hpp:44
void push_back(const value_type &val)
Definition: IntVector.hpp:426
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:842
Decodes data from an Arithmetic character stream.
auto make_wt(const Dxx_t &v, size_t max_char) -> std::vector< IntVector< uint_t< 1 >>>
void write_unary(value_t v)
Definition: BitOStream.hpp:105
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:23
Wrapper for input streams that provides bitwise reading functionality.
Definition: BitIStream.hpp:16
void decode(rhs_t &rhs, BitIStream &bin, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:122
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:50
auto recover_D_from_encoding(const Dxx_t &Dpi, const Dxx_t &Dsi, const b_t &b, const Bde_t &Bde, D_t *out)
void encode(const rhs_t &rhs, BitOStream &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:535
Provides access to runtime and memory measurement in statistics phases.
Definition: StatPhase.hpp:44
Algorithm(Algorithm const &)=default
void decode(rhs_t &D, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:242
auto recover_Dxx(const std::vector< IntVector< uint_t< 1 >>> &bvs, size_t size) -> std::vector< size_t >
void encode(const rhs_t &rhs, BitOStream &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:76
void decode(rhs_t &rhs, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:92
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:165
Encodes data to an ASCII character stream.
static Meta meta()
Definition: DRCoder.hpp:41
typename uint_dispatch_t< N >::type uint_t
Definition: uint_t.hpp:165
Env & env()
Provides access to the environment that the algorithm works in.
Definition: Algorithm.hpp:51
static Meta meta()
Definition: DRCoder.hpp:14
void resize(size_type n)
Definition: IntVector.hpp:327
Wrapper for output streams that provides bitwise writing functionality.
Definition: BitOStream.hpp:17
void decode(rhs_t &rhs, BitIStream &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:82
static Meta meta()
Definition: DRCoder.hpp:487
void decode(rhs_t &rhs, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:508
bool as_bool() const
std::vector< size_t > create_dsigma_from_dpi_and_sorted_indices(const SortedIndices &sorted_indices, const Dpi_t &Dpi)
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:145
void encode(const rhs_t &rhs, BitOStream &bout, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:106
void write_compressed_int(T v, size_t b=7)
Writes a compressed integer to the input.
Definition: BitOStream.hpp:151
static Meta meta()
Definition: DRCoder.hpp:98
void encode(const rhs_t &rhs, BitOStream &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:495
void templated(const std::string &accepted_type)
Declares that this option accepts values of the specified Algorithm type T.
Definition: Meta.hpp:93
void decode(rhs_t &rhs, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:58
static Meta meta()
Definition: DRCoder.hpp:156
void decode_unary_diff(vec_t &vec, BitIStream &in, const size_t bit_width, const size_t diff_bit_width, const bool sign)
Definition: DRCoder.hpp:440
void write_int(T value, size_t bits=sizeof(T) *CHAR_BIT)
Writes the bit representation of an integer in MSB first order to the output.
Definition: BitOStream.hpp:98
auto encode_unary_diff(vec_t &vec, BitOStream &out, const size_t bit_width, const size_t diff_bit_width, const bool sign, StatPhase &phase) -> uint64_t
Definition: DRCoder.hpp:292
void reserve(size_type n)
Definition: IntVector.hpp:357
static Meta meta()
Definition: DRCoder.hpp:524
void decode(rhs_t &rhs, BitIStream &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:500
OptionBuilder option(const std::string &name)
Declares an accepted option for this algorithm.
Definition: Meta.hpp:216
bool eof() const
TODO document.
Definition: BitIStream.hpp:191
uint8_t read_bit()
Reads the next single bit from the input.
Definition: BitIStream.hpp:91
void decode(rhs_t &rhs, BitIStream &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:769
Interface for algorithms.
Definition: Algorithm.hpp:15
void decode(rhs_t &rhs, std::shared_ptr< BitIStream > &in, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:31
T read_int(size_t amount=sizeof(T) *CHAR_BIT)
Reads the integer value of the next amount bits in MSB first order.
Definition: BitIStream.hpp:119
void dynamic()
Declares that this option accepts values of a simple type that can be parsed from a string (e...
Definition: Meta.hpp:150
Decodes data from an Huffman character stream.
void encode(const rhs_t &rhs, std::shared_ptr< BitOStream > &out, size_t bit_width, size_t max_value) const
Definition: DRCoder.hpp:88