All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
"Classes and functions related to context expansion"

Classes

class  ContextFstImpl< Arc, LabelT >
 
class  ContextFst< Arc, LabelT >
 
class  StateIterator< ContextFst< A > >
 
class  ArcIterator< ContextFst< A > >
 
class  ContextMatcher< Arc, LabelT >
 

Functions

template<class Arc >
void AddSubsequentialLoop (typename Arc::Label subseq_symbol, MutableFst< Arc > *fst)
 Modifies an FST so that it transuces the same paths, but the input side of the paths can all have the subsequential symbol '$' appended to them any number of times (we could easily specify the number of times, but accepting any number of repetitions is just more convenient). More...
 
template<class I >
void WriteILabelInfo (std::ostream &os, bool binary, const vector< vector< I > > &info)
 Useful utility function for writing these vectors to disk. More...
 
template<class I >
void ReadILabelInfo (std::istream &is, bool binary, vector< vector< I > > *info)
 Useful utility function for reading these vectors from disk. More...
 
template<class I >
SymbolTable * CreateILabelInfoSymbolTable (const vector< vector< I > > &info, const SymbolTable &phones_symtab, std::string separator, std::string disambig_prefix)
 The following function is mainly of use for printing and debugging. More...
 
void ComposeContext (const vector< int32 > &disambig_syms, int N, int P, VectorFst< StdArc > *ifst, VectorFst< StdArc > *ofst, vector< vector< int32 > > *ilabels_out)
 Used in the command-line tool fstcomposecontext. More...
 
template<class Arc , class LabelT >
void ComposeContextFst (const ContextFst< Arc, LabelT > &ifst1, const Fst< Arc > &ifst2, MutableFst< Arc > *ofst, const ComposeOptions &opts=ComposeOptions())
 
StateId FindState (const vector< LabelT > &seq)
 Finds state-id corresponding to this vector of phones. Inserts it if necessary. More...
 
Label FindLabel (const vector< LabelT > &label_info)
 Finds the label index corresponding to this context-window of phones. More...
 
StateId Start ()
 
 ContextFstImpl (const ContextFstImpl &other)
 
Weight Final (StateId s)
 
size_t NumArcs (StateId s)
 
size_t NumInputEpsilons (StateId s)
 
void InitArcIterator (StateId s, ArcIteratorData< Arc > *data)
 
void CreateDisambigArc (StateId s, Label olabel, Arc *oarc)
 
bool CreatePhoneOrEpsArc (StateId src, StateId dst, Label olabel, const vector< LabelT > &phone_seq, Arc *oarc)
 
bool CreateArc (StateId s, Label olabel, Arc *oarc)
 
void Expand (StateId s)
 
 ContextFst (const ContextFst< Arc, LabelT > &fst, bool reset=false)
 
bool Find (Label match_label)
 
virtual void InitStateIterator (StateIteratorData< Arc > *data) const
 

Detailed Description

Function Documentation

void AddSubsequentialLoop ( typename Arc::Label  subseq_symbol,
MutableFst< Arc > *  fst 
)

Modifies an FST so that it transuces the same paths, but the input side of the paths can all have the subsequential symbol '$' appended to them any number of times (we could easily specify the number of times, but accepting any number of repetitions is just more convenient).

The actual way we do this is for each final state, we add a transition with weight equal to the final-weight of that state, with input-symbol '$' and output-symbols <eps>, and ending in a new super-final state that has unit final-probability and a unit-weight self-loop with '$' on its input and <eps> on its output. The reason we don't just add a loop to each final-state has to do with preserving stochasticity (see Preserving stochasticity and testing it). We keep the final-probability in all the original final-states rather than setting them to zero, so the resulting FST can accept zero '$' symbols at the end (in case we had no right context).

Definition at line 401 of file context-fst-inl.h.

References rnnlm::i.

Referenced by fst::ComposeContext(), main(), and TrainingGraphCompiler::TrainingGraphCompiler().

