FST  openfst-1.8.3
OpenFst Library
sparse-power-weight.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 // Cartesian power weight semiring operation definitions, using
19 // SparseTupleWeight as underlying representation.
20 
21 #ifndef FST_SPARSE_POWER_WEIGHT_H_
22 #define FST_SPARSE_POWER_WEIGHT_H_
23 
24 #include <climits>
25 #include <cstddef>
26 #include <cstdint>
27 #include <random>
28 #include <string>
29 
31 #include <fst/weight.h>
32 
33 namespace fst {
34 
35 // Sparse cartesian power semiring: W ^ n
36 //
37 // Forms:
38 //
39 // - a left semimodule when W is a left semiring,
40 // - a right semimodule when W is a right semiring,
41 // - a bisemimodule when W is a semiring,
42 // the free semimodule of rank n over W
43 //
44 // The Times operation is overloaded to provide the left and right scalar
45 // products.
46 //
47 // K is the key value type. kNoKey (-1) is reserved for internal use
48 template <class W, class K = int>
49 class SparsePowerWeight : public SparseTupleWeight<W, K> {
50  public:
53 
54  SparsePowerWeight() = default;
55 
56  explicit SparsePowerWeight(const Base &weight) : Base(weight) {}
57 
58  template <class Iterator>
59  SparsePowerWeight(Iterator begin, Iterator end) : Base(begin, end) {}
60 
61  // Initialize component `key` to `weight`, with `default_weight` for all
62  // other components.
63  SparsePowerWeight(const K &key, const W &weight,
64  const W &default_weight = W::Zero())
65  : Base(key, weight, default_weight) {}
66 
67  static const SparsePowerWeight &Zero() {
68  static const SparsePowerWeight zero(Base::Zero());
69  return zero;
70  }
71 
72  static const SparsePowerWeight &One() {
73  static const SparsePowerWeight one(Base::One());
74  return one;
75  }
76 
77  static const SparsePowerWeight &NoWeight() {
78  static const SparsePowerWeight no_weight(Base::NoWeight());
79  return no_weight;
80  }
81 
82  // Overide this: Overwrite the Type method to reflect the key type if using
83  // a non-default key type.
84  static const std::string &Type() {
85  static const std::string *const type = [] {
86  std::string type = W::Type() + "_^n";
87  if (sizeof(K) != sizeof(uint32_t)) {
88  type += "_" + std::to_string(CHAR_BIT * sizeof(K));
89  }
90  return new std::string(type);
91  }();
92  return *type;
93  }
94 
95  static constexpr uint64_t Properties() {
96  return W::Properties() &
98  }
99 
100  SparsePowerWeight Quantize(float delta = kDelta) const {
101  return SparsePowerWeight(Base::Quantize(delta));
102  }
103 
105 };
106 
107 template <class W, class K, class M>
110  const M &operator_mapper) {
112  SparseTupleWeightMap(&result, w1, w2, operator_mapper);
113  return result;
114 }
115 
116 // Semimodule plus operation.
117 template <class W, class K>
119  const SparsePowerWeight<W, K> &w2) {
120  return SparsePowerWeightMap(w1, w2, [](const K &k, const W &v1, const W &v2) {
121  return Plus(v1, v2);
122  });
123 }
124 
125 // Semimodule minus operation.
126 template <class W, class K>
128  const SparsePowerWeight<W, K> &w2) {
129  return SparsePowerWeightMap(w1, w2, [](const K &k, const W &v1, const W &v2) {
130  return Minus(v1, v2);
131  });
132 }
133 
134 // Semimodule times operation.
135 template <class W, class K>
137  const SparsePowerWeight<W, K> &w2) {
138  return SparsePowerWeightMap(w1, w2, [](const K &k, const W &v1, const W &v2) {
139  return Times(v1, v2);
140  });
141 }
142 
143 // Semimodule divide operation.
144 template <class W, class K>
146  const SparsePowerWeight<W, K> &w2,
147  DivideType type = DIVIDE_ANY) {
148  return SparsePowerWeightMap(w1, w2,
149  [type](const K &k, const W &v1, const W &v2) {
150  return Divide(v1, v2, type);
151  });
152 }
153 
154 // Semimodule dot product operation.
155 template <class W, class K>
156 inline const W &DotProduct(const SparsePowerWeight<W, K> &w1,
157  const SparsePowerWeight<W, K> &w2) {
158  const SparsePowerWeight<W, K> product = Times(w1, w2);
159  W result(W::Zero());
160  for (SparseTupleWeightIterator<W, K> it(product); !it.Done(); it.Next()) {
161  result = Plus(result, it.Value().second);
162  }
163  return result;
164 }
165 
166 template <class W, class K>
167 inline bool ApproxEqual(const SparsePowerWeight<W, K> &w1,
168  const SparsePowerWeight<W, K> &w2,
169  float delta = kDelta) {
170  auto result = SparsePowerWeightMap(
171  w1, w2, [delta](const K &k, const W &v1, const W &v2) {
172  return ApproxEqual(v1, v2, delta) ? W::One() : W::Zero();
173  });
174  return result == SparsePowerWeight<W, K>::One();
175 }
176 
177 template <class W, class K>
178 inline SparsePowerWeight<W, K> Times(const W &k,
179  const SparsePowerWeight<W, K> &w2) {
180  const SparseTupleWeight<W, K> t2(k);
181  const SparsePowerWeight<W, K> w1(t2);
182  return Times(w1, w2);
183 }
184 
185 template <class W, class K>
187  const W &k) {
188  const SparseTupleWeight<W, K> t2(k);
189  const SparsePowerWeight<W, K> w2(t2);
190  return Times(w1, w2);
191 }
192 
193 template <class W, class K>
195  const W &k,
196  DivideType divide_type = DIVIDE_ANY) {
197  const SparseTupleWeight<W, K> t2(k);
198  const SparsePowerWeight<W, K> w2(t2);
199  return Divide(w1, w2, divide_type);
200 }
201 
202 // This function object generates weights over the Cartesian power of rank
203 // n over the underlying weight. This is intended primarily for testing.
204 template <class W, class K>
206  public:
209 
210  explicit WeightGenerate(uint64_t seed = std::random_device()(),
211  bool allow_zero = true, size_t sparse_power_rank = 3)
212  : generate_(seed, allow_zero), sparse_power_rank_(sparse_power_rank) {}
213 
214  Weight operator()() const {
215  Weight weight;
216  for (size_t i = 1; i <= sparse_power_rank_; ++i) {
217  weight.PushBack(i, generate_(), true);
218  }
219  return weight;
220  }
221 
222  private:
223  const Generate generate_;
224  const size_t sparse_power_rank_;
225 };
226 
227 } // namespace fst
228 
229 #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()
static const SparsePowerWeight & One()
ErrorWeight Plus(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:61
void SparseTupleWeightMap(SparseTupleWeight< W, K > *result, const SparseTupleWeight< W, K > &w1, const SparseTupleWeight< W, K > &w2, const M &operator_mapper)
static const SparseTupleWeight & Zero()
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:64
static const SparseTupleWeight & One()
constexpr uint64_t kIdempotent
Definition: weight.h:147
SparsePowerWeight< W, K > SparsePowerWeightMap(const SparsePowerWeight< W, K > &w1, const SparsePowerWeight< W, K > &w2, const M &operator_mapper)
static const SparseTupleWeight & NoWeight()
constexpr uint64_t kRightSemiring
Definition: weight.h:139
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:154
static const SparsePowerWeight & Zero()
constexpr uint64_t kCommutative
Definition: weight.h:144
SparsePowerWeight< typename W::ReverseWeight, K > ReverseWeight
WeightGenerate(uint64_t seed=std::random_device()(), bool allow_zero=true, size_t sparse_power_rank=3)
static const std::string & Type()
LogWeightTpl< T > Minus(const LogWeightTpl< T > &w1, const LogWeightTpl< T > &w2)
Definition: float-weight.h:543
ErrorWeight Divide(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:67
SparseTupleWeight Quantize(float delta=kDelta) const
SparsePowerWeight(const Base &weight)
static constexpr uint64_t Properties()
DivideType
Definition: weight.h:165
constexpr uint64_t kLeftSemiring
Definition: weight.h:136
ReverseWeight Reverse() const
constexpr float kDelta
Definition: weight.h:133
ReverseWeight Reverse() const
bool ApproxEqual(const ErrorWeight &, const ErrorWeight &, float)
Definition: error-weight.h:58