Fst_extensions

Classes

struct  DeterminizeLatticeOptions
 
struct  DeterminizeLatticePrunedOptions
 
struct  DeterminizeLatticePhonePrunedOptions
 

Functions

template<class Weight , class IntType >
bool DeterminizeLattice (const Fst< ArcTpl< Weight > > &ifst, MutableFst< ArcTpl< Weight > > *ofst, DeterminizeLatticeOptions opts=DeterminizeLatticeOptions(), bool *debug_ptr=NULL)
 This function implements the normal version of DeterminizeLattice, in which the output strings are represented using sequences of arcs, where all but the first one has an epsilon on the input side. More...
 
template<class Weight , class IntType >
bool DeterminizeLattice (const Fst< ArcTpl< Weight > > &ifst, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticeOptions opts, bool *debug_ptr)
 
template<class F >
bool DeterminizeStar (F &ifst, MutableFst< typename F::Arc > *ofst, float delta=kDelta, bool *debug_ptr=NULL, int max_states=-1, bool allow_partial=false)
 This function implements the normal version of DeterminizeStar, in which the output strings are represented using sequences of arcs, where all but the first one has an epsilon on the input side. More...
 
template<class F >
bool DeterminizeStar (F &ifst, MutableFst< GallicArc< typename F::Arc > > *ofst, float delta, bool *debug_ptr, int max_states, bool allow_partial)
 
template<class Weight >
bool DeterminizeLatticePruned (const ExpandedFst< ArcTpl< Weight > > &ifst, double prune, MutableFst< ArcTpl< Weight > > *ofst, DeterminizeLatticePrunedOptions opts=DeterminizeLatticePrunedOptions())
 This function implements the normal version of DeterminizeLattice, in which the output strings are represented using sequences of arcs, where all but the first one has an epsilon on the input side. More...
 
template<class Weight , class IntType >
bool DeterminizeLatticePruned (const ExpandedFst< ArcTpl< Weight > > &ifst, double beam, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePrunedOptions opts)
 
template<class Weight >
ArcTpl< Weight >::Label DeterminizeLatticeInsertPhones (const kaldi::TransitionModel &trans_model, MutableFst< ArcTpl< Weight > > *fst)
 This function takes in lattices and inserts phones at phone boundaries. More...
 
template<class Weight >
void DeterminizeLatticeDeletePhones (typename ArcTpl< Weight >::Label first_phone_label, MutableFst< ArcTpl< Weight > > *fst)
 This function takes in lattices and deletes "phones" from them. More...
 
template<class Weight , class IntType >
bool DeterminizeLatticePhonePruned (const kaldi::TransitionModel &trans_model, const ExpandedFst< ArcTpl< Weight > > &ifst, double prune, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePhonePrunedOptions opts=DeterminizeLatticePhonePrunedOptions())
 This function is a wrapper of DeterminizeLatticePhonePrunedFirstPass() and DeterminizeLatticePruned(). More...
 
template<class Weight , class IntType >
bool DeterminizeLatticePhonePruned (const kaldi::TransitionModel &trans_model, MutableFst< ArcTpl< Weight > > *ifst, double prune, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePhonePrunedOptions opts=DeterminizeLatticePhonePrunedOptions())
 "Destructive" version of DeterminizeLatticePhonePruned() where the input lattice might be changed. More...
 
bool DeterminizeLatticePhonePrunedWrapper (const kaldi::TransitionModel &trans_model, MutableFst< kaldi::LatticeArc > *ifst, double prune, MutableFst< kaldi::CompactLatticeArc > *ofst, DeterminizeLatticePhonePrunedOptions opts=DeterminizeLatticePhonePrunedOptions())
 This function is a wrapper of DeterminizeLatticePhonePruned() that works for Lattice type FSTs. More...
 

Detailed Description

Function Documentation

◆ DeterminizeLattice() [1/2]

bool DeterminizeLattice ( const Fst< ArcTpl< Weight > > &  ifst,
MutableFst< ArcTpl< Weight > > *  ofst,
DeterminizeLatticeOptions  opts = DeterminizeLatticeOptions(),
bool debug_ptr = NULL 
)