402  {
403  typedef typename Arc::StateId StateId;
404  typedef typename Arc::Weight Weight;
405 
406  vector<StateId> final_states;
407  for (StateIterator<MutableFst<Arc> > siter(*fst); !siter.Done(); siter.Next()) {
408  StateId s = siter.Value();
409  if (fst->Final(s) != Weight::Zero()) final_states.push_back(s);
410  }
411 
412  StateId superfinal = fst->AddState();
413  Arc arc(subseq_symbol, 0, Weight::One(), superfinal);
414  fst->AddArc(superfinal, arc); // loop at superfinal.
415  fst->SetFinal(superfinal, Weight::One());
416 
417  for (size_t i = 0; i < final_states.size(); i++) {
418  StateId s = final_states[i];
419  fst->AddArc(s, Arc(subseq_symbol, 0, fst->Final(s), superfinal));
420  // No, don't remove the final-weights of the original states..
421  // this is so we can add the subsequential loop in cases where
422  // there is no context, and it won't hurt.
423  // fst->SetFinal(s, Weight::Zero());
424  arc.nextstate = final_states[i];
425  }
426 }
fst::StdArc::StateId StateId
Definition: graph.dox:21
fst::StdArc::Weight Weight
void ComposeContext ( const vector< int32 > &  disambig_syms,
int  N,
int  P,
VectorFst< StdArc > *  ifst,
VectorFst< StdArc > *  ofst,
vector< vector< int32 > > *  ilabels_out 
)
inline

Used in the command-line tool fstcomposecontext.

It creates a context FST and composes it on the left with "ifst" to make "ofst". It outputs the label information to ilabels_out. "ifst" is mutable because we need to add the subsequential loop.

Definition at line 508 of file context-fst-inl.h.

References fst::AddSubsequentialLoop(), fst::ComposeContextFst(), fst::GetInputSymbols(), rnnlm::i, and ContextFst< Arc, LabelT >::ILabelInfo().

Referenced by main().

