345 typedef std::priority_queue<std::pair<BaseFloat, int32>,
346 std::vector<std::pair<BaseFloat, int32> >,
367 unordered_map<std::pair<int32,int32>,
383 composed_states->clear();
384 composed_states->reserve(
clat_out_->NumStates());
387 for (; iter != end; ++iter) {
388 int32 lat_state = *iter;
390 composed_states->insert(composed_states->end(),
395 static_cast<int32>(composed_states->size()) ==
401 if (current_num_arcs == 0) {
405 int32 ans =
static_cast<int32>(current_num_arcs *
407 if (ans == current_num_arcs)
408 ans = current_num_arcs + 1;
421 std::vector<int32> all_composed_states;
435 std::vector<ComposedStateInfo>::iterator
439 state_iter->depth = 0;
443 for (; state_iter != state_end; ++state_iter) {
444 state_iter->forward_cost = std::numeric_limits<double>::infinity();
445 state_iter->prev_composed_state = -1;
448 std::vector<int32>::const_iterator state_index_iter = composed_states.begin(),
449 state_index_end = composed_states.end();
450 for (; state_index_iter != state_index_end; ++state_index_iter) {
451 int32 composed_state_index = *state_index_iter;
453 composed_state_index];
459 fst::ArcIterator<CompactLattice> aiter(*
clat_out_,
460 composed_state_index);
461 for (; !aiter.Done(); aiter.Next()) {
464 next_forward_cost = forward_cost + arc_cost;
479 std::vector<int32>::const_reverse_iterator iter = composed_states.rbegin(),
480 end = composed_states.rend();
481 for (; iter != end; ++iter) {
482 int32 composed_state_index = *iter;
486 fst::ArcIterator<CompactLattice> aiter(*
clat_out_,
487 composed_state_index);
488 for (; !aiter.Done(); aiter.Next()) {
492 this_backward_cost = arc_cost + next_backward_cost;
493 if (this_backward_cost < backward_cost)
494 backward_cost = this_backward_cost;
514 for (
int32 composed_state_index = 0; composed_state_index < num_states;
515 ++composed_state_index) {
530 std::vector<std::pair<BaseFloat, int32> > queue_elements;
531 queue_elements.reserve(num_states);
535 std::vector<int32>::const_iterator iter = composed_states.begin(),
536 end = composed_states.end();
537 for (; iter != end; ++iter) {
538 int32 composed_state_index = *iter;
543 if (prev_composed_state < 0) {
567 if (expected_cost_offset < current_cutoff) {
568 queue_elements.push_back(std::pair<BaseFloat, int32>(
569 expected_cost_offset, composed_state_index));
574 QueueType temp_queue(queue_elements.begin(), queue_elements.end());
580 fst::kTopSorted &&
clat_in_.NumStates() > 0 &&
585 for (
int32 s = num_lat_states - 1; s >= 0; s--) {
587 std::vector<std::pair<double, int32> > arc_costs;
589 if (backward_cost != std::numeric_limits<double>::infinity())
590 arc_costs.push_back(std::pair<BaseFloat,int32>(backward_cost, -1));
591 fst::ArcIterator<CompactLattice> aiter(
clat_in_, s);
593 for (; !aiter.Done(); aiter.Next(), ++arc_index) {
599 "Possibly not all states of input lattice are co-accessible?");
600 arc_costs.push_back(std::pair<BaseFloat,int32>(backward_cost, arc_index));
602 std::sort(arc_costs.begin(), arc_costs.end());
604 "Possibly not all states of input lattice are co-accessible?");
605 backward_cost = arc_costs[0].first;
609 std::vector<std::pair<double, int32> >::const_iterator
610 src_iter = arc_costs.begin(), src_end = arc_costs.end();
611 std::vector<std::pair<BaseFloat, int32> >::iterator
613 for (; src_iter != src_end; ++src_iter, ++dest_iter) {
614 dest_iter->first =
BaseFloat(src_iter->first - backward_cost);
615 dest_iter->second = src_iter->second;
644 composed_state.
depth = 0;
646 composed_state.
backward_cost = std::numeric_limits<double>::infinity();
659 std::pair<BaseFloat, int32>(expected_cost_offset,
666 int32 src_composed_state) {
672 int32 lat_state = src_composed_state_info.lat_state;
676 int32 sorted_arc_index = src_composed_state_info.sorted_arc_index,
687 if (sorted_arc_index + 1 == num_sorted_arcs) {
688 src_composed_state_info.sorted_arc_index = -1;
689 src_composed_state_info.arc_delta_cost =
690 std::numeric_limits<BaseFloat>::infinity();
691 expected_cost_offset =
692 std::numeric_limits<BaseFloat>::infinity();
694 src_composed_state_info.sorted_arc_index = sorted_arc_index + 1;
695 src_composed_state_info.arc_delta_cost =
697 expected_cost_offset =
698 (src_composed_state_info.forward_cost +
700 src_composed_state_info.delta_backward_cost +
717 expected_cost_offset, src_composed_state);
724 int32 lm_state = src_composed_state_info.lm_state;
726 if (lm_final_cost != std::numeric_limits<BaseFloat>::infinity()) {
734 final_lat_weight.SetValue1(final_lat_weight.Value1() +
736 final_weight.SetWeight(final_lat_weight);
737 clat_out_->SetFinal(src_composed_state, final_weight);
739 if (final_cost < src_composed_state_info.backward_cost)
740 src_composed_state_info.backward_cost = final_cost;
759 src_composed_state]);
762 fst::ArcIterator<CompactLattice> aiter(
clat_in_, src_lat_state);
763 aiter.Seek(arc_index);
769 int32 dest_lat_state = lat_arc.nextstate,
770 ilabel = lat_arc.ilabel,
771 olabel = lat_arc.olabel;
780 lm_arc.nextstate = src_info->
lm_state;
788 int32 dest_lm_state = lm_arc.nextstate;
797 int32 dest_composed_state;
803 typedef std::unordered_map<std::pair<int32,int32>,
int32,
805 int32 new_composed_state =
clat_out_->NumStates();
806 std::pair<const std::pair<int32,int32>, int32> value(
807 std::pair<int32,int32>(dest_lat_state, dest_lm_state), new_composed_state);
808 std::pair<MapType::iterator, bool> ret =
816 dest_composed_state = new_composed_state;
825 dest_info->
lm_state = dest_lm_state;
831 std::numeric_limits<double>::infinity();
854 dest_composed_state);
857 dest_composed_state = ret.first->second;
863 new_arc.nextstate = dest_composed_state;
866 new_arc.ilabel = ilabel;
867 new_arc.olabel = olabel;
868 new_arc.weight = lat_arc.weight;
872 weight.SetValue1(
fst::Times(weight.Value1(), lm_arc.weight).Value());
873 new_arc.weight.SetWeight(weight);
874 clat_out_->AddArc(src_composed_state, new_arc);
879 int32 num_states = clat.NumStates(),
881 for (
int32 s = 0; s < num_states; s++)
882 num_arcs += clat.NumArcs(s);
889 KALDI_WARN <<
"Input lattice to composition is empty.";
917 num_states_in =
clat_in_.NumStates(),
920 std::ostringstream os;
921 os <<
"Input lattice had " << num_arcs_in <<
'/' << num_states_in
922 <<
" arcs/states; output lattice has " << num_arcs_out <<
'/' 924 if (num_arcs_out != orig_num_arcs_out) {
925 os <<
" (before pruning: " << orig_num_arcs_out <<
'/' 926 << orig_num_states_out <<
")";
936 os <<
". Effective beam was " << effective_beam;
942 KALDI_WARN <<
"Composed lattice has no states: something went wrong.";
BaseFloat delta_backward_cost
std::vector< LatticeStateInfo > lat_state_info_
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
virtual bool GetArc(StateId s, Label ilabel, Arc *oarc)=0
Note: ilabel must not be epsilon.
std::vector< ComposedStateInfo > composed_state_info_
const ComposeLatticePrunedOptions & opts_
virtual Weight Final(StateId s)=0
fst::DeterministicOnDemandFst< fst::StdArc > * det_fst_
void ComputeDeltaBackwardCosts(const std::vector< int32 > &composed_states)
int32 GetVerboseLevel()
Get verbosity level, usually set via command line '–verbose=' switch.
void ProcessTransition(int32 composed_src_state, int32 arc_index)
BaseFloat current_cutoff_
virtual StateId Start()=0
PrunedCompactLatticeComposer implements an algorithm for pruned composition.
std::priority_queue< std::pair< BaseFloat, int32 >, std::vector< std::pair< BaseFloat, int32 > >, std::greater< std::pair< BaseFloat, int32 > > > QueueType
unordered_map< std::pair< int32, int32 >, int32, PairHasher< int32 > > pair_to_state_
PrunedCompactLatticeComposer(const ComposeLatticePrunedOptions &opts, const CompactLattice &clat, fst::DeterministicOnDemandFst< fst::StdArc > *det_fst, CompactLattice *composed_clat)
LatticeWeightTpl< FloatType > Times(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
void ComputeBackwardCosts(const std::vector< int32 > &composed_states)
void ProcessQueueElement(int32 composed_state_to_expand)
void ComputeForwardCosts(const std::vector< int32 > &composed_states)
int32 GetCurrentArcLimit() const
double ConvertToCost(const LatticeWeightTpl< Float > &w)
std::vector< std::pair< BaseFloat, int32 > > arc_delta_costs
std::set< int32 > accessed_lat_states_
void ComposeCompactLatticePruned(const ComposeLatticePrunedOptions &opts, const CompactLattice &clat, fst::DeterministicOnDemandFst< fst::StdArc > *det_fst, CompactLattice *composed_clat)
Does pruned composition of a lattice 'clat' with a DeterministicOnDemandFst 'det_fst'; implements LM ...
std::vector< int32 > composed_states
fst::VectorFst< CompactLatticeArc > CompactLattice
QueueType composed_state_queue_
fst::StdArc::Weight Weight
float lattice_compose_beam
void GetTopsortedStateList(std::vector< int32 > *composed_states) const
#define KALDI_ASSERT(cond)
int32 prev_composed_state
fst::ArcTpl< CompactLatticeWeight > CompactLatticeArc
void ComputeLatticeStateInfo()
void RecomputePruningInfo()
void TopSortCompactLatticeIfNeeded(CompactLattice *clat)
Topologically sort the compact lattice if not already topologically sorted.
static int32 TotalNumArcs(const CompactLattice &clat)
CompactLattice * clat_out_
const CompactLattice & clat_in_
A hashing function-object for pairs of ints.
bool output_reached_final_