This function implements the normal version of DeterminizeLattice, in which the output strings are represented using sequences of arcs, where all but the first one has an epsilon on the input side.

The debug_ptr argument is an optional pointer to a bool that, if it becomes true while the algorithm is executing, the algorithm will print a traceback and terminate (used in fstdeterminizestar.cc debug non-terminating determinization). More efficient if ifst is arc-sorted on input label. If the number of arcs gets more than max_states, it will throw std::runtime_error (otherwise this code does not use exceptions). This is mainly useful for debug.

Definition at line 1264 of file determinize-lattice-inl.h.

References LatticeDeterminizer< Weight, IntType >::Determinize(), and LatticeDeterminizer< Weight, IntType >::Output().

Referenced by DeterminizeLatticeOptions::DeterminizeLatticeOptions(), kaldi::DeterminizeLatticeWrapper(), main(), and kaldi::RandDeterministicCompactLattice().

1267  {
1268  ofst->SetInputSymbols(ifst.InputSymbols());
1269  ofst->SetOutputSymbols(ifst.OutputSymbols());
1270  LatticeDeterminizer<Weight, IntType> det(ifst, opts);
1271  if (!det.Determinize(debug_ptr))
1272  return false;
1273  det.Output(ofst);
1274  return true;
1275 }

◆ DeterminizeLattice() [2/2]

bool DeterminizeLattice ( const Fst< ArcTpl< Weight > > &  ifst,
MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *  ofst,
DeterminizeLatticeOptions  opts,
bool debug_ptr 
)

Definition at line 1281 of file determinize-lattice-inl.h.

References LatticeDeterminizer< Weight, IntType >::Determinize(), and LatticeDeterminizer< Weight, IntType >::Output().

1284  {
1285  ofst->SetInputSymbols(ifst.InputSymbols());
1286  ofst->SetOutputSymbols(ifst.OutputSymbols());
1287  LatticeDeterminizer<Weight, IntType> det(ifst, opts);
1288  if (!det.Determinize(debug_ptr))
1289  return false;
1290  det.Output(ofst);
1291  return true;
1292 }

◆ DeterminizeLatticeDeletePhones()

void DeterminizeLatticeDeletePhones ( typename ArcTpl< Weight >::Label  first_phone_label,
MutableFst< ArcTpl< Weight > > *  fst 
)

This function takes in lattices and deletes "phones" from them.

The "phones" here are actually any label that is larger than first_phone_label because when we insert phones into the lattice, we map the original phone label to (first_phone_label + original_phone_label). It is supposed to be used together with DeterminizeLatticeInsertPhones()

Definition at line 1352 of file determinize-lattice-pruned.cc.

References LatticeDeterminizerPruned< Weight, IntType >::Element::state.

Referenced by fst::DeterminizeLatticePhonePrunedFirstPass(), and DeterminizeLatticePhonePrunedOptions::Register().

1354  {
1355  // Define some types.
1356  typedef ArcTpl<Weight> Arc;
1357  typedef typename Arc::StateId StateId;
1358  typedef typename Arc::Label Label;
1359 
1360  // Delete phones here.
1361  for (StateIterator<MutableFst<Arc> > siter(*fst);
1362  !siter.Done(); siter.Next()) {
1363  StateId state = siter.Value();
1364  for (MutableArcIterator<MutableFst<Arc> > aiter(fst, state);
1365  !aiter.Done(); aiter.Next()) {
1366  Arc arc = aiter.Value();
1367 
1368  if (arc.ilabel >= first_phone_label)
1369  arc.ilabel = 0;
1370 
1371  aiter.SetValue(arc);
1372  }
1373  }
1374 }
fst::StdArc::StateId StateId
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
Definition: graph.dox:21
fst::StdArc::Label Label

◆ DeterminizeLatticeInsertPhones()

ArcTpl< Weight >::Label DeterminizeLatticeInsertPhones ( const kaldi::TransitionModel trans_model,
MutableFst< ArcTpl< Weight > > *  fst 
)

This function takes in lattices and inserts phones at phone boundaries.