512  {
513  assert(ifst != NULL && ofst != NULL);
514  assert(N > 0);
515  assert(P >= 0);
516  assert(P < N);
517 
518  vector<int32> disambig_syms(disambig_syms_in);
519  std::sort(disambig_syms.begin(), disambig_syms.end());
520  vector<int32> all_syms;
521  GetInputSymbols(*ifst, false/*no eps*/, &all_syms);
522  std::sort(all_syms.begin(), all_syms.end());
523  vector<int32> phones;
524  for (size_t i = 0; i < all_syms.size(); i++)
525  if (!std::binary_search(disambig_syms.begin(),
526  disambig_syms.end(), all_syms[i]))
527  phones.push_back(all_syms[i]);
528 
529  // Get subsequential symbol that does not clash with
530  // any disambiguation symbol or symbol in the FST.
531  int32 subseq_sym = 1;
532  if (!all_syms.empty())
533  subseq_sym = std::max(subseq_sym, all_syms.back() + 1);
534  if (!disambig_syms.empty())
535  subseq_sym = std::max(subseq_sym, disambig_syms.back() + 1);
536 
537  // if P == N-1, it's left-context, and no subsequential symbol needed.
538  if (P != N-1)
539  AddSubsequentialLoop(subseq_sym, ifst);
540  ContextFst<StdArc, int32> cfst(subseq_sym, phones, disambig_syms, N, P);
541  ComposeContextFst(cfst, *ifst, ofst);
542  *ilabels_out = cfst.ILabelInfo();
543 }
void GetInputSymbols(const Fst< Arc > &fst, bool include_eps, vector< I > *symbols)
GetInputSymbols gets the list of symbols on the input of fst (including epsilon, if include_eps == tr...
void AddSubsequentialLoop(typename Arc::Label subseq_symbol, MutableFst< Arc > *fst)
Modifies an FST so that it transuces the same paths, but the input side of the paths can all have the...
void ComposeContextFst(const ContextFst< Arc, LabelT > &ifst1, const Fst< Arc > &ifst2, MutableFst< Arc > *ofst, const ComposeOptions &opts=ComposeOptions())
Definition: context-fst.h:491
void fst::ComposeContextFst ( const ContextFst< Arc, LabelT > &  ifst1,
const Fst< Arc > &  ifst2,
MutableFst< Arc > *  ofst,
const ComposeOptions &  opts = ComposeOptions() 
)

Definition at line 491 of file context-fst.h.

Referenced by TrainingGraphCompiler::CompileGraph(), TrainingGraphCompiler::CompileGraphs(), fst::ComposeContext(), and fst::TestContextFst().

493  {
494  ComposeFstOptions<Arc, ContextMatcher<Arc, LabelT> > nopts;
495  nopts.gc_limit = 0; // Cache only the most recent state for fastest copy.
496  *ofst = ComposeFst<Arc>(ifst1, ifst2, nopts);
497  if (opts.connect)
498  Connect(ofst);
499 }
ContextFst ( const ContextFst< Arc, LabelT > &  fst,
bool  reset = false 
)

Definition at line 361 of file context-fst-inl.h.

References ContextFst< Arc, LabelT >::impl_.

361  {
362  if (reset) {
363  impl_ = new ContextFstImpl<Arc, LabelT>(*(fst.impl_));
364  // Copy constructor of ContextFstImpl.
365  // Main use of calling with reset = true is to free up memory
366  // (e.g. then you could delete original one). Might be useful in transcription
367  // expansion during training.
368  } else {
369  impl_ = fst.impl_;
370  impl_->IncrRefCount();
371  }
372 }
Definition: graph.dox:21
ContextFstImpl< Arc, LabelT > * impl_
Definition: context-fst.h:310
ContextFstImpl ( const ContextFstImpl< Arc, LabelT > &  other)

Definition at line 88 of file context-fst-inl.h.

References KALDI_ERR.

88  :
89  phone_syms_(other.phone_syms_),
90  disambig_syms_(other.disambig_syms_) {
91  KALDI_ERR << "ContextFst copying not yet supported "
92  << "[not hard, but would have to test.]";
93 }
kaldi::ConstIntegerSet< Label > phone_syms_
Definition: context-fst.h:178
kaldi::ConstIntegerSet< Label > disambig_syms_
Definition: context-fst.h:179
#define KALDI_ERR
Definition: kaldi-error.h:127
bool CreateArc ( StateId  s,
Label  olabel,
Arc *  oarc 
)

Definition at line 272 of file context-fst-inl.h.

References rnnlm::i, and KALDI_ERR.

274  {
275  // Returns true to indicate the arc exists.
276 
277  if (olabel == 0) return false; // No epsilon-output arcs in this FST.
278 
279  const vector<LabelT> &seq = state_seqs_[s];
280 
281  if (IsDisambigSymbol(olabel)) { // Disambiguation-symbol arcs.. create self-loop.
282  CreateDisambigArc(s, olabel, oarc);
283  return true;
284  } else if (IsPhoneSymbol(olabel) || olabel == subsequential_symbol_) {
285  // If all is OK, we shift the old sequence left by 1 and push on the new phone.
286 
287  if (olabel != subsequential_symbol_ && !seq.empty() &&
288  seq.back() == subsequential_symbol_) {
289  return false; // Phone not allowed to follow subsequential symbol.
290  }
291 
292  if (olabel == subsequential_symbol_ &&
293  (P_ == N_-1 || seq[P_] == subsequential_symbol_)) {
294  // We already had "enough" subsequential symbols in a row and don't want to
295  // accept any more, or we'd be making the subsequential symbol the central phone.
296  return false;
297  }
298 
299  vector<LabelT> newseq(N_-1); // seq shifted left by 1.
300  for (int i = 0;i < N_-2;i++) newseq[i] = seq[i+1];
301  if (N_ > 1) newseq[N_-2] = olabel;
302 
303  vector<LabelT> phoneseq(seq); // copy it before FindState which
304  // possibly changes the address.
305  StateId nextstate = FindState(newseq);
306 
307  phoneseq.push_back(olabel); // Now it's the full context window of size N_.
308  for (int i = 1; i < N_ ; i++)
309  if (phoneseq[i] == subsequential_symbol_) phoneseq[i] = 0; // don't put subseq. symbol on
310  // the output arcs, just 0.
311  return CreatePhoneOrEpsArc(s, nextstate, olabel, phoneseq, oarc);
312  } else {
313  KALDI_ERR << "ContextFst: CreateArc, invalid olabel supplied [confusion "
314  << "about phone list or disambig symbols?]: " << olabel;
315  }
316  return false; // won't get here. suppress compiler error.
317 }
bool CreatePhoneOrEpsArc(StateId src, StateId dst, Label olabel, const vector< LabelT > &phone_seq, Arc *oarc)
bool IsDisambigSymbol(Label lab)
Definition: context-fst.h:159
void CreateDisambigArc(StateId s, Label olabel, Arc *oarc)
StateId FindState(const vector< LabelT > &seq)
Finds state-id corresponding to this vector of phones. Inserts it if necessary.
Arc::StateId StateId
Definition: context-fst.h:95
#define KALDI_ERR
Definition: kaldi-error.h:127
vector< vector< LabelT > > state_seqs_
Definition: context-fst.h:171
bool IsPhoneSymbol(Label lab)
Definition: context-fst.h:162
void CreateDisambigArc ( StateId  s,
Label  olabel,
Arc *  oarc 
)
inlineprivate

Definition at line 221 of file context-fst-inl.h.

223  { // called from CreateArc.
224  // Creates a self-loop arc corresponding to the disambiguation symbol.
225  vector<LabelT> label_info; // (olabel);
226  label_info.push_back(-olabel); // olabel is a disambiguation symbol. Use its negative
227  // so we can easily distinguish them.
228  Label ilabel = FindLabel(label_info);
229  oarc->ilabel = ilabel;
230  oarc->olabel = olabel;
231  oarc->weight = Weight::One();
232  oarc->nextstate = s; // self-loop.
233 }
Arc::Label Label
Definition: context-fst.h:96
Label FindLabel(const vector< LabelT > &label_info)
Finds the label index corresponding to this context-window of phones.
SymbolTable * CreateILabelInfoSymbolTable ( const vector< vector< I > > &  info,
const SymbolTable &  phones_symtab,
std::string  separator,
std::string  initial_disambig 
)

The following function is mainly of use for printing and debugging.

Definition at line 453 of file context-fst-inl.h.

References rnnlm::i, rnnlm::j, and KALDI_ERR.

Referenced by main().

456  { // e.g. separator = "/", initial-disambig="#-1"
457  assert(std::numeric_limits<I>::is_signed); // make sure is signed type.
458  assert(!info.empty());
459  assert(info[0].empty());
460  SymbolTable *ans = new SymbolTable("ilabel-info-symtab");
461  int64 s = ans->AddSymbol(phones_symtab.Find(static_cast<int64>(0)));
462  assert(s == 0);
463  for (size_t i = 1; i < info.size(); i++) {
464  if (info[i].size() == 0) {
465  KALDI_ERR << "Invalid ilabel-info";
466  }
467  if (info[i].size() == 1 &&
468  info[i][0] <= 0) {
469  if (info[i][0] == 0) { // special symbol at start that we want to call #-1.
470  s = ans->AddSymbol(initial_disambig);
471  if (s != i) {
472  KALDI_ERR << "Disambig symbol " << initial_disambig
473  << " already in vocab";
474  }
475  } else {
476  std::string disambig_sym = phones_symtab.Find(-info[i][0]);
477  if (disambig_sym == "") {
478  KALDI_ERR << "Disambig symbol " << -info[i][0]
479  << " not in phone symbol-table";
480  }
481  s = ans->AddSymbol(disambig_sym);
482  if (s != i) {
483  KALDI_ERR << "Disambig symbol " << disambig_sym
484  << " already in vocab";
485  }
486  }
487  } else {
488  // is a phone-context-window.
489  std::string newsym;
490  for (size_t j = 0; j < info[i].size(); j++) {
491  std::string phonesym = phones_symtab.Find(info[i][j]);
492  if (phonesym == "") {
493  KALDI_ERR << "Symbol " << info[i][j]
494  << " not in phone symbol-table";
495  }
496  if (j != 0) newsym += separator;
497  newsym += phonesym;
498  }
499  int64 s = ans->AddSymbol(newsym);
500  if (s != static_cast<int64>(i)) {
501  KALDI_ERR << "Some problem with duplicate symbols";
502  }
503  }
504  }
505  return ans;
506 }
#define KALDI_ERR
Definition: kaldi-error.h:127
bool CreatePhoneOrEpsArc ( StateId  src,
StateId  dst,
Label  olabel,
const vector< LabelT > &  phone_seq,
Arc *  oarc 
)
inlineprivate

Definition at line 236 of file context-fst-inl.h.

240  {
241  // called from CreateArc.
242  // creates the arc with a phone's state on its input labels (or epsilon).
243  // returns true if it created the arc.
244  // returns false if it could not create an arc due to the decision-tree returning false
245  // [this only happens if opts_.behavior_on_failure == ContextFstOptions::kNoArc].
246 
247  assert(phone_seq[P_] != subsequential_symbol_); // would be coding error.
248 
249  if (phone_seq[P_] == 0) { // this can happen at the beginning of the graph.
250  // we don't output a real phone. Epsilon arc (but sometimes we need to
251  // use a special disambiguation symbol instead of epsilon).
252  *oarc = Arc(pseudo_eps_symbol_, olabel, Weight::One(), dst);
253  // This 1 is a "special" disambiguation symbol (#-1 in printed form) that
254  // we use to represent epsilons.
255  return true;
256  } else {
257  // have a phone in central position.
258  Label ilabel = FindLabel(phone_seq);
259  *oarc = Arc(ilabel, olabel, Weight::One(), dst);
260  return true;
261  }
262 }
Arc::Label Label
Definition: context-fst.h:96
Label FindLabel(const vector< LabelT > &label_info)
Finds the label index corresponding to this context-window of phones.
void Expand ( StateId  s)

Definition at line 322 of file context-fst-inl.h.

322  { // expands arcs only [not final state weight].
323  assert(static_cast<size_t>(s) < state_seqs_.size()); // make sure state exists already.
324 
325  // We just try adding all possible symbols on the output side.
326  Arc arc;
327  if (this->CreateArc(s, subsequential_symbol_, &arc)) {
328 #ifdef HAVE_OPENFST_GE_10400
329  this->PushArc(s, arc);
330 #else
331  this->AddArc(s, arc);
332 #endif
333  }
335  iter != phone_syms_.end(); ++iter) {
336  Label phone = *iter;
337  if (this->CreateArc(s, phone, &arc)) {
338 #ifdef HAVE_OPENFST_GE_10400
339  this->PushArc(s, arc);
340 #else
341  this->AddArc(s, arc);
342 #endif
343  }
344  }
346  iter != disambig_syms_.end(); ++iter) {
347  Label disambig_sym = *iter;
348  if (this->CreateArc(s, disambig_sym, &arc)) {
349 #ifdef HAVE_OPENFST_GE_10400
350  this->PushArc(s, arc);
351 #else
352  this->AddArc(s, arc);
353 #endif
354  }
355  }
356  this->SetArcs(s); // mark the arcs as "done". [so HasArcs returns true].
357 }
kaldi::ConstIntegerSet< Label > phone_syms_
Definition: context-fst.h:178
iterator begin() const
iterator end() const
kaldi::ConstIntegerSet< Label > disambig_syms_
Definition: context-fst.h:179
Arc::Label Label
Definition: context-fst.h:96
vector< vector< LabelT > > state_seqs_
Definition: context-fst.h:171
bool CreateArc(StateId s, Label olabel, Arc *oarc)
std::vector< I >::const_iterator iterator
ContextFstImpl< Arc, LabelT >::Weight Final ( StateId  s)

