Cambridge SMT System
weights.gtest.cpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use these files except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 // Copyright 2012 - Gonzalo Iglesias, AdriĆ  de Gispert, William Byrne
14 
21 #include <openfst.h>
22 #include <googletesting.h>
23 
24 #ifndef GMAINTEST
25 #include "main.custom_assert.hpp"
26 #include "main.logger.hpp"
27 #endif
28 
29 #include "params.hpp"
30 #include "tropical-sparse-tuple-weight.h"
31 #include "tropical-sparse-tuple-weight-decls.h"
33 
37 
38 #include "fstutils.mapper.hpp"
39 
41 
42 namespace bfs = boost::filesystem;
43 
44 //Convert a std weightto tropical sparse weight and back
45 TEST ( tropicalsparseweight, makesparseweight ) {
46  fst::StdToVector<float> mw ( 1 );
47  fst::StdArc::Weight stdweight ( 3.0f );
48  fst::TropicalSparseTupleWeight<float> w = mw ( stdweight );
50  EXPECT_EQ ( mw2 ( w ).Value(), 3.0f );
51 };
52 
54 TEST ( tropicalsparseweight, makeweight2 ) {
56  TupleArc32::Weight w = mw ( 3.0f );
58  EXPECT_EQ ( mw2 ( w ).Value(), 3.0f );
59 }
60 
62 TEST ( lexicographic, makeweight_stdarc ) {
64  fst::StdArc::Weight w = mw ( 3.0f );
65  EXPECT_EQ ( 3.0f, w.Value() );
66  fst::StdArc::Weight w2 = 4.0f;
67  EXPECT_EQ ( 4.0f, mw ( w2 ) );
68 }
69 
71 TEST ( lexicographic, makeweight_lexstdarc ) {
73  fst::LexStdArc::Weight w = mw ( 3.0f );
74  EXPECT_EQ ( 3.0f, w.Value1() );
75  EXPECT_EQ ( fst::StdArc::Weight::One(), w.Value2() );
76  fst::LexStdArc::Weight w2 ( 6.5f, 7.0f );
77  fst::LexStdArc::Weight w2check ( 6.5f, fst::StdArc::Weight::One() );
78  EXPECT_EQ ( w2check, mw ( w2 ) );
79 }
80 
82 TEST ( lexicographic, makeweight2_stdarc ) {
84  fst::StdArc::Weight w = mw ( 2.0f );
85  EXPECT_EQ ( 2.0f, w.Value() );
86  fst::StdArc::Weight w2 = 4.5f;
87  EXPECT_EQ ( 4.5f, mw ( w2 ) );
88 }
89 
91 TEST ( lexicographic, makeweight2_lexstdarc ) {
93  fst::LexStdArc::Weight w = mw ( 2.0f );
94  EXPECT_EQ ( 2.0f, w.Value1() );
95  EXPECT_EQ ( 2.0f, w.Value2() );
96  fst::LexStdArc::Weight w2 ( 7.5f, 8.5f );
97  fst::LexStdArc::Weight w2check ( 8.5f, 8.5f );
98  EXPECT_EQ ( w2check, mw ( w2 ) );
99 };
100 
102 TEST ( lexicographic, copyw2tow1_stdarc ) {
103  fst::VectorFst<fst::StdArc> a;
104  a.AddState();
105  a.AddState();
106  a.SetStart ( 0 );
107  a.SetFinal ( 1, fst::StdArc::Weight::One() );
108  fst::StdArc::Weight wa ( 3.0f );
109  a.AddArc ( 0, fst::StdArc ( 1, 1, wa, 1 ) );
110  //Should do nothing at all...
112  fst::Map<fst::StdArc> ( &a,
114  ( mw ) );
115  fst::VectorFst<fst::StdArc> b;
116  b.AddState();
117  b.AddState();
118  b.SetStart ( 0 );
119  b.SetFinal ( 1, fst::StdArc::Weight::One() );
120  fst::StdArc::Weight wb ( 3.0f );
121  b.AddArc ( 0, fst::StdArc ( 1, 1, wb, 1 ) );
122  EXPECT_TRUE ( Equivalent ( a, b ) );
123 }
124 
126 TEST ( lexicographic, copyw2tow1_lexstdarc ) {
127  fst::VectorFst<fst::LexStdArc> a;
128  a.AddState();
129  a.AddState();
130  a.SetStart ( 0 );
131  a.SetFinal ( 1, fst::LexStdWeight::One() );
132  fst::LexStdWeight wa ( 3.0f, 2.0f );
133  a.AddArc ( 0, fst::LexStdArc ( 1, 1, wa, 1 ) );
135  fst::Map<fst::LexStdArc> ( &a,
137  ( mw ) );
138  fst::VectorFst<fst::LexStdArc> b;
139  b.AddState();
140  b.AddState();
141  b.SetStart ( 0 );
142  b.SetFinal ( 1, fst::LexStdWeight::One() );
143  fst::LexStdWeight wb ( 2.0f, 2.0f );
144  b.AddArc ( 0, fst::LexStdArc ( 1, 1, wb, 1 ) );
145  EXPECT_TRUE ( Equivalent ( a, b ) );
146 }
147 
148 // Test new hifst-tailored makeweights functor
149 // specialized for tropicalsparseweight.
150 TEST(tropicalsparseweight, makeweighthifst) {
152  using namespace HifstConstants;
153  {
154  unordered_map<std::string, boost::any> v;
155  // Not disabling rule features:
156  v[kHifstDisableRuleFeatures] = std::string ( "no" );
157  // One language model with feature weight value 1.
158  v[kLmFeatureweights] = std::string ( "1" );
160  MakeWeightHifst<TupleArc32> mwh(rg);
161  TupleArc32::Weight w = mwh ( 3.0f );
162  EXPECT_TRUE(ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,1,2,3,"
163  || ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,2,3"
164  );
165  w = mwh ( 6.0f , 8 );
166  EXPECT_TRUE(ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,2,2,6,-10,1,"
167  || ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,2,6,-10,1"
168  );
169  }
170  {
171  unordered_map<std::string, boost::any> v;
172  v[kHifstDisableRuleFeatures] = std::string ( "yes" );
173  // Two language models:
174  v[kLmFeatureweights] = std::string ( "1,0.5" );
176  MakeWeightHifst<TupleArc32> mwh(rg);
177  TupleArc32::Weight w = mwh ( 3.0f );
178  EXPECT_TRUE(ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,1,3,3,"
179  || ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,3,3"
180  );
181  w = mwh ( 6.0f , 8 );
182  EXPECT_TRUE(ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,1,3,6,"
183  || ucam::util::toString<TupleArc32::Weight>(w, 0) == "0,3,6"
184  );
185  }
186 }
187 // In this context, the mapper should ignore, because we keep track separately of
188 // of the different language models.
189 // \todo: Hifst needs to be refactored in such a way that this mapper doesn't actually run.
190 // alternatively, we can consider emulating the lexicographic semiring
191 
192 TEST(tropicalsparseweight, makeweighthifstMapper) {
193  using namespace HifstConstants;
194 
195  typedef TupleArc32 Arc;
196  typedef Arc::Weight Weight;
197  fst::VectorFst<Arc> a;
198  a.AddState();
199  a.AddState();
200  a.SetStart ( 0 );
201  a.SetFinal ( 1, Weight::One() );
202  Weight wa;
203  wa.Push(1, 1.0f);
204  wa.Push(2, 2.0f);
205  wa.Push(3, 3.0f);
206  a.AddArc ( 0, Arc ( 1, 1, wa, 1 ) );
207  unordered_map<std::string, boost::any> v;
208  // irrelevant parameters for this test, but must be initialized.
209  v[kHifstDisableRuleFeatures] = std::string ( "no" );
210  // two language models:
211  v[kLmFeatureweights] = std::string ( "1,0.5" );
214  fst::Map<Arc> ( &a,
216  ( mw ) );
217  fst::VectorFst<Arc> b;
218  b.AddState();
219  b.AddState();
220  b.SetStart ( 0 );
221  b.SetFinal ( 1, Weight::One() );
222  Weight wb;
223  wb.Push(1, 1.0f);
224  wb.Push(2, 2.0f);
225  wb.Push(3, 3.0f);
226  b.AddArc ( 0, Arc ( 1, 1, wb, 1 ) );
227  EXPECT_TRUE ( Equivalent ( a, b ) );
228 }
229 
230 TEST(lexicographic, makeweighthifst) {
232  unordered_map<std::string, boost::any> v;
234  MakeWeightHifst<fst::LexStdArc> mw(rg);
235  fst::LexStdArc::Weight w = mw ( 2.0f );
236  EXPECT_EQ ( 2.0f, w.Value1() );
237  EXPECT_EQ ( 2.0f, w.Value2() );
238  fst::LexStdArc::Weight w2 ( 7.5f, 8.5f );
239  fst::LexStdArc::Weight w2check ( 8.5f, 8.5f );
240  EXPECT_EQ ( w2check, mw ( w2 ) );
241 }
242 
243 // @todo Test that it stores the language model score in
244 // a fixed position
245 // and it deletes scores on the same position when copied.
246 // TEST(tropicalsparseweight, makeweighthifstLocalLm) {
247 // EXPECT_TRUE(0);
248 // }
249 
250 // We need sparse tuple weight to do the same work as the lexicographic semiring
251 // this test simply shows the way these weights work.
252 // Although there are notes in the documentation suggesting
253 // that the list is sorted, this is not actually true.
254 // Also, indices can be repeated.
255 TEST(tropicalsparseweight, removeKthWeight) {
256  using namespace fst;
257  TupleArc32::Weight w,w2;
258  w.Push(6,6);
259  w.Push(5,5);
260  w.Push(8,0);
261  w.Push(5,-2);
262  w.SetDefaultValue(300);
263  std::stringstream ss; ss << w;
264  EXPECT_TRUE ( ss.str() == "300,3,6,6,5,5,5,-2,"
265  || ss.str() == "300,6,6,5,5,5,-2"); // openfst 1.5.0 does not print counts of weights
266  // remove weight 5.
267 
268  // this does not copy default value
269  for (SparseTupleWeightIterator<StdArc::Weight, int> it(w); !it.Done(); it.Next()) {
270  if (it.Value().first != 5) // you cannot break;
271  w2.Push(it.Value());
272  }
273  std::stringstream ss2; ss2 << w2;
274  EXPECT_TRUE ( ss2.str() == "0,1,6,6,"
275  || ss2.str() == "0,6,6"
276  );
277  w2.SetDefaultValue(w.DefaultValue());
278  std::stringstream ss3; ss3 << w2;
279  EXPECT_TRUE ( ss3.str() == "300,1,6,6,"
280  || ss3.str() == "300,6,6"
281  );
282  // This is implemented in SparseTupleWeightMap (sparse-tuple-weight.h)
283  // The default value is used for Times operation if not available.
284  TupleArc32::Weight w3=Times(w,w2);
285  // std::cerr << w3 << std::endl;
286  // 600,3,6,12,5,305,5,298
287 }
288 
289 
290 
291 
292 
293 #ifndef GMAINTEST
294 
295 int main ( int argc, char **argv ) {
296  ::testing::InitGoogleTest ( &argc, argv );
297  return RUN_ALL_TESTS();
298 }
299 #endif
Unit testing: google testing common header.
Convenience functors/functions for lexicographic<tropical,tropical> semiring.
LexStdArc::Weight LexStdWeight
Definition: fstio.hpp:27
Convenience functions for tropical sparse vector weight.
const std::string kHifstDisableRuleFeatures
templated Mapper that modifies weights over an FST, passing through the other values of the arc...
Implements Tropical Sparse tuple weight semiring, extending from openfst SparsePowerWeight class...
std::string const kLmFeatureweights
Static variables for logger. Include only once from main file.
Templated functor that creates a weight given a float.
Functor to convert sparse tuple weight to tropical (single weight)
Headers for standalone shared library.
Convenience functions to parse parameters from a string.
fst::ArcTpl< TupleW32 > TupleArc32
Templated functor that creates a weight given a float.
LexicographicArc< StdArc::Weight, StdArc::Weight > LexStdArc
Generalized weight mapper functor.
Functor that converts tropical to sparse tuple weight.
int main(int argc, char **argv)
TropicalSparseTupleWeight< T > Times(const TropicalSparseTupleWeight< T > &w1, const TropicalSparseTupleWeight< T > &w2)
Convenience functors that allow transparent handling for weights within hifst.
TEST(tropicalsparseweight, makesparseweight)
Unit testing: google testing common header.
Static variable for custom_assert. Include only once from main file.