It uses the transition model to work out the transition_id to phone map. The returning value is the starting index of the phone label. Typically we pick (maximum_output_label_index + 1) as this value. The inserted phones are then mapped to (returning_value + original_phone_label) in the new lattice. The returning value will be used by DeterminizeLatticeDeletePhones() where it works out the phones according to this value.

Definition at line 1296 of file determinize-lattice-pruned.cc.

References fst::HighestNumberedInputSymbol(), TransitionModel::IsSelfLoop(), KALDI_ASSERT, LatticeDeterminizerPruned< Weight, IntType >::Element::state, TransitionModel::TransitionIdToHmmState(), and TransitionModel::TransitionIdToPhone().

Referenced by fst::DeterminizeLatticePhonePrunedFirstPass(), and DeterminizeLatticePhonePrunedOptions::Register().

1298  {
1299  // Define some types.
1300  typedef ArcTpl<Weight> Arc;
1301  typedef typename Arc::StateId StateId;
1302  typedef typename Arc::Label Label;
1303 
1304  // Work out the first phone symbol. This is more related to the phone
1305  // insertion function, so we put it here and make it the returning value of
1306  // DeterminizeLatticeInsertPhones().
1307  Label first_phone_label = HighestNumberedInputSymbol(*fst) + 1;
1308 
1309  // Insert phones here.
1310  for (StateIterator<MutableFst<Arc> > siter(*fst);
1311  !siter.Done(); siter.Next()) {
1312  StateId state = siter.Value();
1313  if (state == fst->Start())
1314  continue;
1315  for (MutableArcIterator<MutableFst<Arc> > aiter(fst, state);
1316  !aiter.Done(); aiter.Next()) {
1317  Arc arc = aiter.Value();
1318 
1319  // Note: the words are on the input symbol side and transition-id's are on
1320  // the output symbol side.
1321  if ((arc.olabel != 0)
1322  && (trans_model.TransitionIdToHmmState(arc.olabel) == 0)
1323  && (!trans_model.IsSelfLoop(arc.olabel))) {
1324  Label phone =
1325  static_cast<Label>(trans_model.TransitionIdToPhone(arc.olabel));
1326 
1327  // Skips <eps>.
1328  KALDI_ASSERT(phone != 0);
1329 
1330  if (arc.ilabel == 0) {
1331  // If there is no word on the arc, insert the phone directly.
1332  arc.ilabel = first_phone_label + phone;
1333  } else {
1334  // Otherwise, add an additional arc.
1335  StateId additional_state = fst->AddState();
1336  StateId next_state = arc.nextstate;
1337  arc.nextstate = additional_state;
1338  fst->AddArc(additional_state,
1339  Arc(first_phone_label + phone, 0,
1340  Weight::One(), next_state));
1341  }
1342  }
1343 
1344  aiter.SetValue(arc);
1345  }
1346  }
1347 
1348  return first_phone_label;
1349 }
fst::StdArc::StateId StateId
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
Definition: graph.dox:21
int32 TransitionIdToHmmState(int32 trans_id) const
bool IsSelfLoop(int32 trans_id) const
fst::StdArc::Label Label
Arc::Label HighestNumberedInputSymbol(const Fst< Arc > &fst)
Returns the highest numbered input symbol id of the FST (or zero for an empty FST.
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
int32 TransitionIdToPhone(int32 trans_id) const

◆ DeterminizeLatticePhonePruned() [1/2]

bool DeterminizeLatticePhonePruned ( const kaldi::TransitionModel trans_model,
MutableFst< ArcTpl< Weight > > *  ifst,
double  beam,
MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *  ofst,
DeterminizeLatticePhonePrunedOptions  opts 
)

"Destructive" version of DeterminizeLatticePhonePruned() where the input lattice might be changed.

Definition at line 1416 of file determinize-lattice-pruned.cc.

References DeterminizeLatticePrunedOptions::delta, DeterminizeLatticePhonePrunedOptions::delta, KALDI_VLOG, KALDI_WARN, DeterminizeLatticePrunedOptions::max_mem, DeterminizeLatticePhonePrunedOptions::max_mem, DeterminizeLatticePhonePrunedOptions::minimize, DeterminizeLatticePhonePrunedOptions::phone_determinize, and DeterminizeLatticePhonePrunedOptions::word_determinize.

Referenced by fst::DeterminizeLatticePhonePruned(), and DeterminizeLatticePhonePrunedOptions::Register().

1421  {
1422  // Returning status.
1423  bool ans = true;
1424 
1425  // Make sure at least one of opts.phone_determinize and opts.word_determinize
1426  // is not false, otherwise calling this function doesn't make any sense.
1427  if ((opts.phone_determinize || opts.word_determinize) == false) {
1428  KALDI_WARN << "Both --phone-determinize and --word-determinize are set to "
1429  << "false, copying lattice without determinization.";
1430  // We are expecting the words on the input side.
1431  ConvertLattice<Weight, IntType>(*ifst, ofst, false);
1432  return ans;
1433  }
1434 
1435  // Determinization options.
1436  DeterminizeLatticePrunedOptions det_opts;
1437  det_opts.delta = opts.delta;
1438  det_opts.max_mem = opts.max_mem;
1439 
1440  // If --phone-determinize is true, do the determinization on phone + word
1441  // lattices.
1442  if (opts.phone_determinize) {
1443  KALDI_VLOG(3) << "Doing first pass of determinization on phone + word "
1444  << "lattices.";
1445  ans = DeterminizeLatticePhonePrunedFirstPass<Weight, IntType>(
1446  trans_model, beam, ifst, det_opts) && ans;
1447 
1448  // If --word-determinize is false, we've finished the job and return here.
1449  if (!opts.word_determinize) {
1450  // We are expecting the words on the input side.
1451  ConvertLattice<Weight, IntType>(*ifst, ofst, false);
1452  return ans;
1453  }
1454  }
1455 
1456  // If --word-determinize is true, do the determinization on word lattices.
1457  if (opts.word_determinize) {
1458  KALDI_VLOG(3) << "Doing second pass of determinization on word lattices.";
1459  ans = DeterminizeLatticePruned<Weight, IntType>(
1460  *ifst, beam, ofst, det_opts) && ans;
1461  }
1462 
1463  // If --minimize is true, push and minimize after determinization.
1464  if (opts.minimize) {
1465  KALDI_VLOG(3) << "Pushing and minimizing on word lattices.";
1466  ans = PushCompactLatticeStrings<Weight, IntType>(ofst) && ans;
1467  ans = PushCompactLatticeWeights<Weight, IntType>(ofst) && ans;
1468  ans = MinimizeCompactLattice<Weight, IntType>(ofst) && ans;
1469  }
1470 
1471  return ans;
1472 }
#define KALDI_WARN
Definition: kaldi-error.h:150
#define KALDI_VLOG(v)
Definition: kaldi-error.h:156

◆ DeterminizeLatticePhonePruned() [2/2]

bool DeterminizeLatticePhonePruned ( const kaldi::TransitionModel trans_model,
const ExpandedFst< ArcTpl< Weight > > &  ifst,
double  prune,
MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *  ofst,
DeterminizeLatticePhonePrunedOptions  opts = DeterminizeLatticePhonePrunedOptions() 
)

This function is a wrapper of DeterminizeLatticePhonePrunedFirstPass() and DeterminizeLatticePruned().

If –phone-determinize is set to true, it first calls DeterminizeLatticePhonePrunedFirstPass() to do the initial pass of determinization on the phone + word lattices. If –word-determinize is set true, it then does a second pass of determinization on the word lattices by calling DeterminizeLatticePruned(). If both are set to false, then it gives a warning and copying the lattices without determinization.

Note: the point of doing first a phone-level determinization pass and then a word-level determinization pass is that it allows us to determinize deeper lattices without "failing early" and returning a too-small lattice due to the max-mem constraint. The result should be the same as word-level determinization in general, but for deeper lattices it is a bit faster, despite the fact that we now have two passes of determinization by default.

Definition at line 1477 of file determinize-lattice-pruned.cc.

References fst::DeterminizeLatticePhonePruned().

1482  {
1483  VectorFst<ArcTpl<Weight> > temp_fst(ifst);
1484  return DeterminizeLatticePhonePruned(trans_model, &temp_fst,
1485  beam, ofst, opts);
1486 }
bool DeterminizeLatticePhonePruned(const kaldi::TransitionModel &trans_model, const ExpandedFst< ArcTpl< Weight > > &ifst, double beam, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePhonePrunedOptions opts)
This function is a wrapper of DeterminizeLatticePhonePrunedFirstPass() and DeterminizeLatticePruned()...

◆ DeterminizeLatticePhonePrunedWrapper()

bool DeterminizeLatticePhonePrunedWrapper ( const kaldi::TransitionModel trans_model,
MutableFst< kaldi::LatticeArc > *  ifst,
double  prune,
MutableFst< kaldi::CompactLatticeArc > *  ofst,
DeterminizeLatticePhonePrunedOptions  opts = DeterminizeLatticePhonePrunedOptions() 
)

This function is a wrapper of DeterminizeLatticePhonePruned() that works for Lattice type FSTs.

It simplifies the calling process by calling TopSort() Invert() and ArcSort() for you. Unlike other determinization routines, the function requires "ifst" to have transition-id's on the input side and words on the output side. This function can be used as the top-level interface to all the determinization code.

Definition at line 1488 of file determinize-lattice-pruned.cc.

References KALDI_ERR.

Referenced by LatticeIncrementalDeterminizer::AcceptRawLatticeChunk(), kaldi::DecodeUtterance(), kaldi::DecodeUtteranceLatticeFaster(), kaldi::DecodeUtteranceLatticeSimple(), SingleUtteranceNnet3DecoderTpl< FST >::GetLattice(), SingleUtteranceNnet2Decoder::GetLattice(), SingleUtteranceGmmDecoder::GetLattice(), SingleUtteranceNnet2DecoderThreaded::GetLattice(), main(), DeterminizeLatticeTask::operator()(), DecodeUtteranceLatticeFasterClass::operator()(), NnetBatchDecoder::ProcessOutputUtterance(), and DeterminizeLatticePhonePrunedOptions::Register().

1493  {
1494  bool ans = true;
1495  Invert(ifst);
1496  if (ifst->Properties(fst::kTopSorted, true) == 0) {
1497  if (!TopSort(ifst)) {
1498  // Cannot topologically sort the lattice -- determinization will fail.
1499  KALDI_ERR << "Topological sorting of state-level lattice failed (probably"
1500  << " your lexicon has empty words or your LM has epsilon cycles"
1501  << ").";
1502  }
1503  }
1504  ILabelCompare<kaldi::LatticeArc> ilabel_comp;
1505  ArcSort(ifst, ilabel_comp);
1506  ans = DeterminizeLatticePhonePruned<kaldi::LatticeWeight, kaldi::int32>(
1507  trans_model, ifst, beam, ofst, opts);
1508  Connect(ofst);
1509  return ans;
1510 }
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ DeterminizeLatticePruned() [1/2]

bool DeterminizeLatticePruned ( const ExpandedFst< ArcTpl< Weight > > &  ifst,
double  beam,
MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *  ofst,
DeterminizeLatticePrunedOptions  opts 
)

Definition at line 1196 of file determinize-lattice-pruned.cc.

References LatticeDeterminizerPruned< Weight, IntType >::Determinize(), KALDI_ASSERT, KALDI_LOG, LatticeDeterminizerPruned< Weight, IntType >::Output(), kaldi::PruneLattice(), and DeterminizeLatticePrunedOptions::retry_cutoff.

Referenced by SingleUtteranceGmmDecoder::GetGaussianPosteriors(), LatticeSimpleDecoder::GetLattice(), LatticeBiglmFasterDecoder::GetLattice(), LatticeFasterDecoderTpl< fst::StdFst, decoder::BackpointerToken >::GetLattice(), main(), DeterminizeLatticeTask::operator()(), DeterminizeLatticePhonePrunedOptions::Register(), and kaldi::SentenceLevelConfidence().

1200  {
1201  ofst->SetInputSymbols(ifst.InputSymbols());
1202  ofst->SetOutputSymbols(ifst.OutputSymbols());
1203  if (ifst.NumStates() == 0) {
1204  ofst->DeleteStates();
1205  return true;
1206  }
1207  KALDI_ASSERT(opts.retry_cutoff >= 0.0 && opts.retry_cutoff < 1.0);
1208  int32 max_num_iters = 10; // avoid the potential for infinite loops if
1209  // retrying.
1210  VectorFst<ArcTpl<Weight> > temp_fst;
1211 
1212  for (int32 iter = 0; iter < max_num_iters; iter++) {
1213  LatticeDeterminizerPruned<Weight, IntType> det(iter == 0 ? ifst : temp_fst,
1214  beam, opts);
1215  double effective_beam;
1216  bool ans = det.Determinize(&effective_beam);
1217  // if it returns false it will typically still produce reasonable output,
1218  // just with a narrower beam than "beam". If the user specifies an infinite
1219  // beam we don't do this beam-narrowing.
1220  if (effective_beam >= beam * opts.retry_cutoff ||
1221  beam == std::numeric_limits<double>::infinity() ||
1222  iter + 1 == max_num_iters) {
1223  det.Output(ofst);
1224  return ans;
1225  } else {
1226  // The code below to set "beam" is a heuristic.
1227  // If effective_beam is very small, we want to reduce by a lot.
1228  // But never change the beam by more than a factor of two.
1229  if (effective_beam < 0.0) effective_beam = 0.0;
1230  double new_beam = beam * sqrt(effective_beam / beam);
1231  if (new_beam < 0.5 * beam) new_beam = 0.5 * beam;
1232  beam = new_beam;
1233  if (iter == 0) temp_fst = ifst;
1234  kaldi::PruneLattice(beam, &temp_fst);
1235  KALDI_LOG << "Pruned state-level lattice with beam " << beam
1236  << " and retrying determinization with that beam.";
1237  }
1238  }
1239  return false; // Suppress compiler warning; this code is unreachable.
1240 }
kaldi::int32 int32
bool PruneLattice(BaseFloat beam, LatType *lat)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
#define KALDI_LOG
Definition: kaldi-error.h:153

◆ DeterminizeLatticePruned() [2/2]

bool DeterminizeLatticePruned ( const ExpandedFst< ArcTpl< Weight > > &  ifst,
double  prune,
MutableFst< ArcTpl< Weight > > *  ofst,
DeterminizeLatticePrunedOptions  opts = DeterminizeLatticePrunedOptions() 
)

This function implements the normal version of DeterminizeLattice, in which the output strings are represented using sequences of arcs, where all but the first one has an epsilon on the input side.

It also prunes using the beam in the "prune" parameter. The input FST must be topologically sorted in order for the algorithm to work. For efficiency it is recommended to sort ilabel as well. Returns true on success, and false if it had to terminate the determinization earlier than specified by the "prune" beam– that is, if it terminated because of the max_mem, max_loop or max_arcs constraints in the options. CAUTION: you may want to use the version below which outputs to CompactLattice.

Definition at line 1248 of file determinize-lattice-pruned.cc.

References LatticeDeterminizerPruned< Weight, IntType >::Determinize(), KALDI_ASSERT, KALDI_WARN, LatticeDeterminizerPruned< Weight, IntType >::Output(), kaldi::PruneLattice(), and DeterminizeLatticePrunedOptions::retry_cutoff.

1251  {
1252  typedef int32 IntType;
1253  ofst->SetInputSymbols(ifst.InputSymbols());
1254  ofst->SetOutputSymbols(ifst.OutputSymbols());
1255  KALDI_ASSERT(opts.retry_cutoff >= 0.0 && opts.retry_cutoff < 1.0);
1256  if (ifst.NumStates() == 0) {
1257  ofst->DeleteStates();
1258  return true;
1259  }
1260  int32 max_num_iters = 10; // avoid the potential for infinite loops if
1261  // retrying.
1262  VectorFst<ArcTpl<Weight> > temp_fst;
1263 
1264  for (int32 iter = 0; iter < max_num_iters; iter++) {
1265  LatticeDeterminizerPruned<Weight, IntType> det(iter == 0 ? ifst : temp_fst,
1266  beam, opts);
1267  double effective_beam;
1268  bool ans = det.Determinize(&effective_beam);
1269  // if it returns false it will typically still
1270  // produce reasonable output, just with a
1271  // narrower beam than "beam".
1272  if (effective_beam >= beam * opts.retry_cutoff ||
1273  iter + 1 == max_num_iters) {
1274  det.Output(ofst);
1275  return ans;
1276  } else {
1277  // The code below to set "beam" is a heuristic.
1278  // If effective_beam is very small, we want to reduce by a lot.
1279  // But never change the beam by more than a factor of two.
1280  if (effective_beam < 0)
1281  effective_beam = 0;
1282  double new_beam = beam * sqrt(effective_beam / beam);
1283  if (new_beam < 0.5 * beam) new_beam = 0.5 * beam;
1284  KALDI_WARN << "Effective beam " << effective_beam << " was less than beam "
1285  << beam << " * cutoff " << opts.retry_cutoff << ", pruning raw "
1286  << "lattice with new beam " << new_beam << " and retrying.";
1287  beam = new_beam;
1288  if (iter == 0) temp_fst = ifst;
1289  kaldi::PruneLattice(beam, &temp_fst);
1290  }
1291  }
1292  return false; // Suppress compiler warning; this code is unreachable.
1293 }
kaldi::int32 int32
#define KALDI_WARN
Definition: kaldi-error.h:150
bool PruneLattice(BaseFloat beam, LatType *lat)
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ DeterminizeStar() [1/2]

bool DeterminizeStar ( F &  ifst,
MutableFst< typename F::Arc > *  ofst,
float  delta = kDelta,
bool debug_ptr = NULL,
int  max_states = -1,
bool  allow_partial = false 
)

This function implements the normal version of DeterminizeStar, in which the output strings are represented using sequences of arcs, where all but the first one has an epsilon on the input side.

The debug_ptr argument is an optional pointer to a bool that, if it becomes true while the algorithm is executing, the algorithm will print a traceback and terminate (used in fstdeterminizestar.cc debug non-terminating determinization). If max_states is positive, it will stop determinization and throw an exception as soon as the max-states is reached. This can be useful in test. If allow_partial is true, the algorithm will output partial results when the specified max_states is reached (when larger than zero), instead of throwing out an error.

Caution, the return status is un-intuitive: this function will return false if determinization completed normally, and true if it was stopped early by reaching the 'max-states' limit, and a partial FST was generated.

Definition at line 625 of file determinize-star-inl.h.

References DeterminizerStar< F >::Determinize(), DeterminizerStar< F >::IsPartial(), and DeterminizerStar< F >::Output().

Referenced by fst::DeterminizeStarInLog(), kaldi::DoFactorMerging(), main(), kaldi::OptimizeFactorTransducer(), fst::SafeDeterminizeMinimizeWrapper(), fst::SafeDeterminizeWrapper(), fst::TestDeterminize(), fst::TestFactor(), and fst::TestMinimize().

627  {
628  ofst->SetOutputSymbols(ifst.OutputSymbols());
629  ofst->SetInputSymbols(ifst.InputSymbols());
630  DeterminizerStar<F> det(ifst, delta, max_states, allow_partial);
631  det.Determinize(debug_ptr);
632  det.Output(ofst);
633  return det.IsPartial();
634 }

◆ DeterminizeStar() [2/2]

bool DeterminizeStar ( F &  ifst,
MutableFst< GallicArc< typename F::Arc > > *  ofst,
float  delta,
bool debug_ptr,
int  max_states,
bool  allow_partial 
)

Definition at line 638 of file determinize-star-inl.h.

References DeterminizerStar< F >::Determinize(), DeterminizerStar< F >::EpsilonClosure::GetEpsilonClosure(), DeterminizerStar< F >::IsPartial(), and DeterminizerStar< F >::Output().

641  {
642  ofst->SetOutputSymbols(ifst.InputSymbols());
643  ofst->SetInputSymbols(ifst.InputSymbols());
644  DeterminizerStar<F> det(ifst, delta, max_states, allow_partial);
645  det.Determinize(debug_ptr);
646  det.Output(ofst);
647  return det.IsPartial();
648 }