55 typedef ArcTpl<Weight>
Arc;
60 void Output(MutableFst<CompactArc> *ofst,
bool destroy =
true) {
67 ofst->SetStart(kNoStateId);
71 for (StateId s = 0;s < nStates;s++) {
77 for (StateId this_state_id = 0; this_state_id < nStates; this_state_id++) {
79 vector<TempArc> &this_vec(this_state.
arcs);
80 typename vector<TempArc>::const_iterator iter = this_vec.begin(), end = this_vec.end();
82 for (;iter != end; ++iter) {
85 vector<Label> olabel_seq;
87 CompactWeight weight(temp_arc.
weight, olabel_seq);
89 ofst->SetFinal(this_state_id, weight);
92 new_arc.ilabel = temp_arc.
ilabel;
93 new_arc.olabel = temp_arc.
ilabel;
94 new_arc.weight = weight;
95 ofst->AddArc(this_state_id, new_arc);
100 if (destroy) { vector<TempArc> temp; temp.swap(this_vec); }
111 void Output(MutableFst<Arc> *ofst,
bool destroy =
true) {
114 ofst->DeleteStates();
116 ofst->SetStart(kNoStateId);
127 for (
OutputStateId this_state_id = 0; this_state_id < nStates; this_state_id++) {
129 vector<TempArc> &this_vec(this_state.
arcs);
131 typename vector<TempArc>::const_iterator iter = this_vec.begin(), end = this_vec.end();
132 for (; iter != end; ++iter) {
133 const TempArc &temp_arc(*iter);
141 for (
size_t i = 0;
i < seq.size();
i++) {
144 arc.nextstate = next_state;
145 arc.weight = (
i == 0 ? temp_arc.
weight : Weight::One());
148 ofst->AddArc(cur_state, arc);
149 cur_state = next_state;
151 ofst->SetFinal(cur_state, (seq.size() == 0 ? temp_arc.
weight : Weight::One()));
156 for (
size_t i = 0;
i+1 < seq.size();
i++) {
160 arc.nextstate = next_state;
161 arc.weight = (
i == 0 ? temp_arc.
weight : Weight::One());
162 arc.ilabel = (
i == 0 ? temp_arc.
ilabel : 0);
164 ofst->AddArc(cur_state, arc);
165 cur_state = next_state;
170 arc.weight = (seq.size() <= 1 ? temp_arc.
weight : Weight::One());
171 arc.ilabel = (seq.size() <= 1 ? temp_arc.
ilabel : 0);
172 arc.olabel = (seq.size() > 0 ? seq.back() : 0);
173 ofst->AddArc(cur_state, arc);
177 if (destroy) { vector<TempArc> temp; temp.swap(this_vec); }
204 vector<OutputState*> temp;
218 vector<Element> empty_subset;
222 for (
typename InitialSubsetHash::iterator iter =
initial_hash_.begin();
254 std::vector<StringId> needed_strings;
263 std::vector<Task*> tasks;
267 tasks.push_back(task);
270 for (
size_t i = 0;
i < tasks.size();
i++)
275 for (
typename InitialSubsetHash::const_iterator
278 const vector<Element> &vec = *(iter->first);
281 needed_strings.push_back(elem.
string);
283 std::sort(needed_strings.begin(), needed_strings.end());
284 needed_strings.erase(std::unique(needed_strings.begin(),
285 needed_strings.end()),
286 needed_strings.end());
296 total_size = repo_size + arcs_size + elems_size;
302 new_total_size = new_repo_size + arcs_size + elems_size;
304 KALDI_VLOG(2) <<
"Rebuilt repository in determinize-lattice: repository shrank from " 305 << repo_size <<
" to " << new_repo_size <<
" bytes (approximately)";
307 if (new_total_size > static_cast<int32>(
opts_.
max_mem * 0.8)) {
313 double effective_beam =
beam_;
320 KALDI_WARN <<
"Did not reach requested beam in determinize-lattice: " 322 <<
" bytes; (repo,arcs,elems) = (" << repo_size <<
"," 323 << arcs_size <<
"," << elems_size
324 <<
"), after rebuilding, repo size was " << new_repo_size
325 <<
", effective beam was " << effective_beam
326 <<
" vs. requested beam " <<
beam_;
356 KALDI_VLOG(1) <<
"Lattice determinization terminated but not " 357 <<
" because of lattice-beam. (#states, #arcs) is ( " 372 if (effective_beam != NULL) {
375 *effective_beam =
queue_.top()->priority_cost -
391 typedef const typename StringRepositoryType::Entry*
StringId;
400 return (state != other.
state ||
string != other.
string ||
406 return state > other.
state;
410 return state < other.
state;
438 size_t operator ()(
const vector<Element> * subset)
const {
439 size_t hash = 0, factor = 1;
440 for (
typename vector<Element>::const_iterator iter= subset->begin(); iter != subset->end(); ++iter) {
442 hash += iter->state +
reinterpret_cast<size_t>(iter->string);
453 bool operator ()(
const vector<Element> * s1,
const vector<Element> * s2)
const {
454 size_t sz = s1->size();
456 if (sz != s2->size())
return false;
457 typename vector<Element>::const_iterator iter1 = s1->begin(),
458 iter1_end = s1->end(), iter2=s2->begin();
459 for (; iter1 < iter1_end; ++iter1, ++iter2) {
460 if (iter1->state != iter2->state ||
461 iter1->string != iter2->string ||
462 !
ApproxEqual(iter1->weight, iter2->weight, delta_))
return false;
475 bool operator ()(
const vector<Element> * s1,
const vector<Element> * s2)
const {
476 size_t sz = s1->size();
478 if (sz != s2->size())
return false;
479 typename vector<Element>::const_iterator iter1 = s1->begin(),
480 iter1_end = s1->end(), iter2=s2->begin();
481 for (; iter1 < iter1_end; ++iter1, ++iter2) {
482 if (iter1->state != iter2->state)
return false;
498 typedef unordered_map<const vector<Element>*,
Element,
507 typename vector<Element>::iterator cur_in = subset->begin(),
508 cur_out = subset->begin(), end = subset->end();
509 while (cur_in != end) {
516 subset->resize(cur_out - subset->begin());
525 const double forward_cost) {
526 typename MinimalSubsetHash::const_iterator iter
529 OutputStateId state_id = iter->second;
534 KALDI_WARN <<
"New cost is less (check the difference is small) " 535 << forward_cost <<
", " 540 OutputStateId state_id =
static_cast<OutputStateId
>(
output_states_.size());
559 StringId *common_prefix) {
560 typename InitialSubsetHash::const_iterator iter
563 const Element &elem = iter->second;
564 *remaining_weight = elem.
weight;
565 *common_prefix = elem.
string;
566 if (elem.
weight == Weight::Zero())
571 vector<Element> subset(subset_in);
587 *remaining_weight = elem.
weight;
588 *common_prefix = elem.
string;
589 if (elem.
weight == Weight::Zero())
595 vector<Element> *initial_subset_ptr =
new vector<Element>(subset_in);
610 const Weight &b_w, StringId b_str)
const {
612 if (weight_comp != 0)
return weight_comp;
614 if (a_str == b_str)
return 0;
615 vector<IntType> a_vec, b_vec;
619 int a_len = a_vec.size(), b_len = b_vec.size();
622 if (a_len > b_len)
return -1;
623 else if (a_len < b_len)
return 1;
624 for(
int i = 0;
i < a_len;
i++) {
625 if (a_vec[
i] < b_vec[
i])
return -1;
626 else if (a_vec[i] > b_vec[i])
return 1;
642 std::priority_queue<Element, vector<Element>, greater<Element> > queue;
643 unordered_map<InputStateId, Element> cur_subset;
644 typedef typename unordered_map<InputStateId, Element>::iterator MapIter;
645 typedef typename vector<Element>::const_iterator VecIter;
647 for (VecIter iter = subset->begin(); iter != subset->end(); ++iter) {
649 cur_subset[iter->state] = *iter;
653 bool sorted = ((
ifst_->Properties(kILabelSorted,
false) & kILabelSorted) != 0);
654 bool replaced_elems =
false;
657 while (queue.size() != 0) {
658 Element elem = queue.top();
668 if (replaced_elems && cur_subset[elem.
state] != elem)
671 KALDI_ERR <<
"Lattice determinization aborted since looped more than " 674 for (ArcIterator<ExpandedFst<Arc> > aiter(*
ifst_, elem.
state); !aiter.Done(); aiter.Next()) {
675 const Arc &arc = aiter.Value();
676 if (sorted && arc.ilabel != 0)
break;
679 && arc.weight != Weight::Zero()) {
681 next_elem.
state = arc.nextstate;
686 MapIter iter = cur_subset.find(next_elem.
state);
687 if (iter == cur_subset.end()) {
691 cur_subset[next_elem.
state] = next_elem;
692 queue.push(next_elem);
704 iter->second.weight, iter->second.string);
709 iter->second.string = next_elem.
string;
710 iter->second.weight = next_elem.
weight;
711 queue.push(next_elem);
712 replaced_elems =
true;
722 subset->reserve(cur_subset.size());
723 MapIter iter = cur_subset.begin(), end = cur_subset.end();
724 for (; iter != end; ++iter) subset->push_back(iter->second);
726 std::sort(subset->begin(), subset->end());
744 Weight final_weight = Weight::Zero();
745 bool is_final =
false;
746 typename vector<Element>::const_iterator iter = minimal_subset.begin(), end = minimal_subset.end();
747 for (; iter != end; ++iter) {
748 const Element &elem = *iter;
750 StringId this_final_string = elem.
string;
751 if (this_final_weight != Weight::Zero() &&
752 (!is_final ||
Compare(this_final_weight, this_final_string,
753 final_weight, final_string) == 1)) {
757 final_weight = this_final_weight;
758 final_string = this_final_string;
769 temp_arc.
string = final_string;
770 temp_arc.
weight = final_weight;
771 state.
arcs.push_back(temp_arc);
781 StringId *common_str) {
786 *tot_weight = Weight::Zero();
789 size_t size = elems->size();
790 vector<IntType> common_prefix;
791 repository_.ConvertToVector((*elems)[0].
string, &common_prefix);
793 for(
size_t i = 1;
i < size;
i++) {
794 weight =
Plus(weight, (*elems)[
i].weight);
795 repository_.ReduceToCommonPrefix((*elems)[
i].
string, &common_prefix);
799 size_t prefix_len = common_prefix.size();
800 for(
size_t i = 0;
i < size;
i++) {
801 (*elems)[
i].weight =
Divide((*elems)[
i].weight, weight, DIVIDE_LEFT);
803 repository_.RemovePrefix((*elems)[
i].
string, prefix_len);
805 *common_str =
repository_.ConvertFromVector(common_prefix);
813 typedef typename vector<Element>::iterator IterType;
817 KALDI_ASSERT(subset->size() < 2 || (*subset)[0].state <= (*subset)[1].state);
819 IterType cur_in = subset->begin(), cur_out = cur_in, end = subset->end();
822 while (cur_in != end) {
825 if (cur_in != cur_out) *cur_out = *cur_in;
827 while (cur_in != end && cur_in->state == cur_out->state) {
828 if (
Compare(cur_in->weight, cur_in->string,
829 cur_out->weight, cur_out->string) == 1) {
831 cur_out->string = cur_in->string;
832 cur_out->weight = cur_in->weight;
839 subset->resize(num_out);
857 OutputStateId nextstate;
860 StringId next_common_str;
865 common_str =
repository_.Concatenate(common_str, next_common_str);
866 tot_weight =
Times(tot_weight, next_tot_weight);
874 temp_arc.
string = common_str;
875 temp_arc.
weight = tot_weight;
887 inline bool operator () (
const pair<Label, Element> &p1,
const pair<Label, Element> &p2) {
888 if (p1.first < p2.first)
return true;
889 else if (p1.first > p2.first)
return false;
891 return p1.second.state < p2.second.state;
906 const vector<Element> &minimal_subset =
output_states_[output_state_id]->minimal_subset;
914 typename vector<Element>::const_iterator iter = minimal_subset.begin(), end = minimal_subset.end();
915 for (;iter != end; ++iter) {
916 const Element &elem = *iter;
917 for (ArcIterator<ExpandedFst<Arc> > aiter(*
ifst_, elem.
state); ! aiter.Done(); aiter.Next()) {
918 const Arc &arc = aiter.Value();
920 && arc.weight != Weight::Zero()) {
921 pair<Label, Element> this_pr;
922 this_pr.first = arc.ilabel;
923 Element &next_elem(this_pr.second);
924 next_elem.
state = arc.nextstate;
930 all_elems.push_back(this_pr);
936 std::sort(all_elems.begin(), all_elems.end(), pc);
938 typedef typename vector<pair<Label, Element> >::const_iterator PairIter;
939 PairIter cur = all_elems.begin(), end = all_elems.end();
945 Label ilabel = cur->first;
946 task->
state = output_state_id;
947 task->
priority_cost = std::numeric_limits<double>::infinity();
948 task->
label = ilabel;
949 while (cur != end && cur->first == ilabel) {
950 task->
subset.push_back(cur->second);
951 const Element &element = cur->second;
977 tolerance = 0.01 + 1.0e-04 * std::abs(best_cost);
979 KALDI_WARN <<
"Cost below best cost was encountered:" 1002 if (
ifst_->Final(state) != Weight::Zero())
1004 for (ArcIterator<ExpandedFst<Arc> > aiter(*
ifst_, state);
1007 const Arc &arc = aiter.Value();
1008 if (arc.ilabel != 0 && arc.weight != Weight::Zero()) {
1022 for (StateId s =
ifst_->NumStates() - 1; s >= 0; s--) {
1025 for (ArcIterator<ExpandedFst<Arc> > aiter(*
ifst_, s);
1026 !aiter.Done(); aiter.Next()) {
1027 const Arc &arc = aiter.Value();
1028 cost = std::min(cost,
1033 if (
ifst_->Start() == kNoStateId)
return;
1037 if (best_cost == std::numeric_limits<double>::infinity())
1038 KALDI_WARN <<
"Total weight of input lattice is zero.";
1050 #if !(__GNUC__ == 4 && __GNUC_MINOR__ == 0) 1051 if(
ifst_->Properties(kExpanded,
false) != 0) {
1054 StateId num_states =
1055 down_cast<
const ExpandedFst<Arc>*,
const Fst<Arc> >(
ifst_)->NumStates();
1060 InputStateId start_id =
ifst_->Start();
1061 if (start_id != kNoStateId) {
1073 vector<Element> subset(1);
1074 subset[0].state = start_id;
1075 subset[0].weight = Weight::One();
1087 OutputStateId initial_state_id = 0;
1109 double forward_cost): minimal_subset(minimal_subset),
1110 forward_cost(forward_cost) { }
1157 inline int operator() (
const Task *t1,
const Task *t2) {
1183 vector<StringId> *needed_strings) {
1184 for (
typename std::vector<Element>::const_iterator iter = vec.begin();
1185 iter != vec.end(); ++iter)
1186 needed_strings->push_back(iter->string);
1195 template<
class Weight,
class IntType>
1197 const ExpandedFst<ArcTpl<Weight> >&ifst,
1201 ofst->SetInputSymbols(ifst.InputSymbols());
1202 ofst->SetOutputSymbols(ifst.OutputSymbols());
1203 if (ifst.NumStates() == 0) {
1204 ofst->DeleteStates();
1208 int32 max_num_iters = 10;
1210 VectorFst<ArcTpl<Weight> > temp_fst;
1212 for (
int32 iter = 0; iter < max_num_iters; iter++) {
1215 double effective_beam;
1221 beam == std::numeric_limits<double>::infinity() ||
1222 iter + 1 == max_num_iters) {
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;
1233 if (iter == 0) temp_fst = ifst;
1235 KALDI_LOG <<
"Pruned state-level lattice with beam " << beam
1236 <<
" and retrying determinization with that beam.";
1247 template<
class Weight>
1250 MutableFst<ArcTpl<Weight> > *ofst,
1252 typedef int32 IntType;
1253 ofst->SetInputSymbols(ifst.InputSymbols());
1254 ofst->SetOutputSymbols(ifst.OutputSymbols());
1256 if (ifst.NumStates() == 0) {
1257 ofst->DeleteStates();
1260 int32 max_num_iters = 10;
1262 VectorFst<ArcTpl<Weight> > temp_fst;
1264 for (
int32 iter = 0; iter < max_num_iters; iter++) {
1267 double effective_beam;
1273 iter + 1 == max_num_iters) {
1280 if (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.";
1288 if (iter == 0) temp_fst = ifst;
1295 template<
class Weight>
1298 MutableFst<ArcTpl<Weight> > *
fst) {
1300 typedef ArcTpl<Weight>
Arc;
1310 for (StateIterator<MutableFst<Arc> > siter(*
fst);
1311 !siter.Done(); siter.Next()) {
1312 StateId
state = siter.Value();
1313 if (state ==
fst->Start())
1315 for (MutableArcIterator<MutableFst<Arc> > aiter(
fst, state);
1316 !aiter.Done(); aiter.Next()) {
1317 Arc arc = aiter.Value();
1321 if ((arc.olabel != 0)
1330 if (arc.ilabel == 0) {
1332 arc.ilabel = first_phone_label + phone;
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));
1344 aiter.SetValue(arc);
1348 return first_phone_label;
1351 template<
class Weight>
1354 MutableFst<ArcTpl<Weight> > *
fst) {
1356 typedef ArcTpl<Weight>
Arc;
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();
1368 if (arc.ilabel >= first_phone_label)
1371 aiter.SetValue(arc);
1379 MutableFst<ArcTpl<kaldi::LatticeWeight> > *
fst);
1392 template<
class Weight,
class IntType>
1396 MutableFst<ArcTpl<Weight> > *
fst,
1404 bool ans = DeterminizeLatticePruned<Weight>(*
fst, beam, fst, opts);
1415 template<
class Weight,
class IntType>
1418 MutableFst<ArcTpl<Weight> > *ifst,
1428 KALDI_WARN <<
"Both --phone-determinize and --word-determinize are set to " 1429 <<
"false, copying lattice without determinization.";
1431 ConvertLattice<Weight, IntType>(*ifst, ofst,
false);
1443 KALDI_VLOG(3) <<
"Doing first pass of determinization on phone + word " 1445 ans = DeterminizeLatticePhonePrunedFirstPass<Weight, IntType>(
1446 trans_model, beam, ifst, det_opts) && ans;
1451 ConvertLattice<Weight, IntType>(*ifst, ofst,
false);
1458 KALDI_VLOG(3) <<
"Doing second pass of determinization on word lattices.";
1459 ans = DeterminizeLatticePruned<Weight, IntType>(
1460 *ifst, beam, ofst, det_opts) && ans;
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;
1476 template<
class Weight,
class IntType>
1479 const ExpandedFst<ArcTpl<Weight> > &ifst,
1483 VectorFst<ArcTpl<Weight> > temp_fst(ifst);
1490 MutableFst<kaldi::LatticeArc> *ifst,
1492 MutableFst<kaldi::CompactLatticeArc> *ofst,
1496 if (ifst->Properties(fst::kTopSorted,
true) == 0) {
1497 if (!TopSort(ifst)) {
1499 KALDI_ERR <<
"Topological sorting of state-level lattice failed (probably" 1500 <<
" your lexicon has empty words or your LM has epsilon cycles" 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);
1516 bool DeterminizeLatticePruned<kaldi::LatticeWeight>(
1517 const ExpandedFst<kaldi::LatticeArc> &ifst,
1519 MutableFst<kaldi::CompactLatticeArc> *ofst,
1523 bool DeterminizeLatticePruned<kaldi::LatticeWeight>(
1524 const ExpandedFst<kaldi::LatticeArc> &ifst,
1526 MutableFst<kaldi::LatticeArc> *ofst,
1530 bool DeterminizeLatticePhonePruned<kaldi::LatticeWeight, kaldi::int32>(
1532 const ExpandedFst<kaldi::LatticeArc> &ifst,
1534 MutableFst<kaldi::CompactLatticeArc> *ofst,
1538 bool DeterminizeLatticePhonePruned<kaldi::LatticeWeight, kaldi::int32>(
1540 MutableFst<kaldi::LatticeArc> *ifst,
1542 MutableFst<kaldi::CompactLatticeArc> *ofst,
fst::StdArc::StateId StateId
void ProcessTransitions(OutputStateId output_state_id)
DeterminizeLatticePrunedOptions opts_
vector< Element > minimal_subset
LatticeWeightTpl< FloatType > Divide(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2, DivideType typ=DIVIDE_ANY)
OutputStateId MinimalToStateId(const vector< Element > &subset, const double forward_cost)
const ExpandedFst< Arc > * ifst_
vector< OutputState * > output_states_
void Output(MutableFst< CompactArc > *ofst, bool destroy=true)
bool operator>(const Element &other) const
vector< char > isymbol_or_final_
~LatticeDeterminizerPruned()
bool DeterminizeLatticePruned(const ExpandedFst< ArcTpl< Weight > > &ifst, double beam, MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *ofst, DeterminizeLatticePrunedOptions opts)
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
LatticeWeightTpl< FloatType > Plus(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
LatticeDeterminizerPruned(const ExpandedFst< Arc > &ifst, double beam, DeterminizeLatticePrunedOptions opts)
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...
bool IsIsymbolOrFinal(InputStateId state)
bool ApproxEqual(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2, float delta=kDelta)
bool operator!=(const Element &other) const
void ComputeBackwardWeight()
Arc::StateId OutputStateId
LatticeWeightTpl< FloatType > Times(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
void InitializeDeterminization()
KALDI_DISALLOW_COPY_AND_ASSIGN(LatticeDeterminizerPruned)
ArcTpl< CompactWeight > CompactArc
void AddStrings(const vector< Element > &vec, vector< StringId > *needed_strings)
Arc::StateId InputStateId
bool DeterminizeLatticePhonePrunedFirstPass(const kaldi::TransitionModel &trans_model, double beam, MutableFst< ArcTpl< Weight > > *fst, const DeterminizeLatticePrunedOptions &opts)
This function does a first pass determinization with phone symbols inserted at phone boundary...
CompactLatticeWeightTpl< Weight, IntType > CompactWeight
LatticeStringRepository< IntType > StringRepositoryType
double ConvertToCost(const LatticeWeightTpl< Float > &w)
int32 TransitionIdToHmmState(int32 trans_id) const
bool IsSelfLoop(int32 trans_id) const
void ProcessFinal(OutputStateId output_state_id)
unordered_map< const vector< Element > *, Element, SubsetKey, SubsetEqual > InitialSubsetHash
bool operator<(const Element &other) const
bool Determinize(double *effective_beam)
fst::StdArc::Weight Weight
OutputStateId InitialToStateId(const vector< Element > &subset_in, double forward_cost, Weight *remaining_weight, StringId *common_prefix)
MinimalSubsetHash minimal_hash_
LatticeStringRepository< IntType > repository_
void NormalizeSubset(vector< Element > *elems, Weight *tot_weight, StringId *common_str)
Arc::Label HighestNumberedInputSymbol(const Fst< Arc > &fst)
Returns the highest numbered input symbol id of the FST (or zero for an empty FST.
void ProcessTransition(OutputStateId ostate_id, Label ilabel, vector< Element > *subset)
int Compare(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
Compare returns -1 if w1 < w2, +1 if w1 > w2, and 0 if w1 == w2.
InitialSubsetHash initial_hash_
bool PruneLattice(BaseFloat beam, LatType *lat)
#define KALDI_ASSERT(cond)
OutputState(const vector< Element > &minimal_subset, double forward_cost)
vector< pair< Label, Element > > all_elems_tmp_
ArcTpl< Weight >::Label DeterminizeLatticeInsertPhones(const kaldi::TransitionModel &trans_model, MutableFst< ArcTpl< Weight > > *fst)
This function takes in lattices and inserts phones at phone boundaries.
std::vector< double > backward_costs_
void Output(MutableFst< Arc > *ofst, bool destroy=true)
void EpsilonClosure(vector< Element > *subset)
const StringRepositoryType::Entry * StringId
unordered_map< const vector< Element > *, OutputStateId, SubsetKey, SubsetEqual > MinimalSubsetHash
void MakeSubsetUnique(vector< Element > *subset)
int32 TransitionIdToPhone(int32 trans_id) const
std::priority_queue< Task *, vector< Task * >, TaskCompare > queue_
bool DeterminizeLatticePhonePrunedWrapper(const kaldi::TransitionModel &trans_model, MutableFst< kaldi::LatticeArc > *ifst, double beam, MutableFst< kaldi::CompactLatticeArc > *ofst, DeterminizeLatticePhonePrunedOptions opts)
This function is a wrapper of DeterminizeLatticePhonePruned() that works for Lattice type FSTs...
void DeterminizeLatticeDeletePhones(typename ArcTpl< Weight >::Label first_phone_label, MutableFst< ArcTpl< Weight > > *fst)
This function takes in lattices and deletes "phones" from them.
void ConvertToMinimal(vector< Element > *subset)
int Compare(const Weight &a_w, StringId a_str, const Weight &b_w, StringId b_str) const
void Copy(const CuMatrixBase< Real > &src, const CuArray< int32 > ©_from_indices, CuMatrixBase< Real > *tgt)
Copies elements from src into tgt as given by copy_from_indices.