lattice-utils-inl.h
Go to the documentation of this file.
1 // fstext/lattice-utils-inl.h
2 
3 // Copyright 2009-2012 Microsoft Corporation Johns Hopkins University (Author: Daniel Povey)
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 #ifndef KALDI_FSTEXT_LATTICE_UTILS_INL_H_
21 #define KALDI_FSTEXT_LATTICE_UTILS_INL_H_
22 // Do not include this file directly. It is included by lattice-utils.h
23 
24 
25 namespace fst {
26 
27 
28 /* Convert from FST with arc-type Weight, to one with arc-type
29  CompactLatticeWeight. Uses FactorFst to identify chains
30  of states which can be turned into a single output arc. */
31 
32 template<class Weight, class Int>
34  const ExpandedFst<ArcTpl<Weight> > &ifst,
35  MutableFst<ArcTpl<CompactLatticeWeightTpl<Weight, Int> > > *ofst,
36  bool invert) {
37  typedef ArcTpl<Weight> Arc;
38  typedef typename Arc::StateId StateId;
39  typedef CompactLatticeWeightTpl<Weight, Int> CompactWeight;
40  typedef ArcTpl<CompactWeight> CompactArc;
41 
42  VectorFst<ArcTpl<Weight> > ffst;
43  std::vector<std::vector<Int> > labels;
44  if (invert) // normal case: want the ilabels as sequences on the arcs of
45  Factor(ifst, &ffst, &labels); // the output... Factor makes seqs of
46  // ilabels.
47  else {
48  VectorFst<ArcTpl<Weight> > invfst(ifst);
49  Invert(&invfst);
50  Factor(invfst, &ffst, &labels);
51  }
52 
53  TopSort(&ffst); // Put the states in ffst in topological order, which is
54  // easier on the eye when reading the text-form lattices and corresponds to
55  // what we get when we generate the lattices in the decoder.
56 
57  ofst->DeleteStates();
58 
59  // The states will be numbered exactly the same as the original FST.
60  // Add the states to the new FST.
61  StateId num_states = ffst.NumStates();
62  for (StateId s = 0; s < num_states; s++) {
63  StateId news = ofst->AddState();
64  assert(news == s);
65  }
66  ofst->SetStart(ffst.Start());
67  for (StateId s = 0; s < num_states; s++) {
68  Weight final_weight = ffst.Final(s);
69  if (final_weight != Weight::Zero()) {
70  CompactWeight final_compact_weight(final_weight, std::vector<Int>());
71  ofst->SetFinal(s, final_compact_weight);
72  }
73  for (ArcIterator<ExpandedFst<Arc> > iter(ffst, s);
74  !iter.Done();
75  iter.Next()) {
76  const Arc &arc = iter.Value();
77  KALDI_PARANOID_ASSERT(arc.weight != Weight::Zero());
78  // note: zero-weight arcs not allowed anyway so weight should not be zero,
79  // but no harm in checking.
80  CompactArc compact_arc(arc.olabel, arc.olabel,
81  CompactWeight(arc.weight, labels[arc.ilabel]),
82  arc.nextstate);
83  ofst->AddArc(s, compact_arc);
84  }
85  }
86 }
87 
88 template<class Weight, class Int>
90  const ExpandedFst<ArcTpl<CompactLatticeWeightTpl<Weight, Int> > > &ifst,
91  MutableFst<ArcTpl<Weight> > *ofst,
92  bool invert) {
93  typedef ArcTpl<Weight> Arc;
94  typedef typename Arc::StateId StateId;
95  typedef typename Arc::Label Label;
96  typedef CompactLatticeWeightTpl<Weight, Int> CompactWeight;
97  typedef ArcTpl<CompactWeight> CompactArc;
98  ofst->DeleteStates();
99  // make the states in the new FST have the same numbers as
100  // the original ones, and add chains of states as necessary
101  // to encode the string-valued weights.
102  StateId num_states = ifst.NumStates();
103  for (StateId s = 0; s < num_states; s++) {
104  StateId news = ofst->AddState();
105  assert(news == s);
106  }
107  ofst->SetStart(ifst.Start());
108  for (StateId s = 0; s < num_states; s++) {
109  CompactWeight final_weight = ifst.Final(s);
110  if (final_weight != CompactWeight::Zero()) {
111  StateId cur_state = s;
112  size_t string_length = final_weight.String().size();
113  for (size_t n = 0; n < string_length; n++) {
114  StateId next_state = ofst->AddState();
115  Label ilabel = 0;
116  Arc arc(ilabel, final_weight.String()[n],
117  (n == 0 ? final_weight.Weight() : Weight::One()),
118  next_state);
119  if (invert) std::swap(arc.ilabel, arc.olabel);
120  ofst->AddArc(cur_state, arc);
121  cur_state = next_state;
122  }
123  ofst->SetFinal(cur_state,
124  string_length > 0 ? Weight::One() : final_weight.Weight());
125  }
126  for (ArcIterator<ExpandedFst<CompactArc> > iter(ifst, s);
127  !iter.Done();
128  iter.Next()) {
129  const CompactArc &arc = iter.Value();
130  size_t string_length = arc.weight.String().size();
131  StateId cur_state = s;
132  // for all but the last element in the string--
133  // add a temporary state.
134  for (size_t n = 0 ; n+1 < string_length; n++) {
135  StateId next_state = ofst->AddState();
136  Label ilabel = (n == 0 ? arc.ilabel : 0),
137  olabel = static_cast<Label>(arc.weight.String()[n]);
138  Weight weight = (n == 0 ? arc.weight.Weight() : Weight::One());
139  Arc new_arc(ilabel, olabel, weight, next_state);
140  if (invert) std::swap(new_arc.ilabel, new_arc.olabel);
141  ofst->AddArc(cur_state, new_arc);
142  cur_state = next_state;
143  }
144  Label ilabel = (string_length <= 1 ? arc.ilabel : 0),
145  olabel = (string_length > 0 ? arc.weight.String()[string_length-1] : 0);
146  Weight weight = (string_length <= 1 ? arc.weight.Weight() : Weight::One());
147  Arc new_arc(ilabel, olabel, weight, arc.nextstate);
148  if (invert) std::swap(new_arc.ilabel, new_arc.olabel);
149  ofst->AddArc(cur_state, new_arc);
150  }
151  }
152 }
153 
154 // This function converts lattices between float and double;
155 // it works for both CompactLatticeWeight and LatticeWeight.
156 template<class WeightIn, class WeightOut>
158  const ExpandedFst<ArcTpl<WeightIn> > &ifst,
159  MutableFst<ArcTpl<WeightOut> > *ofst) {
160  typedef ArcTpl<WeightIn> ArcIn;
161  typedef ArcTpl<WeightOut> ArcOut;
162  typedef typename ArcIn::StateId StateId;
163  ofst->DeleteStates();
164  // The states will be numbered exactly the same as the original FST.
165  // Add the states to the new FST.
166  StateId num_states = ifst.NumStates();
167  for (StateId s = 0; s < num_states; s++) {
168  StateId news = ofst->AddState();
169  assert(news == s);
170  }
171  ofst->SetStart(ifst.Start());
172  for (StateId s = 0; s < num_states; s++) {
173  WeightIn final_iweight = ifst.Final(s);
174  if (final_iweight != WeightIn::Zero()) {
175  WeightOut final_oweight;
176  ConvertLatticeWeight(final_iweight, &final_oweight);
177  ofst->SetFinal(s, final_oweight);
178  }
179  for (ArcIterator<ExpandedFst<ArcIn> > iter(ifst, s);
180  !iter.Done();
181  iter.Next()) {
182  ArcIn arc = iter.Value();
183  KALDI_PARANOID_ASSERT(arc.weight != WeightIn::Zero());
184  ArcOut oarc;
185  ConvertLatticeWeight(arc.weight, &oarc.weight);
186  oarc.ilabel = arc.ilabel;
187  oarc.olabel = arc.olabel;
188  oarc.nextstate = arc.nextstate;
189  ofst->AddArc(s, oarc);
190  }
191  }
192 }
193 
194 
195 
196 template<class Weight, class ScaleFloat>
198  const std::vector<std::vector<ScaleFloat> > &scale,
199  MutableFst<ArcTpl<Weight> > *fst) {
200  assert(scale.size() == 2 && scale[0].size() == 2 && scale[1].size() == 2);
201  if (scale == DefaultLatticeScale()) // nothing to do.
202  return;
203  typedef ArcTpl<Weight> Arc;
204  typedef MutableFst<Arc> Fst;
205  typedef typename Arc::StateId StateId;
206  StateId num_states = fst->NumStates();
207  for (StateId s = 0; s < num_states; s++) {
208  for (MutableArcIterator<Fst> aiter(fst, s);
209  !aiter.Done();
210  aiter.Next()) {
211  Arc arc = aiter.Value();
212  arc.weight = Weight(ScaleTupleWeight(arc.weight, scale));
213  aiter.SetValue(arc);
214  }
215  Weight final_weight = fst->Final(s);
216  if (final_weight != Weight::Zero())
217  fst->SetFinal(s, Weight(ScaleTupleWeight(final_weight, scale)));
218  }
219 }
220 
221 template<class Weight, class Int>
223  MutableFst<ArcTpl<CompactLatticeWeightTpl<Weight, Int> > > *fst) {
225  typedef ArcTpl<W> Arc;
226  typedef MutableFst<Arc> Fst;
227  typedef typename Arc::StateId StateId;
228  StateId num_states = fst->NumStates();
229  for (StateId s = 0; s < num_states; s++) {
230  for (MutableArcIterator<Fst> aiter(fst, s);
231  !aiter.Done();
232  aiter.Next()) {
233  Arc arc = aiter.Value();
234  arc.weight = W(arc.weight.Weight(), std::vector<Int>());
235  aiter.SetValue(arc);
236  }
237  W final_weight = fst->Final(s);
238  if (final_weight != W::Zero())
239  fst->SetFinal(s, W(final_weight.Weight(), std::vector<Int>()));
240  }
241 }
242 
243 template<class Weight, class Int>
245  const ExpandedFst<ArcTpl<CompactLatticeWeightTpl<Weight, Int> > > &fst) {
247  typedef ArcTpl<W> Arc;
248  typedef ExpandedFst<Arc> Fst;
249  typedef typename Arc::StateId StateId;
250  StateId num_states = fst.NumStates();
251  for (StateId s = 0; s < num_states; s++) {
252  for (ArcIterator<Fst> aiter(fst, s);
253  !aiter.Done();
254  aiter.Next()) {
255  const Arc &arc = aiter.Value();
256  if (!arc.weight.String().empty()) return true;
257  }
258  W final_weight = fst.Final(s);
259  if (!final_weight.String().empty()) return true;
260  }
261  return false;
262 }
263 
264 
265 template <class Real>
267  const ExpandedFst<ArcTpl<TropicalWeight> > &ifst,
268  MutableFst<ArcTpl<LatticeWeightTpl<Real> > > *ofst) {
269  int32 num_states_cache = 50000;
270  fst::CacheOptions cache_opts(true, num_states_cache);
271  fst::MapFstOptions mapfst_opts(cache_opts);
273  MapFst<StdArc, ArcTpl<LatticeWeightTpl<Real> >,
274  StdToLatticeMapper<Real> > map_fst(ifst, mapper, mapfst_opts);
275  *ofst = map_fst;
276 }
277 
278 
279 }
280 
281 
282 #endif
fst::StdArc::StateId StateId
void RemoveAlignmentsFromCompactLattice(MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, Int > > > *fst)
Removes state-level alignments (the strings that are part of the weights).
LatticeWeightTpl< FloatType > ScaleTupleWeight(const LatticeWeightTpl< FloatType > &w, const std::vector< std::vector< ScaleFloatType > > &scale)
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
Definition: graph.dox:21
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
kaldi::int32 int32
void ConvertLatticeWeight(const LatticeWeightTpl< Float1 > &w_in, LatticeWeightTpl< Float2 > *w_out)
Define some ConvertLatticeWeight functions that are used in various lattice conversions...
void ScaleLattice(const std::vector< std::vector< ScaleFloat > > &scale, MutableFst< ArcTpl< Weight > > *fst)
Scales the pairs of weights in LatticeWeight or CompactLatticeWeight by viewing the pair (a...
bool CompactLatticeHasAlignment(const ExpandedFst< ArcTpl< CompactLatticeWeightTpl< Weight, Int > > > &fst)
Returns true if lattice has alignments, i.e.
struct rnnlm::@11::@12 n
void ConvertLattice(const ExpandedFst< ArcTpl< Weight > > &ifst, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, Int > > > *ofst, bool invert)
Convert lattice from a normal FST to a CompactLattice FST.
#define KALDI_PARANOID_ASSERT(cond)
Definition: kaldi-error.h:206
void Factor(const Fst< Arc > &fst, MutableFst< Arc > *ofst, std::vector< std::vector< I > > *symbols_out)
Factor identifies linear chains of states with an olabel (if any) only on the first arc of the chain...
Definition: factor-inl.h:69
fst::StdArc::Label Label
fst::StdArc::Weight Weight
Class StdToLatticeMapper maps a normal arc (StdArc) to a LatticeArc by putting the StdArc weight as t...
void ConvertFstToLattice(const ExpandedFst< ArcTpl< TropicalWeight > > &ifst, MutableFst< ArcTpl< LatticeWeightTpl< Real > > > *ofst)
Converts TropicalWeight to LatticeWeight (puts all the weight on the first float in the lattice&#39;s pai...
std::vector< std::vector< double > > DefaultLatticeScale()
Returns a default 2x2 matrix scaling factor for LatticeWeight.