FST  openfst-1.8.3
OpenFst Library
elias.h
Go to the documentation of this file.
1 // Copyright 2005-2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the 'License');
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an 'AS IS' BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // Compresses and decompresses unweighted FSTs.
19 
20 #ifndef FST_EXTENSIONS_COMPRESS_ELIAS_H_
21 #define FST_EXTENSIONS_COMPRESS_ELIAS_H_
22 
23 #include <stack>
24 #include <vector>
25 
26 #include <fst/compat.h>
27 namespace fst {
28 
29 template <class Var>
30 class Elias {
31  public:
32  // A subroutine for Delta encoding.
33  static void GammaEncode(const Var &input, std::vector<bool> *code);
34 
35  // Elias Delta encoding for a single integer.
36  static void DeltaEncode(const Var &input, std::vector<bool> *code);
37 
38  // Batch decoding of a set of integers.
39  static void BatchDecode(const std::vector<bool> &input,
40  std::vector<Var> *output);
41 };
42 
43 template <class Var>
44 void Elias<Var>::GammaEncode(const Var &input, std::vector<bool> *code) {
45  Var input_copy = input;
46  std::stack<bool> reverse_code;
47  while (input_copy > 0) {
48  reverse_code.push(input_copy % 2);
49  input_copy = input_copy / 2;
50  }
51  code->resize(reverse_code.size() - 1, false);
52  while (!reverse_code.empty()) {
53  code->push_back(reverse_code.top());
54  reverse_code.pop();
55  }
56 }
57 
58 template <class Var>
59 void Elias<Var>::DeltaEncode(const Var &input, std::vector<bool> *code) {
60  Var input_copy = input + 1;
61  std::stack<bool> reverse_remainder;
62  Var auxvar = 0;
63  while (input_copy != 0) {
64  reverse_remainder.push(input_copy % 2);
65  input_copy = input_copy / 2;
66  auxvar = auxvar + 1;
67  }
68  GammaEncode(auxvar, code);
69  reverse_remainder.pop();
70  while (!reverse_remainder.empty()) {
71  code->push_back(reverse_remainder.top());
72  reverse_remainder.pop();
73  }
74 }
75 
76 template <class Var>
77 void Elias<Var>::BatchDecode(const std::vector<bool> &input,
78  std::vector<Var> *output) {
79  Var lead_zeros = 0;
80  Var remainder_bits = 0;
81  Var current_word = 1;
82  Var value = 1;
83  for (auto it = input.cbegin(); it != input.cend();) {
84  lead_zeros = 0;
85  remainder_bits = 0;
86  current_word = 1;
87  value = 1;
88  while (!*it) {
89  ++it;
90  ++lead_zeros;
91  }
92  ++it;
93  while (lead_zeros > 0) {
94  --lead_zeros;
95  current_word = 2 * current_word + *it;
96  ++it;
97  }
98  --current_word;
99  while (current_word > 0) {
100  value = 2 * value + *it;
101  --current_word;
102  ++it;
103  }
104  output->push_back(value - 1);
105  }
106 }
107 
108 } // namespace fst
109 
110 #endif // FST_EXTENSIONS_COMPRESS_ELIAS_H_
static void GammaEncode(const Var &input, std::vector< bool > *code)
Definition: elias.h:44
static void BatchDecode(const std::vector< bool > &input, std::vector< Var > *output)
Definition: elias.h:77
static void DeltaEncode(const Var &input, std::vector< bool > *code)
Definition: elias.h:59