FST  openfst-1.7.2
OpenFst Library
sparse-power-weight.h
Go to the documentation of this file.
1 // See www.openfst.org for extensive documentation on this weighted
2 // finite-state transducer library.
3 //
4 // Cartesian power weight semiring operation definitions, using
5 // SparseTupleWeight as underlying representation.
6 
7 #ifndef FST_SPARSE_POWER_WEIGHT_H_
8 #define FST_SPARSE_POWER_WEIGHT_H_
9 
10 #include <climits>
11 #include <string>
12 
14 #include <fst/weight.h>
15 
16 
17 namespace fst {
18 
19 // Sparse cartesian power semiring: W ^ n
20 //
21 // Forms:
22 //
23 // - a left semimodule when W is a left semiring,
24 // - a right semimodule when W is a right semiring,
25 // - a bisemimodule when W is a semiring,
26 // the free semimodule of rank n over W
27 //
28 // The Times operation is overloaded to provide the left and right scalar
29 // products.
30 //
31 // K is the key value type. kNoKey (-1) is reserved for internal use
32 template <class W, class K = int>
33 class SparsePowerWeight : public SparseTupleWeight<W, K> {
34  public:
36 
38 
40  : SparseTupleWeight<W, K>(weight) {}
41 
42  template <class Iterator>
44  : SparseTupleWeight<W, K>(begin, end) {}
45 
46  // Initialize component `key` to `weight`, with `default_weight` for all
47  // other components.
48  SparsePowerWeight(const K &key, const W &weight,
49  const W &default_weight = W::Zero())
50  : SparseTupleWeight<W, K>(key, weight, default_weight) {}
51 
52  static const SparsePowerWeight &Zero() {
54  return zero;
55  }
56 
57  static const SparsePowerWeight &One() {
59  return one;
60  }
61 
62  static const SparsePowerWeight &NoWeight() {
63  static const SparsePowerWeight no_weight(
65  return no_weight;
66  }
67 
68  // Overide this: Overwrite the Type method to reflect the key type if using
69  // a non-default key type.
70  static const string &Type() {
71  static const string *const type = [] {
72  string type = W::Type() + "_^n";
73  if (sizeof(K) != sizeof(uint32)) {
74  type += "_" + std::to_string(CHAR_BIT * sizeof(K));
75  }
76  return new string(type);
77  }();
78  return *type;
79  }
80 
81  static constexpr uint64 Properties() {
82  return W::Properties() &
84  }
85 
86  SparsePowerWeight Quantize(float delta = kDelta) const {
88  }
89 
92  }
93 };
94 
95 template <class W, class K, class M>
97  const SparsePowerWeight<W, K> &w1,
98  const SparsePowerWeight<W, K> &w2,
99  const M &operator_mapper) {
101  SparseTupleWeightMap(&result, w1, w2, operator_mapper);
102  return result;
103 }
104 
105 // Semimodule plus operation.
106 template <class W, class K>
108  const SparsePowerWeight<W, K> &w2) {
109  return SparsePowerWeightMap(w1, w2, [](const K &k, const W &v1, const W &v2) {
110  return Plus(v1, v2);
111  });
112 }
113 
114 // Semimodule times operation.
115 template <class W, class K>
117  const SparsePowerWeight<W, K> &w2) {
118  return SparsePowerWeightMap(w1, w2, [](const K &k, const W &v1, const W &v2) {
119  return Times(v1, v2);
120  });
121 }
122 
123 // Semimodule divide operation.
124 template <class W, class K>
126  const SparsePowerWeight<W, K> &w2,
127  DivideType type = DIVIDE_ANY) {
128  return SparsePowerWeightMap(w1, w2,
129  [type](const K &k, const W &v1, const W &v2) {
130  return Divide(v1, v2, type);
131  });
132 }
133 
134 // Semimodule dot product operation.
135 template <class W, class K>
136 inline const W &DotProduct(const SparsePowerWeight<W, K> &w1,
137  const SparsePowerWeight<W, K> &w2) {
138  const SparsePowerWeight<W, K> product = Times(w1, w2);
139  W result(W::Zero());
140  for (SparseTupleWeightIterator<W, K> it(product); !it.Done(); it.Next()) {
141  result = Plus(result, it.Value().second);
142  }
143  return result;
144 }
145 
146 template <class W, class K>
147 inline bool ApproxEqual(const SparsePowerWeight<W, K> &w1,
148  const SparsePowerWeight<W, K> &w2,
149  float delta = kDelta) {
150  auto result = SparsePowerWeightMap(
151  w1, w2, [delta](const K &k, const W &v1, const W &v2) {
152  return ApproxEqual(v1, v2, delta) ? W::One() : W::Zero();
153  });
154  return result == SparsePowerWeight<W, K>::One();
155 }
156 
157 template <class W, class K>
158 inline SparsePowerWeight<W, K> Times(const W &k,
159  const SparsePowerWeight<W, K> &w2) {
160  const SparseTupleWeight<W, K> t2(k);
161  const SparsePowerWeight<W, K> w1(t2);
162  return Times(w1, w2);
163 }
164 
165 template <class W, class K>
167  const W &k) {
168  const SparseTupleWeight<W, K> t2(k);
169  const SparsePowerWeight<W, K> w2(t2);
170  return Times(w1, w2);
171 }
172 
173 template <class W, class K>
175  const W &k,
176  DivideType divide_type = DIVIDE_ANY) {
177  const SparseTupleWeight<W, K> t2(k);
178  const SparsePowerWeight<W, K> w2(t2);
179  return Divide(w1, w2, divide_type);
180 }
181 
182 // This function object generates weights over the Cartesian power of rank
183 // n over the underlying weight. This is intended primarily for testing.
184 template <class W, class K>
186  public:
189 
190  explicit WeightGenerate(bool allow_zero = true,
191  size_t sparse_power_rank = 3)
192  : generate_(allow_zero), sparse_power_rank_(sparse_power_rank) {}
193 
194  Weight operator()() const {
195  Weight weight;
196  for (size_t i = 1; i <= sparse_power_rank_; ++i) {
197  weight.PushBack(i, generate_(), true);
198  }
199  return weight;
200  }
201 
202  private:
203  const Generate generate_;
204  const size_t sparse_power_rank_;
205 };
206 
207 } // namespace fst
208 
209 #endif // FST_SPARSE_POWER_WEIGHT_H_
void PushBack(const K &key, const W &weight, bool default_value_check=true)
SparsePowerWeight(const K &key, const W &weight, const W &default_weight=W::Zero())
static const SparsePowerWeight & NoWeight()
ExpectationWeight< X1, X2 > Divide(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2, DivideType typ=DIVIDE_ANY)
uint64_t uint64
Definition: types.h:32
static const SparsePowerWeight & One()
static const string & Type()
static constexpr uint64 Properties()
constexpr uint64 kRightSemiring
Definition: weight.h:115
void SparseTupleWeightMap(SparseTupleWeight< W, K > *result, const SparseTupleWeight< W, K > &w1, const SparseTupleWeight< W, K > &w2, const M &operator_mapper)
ExpectationWeight< X1, X2 > Times(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2)
constexpr uint64 kCommutative
Definition: weight.h:120
constexpr uint64 kLeftSemiring
Definition: weight.h:112
SparsePowerWeight< W, K > SparsePowerWeightMap(const SparsePowerWeight< W, K > &w1, const SparsePowerWeight< W, K > &w2, const M &operator_mapper)
SparsePowerWeight(Iterator begin, Iterator end)
SparsePowerWeight Quantize(float delta=kDelta) const
W DotProduct(const PowerWeight< W, n > &w1, const PowerWeight< W, n > &w2)
Definition: power-weight.h:138
static const SparsePowerWeight & Zero()
SparsePowerWeight< typename W::ReverseWeight, K > ReverseWeight
constexpr uint64 kIdempotent
Definition: weight.h:123
ExpectationWeight< X1, X2 > Plus(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2)
uint32_t uint32
Definition: types.h:31
constexpr bool ApproxEqual(const FloatWeightTpl< T > &w1, const FloatWeightTpl< T > &w2, float delta=kDelta)
Definition: float-weight.h:140
WeightGenerate(bool allow_zero=true, size_t sparse_power_rank=3)
DivideType
Definition: weight.h:142
constexpr float kDelta
Definition: weight.h:109
ReverseWeight Reverse() const
SparsePowerWeight(const SparseTupleWeight< W, K > &weight)