Definition at line 148 of file context-fst-inl.h.

148  {
149  assert(static_cast<size_t>(s) < state_seqs_.size()); // make sure state exists already.
150  if (!this->HasFinal(s)) { // Work out final-state weight.
151  const vector<LabelT> &seq = state_seqs_[s];
152 
153  bool final_ok;
154  assert(static_cast<int32>(seq.size()) == N_-1);
155 
156  if (P_ < N_ - 1) {
157  /* Note that P_ (in zero based indexing) is the "central position", and for arcs out of
158  this state the thing at P_ will be the one we expand. If this is the subsequential symbol,
159  it means we will output nothing (and will obviously never output anything). Thus we make
160  this state the final state.
161  */
162  final_ok = (seq[P_] == subsequential_symbol_);
163  } else {
164  /* If P_ == N_-1, then the "central phone" is the last one in the list (we have a left-context system).
165  In this case everything is output immediately and there is no need for a subsequential symbol.
166  Here, any state in the FST can be the final state.
167  */
168  final_ok = true;
169  }
170  Weight w = final_ok ? Weight::One() : Weight::Zero();
171  this->SetFinal(s, w);
172  return w;
173  }
174  return CacheImpl<Arc>::Final(s);
175 }
Arc::Weight Weight
Definition: context-fst.h:94
vector< vector< LabelT > > state_seqs_
Definition: context-fst.h:171
bool Find ( typename Arc::Label  match_label)

