Cambridge SMT System
function-weight.cpp
Go to the documentation of this file.
1 //Copyright (c) 2012, University of Cambridge
2 //All rights reserved.
3 //
4 //Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met://
5 //
6 // * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 // * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 // * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9 //
10 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11 
12 #include "function-weight.h"
13 #include <fst/fstlib.h>
14 #include <limits>
15 #include <ostream>
16 #include <iostream>
17 #include <algorithm>
18 
19 std::ostream& operator<< (std::ostream& os, const MertLine& ml) {
20  return os << "x:" << ml.x << " y:" << ml.y << " m:" << ml.m;
21 }
22 
23 std::istream& operator>> (std::istream& is, MertLine& ml) {
24  // Two chars to pull out values
25  char a, b;
26  is >> a >> b >> ml.x >> a >> b >> ml.y >> a >> b >> ml.m;
27  return is;
28 }
29 
30 std::ostream& operator<< (std::ostream& os, const MertList& l) {
31  os << "[";
32  for (std::list<MertLine>::const_iterator it = l.begin(); it != l.end(); it++) {
33  os << *it << ", ";
34  }
35  return os << "]";
36 }
37 
38 bool operator== (const MertLine& thisML, const MertLine& that) {
39  return thisML.y == that.y && thisML.m == that.m;
40 }
41 
43  l1 (l1), l2 (l2) {
44 }
45 
47  MertIter i2end) :
48  i1 (i1), i2 (i2), i1end (i1end), i2end (i2end) {
49  if (i1 == i1end && i2 != i2end) {
50  currIter = i2;
51  currList = 2;
52  } else if (i1 != i1end && i2 == i2end) {
53  currIter = i1;
54  currList = 1;
55  } else if (i1 != i1end && i2 != i2end) {
56  if (i1->m > i2->m) {
57  currIter = i1;
58  currList = 1;
59  } else {
60  currIter = i2;
61  currList = 2;
62  }
63  }
64 }
65 /*
66  CompIter::cl_iterator(const const_iterator& that) :
67  i1(that.i1), i2(that.i2), currList(that.currList), currIter(that.currIter) {
68  }
69 
70  const CompIter& CompIter::operator=(const const_iterator& that) {
71  i1 = that.i1;
72  i2 = that.i2;
73  currList = that.currList;
74  currIter = that.currIter;
75  return *this;
76  }
77  */
79  return *currIter;
80 }
81 
83  if (currList == 1 && i1 != i1end) {
84  ++i1;
85  } else if (currList == 2 && i2 != i2end) {
86  ++i2;
87  }
88  if (i2 != i2end && i1 != i1end) {
89  if (i1->m > i2->m) {
90  currIter = i1;
91  currList = 1;
92  } else {
93  currIter = i2;
94  currList = 2;
95  }
96  }
97  if (i2 == i2end && i1 != i1end) {
98  currIter = i1;
99  currList = 1;
100  } else if (i2 != i2end && i1 == i1end) {
101  currIter = i2;
102  currList = 2;
103  }
104  return *this;
105 }
106 
108  CompIter ans = *this;
109  ++ (*this);
110  return ans;
111 }
112 
113 bool CompIter::operator== (const CompIter& that) {
114  if (this->isEnd() == that.isEnd() ) {
115  return true;
116  }
117  bool equals = true;
118  equals &= this->i1 == that.i1;
119  equals &= this->i2 == that.i2;
120  equals &= this->currList == that.currList;
121  equals &= this->currIter == that.currIter;
122  return equals;
123 }
124 
125 bool CompIter::operator!= (const CompIter& that) {
126  return ! (*this == that);
127 }
128 
129 bool CompIter::isEnd() const {
130  return i1 == i1end && i2 == i2end;
131 }
132 
134  return CompIter (l1.begin(), l2.begin(), l1.end(), l2.end() );
135 }
136 
138  return CompIter (l1.end(), l2.end(), l1.end(), l2.end() );
139 }
140 
141 bool ApproxEqual (const FunctionWeight& w1,
142  const FunctionWeight& w2, float delta) {
143  return w1 == w2;
144 }
145 
147  if (this->values.size() != w1.values.size() ) {
148  return false;
149  }
150  return equal (this->values.begin(), this->values.end(), w1.values.begin() );
151 }
152 
154  return ! (*this == w1);
155 }
156 
157 fst::TropicalWeightTpl<F> FunctionWeight::Map (F gamma) const {
158  //Assuming that we're a monomial weight
159  MertLine l = values.front();
160  return fst::TropicalWeightTpl<F> (l.m * gamma + l.y);
161 }
162 
164  const FunctionWeight& w2) {
165  if (w1 == FunctionWeight::Zero() || w2 == FunctionWeight::Zero() ) {
166  return FunctionWeight::Zero();
167  };
168  MertList singleton;
169  MertList fullList;
170  if (w1.values.size() == 1) {
171  singleton = w1.values;
172  fullList = w2.values;
173  } else if (w2.values.size() == 1) {
174  singleton = w2.values;
175  fullList = w1.values;
176  } else {
177  cout << "No singleton list!" << endl;
178  exit (1);
179  }
180  MertLine multiplier = singleton.front();
181  MertList output;
182  /* if(multiplier == zeroLine)
183  {
184  output.push_back(zeroLine);
185  return output;
186  }*/
187  for (MertIter it = fullList.begin(); it != fullList.end(); ++it) {
188  MertLine l (*it);
189  l.y += multiplier.y;
190  l.m += multiplier.m;
191  //l.t.push_back(multiplier.t.front());
192  output.push_back (l);
193  }
194  return FunctionWeight (output);
195 }
196 
198  const FunctionWeight& w2) {
199  MertList outputList;
200  if (w1 == FunctionWeight::Zero() ) {
201  outputList.insert (outputList.begin(), w2.values.begin(), w2.values.end() );
202  return FunctionWeight (outputList);
203  } else if (w2 == FunctionWeight::Zero() ) {
204  outputList.insert (outputList.begin(), w1.values.begin(), w1.values.end() );
205  return FunctionWeight (outputList);
206  }
207  CompositeList lines (w1.values, w2.values);
208  // Use a dummy variable to represent the start of the list
209  static const MertLine dummy (0, 0, 0);
210  outputList.push_front (dummy);
211  MertList::iterator output = outputList.begin();
212  for (CompIter l = lines.begin(); l != lines.end(); ++l) {
213  if (output != outputList.begin() ) {
214  if (output->m == (*l).m) {
215  if ( (*l).y >= output->y)
216  continue;
217  --output;
218  }
219  while (output != outputList.begin() ) {
220  (*l).x = ( (*l).y - output->y) / (output->m - (*l).m);
221  if (output->x < (*l).x)
222  break;
223  --output;
224  }
225  if (output == outputList.begin() )
226  (*l).x = -std::numeric_limits<double>::infinity();
227  output = outputList.insert (++output, *l);
228  } else {
229  output = outputList.insert (++output, *l);
230  }
231  }
232  //Pop the dummy variable off
233  outputList.pop_front();
234  //Erase any non-contributing lines off the list
235  outputList.erase (++output, outputList.end() );
236  FunctionWeight out (outputList);
237  return out;
238 }
239 
240 std::ostream& operator<< (std::ostream& strm, const FunctionWeight& w) {
241  const MertList v = w.Value();
242  strm << v.size();
243  for (MertList::const_iterator it = v.begin(); it != v.end(); ++it) {
244  MertLine l = *it;
245  strm << l.y << l.m;
246  }
247  return strm;
248 }
249 
250 std::istream& operator>> (std::istream& strm, FunctionWeight& w) {
251  MertList::size_type size;
252  strm >> size;
253  MertList outList;
254  for (MertList::size_type i = 0; i < size; ++i) {
255  MertLine l;
256  strm >> l.y >> l.m;
257  outList.push_back (l);
258  }
259  FunctionWeight tw (outList);
260  w.values = outList;
261  return strm;
262 }
263 
264 std::ostream& FunctionWeight::Write (std::ostream& strm) const {
265  const MertList v = this->Value();
266  strm << v.size();
267  for (MertList::const_iterator it = v.begin(); it != v.end(); ++it) {
268  MertLine l = *it;
269  strm << l.y << l.m;
270  }
271  return strm;
272 }
273 
274 std::istream& FunctionWeight::Read (std::istream& strm) {
275  MertList::size_type size;
276  strm >> size;
277  MertList outList;
278  for (MertList::size_type i = 0; i < size; ++i) {
279  MertLine l;
280  strm >> l.y >> l.m;
281  outList.push_back (l);
282  }
283  this->values = outList;
284  return strm;
285 }
286 
287 std::size_t FunctionWeight::Hash() const {
288  cout << "aaw35 Tried to access hash function" << endl;
289  exit (1);
290 }
291 
293  return false;
294 }
295 
297  const FunctionWeight&, fst::DivideType) {
298  cout << "aaw35 Tried to access divide function" << endl;
299  exit (1);
300 }
301 
303  return *this;
304 }
305 
fst::TropicalWeightTpl< F > Map(F) const
bool Member() const
MertList::iterator MertIter
bool operator==(const MertLine &thisML, const MertLine &that)
double F
std::ostream & operator<<(std::ostream &os, const MertLine &ml)
static const FunctionWeight & Zero()
bool operator==(const FunctionWeight &) const
CompositeList(const MertList &l1, const MertList &l2)
std::ostream & Write(std::ostream &strm) const
const MertList & Value() const
bool operator==(const cl_iterator &)
bool operator!=(const FunctionWeight &) const
bool operator!=(const cl_iterator &)
FunctionWeight Times(const FunctionWeight &w1, const FunctionWeight &w2)
std::istream & Read(std::istream &strm)
FunctionWeight Divide(const FunctionWeight &fw1, const FunctionWeight &, fst::DivideType t=fst::DIVIDE_ANY)
cl_iterator begin()
std::list< MertLine > MertList
cl_iterator end()
CompositeList::cl_iterator CompIter
std::size_t Hash() const
ReverseWeight Reverse() const
cl_iterator(MertIter, MertIter, MertIter, MertIter)
std::istream & operator>>(std::istream &is, MertLine &ml)
FunctionWeight Plus(const FunctionWeight &w1, const FunctionWeight &w2)
bool ApproxEqual(const FunctionWeight &w1, const FunctionWeight &w2, float delta)