FST  openfst-1.7.1
OpenFst Library
weight_test.cc
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 // Regression test for FST weights.
5 
6 #include <cstdlib>
7 #include <ctime>
8 
9 #include <fst/flags.h>
10 #include <fst/log.h>
11 #include <fst/expectation-weight.h>
12 #include <fst/float-weight.h>
14 #include <fst/power-weight.h>
15 #include <fst/product-weight.h>
16 #include <fst/set-weight.h>
17 #include <fst/signed-log-weight.h>
19 #include <fst/string-weight.h>
20 #include <fst/union-weight.h>
21 #include <fst/test/weight-tester.h>
22 
23 DEFINE_int32(seed, -1, "random seed");
24 DEFINE_int32(repeat, 10000, "number of test repetitions");
25 
26 namespace {
27 
28 using fst::Adder;
30 using fst::GALLIC;
31 using fst::GallicWeight;
33 using fst::LogWeight;
34 using fst::LogWeightTpl;
35 using fst::MinMaxWeight;
37 using fst::NaturalLess;
38 using fst::PowerWeight;
39 using fst::ProductWeight;
40 using fst::SetWeight;
43 using fst::SET_BOOLEAN;
47 using fst::StringWeight;
48 using fst::STRING_LEFT;
49 using fst::STRING_RIGHT;
52 using fst::UnionWeight;
53 using fst::WeightConvert;
55 using fst::WeightTester;
56 
57 template <class T>
58 void TestTemplatedWeights(int repeat) {
59  using TropicalWeightGenerate = WeightGenerate<TropicalWeightTpl<T>>;
60  TropicalWeightGenerate tropical_generate;
61  WeightTester<TropicalWeightTpl<T>, TropicalWeightGenerate> tropical_tester(
62  tropical_generate);
63  tropical_tester.Test(repeat);
64 
65  using LogWeightGenerate = WeightGenerate<LogWeightTpl<T>>;
66  LogWeightGenerate log_generate;
67  WeightTester<LogWeightTpl<T>, LogWeightGenerate> log_tester(log_generate);
68  log_tester.Test(repeat);
69 
70  using MinMaxWeightGenerate = WeightGenerate<MinMaxWeightTpl<T>>;
71  MinMaxWeightGenerate minmax_generate(true);
72  WeightTester<MinMaxWeightTpl<T>, MinMaxWeightGenerate> minmax_tester(
73  minmax_generate);
74  minmax_tester.Test(repeat);
75 
76  using SignedLogWeightGenerate = WeightGenerate<SignedLogWeightTpl<T>>;
77  SignedLogWeightGenerate signedlog_generate;
78  WeightTester<SignedLogWeightTpl<T>, SignedLogWeightGenerate>
79  signedlog_tester(signedlog_generate);
80  signedlog_tester.Test(repeat);
81 }
82 
83 template <class Weight>
84 void TestAdder(int n) {
85  Weight sum = Weight::Zero();
86  Adder<Weight> adder;
87  for (int i = 0; i < n; ++i) {
88  sum = Plus(sum, Weight::One());
89  adder.Add(Weight::One());
90  }
91  CHECK(ApproxEqual(sum, adder.Sum()));
92 }
93 
94 template <class Weight>
95 void TestSignedAdder(int n) {
96  Weight sum = Weight::Zero();
97  Adder<Weight> adder;
98  const Weight minus_one = Minus(Weight::Zero(), Weight::One());
99  for (int i = 0; i < n; ++i) {
100  if (i < n/4 || i > 3*n/4) {
101  sum = Plus(sum, Weight::One());
102  adder.Add(Weight::One());
103  } else {
104  sum = Minus(sum, Weight::One());
105  adder.Add(minus_one);
106  }
107  }
108  CHECK(ApproxEqual(sum, adder.Sum()));
109 }
110 
111 template <typename Weight1, typename Weight2>
112 void TestWeightConversion(Weight1 w1) {
113  // Tests round-trp conversion.
114  WeightConvert<Weight2, Weight1> to_w1_;
115  WeightConvert<Weight1, Weight2> to_w2_;
116  Weight2 w2 = to_w2_(w1);
117  Weight1 nw1 = to_w1_(w2);
118  CHECK_EQ(w1, nw1);
119 }
120 
121 template <typename FromWeight, typename ToWeight>
122 void TestWeightCopy(FromWeight w) {
123  // Test copy constructor.
124  const ToWeight to_copied(w);
125  const FromWeight roundtrip_copied(to_copied);
126  CHECK_EQ(w, roundtrip_copied);
127 
128  // Test copy assign.
129  ToWeight to_copy_assigned;
130  to_copy_assigned = w;
131  CHECK_EQ(to_copied, to_copy_assigned);
132 
133  FromWeight roundtrip_copy_assigned;
134  roundtrip_copy_assigned = to_copy_assigned;
135  CHECK_EQ(w, roundtrip_copy_assigned);
136 }
137 
138 template <typename FromWeight, typename ToWeight>
139 void TestWeightMove(FromWeight w) {
140  // Assume FromWeight -> FromWeight copy works.
141  const FromWeight orig(w);
142  ToWeight to_moved(std::move(w));
143  const FromWeight roundtrip_moved(std::move(to_moved));
144  CHECK_EQ(orig, roundtrip_moved);
145 
146  // Test move assign.
147  w = orig;
148  ToWeight to_move_assigned;
149  to_move_assigned = std::move(w);
150  FromWeight roundtrip_move_assigned;
151  roundtrip_move_assigned = std::move(to_move_assigned);
152  CHECK_EQ(orig, roundtrip_move_assigned);
153 }
154 
155 template <class Weight>
156 void TestImplicitConversion() {
157  // Only test a few of the operations; assumes they are implemented with the
158  // same pattern.
159  CHECK(Weight(2.0f) == 2.0f);
160  CHECK(Weight(2.0) == 2.0);
161  CHECK(2.0f == Weight(2.0f));
162  CHECK(2.0 == Weight(2.0));
163 
164  CHECK_EQ(Weight::Zero(), Times(Weight::Zero(), 3.0f));
165  CHECK_EQ(Weight::Zero(), Times(Weight::Zero(), 3.0));
166  CHECK_EQ(Weight::Zero(), Times(3.0, Weight::Zero()));
167 
168  CHECK_EQ(Weight(3.0), Plus(Weight::Zero(), 3.0f));
169  CHECK_EQ(Weight(3.0), Plus(Weight::Zero(), 3.0));
170  CHECK_EQ(Weight(3.0), Plus(3.0, Weight::Zero()));
171 }
172 
173 void TestPowerWeightGetSetValue() {
174  PowerWeight<LogWeight, 3> w;
175  // LogWeight has unspecified initial value, so don't check it.
176  w.SetValue(0, LogWeight(2));
177  w.SetValue(1, LogWeight(3));
178  CHECK_EQ(LogWeight(2), w.Value(0));
179  CHECK_EQ(LogWeight(3), w.Value(1));
180 }
181 
182 void TestSparsePowerWeightGetSetValue() {
183  const LogWeight default_value(17);
184  SparsePowerWeight<LogWeight> w;
185  w.SetDefaultValue(default_value);
186 
187  // All gets should be the default.
188  CHECK_EQ(default_value, w.Value(0));
189  CHECK_EQ(default_value, w.Value(100));
190 
191  // First set should fill first_.
192  w.SetValue(10, LogWeight(10));
193  CHECK_EQ(LogWeight(10), w.Value(10));
194  w.SetValue(10, LogWeight(20));
195  CHECK_EQ(LogWeight(20), w.Value(10));
196 
197  // Add a smaller index.
198  w.SetValue(5, LogWeight(5));
199  CHECK_EQ(LogWeight(5), w.Value(5));
200  CHECK_EQ(LogWeight(20), w.Value(10));
201 
202  // Add some larger indices.
203  w.SetValue(30, LogWeight(30));
204  CHECK_EQ(LogWeight(5), w.Value(5));
205  CHECK_EQ(LogWeight(20), w.Value(10));
206  CHECK_EQ(LogWeight(30), w.Value(30));
207 
208  w.SetValue(29, LogWeight(29));
209  CHECK_EQ(LogWeight(5), w.Value(5));
210  CHECK_EQ(LogWeight(20), w.Value(10));
211  CHECK_EQ(LogWeight(29), w.Value(29));
212  CHECK_EQ(LogWeight(30), w.Value(30));
213 
214  w.SetValue(31, LogWeight(31));
215  CHECK_EQ(LogWeight(5), w.Value(5));
216  CHECK_EQ(LogWeight(20), w.Value(10));
217  CHECK_EQ(LogWeight(29), w.Value(29));
218  CHECK_EQ(LogWeight(30), w.Value(30));
219  CHECK_EQ(LogWeight(31), w.Value(31));
220 
221  // Replace a value.
222  w.SetValue(30, LogWeight(60));
223  CHECK_EQ(LogWeight(60), w.Value(30));
224 
225  // Replace a value with the default.
226  CHECK_EQ(5, w.Size());
227  w.SetValue(30, default_value);
228  CHECK_EQ(default_value, w.Value(30));
229  CHECK_EQ(4, w.Size());
230 
231  // Replace lowest index by the default value.
232  w.SetValue(5, default_value);
233  CHECK_EQ(default_value, w.Value(5));
234  CHECK_EQ(3, w.Size());
235 
236  // Clear out everything.
237  w.SetValue(31, default_value);
238  w.SetValue(29, default_value);
239  w.SetValue(10, default_value);
240  CHECK_EQ(0, w.Size());
241 
242  CHECK_EQ(default_value, w.Value(5));
243  CHECK_EQ(default_value, w.Value(10));
244  CHECK_EQ(default_value, w.Value(29));
245  CHECK_EQ(default_value, w.Value(30));
246  CHECK_EQ(default_value, w.Value(31));
247 }
248 
249 // If this test fails, it is possible that x == x will not
250 // hold for FloatWeight, breaking NaturalLess and probably more.
251 // To trigger these failures, use g++ -O -m32 -mno-sse.
252 // Google-only...
253 // This will never fail in google3, as those options aren't used.
254 // ...Google-only
255 template <class T>
256 bool FloatEqualityIsReflexive(T m) {
257  // The idea here is that x is spilled to memory, but
258  // y remains in an 80-bit register with extra precision,
259  // causing it to compare unequal to x.
260  volatile T x = 1.111;
261  x *= m;
262 
263  T y = 1.111;
264  y *= m;
265 
266  return x == y;
267 }
268 
269 void TestFloatEqualityIsReflexive() {
270  // Use a volatile test_value to avoid excessive inlining / optimization
271  // breaking what we're trying to test.
272  volatile double test_value = 1.1;
273  CHECK(FloatEqualityIsReflexive(static_cast<float>(test_value)));
274  CHECK(FloatEqualityIsReflexive(test_value));
275 }
276 
277 } // namespace
278 
279 int main(int argc, char **argv) {
280  std::set_new_handler(FailedNewHandler);
281  SET_FLAGS(argv[0], &argc, &argv, true);
282 
283  LOG(INFO) << "Seed = " << FLAGS_seed;
284  srand(FLAGS_seed);
285 
286  TestTemplatedWeights<float>(FLAGS_repeat);
287  TestTemplatedWeights<double>(FLAGS_repeat);
288  FLAGS_fst_weight_parentheses = "()";
289  TestTemplatedWeights<float>(FLAGS_repeat);
290  TestTemplatedWeights<double>(FLAGS_repeat);
291  FLAGS_fst_weight_parentheses = "";
292 
293  // Makes sure type names for templated weights are consistent.
294  CHECK(TropicalWeight::Type() == "tropical");
295  CHECK(TropicalWeightTpl<double>::Type() != TropicalWeightTpl<float>::Type());
296  CHECK(LogWeight::Type() == "log");
297  CHECK(LogWeightTpl<double>::Type() != LogWeightTpl<float>::Type());
298  TropicalWeightTpl<double> w(2.0);
299  TropicalWeight tw(2.0);
300  CHECK_EQ(w.Value(), tw.Value());
301 
302  TestAdder<TropicalWeight>(1000);
303  TestAdder<LogWeight>(1000);
304  TestSignedAdder<SignedLogWeight>(1000);
305 
306  TestImplicitConversion<LogWeight>();
307  TestImplicitConversion<TropicalWeight>();
308  TestImplicitConversion<MinMaxWeight>();
309 
310  TestWeightConversion<TropicalWeight, LogWeight>(2.0);
311 
312  using LeftStringWeight = StringWeight<int>;
313  using LeftStringWeightGenerate = WeightGenerate<LeftStringWeight>;
314  LeftStringWeightGenerate left_string_generate;
315  WeightTester<LeftStringWeight, LeftStringWeightGenerate> left_string_tester(
316  left_string_generate);
317  left_string_tester.Test(FLAGS_repeat);
318 
319  using RightStringWeight = StringWeight<int, STRING_RIGHT>;
320  using RightStringWeightGenerate = WeightGenerate<RightStringWeight>;
321  RightStringWeightGenerate right_string_generate;
322  WeightTester<RightStringWeight, RightStringWeightGenerate>
323  right_string_tester(right_string_generate);
324  right_string_tester.Test(FLAGS_repeat);
325 
326  // STRING_RESTRICT not tested since it requires equal strings,
327  // so would fail.
328 
329  using IUSetWeight = SetWeight<int, SET_INTERSECT_UNION>;
330  using IUSetWeightGenerate = WeightGenerate<IUSetWeight>;
331  IUSetWeightGenerate iu_set_generate;
332  WeightTester<IUSetWeight, IUSetWeightGenerate>
333  iu_set_tester(iu_set_generate);
334  iu_set_tester.Test(FLAGS_repeat);
335 
336  using UISetWeight = SetWeight<int, SET_UNION_INTERSECT>;
337  using UISetWeightGenerate = WeightGenerate<UISetWeight>;
338  UISetWeightGenerate ui_set_generate;
339  WeightTester<UISetWeight, UISetWeightGenerate>
340  ui_set_tester(ui_set_generate);
341  ui_set_tester.Test(FLAGS_repeat);
342 
343  // SET_INTERSECT_UNION_RESTRICT not tested since it requires equal sets,
344  // so would fail.
345 
346  using BoolSetWeight = SetWeight<int, SET_BOOLEAN>;
347  using BoolSetWeightGenerate = WeightGenerate<BoolSetWeight>;
348  BoolSetWeightGenerate bool_set_generate;
349  WeightTester<BoolSetWeight, BoolSetWeightGenerate>
350  bool_set_tester(bool_set_generate);
351  bool_set_tester.Test(FLAGS_repeat);
352 
353  TestWeightConversion<IUSetWeight, UISetWeight>(iu_set_generate());
354 
355  TestWeightCopy<IUSetWeight, UISetWeight>(iu_set_generate());
356  TestWeightCopy<IUSetWeight, BoolSetWeight>(iu_set_generate());
357  TestWeightCopy<UISetWeight, IUSetWeight>(ui_set_generate());
358  TestWeightCopy<UISetWeight, BoolSetWeight>(ui_set_generate());
359  TestWeightCopy<BoolSetWeight, IUSetWeight>(bool_set_generate());
360  TestWeightCopy<BoolSetWeight, UISetWeight>(bool_set_generate());
361 
362  TestWeightMove<IUSetWeight, UISetWeight>(iu_set_generate());
363  TestWeightMove<IUSetWeight, BoolSetWeight>(iu_set_generate());
364  TestWeightMove<UISetWeight, IUSetWeight>(ui_set_generate());
365  TestWeightMove<UISetWeight, BoolSetWeight>(ui_set_generate());
366  TestWeightMove<BoolSetWeight, IUSetWeight>(bool_set_generate());
367  TestWeightMove<BoolSetWeight, UISetWeight>(bool_set_generate());
368 
369  // COMPOSITE WEIGHTS AND TESTERS - DEFINITIONS
370 
371  using TropicalGallicWeight = GallicWeight<int, TropicalWeight>;
372  using TropicalGallicWeightGenerate = WeightGenerate<TropicalGallicWeight>;
373  TropicalGallicWeightGenerate tropical_gallic_generate(true);
374  WeightTester<TropicalGallicWeight, TropicalGallicWeightGenerate>
375  tropical_gallic_tester(tropical_gallic_generate);
376 
377  using TropicalGenGallicWeight = GallicWeight<int, TropicalWeight, GALLIC>;
378  using TropicalGenGallicWeightGenerate =
379  WeightGenerate<TropicalGenGallicWeight>;
380  TropicalGenGallicWeightGenerate tropical_gen_gallic_generate(false);
381  WeightTester<TropicalGenGallicWeight, TropicalGenGallicWeightGenerate>
382  tropical_gen_gallic_tester(tropical_gen_gallic_generate);
383 
384  using TropicalProductWeight = ProductWeight<TropicalWeight, TropicalWeight>;
385  using TropicalProductWeightGenerate = WeightGenerate<TropicalProductWeight>;
386  TropicalProductWeightGenerate tropical_product_generate;
387  WeightTester<TropicalProductWeight, TropicalProductWeightGenerate>
388  tropical_product_tester(tropical_product_generate);
389 
390  using TropicalLexicographicWeight =
391  LexicographicWeight<TropicalWeight, TropicalWeight>;
392  using TropicalLexicographicWeightGenerate =
393  WeightGenerate<TropicalLexicographicWeight>;
394  TropicalLexicographicWeightGenerate tropical_lexicographic_generate;
395  WeightTester<TropicalLexicographicWeight,
396  TropicalLexicographicWeightGenerate>
397  tropical_lexicographic_tester(tropical_lexicographic_generate);
398 
399  using TropicalCubeWeight = PowerWeight<TropicalWeight, 3>;
400  using TropicalCubeWeightGenerate = WeightGenerate<TropicalCubeWeight>;
401  TropicalCubeWeightGenerate tropical_cube_generate;
402  WeightTester<TropicalCubeWeight, TropicalCubeWeightGenerate>
403  tropical_cube_tester(tropical_cube_generate);
404 
405  using FirstNestedProductWeight =
406  ProductWeight<TropicalProductWeight, TropicalWeight>;
407  using FirstNestedProductWeightGenerate =
408  WeightGenerate<FirstNestedProductWeight>;
409  FirstNestedProductWeightGenerate first_nested_product_generate;
410  WeightTester<FirstNestedProductWeight, FirstNestedProductWeightGenerate>
411  first_nested_product_tester(first_nested_product_generate);
412 
413  using SecondNestedProductWeight =
414  ProductWeight<TropicalWeight, TropicalProductWeight>;
415  using SecondNestedProductWeightGenerate =
416  WeightGenerate<SecondNestedProductWeight>;
417  SecondNestedProductWeightGenerate second_nested_product_generate;
418  WeightTester<SecondNestedProductWeight, SecondNestedProductWeightGenerate>
419  second_nested_product_tester(second_nested_product_generate);
420 
421  using NestedProductCubeWeight = PowerWeight<FirstNestedProductWeight, 3>;
422  using NestedProductCubeWeightGenerate =
423  WeightGenerate<NestedProductCubeWeight>;
424  NestedProductCubeWeightGenerate nested_product_cube_generate;
425  WeightTester<NestedProductCubeWeight, NestedProductCubeWeightGenerate>
426  nested_product_cube_tester(nested_product_cube_generate);
427 
428  using SparseNestedProductCubeWeight =
429  SparsePowerWeight<NestedProductCubeWeight, size_t>;
430  using SparseNestedProductCubeWeightGenerate =
431  WeightGenerate<SparseNestedProductCubeWeight>;
432  SparseNestedProductCubeWeightGenerate sparse_nested_product_cube_generate;
433  WeightTester<SparseNestedProductCubeWeight,
434  SparseNestedProductCubeWeightGenerate>
435  sparse_nested_product_cube_tester(sparse_nested_product_cube_generate);
436 
437  using LogSparsePowerWeight = SparsePowerWeight<LogWeight, size_t>;
438  using LogSparsePowerWeightGenerate = WeightGenerate<LogSparsePowerWeight>;
439  LogSparsePowerWeightGenerate log_sparse_power_generate;
440  WeightTester<LogSparsePowerWeight, LogSparsePowerWeightGenerate>
441  log_sparse_power_tester(log_sparse_power_generate);
442 
443  using LogLogExpectationWeight = ExpectationWeight<LogWeight, LogWeight>;
444  using LogLogExpectationWeightGenerate =
445  WeightGenerate<LogLogExpectationWeight>;
446  LogLogExpectationWeightGenerate log_log_expectation_generate;
447  WeightTester<LogLogExpectationWeight, LogLogExpectationWeightGenerate>
448  log_log_expectation_tester(log_log_expectation_generate);
449 
450  using LogLogSparseExpectationWeight =
451  ExpectationWeight<LogWeight, LogSparsePowerWeight>;
452  using LogLogSparseExpectationWeightGenerate =
453  WeightGenerate<LogLogSparseExpectationWeight>;
454  LogLogSparseExpectationWeightGenerate log_log_sparse_expectation_generate;
455  WeightTester<LogLogSparseExpectationWeight,
456  LogLogSparseExpectationWeightGenerate>
457  log_log_sparse_expectation_tester(log_log_sparse_expectation_generate);
458 
459  struct UnionWeightOptions {
460  using Compare = NaturalLess<TropicalWeight>;
461 
462  struct Merge {
463  TropicalWeight operator()(const TropicalWeight &w1,
464  const TropicalWeight &w2) const {
465  return w1;
466  }
467  };
468 
469  using ReverseOptions = UnionWeightOptions;
470  };
471 
472  using TropicalUnionWeight = UnionWeight<TropicalWeight, UnionWeightOptions>;
473  using TropicalUnionWeightGenerate = WeightGenerate<TropicalUnionWeight>;
474  TropicalUnionWeightGenerate tropical_union_generate;
475  WeightTester<TropicalUnionWeight, TropicalUnionWeightGenerate>
476  tropical_union_tester(tropical_union_generate);
477 
478  // COMPOSITE WEIGHTS AND TESTERS - TESTING
479 
480  // Tests composite weight I/O with parentheses.
481  FLAGS_fst_weight_parentheses = "()";
482 
483  // Unnested composite.
484  tropical_gallic_tester.Test(FLAGS_repeat);
485  tropical_gen_gallic_tester.Test(FLAGS_repeat);
486  tropical_product_tester.Test(FLAGS_repeat);
487  tropical_lexicographic_tester.Test(FLAGS_repeat);
488  tropical_cube_tester.Test(FLAGS_repeat);
489  log_sparse_power_tester.Test(FLAGS_repeat);
490  log_log_expectation_tester.Test(FLAGS_repeat, false);
491  tropical_union_tester.Test(FLAGS_repeat, false);
492 
493  // Nested composite.
494  first_nested_product_tester.Test(FLAGS_repeat);
495  second_nested_product_tester.Test(5);
496  nested_product_cube_tester.Test(FLAGS_repeat);
497  sparse_nested_product_cube_tester.Test(FLAGS_repeat);
498  log_log_sparse_expectation_tester.Test(FLAGS_repeat, false);
499 
500  // ... and tests composite weight I/O without parentheses.
501  FLAGS_fst_weight_parentheses = "";
502 
503  // Unnested composite.
504  tropical_gallic_tester.Test(FLAGS_repeat);
505  tropical_product_tester.Test(FLAGS_repeat);
506  tropical_lexicographic_tester.Test(FLAGS_repeat);
507  tropical_cube_tester.Test(FLAGS_repeat);
508  log_sparse_power_tester.Test(FLAGS_repeat);
509  log_log_expectation_tester.Test(FLAGS_repeat, false);
510  tropical_union_tester.Test(FLAGS_repeat, false);
511 
512  // Nested composite.
513  second_nested_product_tester.Test(FLAGS_repeat);
514  log_log_sparse_expectation_tester.Test(FLAGS_repeat, false);
515 
516  TestPowerWeightGetSetValue();
517  TestSparsePowerWeightGetSetValue();
518 
519  TestFloatEqualityIsReflexive();
520 
521  std::cout << "PASS" << std::endl;
522 
523  return 0;
524 }
#define LOG(type)
Definition: log.h:48
ExpectationWeight< X1, X2 > Times(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2)
DEFINE_int32(seed,-1,"random seed")
int main(int argc, char **argv)
Definition: weight_test.cc:279
SignedLogWeightTpl< T > Minus(const SignedLogWeightTpl< T > &w1, const SignedLogWeightTpl< T > &w2)
void FailedNewHandler()
Definition: compat.cc:25
#define SET_FLAGS(usage, argc, argv, rmflags)
Definition: flags.h:214
LogWeightTpl< float > LogWeight
Definition: float-weight.h:446
TropicalWeightTpl< float > TropicalWeight
Definition: float-weight.h:244
ExpectationWeight< X1, X2 > Plus(const ExpectationWeight< X1, X2 > &w1, const ExpectationWeight< X1, X2 > &w2)
MinMaxWeightTpl< float > MinMaxWeight
Definition: float-weight.h:667
#define CHECK_EQ(x, y)
Definition: log.h:62
constexpr bool ApproxEqual(const FloatWeightTpl< T > &w1, const FloatWeightTpl< T > &w2, float delta=kDelta)
Definition: float-weight.h:140
#define CHECK(x)
Definition: log.h:61
SignedLogWeightTpl< float > SignedLogWeight