Definition at line 377 of file context-fst-inl.h.

References ContextFst< Arc, LabelT >::CreateArc().

Referenced by ContextMatcher< Arc, LabelT >::Find_().

377  {
378  assert(s_ != kNoStateId);
379  // we know at this point that match_type_ == MATCH_OUTPUT. we are matching output.
380 
381  if (match_label == kNoLabel) {
382  // A ContextFst has no epsilons on its output. So
383  // we don't need to match self-loops on the other FST.
384  ready_ = false;
385  return false;
386  } else if (match_label == 0) {
387  arc_.ilabel = 0;
388  arc_.olabel = kNoLabel; // epsilon_L
389  arc_.weight = Weight::One();
390  arc_.nextstate = s_; // loop.
391  ready_ = true;
392  return true; // epsilon_L loop.
393  } else {
394  const ContextFst<Arc, LabelT> *cfst = static_cast<const ContextFst<Arc, LabelT>*> (fst_); // we checked in initializer, that it is.
395  ready_ = cfst->CreateArc(s_, match_label, &arc_);
396  return ready_;
397  }
398 }
const FST * fst_
Definition: context-fst.h:469
ContextFstImpl< Arc, LabelT >::Label FindLabel ( const vector< LabelT > &  label_info)
private

Finds the label index corresponding to this context-window of phones.

Inserts it if necessary.

Definition at line 60 of file context-fst-inl.h.

60  {
61  // Finds ilabel corresponding to this information.. Creates new ilabel if necessary.
62  VectorToLabelIter iter = ilabel_map_.find(label_vec);
63  if (iter == ilabel_map_.end()) { // Not already in map.
64  Label this_label = ilabel_info_.size();
65  ilabel_info_.push_back(label_vec);
66  ilabel_map_[label_vec] = this_label;
67  return this_label;
68  } else {
69  return iter->second;
70  }
71 }
Arc::Label Label
Definition: context-fst.h:96
vector< vector< LabelT > > ilabel_info_
Definition: context-fst.h:175
VectorToLabelType::const_iterator VectorToLabelIter
Definition: context-fst.h:107
VectorToLabelType ilabel_map_
Definition: context-fst.h:174
ContextFstImpl< Arc, LabelT >::StateId FindState ( const vector< LabelT > &  seq)
private

Finds state-id corresponding to this vector of phones. Inserts it if necessary.

Definition at line 37 of file context-fst-inl.h.

37  {
38  // Finds state-id corresponding to this vector of phones. Inserts it if
39  // necessary.
40  assert(static_cast<int32>(seq.size()) == N_-1);
41  VectorToStateIter iter = state_map_.find(seq);
42  if (iter == state_map_.end()) { // Not already in map.
43  StateId this_state_id = (StateId)state_seqs_.size();
44  //This check is not needed with OpenFst >= 1.4
45 #ifndef HAVE_OPENFST_GE_10400
46  StateId this_state_id_check = CacheImpl<Arc>::AddState();
47  // goes back to VectorFstBaseImpl<Arc>, inherited via CacheFst<Arc>
48  assert(this_state_id == this_state_id_check);
49 #endif
50  state_seqs_.push_back(seq);
51  state_map_[seq] = this_state_id;
52  return this_state_id;
53  } else {
54  return iter->second;
55  }
56 }
VectorToStateType state_map_
Definition: context-fst.h:170
VectorToStateType::const_iterator VectorToStateIter
Definition: context-fst.h:106
Arc::StateId StateId
Definition: context-fst.h:95
vector< vector< LabelT > > state_seqs_
Definition: context-fst.h:171
void InitArcIterator ( StateId  s,
ArcIteratorData< Arc > *  data 
)

Definition at line 213 of file context-fst-inl.h.

213  {
214  if (!this->HasArcs(s))
215  Expand(s);
217 }
void Expand(StateId s)
void InitStateIterator ( StateIteratorData< Arc > *  data) const
inlinevirtual

Definition at line 372 of file context-fst.h.

372  {
373  data->base = new StateIterator< ContextFst<A> >(*this);
374 }
size_t NumArcs ( StateId  s)

Definition at line 180 of file context-fst-inl.h.

References KALDI_ASSERT, and fst::NumArcs().

180  {
181  if (this->HasArcs(s)) {
182  return CacheImpl<Arc>::NumArcs(s);
183  }
184  KALDI_ASSERT(s >= 0 && s < state_seqs_.size());
185  const vector<LabelT> &seq = state_seqs_[s];
186  KALDI_ASSERT(seq.size() == N_ - 1);
187  if (!seq.empty() && seq.back() == subsequential_symbol_) {
188  // State is not a "normal" state because it just saw the subsequential symbol,
189  // hence it cannot accept phones.
190 
191  if (P_ == N_ - 1 || seq[P_] == subsequential_symbol_) { // don't
192  // accept subsequential symbol.. c.f. logic in CreateArc().
193  return disambig_syms_.size();
194  } else {
195  return disambig_syms_.size() + 1; // Accept disambig syms and
196  // subsequential symbol.
197  }
198  } else {
199  // For normal states, in general there is potentially an arc for each phone and an arc
200  // for each disambiguation symbol, plus one for the subsequential symbol.
201  return phone_syms_.size() + disambig_syms_.size() + 1;
202  }
203 }
kaldi::ConstIntegerSet< Label > phone_syms_
Definition: context-fst.h:178
kaldi::ConstIntegerSet< Label > disambig_syms_
Definition: context-fst.h:179
vector< vector< LabelT > > state_seqs_
Definition: context-fst.h:171
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:169
Arc::StateId NumArcs(const ExpandedFst< Arc > &fst)
Returns the total number of arcs in an FST.
size_t NumInputEpsilons ( StateId  s)

Definition at line 206 of file context-fst-inl.h.

206  {
207  if (!this->HasArcs(s))
208  Expand(s);
210 }
void Expand(StateId s)
void ReadILabelInfo ( std::istream &  is,
bool  binary,
vector< vector< I > > *  info 
)

Useful utility function for reading these vectors from disk.

writes as int32 (see WriteILabelInfo above).

Definition at line 440 of file context-fst-inl.h.

References rnnlm::i, kaldi::ReadBasicType(), and kaldi::ReadIntegerVector().

Referenced by main(), and fst::TestContextFst().

441  {
442  I sz = info->size();
443  kaldi::ReadBasicType(is, binary, &sz);
444  assert(info != NULL);
445  info->resize(sz);
446  for (int i = 0; i < sz; i++) {
447  kaldi::ReadIntegerVector(is, binary, &((*info)[i]));
448  }
449 }
void ReadBasicType(std::istream &is, bool binary, T *t)
ReadBasicType is the name of the read function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:55
void ReadIntegerVector(std::istream &is, bool binary, std::vector< T > *v)
Function for reading STL vector of integer types.
Definition: io-funcs-inl.h:232
ContextFstImpl< Arc, LabelT >::StateId Start ( )

Definition at line 75 of file context-fst-inl.h.

75  {
76  if (! CacheImpl<Arc>::HasStart()) {
77  vector<LabelT> vec(N_-1, 0); // Vector of N_-1 epsilons. [e.g. N = 3].
78  StateId s = FindState(vec);
79  assert(s == 0);
80  this->SetStart(s);
81  }
82  return CacheImpl<Arc>::Start();
83 }
StateId FindState(const vector< LabelT > &seq)
Finds state-id corresponding to this vector of phones. Inserts it if necessary.
Arc::StateId StateId
Definition: context-fst.h:95
void WriteILabelInfo ( std::ostream &  os,
bool  binary,
const vector< vector< I > > &  info 
)

Useful utility function for writing these vectors to disk.

writes as int32 for binary compatibility since I will typically be "int".

Definition at line 429 of file context-fst-inl.h.

References rnnlm::i, kaldi::WriteBasicType(), and kaldi::WriteIntegerVector().

Referenced by main(), and fst::TestContextFst().

430  {
431  I sz = info.size();
432  kaldi::WriteBasicType(os, binary, sz);
433  for (I i = 0; i < sz; i++) {
434  kaldi::WriteIntegerVector(os, binary, info[i]);
435  }
436 }
void WriteIntegerVector(std::ostream &os, bool binary, const std::vector< T > &v)
Function for writing STL vectors of integer types.
Definition: io-funcs-inl.h:198
void WriteBasicType(std::ostream &os, bool binary, T t)
WriteBasicType is the name of the write function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:34