39 vector<BaseFloat> loglikes;
41 int32 cur_state = nbest.Start();
42 int32 prev_frame = -1;
45 Weight w = nbest.Final(cur_state);
46 if (w != Weight::Zero()) {
48 if (per_frame_loglikes != NULL) {
51 *per_frame_loglikes = vec;
56 fst::ArcIterator<Lattice> iter(nbest, cur_state);
59 if (arc.ilabel != 0) {
64 loglikes.push_back(acwt);
66 }
else if (acwt == acwt){
67 if (prev_frame > -1) {
68 loglikes[prev_frame] += acwt;
73 cur_state = arc.nextstate;
79 if (!lat.Properties(fst::kTopSorted,
true))
80 KALDI_ERR <<
"Input lattice must be topologically sorted.";
82 int32 num_states = lat.NumStates();
84 times->resize(num_states, -1);
86 for (
int32 state = 0; state < num_states; state++) {
87 int32 cur_time = (*times)[state];
88 for (fst::ArcIterator<Lattice> aiter(lat, state); !aiter.Done();
92 if (arc.ilabel != 0) {
94 if ((*times)[arc.nextstate] == -1) {
95 (*times)[arc.nextstate] = cur_time + 1;
101 if ((*times)[arc.nextstate] == -1)
102 (*times)[arc.nextstate] = cur_time;
108 return (*std::max_element(times->begin(), times->end()));
112 if (!lat.Properties(fst::kTopSorted,
true))
113 KALDI_ERR <<
"Input lattice must be topologically sorted.";
115 int32 num_states = lat.NumStates();
117 times->resize(num_states, -1);
120 for (
int32 state = 0; state < num_states; state++) {
121 int32 cur_time = (*times)[state];
122 for (fst::ArcIterator<CompactLattice> aiter(lat, state); !aiter.Done();
125 int32 arc_len =
static_cast<int32>(arc.weight.String().size());
126 if ((*times)[arc.nextstate] == -1)
127 (*times)[arc.nextstate] = cur_time + arc_len;
129 KALDI_ASSERT((*times)[arc.nextstate] == cur_time + arc_len);
132 int32 this_utt_len = (*times)[state] + lat.Final(state).String().size();
133 if (utt_len == -1) utt_len = this_utt_len;
135 if (this_utt_len != utt_len) {
137 "seem to have a consistent length.";
138 utt_len = std::max(utt_len, this_utt_len);
144 KALDI_WARN <<
"Utterance does not have a final-state.";
151 vector<double> *alpha) {
160 if (clat.Properties(fst::kTopSorted,
true) == 0) {
161 KALDI_WARN <<
"Input lattice must be topologically sorted.";
164 if (clat.Start() != 0) {
165 KALDI_WARN <<
"Input lattice must start from state 0.";
169 int32 num_states = clat.NumStates();
176 for (StateId s = 0; s < num_states; s++) {
177 double this_alpha = (*alpha)[s];
178 for (ArcIterator<CompactLattice> aiter(clat, s); !aiter.Done(); aiter.Next()) {
179 const Arc &arc = aiter.Value();
180 double arc_like = -(arc.weight.Weight().Value1() + arc.weight.Weight().Value2());
181 (*alpha)[arc.nextstate] =
LogAdd((*alpha)[arc.nextstate], this_alpha + arc_like);
189 vector<double> *beta) {
198 if (clat.Properties(fst::kTopSorted,
true) == 0) {
199 KALDI_WARN <<
"Input lattice must be topologically sorted.";
202 if (clat.Start() != 0) {
203 KALDI_WARN <<
"Input lattice must start from state 0.";
207 int32 num_states = clat.NumStates();
213 for (StateId s = num_states-1; s >= 0; s--) {
214 Weight f = clat.Final(s);
215 double this_beta = -(f.Weight().Value1()+f.Weight().Value2());
216 for (ArcIterator<CompactLattice> aiter(clat, s); !aiter.Done(); aiter.Next()) {
217 const Arc &arc = aiter.Value();
218 double arc_like = -(arc.weight.Weight().Value1()+arc.weight.Weight().Value2());
219 double arc_beta = (*beta)[arc.nextstate] + arc_like;
220 this_beta =
LogAdd(this_beta, arc_beta);
222 (*beta)[s] = this_beta;
228 template<
class LatType>
235 if (!lat->Properties(fst::kTopSorted,
true)) {
236 if (fst::TopSort(lat) ==
false) {
243 int32 start = lat->Start();
244 int32 num_states = lat->NumStates();
245 if (num_states == 0)
return false;
246 std::vector<double> forward_cost(num_states,
247 std::numeric_limits<double>::infinity());
248 forward_cost[start] = 0.0;
250 double best_final_cost = std::numeric_limits<double>::infinity();
253 for (
int32 state = 0; state < num_states; state++) {
254 double this_forward_cost = forward_cost[state];
255 for (fst::ArcIterator<LatType> aiter(*lat, state);
258 const Arc &arc(aiter.Value());
259 StateId nextstate = arc.nextstate;
260 KALDI_ASSERT(nextstate > state && nextstate < num_states);
261 double next_forward_cost = this_forward_cost +
263 if (forward_cost[nextstate] > next_forward_cost)
264 forward_cost[nextstate] = next_forward_cost;
266 Weight final_weight = lat->Final(state);
267 double this_final_cost = this_forward_cost +
269 if (this_final_cost < best_final_cost)
270 best_final_cost = this_final_cost;
272 int32 bad_state = lat->AddState();
273 double cutoff = best_final_cost + beam;
280 std::vector<double> &backward_cost(forward_cost);
281 for (
int32 state = num_states - 1; state >= 0; state--) {
282 double this_forward_cost = forward_cost[state];
283 double this_backward_cost =
ConvertToCost(lat->Final(state));
284 if (this_backward_cost + this_forward_cost > cutoff
285 && this_backward_cost != std::numeric_limits<double>::infinity())
286 lat->SetFinal(state, Weight::Zero());
287 for (fst::MutableArcIterator<LatType> aiter(lat, state);
290 Arc arc(aiter.Value());
291 StateId nextstate = arc.nextstate;
292 KALDI_ASSERT(nextstate > state && nextstate < num_states);
294 arc_backward_cost = arc_cost + backward_cost[nextstate],
295 this_fb_cost = this_forward_cost + arc_backward_cost;
296 if (arc_backward_cost < this_backward_cost)
297 this_backward_cost = arc_backward_cost;
298 if (this_fb_cost > cutoff) {
299 arc.nextstate = bad_state;
303 backward_cost[state] = this_backward_cost;
306 return (lat->NumStates() > 0);
315 double *acoustic_like_sum) {
324 if (acoustic_like_sum) *acoustic_like_sum = 0.0;
327 if (lat.Properties(fst::kTopSorted,
true) == 0)
328 KALDI_ERR <<
"Input lattice must be topologically sorted.";
331 int32 num_states = lat.NumStates();
332 vector<int32> state_times;
335 std::vector<double> &beta(alpha);
340 post->resize(max_time);
344 for (StateId s = 0; s < num_states; s++) {
345 double this_alpha = alpha[s];
346 for (ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
347 const Arc &arc = aiter.Value();
349 alpha[arc.nextstate] =
LogAdd(alpha[arc.nextstate], this_alpha + arc_like);
351 Weight f = lat.Final(s);
352 if (f != Weight::Zero()) {
353 double final_like = this_alpha - (f.Value1() + f.Value2());
354 tot_forward_prob =
LogAdd(tot_forward_prob, final_like);
356 "Lattice is inconsistent (final-prob not at max_time)");
359 for (StateId s = num_states-1; s >= 0; s--) {
360 Weight f = lat.Final(s);
361 double this_beta = -(f.Value1() + f.Value2());
362 for (ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
363 const Arc &arc = aiter.Value();
365 arc_beta = beta[arc.nextstate] + arc_like;
366 this_beta =
LogAdd(this_beta, arc_beta);
367 int32 transition_id = arc.ilabel;
370 if (transition_id != 0 || acoustic_like_sum != NULL) {
371 double posterior =
Exp(alpha[s] + arc_beta - tot_forward_prob);
373 if (transition_id != 0)
374 (*post)[state_times[s]].push_back(std::make_pair(transition_id,
375 static_cast<kaldi::BaseFloat>(posterior)));
376 if (acoustic_like_sum != NULL)
377 *acoustic_like_sum -= posterior * arc.weight.Value2();
380 if (acoustic_like_sum != NULL && f != Weight::Zero()) {
382 posterior =
Exp(alpha[s] + final_logprob - tot_forward_prob);
383 *acoustic_like_sum -= posterior * f.Value2();
387 double tot_backward_prob = beta[0];
388 if (!
ApproxEqual(tot_forward_prob, tot_backward_prob, 1e-8)) {
389 KALDI_WARN <<
"Total forward probability over lattice = " << tot_forward_prob
390 <<
", while total backward probability = " << tot_backward_prob;
393 for (
int32 t = 0; t < max_time; t++)
395 return tot_backward_prob;
400 const vector<int32> &silence_phones,
401 vector< std::set<int32> > *active_phones) {
403 vector<int32> state_times;
404 int32 num_states = lat.NumStates();
406 active_phones->clear();
407 active_phones->resize(max_time);
408 for (
int32 state = 0; state < num_states; state++) {
409 int32 cur_time = state_times[state];
410 for (fst::ArcIterator<Lattice> aiter(lat, state); !aiter.Done();
413 if (arc.ilabel != 0) {
415 if (!std::binary_search(silence_phones.begin(),
416 silence_phones.end(), phone))
417 (*active_phones)[cur_time].insert(phone);
426 int32 num_states = lat->NumStates();
427 for (
int32 state = 0; state < num_states; state++) {
428 for (fst::MutableArcIterator<Lattice> aiter(lat, state); !aiter.Done();
430 Arc arc(aiter.Value());
432 if ((arc.ilabel != 0)
444 static inline double LogAddOrMax(
bool viterbi,
double a,
double b) {
446 return std::max(a, b);
451 template<
typename LatticeType>
454 vector<double> *alpha,
455 vector<double> *beta) {
460 StateId num_states = lat.NumStates();
461 KALDI_ASSERT(lat.Properties(fst::kTopSorted,
true) == fst::kTopSorted);
471 for (StateId s = 0; s < num_states; s++) {
472 double this_alpha = (*alpha)[s];
473 for (fst::ArcIterator<LatticeType> aiter(lat, s); !aiter.Done();
475 const Arc &arc = aiter.Value();
477 (*alpha)[arc.nextstate] =
LogAddOrMax(viterbi, (*alpha)[arc.nextstate],
478 this_alpha + arc_like);
480 Weight f = lat.Final(s);
481 if (f != Weight::Zero()) {
483 tot_forward_prob =
LogAddOrMax(viterbi, tot_forward_prob, final_like);
486 for (StateId s = num_states-1; s >= 0; s--) {
488 for (fst::ArcIterator<LatticeType> aiter(lat, s); !aiter.Done();
490 const Arc &arc = aiter.Value();
492 arc_beta = (*beta)[arc.nextstate] + arc_like;
493 this_beta =
LogAddOrMax(viterbi, this_beta, arc_beta);
495 (*beta)[s] = this_beta;
497 double tot_backward_prob = (*beta)[lat.Start()];
498 if (!
ApproxEqual(tot_forward_prob, tot_backward_prob, 1e-8)) {
499 KALDI_WARN <<
"Total forward probability over lattice = " << tot_forward_prob
500 <<
", while total backward probability = " << tot_backward_prob;
503 return 0.5 * (tot_backward_prob + tot_forward_prob);
510 vector<double> *alpha,
511 vector<double> *beta);
516 vector<double> *alpha,
517 vector<double> *beta);
528 return logprob < other.
logprob;
538 if (clat->Start() == fst::kNoStateId) {
539 KALDI_WARN <<
"Limiting depth of empty lattice.";
542 if (clat->Properties(fst::kTopSorted,
true) == 0) {
544 KALDI_ERR <<
"Topological sorting of lattice failed.";
547 vector<int32> state_times;
551 std::vector<double> alpha;
552 std::vector<double> beta;
557 std::vector<std::vector<LatticeArcRecord> > arc_records(T);
559 StateId num_states = clat->NumStates();
560 for (StateId s = 0; s < num_states; s++) {
561 for (fst::ArcIterator<CompactLattice> aiter(*clat, s); !aiter.Done();
563 const Arc &arc = aiter.Value();
565 arc_record.
state = s;
566 arc_record.
arc = aiter.Position();
571 int32 num_frames = arc.weight.String().size(), start_t = state_times[s];
572 for (
int32 t = start_t; t < start_t + num_frames; t++) {
574 arc_records[t].push_back(arc_record);
578 StateId dead_state = clat->AddState();
581 size_t max_depth = max_depth_per_frame;
582 for (
int32 t = 0; t < T; t++) {
583 size_t size = arc_records[t].size();
584 if (size > max_depth) {
587 size_t cutoff = size - max_depth;
588 std::nth_element(arc_records[t].begin(),
589 arc_records[t].begin() + cutoff,
590 arc_records[t].end());
591 for (
size_t index = 0; index < cutoff; index++) {
593 fst::MutableArcIterator<CompactLattice> aiter(clat, record.
state);
594 aiter.Seek(record.
arc);
595 Arc arc = aiter.Value();
596 if (arc.nextstate != dead_state) {
597 arc.nextstate = dead_state;
609 if (clat->Properties(fst::kTopSorted,
true) == 0) {
610 if (fst::TopSort(clat) ==
false) {
611 KALDI_ERR <<
"Topological sorting failed";
617 if (lat->Properties(fst::kTopSorted,
true) == 0) {
618 if (fst::TopSort(lat) ==
false) {
619 KALDI_ERR <<
"Topological sorting failed";
631 if (clat.Properties(fst::kTopSorted,
true) == 0) {
632 KALDI_ERR <<
"Lattice input to CompactLatticeDepth was not topologically " 635 if (clat.Start() == fst::kNoStateId) {
639 size_t num_arc_frames = 0;
642 vector<int32> state_times;
645 if (num_frames != NULL)
647 for (StateId s = 0; s < clat.NumStates(); s++) {
648 for (fst::ArcIterator<CompactLattice> aiter(clat, s); !aiter.Done();
651 num_arc_frames += arc.weight.String().size();
653 num_arc_frames += clat.Final(s).String().size();
655 return num_arc_frames /
static_cast<BaseFloat>(t);
660 std::vector<int32> *depth_per_frame) {
662 if (clat.Properties(fst::kTopSorted,
true) == 0) {
663 KALDI_ERR <<
"Lattice input to CompactLatticeDepthPerFrame was not " 664 <<
"topologically sorted.";
666 if (clat.Start() == fst::kNoStateId) {
667 depth_per_frame->clear();
670 vector<int32> state_times;
673 depth_per_frame->clear();
677 depth_per_frame->resize(T, 0);
678 for (StateId s = 0; s < clat.NumStates(); s++) {
679 int32 start_time = state_times[s];
680 for (fst::ArcIterator<CompactLattice> aiter(clat, s); !aiter.Done();
683 int32 len = arc.weight.String().size();
684 for (
int32 t = start_time; t < start_time + len; t++) {
686 (*depth_per_frame)[t]++;
689 int32 final_len = clat.Final(s).String().size();
690 for (
int32 t = start_time; t < start_time + final_len; t++) {
692 (*depth_per_frame)[t]++;
704 int32 num_states = clat->NumStates();
705 for (
int32 state = 0; state < num_states; state++) {
706 for (fst::MutableArcIterator<CompactLattice> aiter(clat, state);
709 Arc arc(aiter.Value());
710 std::vector<int32> phone_seq;
711 const std::vector<int32> &tid_seq = arc.weight.String();
712 for (std::vector<int32>::const_iterator iter = tid_seq.begin();
713 iter != tid_seq.end(); ++iter) {
717 arc.weight.SetString(phone_seq);
720 Weight f = clat->Final(state);
721 if (f != Weight::Zero()) {
722 std::vector<int32> phone_seq;
723 const std::vector<int32> &tid_seq = f.String();
724 for (std::vector<int32>::const_iterator iter = tid_seq.begin();
725 iter != tid_seq.end(); ++iter) {
729 f.SetString(phone_seq);
730 clat->SetFinal(state, f);
736 const std::vector<int32> &alignment,
737 const std::vector<int32> &silence_phones,
744 uint64 props = lat->Properties(fst::kFstProperties,
748 KALDI_ASSERT(max_silence_error >= 0.0 && max_silence_error <= 1.0);
749 vector<int32> state_times;
750 int32 num_states = lat->NumStates();
752 KALDI_ASSERT(num_frames == static_cast<int32>(alignment.size()));
753 for (
int32 state = 0; state < num_states; state++) {
754 int32 cur_time = state_times[state];
755 for (fst::MutableArcIterator<Lattice> aiter(lat, state); !aiter.Done();
758 if (arc.ilabel != 0) {
760 KALDI_WARN <<
"Lattice has out-of-range transition-ids: " 761 <<
"lattice/model mismatch?";
767 if (phone == ref_phone) {
770 if (std::binary_search(silence_phones.begin(), silence_phones.end(), phone))
771 frame_error = max_silence_error;
778 arc.weight.SetValue1(arc.weight.Value1() + delta_cost);
786 lat->SetProperties(props,
787 ~(fst::kWeighted|fst::kUnweighted));
796 const std::vector<int32> &silence_phones,
798 const std::vector<int32> &num_ali,
799 std::string criterion,
800 bool one_silence_class,
807 KALDI_ASSERT(criterion ==
"mpfe" || criterion ==
"smbr");
808 bool is_mpfe = (criterion ==
"mpfe");
810 if (lat.Properties(fst::kTopSorted,
true) == 0)
811 KALDI_ERR <<
"Input lattice must be topologically sorted.";
814 int32 num_states = lat.NumStates();
815 vector<int32> state_times;
817 KALDI_ASSERT(max_time == static_cast<int32>(num_ali.size()));
819 alpha_smbr(num_states, 0),
821 beta_smbr(num_states, 0);
824 double tot_forward_score = 0;
827 post->resize(max_time);
831 for (StateId s = 0; s < num_states; s++) {
832 double this_alpha = alpha[s];
833 for (ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
834 const Arc &arc = aiter.Value();
836 alpha[arc.nextstate] =
LogAdd(alpha[arc.nextstate], this_alpha + arc_like);
838 Weight f = lat.Final(s);
839 if (f != Weight::Zero()) {
840 double final_like = this_alpha - (f.Value1() + f.Value2());
841 tot_forward_prob =
LogAdd(tot_forward_prob, final_like);
843 "Lattice is inconsistent (final-prob not at max_time)");
847 for (StateId s = num_states-1; s >= 0; s--) {
848 Weight f = lat.Final(s);
849 double this_beta = -(f.Value1() + f.Value2());
850 for (ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
851 const Arc &arc = aiter.Value();
853 arc_beta = beta[arc.nextstate] + arc_like;
854 this_beta =
LogAdd(this_beta, arc_beta);
859 double tot_backward_prob = beta[0];
861 if (!
ApproxEqual(tot_forward_prob, tot_backward_prob, 1e-6)) {
862 KALDI_ERR <<
"Total forward probability over lattice = " << tot_forward_prob
863 <<
", while total backward probability = " << tot_backward_prob;
868 for (StateId s = 0; s < num_states; s++) {
869 double this_alpha = alpha[s];
870 for (ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
871 const Arc &arc = aiter.Value();
873 double frame_acc = 0.0;
874 if (arc.ilabel != 0) {
875 int32 cur_time = state_times[s];
878 bool phone_is_sil = std::binary_search(silence_phones.begin(),
879 silence_phones.end(),
881 ref_phone_is_sil = std::binary_search(silence_phones.begin(),
882 silence_phones.end(),
884 both_sil = phone_is_sil && ref_phone_is_sil;
888 if (!one_silence_class)
889 frame_acc = (pdf == ref_pdf && !phone_is_sil) ? 1.0 : 0.0;
891 frame_acc = (pdf == ref_pdf || both_sil) ? 1.0 : 0.0;
893 if (!one_silence_class)
894 frame_acc = (phone == ref_phone && !phone_is_sil) ? 1.0 : 0.0;
896 frame_acc = (phone == ref_phone || both_sil) ? 1.0 : 0.0;
899 double arc_scale =
Exp(alpha[s] + arc_like - alpha[arc.nextstate]);
900 alpha_smbr[arc.nextstate] += arc_scale * (alpha_smbr[s] + frame_acc);
902 Weight f = lat.Final(s);
903 if (f != Weight::Zero()) {
904 double final_like = this_alpha - (f.Value1() + f.Value2());
905 double arc_scale =
Exp(final_like - tot_forward_prob);
906 tot_forward_score += arc_scale * alpha_smbr[s];
908 "Lattice is inconsistent (final-prob not at max_time)");
912 for (StateId s = num_states-1; s >= 0; s--) {
913 for (ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
914 const Arc &arc = aiter.Value();
916 arc_beta = beta[arc.nextstate] + arc_like;
917 double frame_acc = 0.0;
918 int32 transition_id = arc.ilabel;
919 if (arc.ilabel != 0) {
920 int32 cur_time = state_times[s];
923 bool phone_is_sil = std::binary_search(silence_phones.begin(),
924 silence_phones.end(), phone),
925 ref_phone_is_sil = std::binary_search(silence_phones.begin(),
926 silence_phones.end(),
928 both_sil = phone_is_sil && ref_phone_is_sil;
932 if (!one_silence_class)
933 frame_acc = (pdf == ref_pdf && !phone_is_sil) ? 1.0 : 0.0;
935 frame_acc = (pdf == ref_pdf || both_sil) ? 1.0 : 0.0;
937 if (!one_silence_class)
938 frame_acc = (phone == ref_phone && !phone_is_sil) ? 1.0 : 0.0;
940 frame_acc = (phone == ref_phone || both_sil) ? 1.0 : 0.0;
943 double arc_scale =
Exp(beta[arc.nextstate] + arc_like - beta[s]);
948 beta_smbr[s] += arc_scale * (beta_smbr[arc.nextstate] + frame_acc);
950 if (transition_id != 0) {
951 double posterior =
Exp(alpha[s] + arc_beta - tot_forward_prob);
952 double acc_diff = alpha_smbr[s] + frame_acc + beta_smbr[arc.nextstate]
954 double posterior_smbr = posterior * acc_diff;
955 (*post)[state_times[s]].push_back(std::make_pair(transition_id,
956 static_cast<BaseFloat>(posterior_smbr)));
962 double tot_backward_score = beta_smbr[0];
964 if (!
ApproxEqual(tot_forward_score, tot_backward_score, 1e-4)) {
965 KALDI_ERR <<
"Total forward score over lattice = " << tot_forward_score
966 <<
", while total backward score = " << tot_backward_score;
970 for (
int32 t = 0; t < max_time; t++)
972 return tot_forward_score;
976 std::vector<int32> *
words,
977 std::vector<int32> *begin_times,
978 std::vector<int32> *lengths) {
980 begin_times->clear();
987 StateId state = clat.Start();
989 if (state == kNoStateId) {
994 Weight
final = clat.Final(state);
995 size_t num_arcs = clat.NumArcs(state);
996 if (
final != Weight::Zero()) {
1001 if (!
final.String().empty()) {
1002 KALDI_WARN <<
"Lattice has alignments on final-weight: probably " 1003 "was not word-aligned (alignments will be approximate)";
1007 if (num_arcs != 1) {
1008 KALDI_WARN <<
"Lattice is not linear: num-arcs = " << num_arcs;
1011 fst::ArcIterator<CompactLattice> aiter(clat, state);
1012 const Arc &arc = aiter.Value();
1013 Label word_id = arc.ilabel;
1015 int32 length = arc.weight.String().size();
1016 words->push_back(word_id);
1017 begin_times->push_back(cur_time);
1018 lengths->push_back(length);
1020 state = arc.nextstate;
1029 std::vector<int32> *
words,
1030 std::vector<int32> *begin_times,
1031 std::vector<int32> *lengths,
1032 std::vector<std::vector<int32> > *prons,
1033 std::vector<std::vector<int32> > *phone_lengths) {
1035 begin_times->clear();
1038 phone_lengths->clear();
1043 using namespace fst;
1044 StateId state = clat.Start();
1046 if (state == kNoStateId) {
1051 Weight
final = clat.Final(state);
1052 size_t num_arcs = clat.NumArcs(state);
1053 if (
final != Weight::Zero()) {
1054 if (num_arcs != 0) {
1058 if (!
final.String().empty()) {
1059 KALDI_WARN <<
"Lattice has alignments on final-weight: probably " 1060 "was not word-aligned (alignments will be approximate)";
1064 if (num_arcs != 1) {
1065 KALDI_WARN <<
"Lattice is not linear: num-arcs = " << num_arcs;
1068 fst::ArcIterator<CompactLattice> aiter(clat, state);
1069 const Arc &arc = aiter.Value();
1070 Label word_id = arc.ilabel;
1072 int32 length = arc.weight.String().size();
1073 words->push_back(word_id);
1074 begin_times->push_back(cur_time);
1075 lengths->push_back(length);
1076 const std::vector<int32> &arc_alignment = arc.weight.String();
1077 std::vector<std::vector<int32> > split_alignment;
1079 std::vector<int32> phones(split_alignment.size());
1080 std::vector<int32> plengths(split_alignment.size());
1081 for (
size_t i = 0;
i < split_alignment.size();
i++) {
1084 plengths[
i] = split_alignment[
i].size();
1086 prons->push_back(phones);
1087 phone_lengths->push_back(plengths);
1090 state = arc.nextstate;
1099 using namespace fst;
1100 if (clat.Properties(fst::kTopSorted,
true) == 0) {
1102 if (!TopSort(&clat_copy))
1103 KALDI_ERR <<
"Was not able to topologically sort lattice (cycles found?)";
1108 shortest_path->DeleteStates();
1109 if (clat.Start() == kNoStateId)
return;
1113 vector<std::pair<double, StateId> > best_cost_and_pred(clat.NumStates() + 1);
1114 StateId superfinal = clat.NumStates();
1115 for (StateId s = 0; s <= clat.NumStates(); s++) {
1116 best_cost_and_pred[s].first = std::numeric_limits<double>::infinity();
1117 best_cost_and_pred[s].second = fst::kNoStateId;
1119 best_cost_and_pred[clat.Start()].first = 0;
1120 for (StateId s = 0; s < clat.NumStates(); s++) {
1121 double my_cost = best_cost_and_pred[s].first;
1122 for (ArcIterator<CompactLattice> aiter(clat, s);
1125 const Arc &arc = aiter.Value();
1127 next_cost = my_cost + arc_cost;
1128 if (next_cost < best_cost_and_pred[arc.nextstate].first) {
1129 best_cost_and_pred[arc.nextstate].first = next_cost;
1130 best_cost_and_pred[arc.nextstate].second = s;
1134 tot_final = my_cost + final_cost;
1135 if (tot_final < best_cost_and_pred[superfinal].first) {
1136 best_cost_and_pred[superfinal].first = tot_final;
1137 best_cost_and_pred[superfinal].second = s;
1140 std::vector<StateId> states;
1141 StateId cur_state = superfinal, start_state = clat.Start();
1142 while (cur_state != start_state) {
1143 StateId prev_state = best_cost_and_pred[cur_state].second;
1144 if (prev_state == kNoStateId) {
1145 KALDI_WARN <<
"Failure in best-path algorithm for lattice (infinite costs?)";
1148 states.push_back(prev_state);
1149 KALDI_ASSERT(cur_state != prev_state &&
"Lattice with cycles");
1150 cur_state = prev_state;
1152 std::reverse(states.begin(), states.end());
1153 for (
size_t i = 0;
i < states.size();
i++)
1154 shortest_path->AddState();
1155 for (StateId s = 0;
static_cast<size_t>(s) < states.size(); s++) {
1156 if (s == 0) shortest_path->SetStart(s);
1157 if (static_cast<size_t>(s + 1) < states.size()) {
1158 bool have_arc =
false;
1160 for (ArcIterator<CompactLattice> aiter(clat, states[s]);
1163 const Arc &arc = aiter.Value();
1164 if (arc.nextstate == states[s+1]) {
1173 shortest_path->AddArc(s,
Arc(cur_arc.ilabel, cur_arc.olabel,
1174 cur_arc.weight, s+1));
1176 shortest_path->SetFinal(s, clat.Final(states[s]));
1184 int32 num_states = clat->NumStates();
1187 for (
int32 state = 0; state < num_states; state++) {
1188 for (fst::MutableArcIterator<CompactLattice> aiter(clat, state);
1189 !aiter.Done(); aiter.Next()) {
1191 Arc arc(aiter.Value());
1193 if (arc.ilabel != 0) {
1197 arc.weight.SetWeight(weight);
1198 aiter.SetValue(arc);
1206 state_id(state), arc_id(arc), tid(tid) { }
1222 if (clat->NumStates() == 0) {
1226 if (!clat->Properties(fst::kTopSorted,
true)) {
1227 if (fst::TopSort(clat) ==
false) {
1232 std::vector<int32> state_times;
1235 std::vector<std::vector<ClatRescoreTuple> > time_to_state(utt_len);
1237 int32 num_states = clat->NumStates();
1239 for (
size_t state = 0; state < num_states; state++) {
1241 int32 t = state_times[state];
1243 for (fst::MutableArcIterator<CompactLattice> aiter(clat, state);
1244 !aiter.Done(); aiter.Next(), arc_id++) {
1246 std::vector<int32> arc_string = arc.weight.String();
1248 for (
size_t offset = 0; offset < arc_string.size(); offset++) {
1250 int32 tid = arc_string[offset];
1254 KALDI_WARN <<
"There appears to be lattice/feature mismatch, " 1263 std::vector<int32> arc_string = clat->Final(state).String();
1264 for (
size_t offset = 0; offset < arc_string.size(); offset++) {
1267 time_to_state[t+offset].push_back(
1273 for (
int32 t = 0; t < utt_len; t++) {
1274 if ((t < utt_len - 1) && decodable->
IsLastFrame(t)) {
1275 KALDI_WARN <<
"Features are too short for lattice: utt-len is " 1276 << utt_len <<
", " << t <<
" is last frame";
1287 if (tmodel != NULL) {
1289 bool frame_has_multiple_pdfs =
false;
1290 for (
size_t i = 1;
i < time_to_state[t].size();
i++) {
1292 frame_has_multiple_pdfs =
true;
1296 if (frame_has_multiple_pdfs) {
1299 if (
WithProb(1.0 / speedup_factor)) {
1300 frame_scale = speedup_factor;
1305 if (frame_scale == 0.0)
1309 for (
size_t i = 0;
i < time_to_state[t].size();
i++) {
1310 int32 state = time_to_state[t][
i].state_id;
1311 int32 arc_id = time_to_state[t][
i].arc_id;
1312 int32 tid = time_to_state[t][
i].tid;
1323 new_lat_weight.
SetValue2(-log_like + curr_clat_weight.
Weight().Value2());
1324 new_clat_weight.
SetWeight(new_lat_weight);
1325 clat->SetFinal(state, new_clat_weight);
1327 fst::MutableArcIterator<CompactLattice> aiter(clat, state);
1336 new_weight.
SetValue2(-log_like + arc.weight.Weight().Value2());
1337 arc.weight.SetWeight(new_weight);
1338 aiter.SetValue(arc);
1362 if (lat->NumStates() == 0) {
1366 if (!lat->Properties(fst::kTopSorted,
true)) {
1367 if (fst::TopSort(lat) ==
false) {
1372 std::vector<int32> state_times;
1375 std::vector<std::vector<int32> > time_to_state(utt_len );
1377 int32 num_states = lat->NumStates();
1379 for (
size_t state = 0; state < num_states; state++) {
1380 int32 t = state_times[state];
1383 if (t >= 0 && t < utt_len)
1384 time_to_state[t].push_back(state);
1387 for (
int32 t = 0; t < utt_len; t++) {
1388 if ((t < utt_len - 1) && decodable->
IsLastFrame(t)) {
1389 KALDI_WARN <<
"Features are too short for lattice: utt-len is " 1390 << utt_len <<
", " << t <<
" is last frame";
1393 for (
size_t i = 0;
i < time_to_state[t].size();
i++) {
1394 int32 state = time_to_state[t][
i];
1395 for (fst::MutableArcIterator<Lattice> aiter(lat, state);
1396 !aiter.Done(); aiter.Next()) {
1398 if (arc.ilabel != 0) {
1399 int32 trans_id = arc.ilabel;
1404 arc.weight.SetValue2(-log_like + arc.weight.Value2());
1405 aiter.SetValue(arc);
1417 const std::vector<int32> &num_ali,
1419 bool convert_to_pdf_ids,
1436 if (convert_to_pdf_ids) {
1439 num_tmp.swap(num_post);
1442 den_tmp.swap(den_post);
1446 cancel, drop_frames, post);
1457 if (lat.Properties(fst::kTopSorted,
true) == 0) {
1459 if (!TopSort(&lat_copy))
1460 KALDI_ERR <<
"Was not able to topologically sort lattice (cycles found?)";
1463 std::vector<int32> max_length(lat.NumStates(), 0);
1464 int32 lattice_max_length = 0;
1465 for (StateId s = 0; s < lat.NumStates(); s++) {
1466 int32 this_max_length = max_length[s];
1467 for (fst::ArcIterator<Lattice> aiter(lat, s); !aiter.Done(); aiter.Next()) {
1468 const Arc &arc = aiter.Value();
1469 bool arc_has_word = (arc.olabel != 0);
1470 StateId nextstate = arc.nextstate;
1471 KALDI_ASSERT(static_cast<size_t>(nextstate) < max_length.size());
1475 KALDI_ASSERT(nextstate > s &&
"Lattice has cycles with words on.");
1476 max_length[nextstate] = std::max(max_length[nextstate],
1477 this_max_length + 1);
1479 max_length[nextstate] = std::max(max_length[nextstate],
1484 lattice_max_length = std::max(lattice_max_length, max_length[s]);
1486 return lattice_max_length;
1494 if (clat.Properties(fst::kTopSorted,
true) == 0) {
1496 if (!TopSort(&clat_copy))
1497 KALDI_ERR <<
"Was not able to topologically sort lattice (cycles found?)";
1500 std::vector<int32> max_length(clat.NumStates(), 0);
1501 int32 lattice_max_length = 0;
1502 for (StateId s = 0; s < clat.NumStates(); s++) {
1503 int32 this_max_length = max_length[s];
1504 for (fst::ArcIterator<CompactLattice> aiter(clat, s);
1505 !aiter.Done(); aiter.Next()) {
1506 const Arc &arc = aiter.Value();
1507 bool arc_has_word = (arc.ilabel != 0);
1512 StateId nextstate = arc.nextstate;
1513 KALDI_ASSERT(static_cast<size_t>(nextstate) < max_length.size());
1514 KALDI_ASSERT(nextstate > s &&
"CompactLattice has cycles");
1516 max_length[nextstate] = std::max(max_length[nextstate],
1517 this_max_length + 1);
1519 max_length[nextstate] = std::max(max_length[nextstate],
1523 lattice_max_length = std::max(lattice_max_length, max_length[s]);
1525 return lattice_max_length;
1536 typedef std::pair<StateId, StateId> StatePair;
1537 typedef unordered_map<StatePair, StateId, PairHasher<StateId> > MapType;
1538 typedef MapType::iterator IterType;
1542 composed_clat->DeleteStates();
1545 std::queue<StatePair> state_queue;
1548 StateId start_state = composed_clat->AddState();
1549 StatePair start_pair(clat.Start(), det_fst->
Start());
1550 composed_clat->SetStart(start_state);
1551 state_queue.push(start_pair);
1552 std::pair<IterType, bool> result =
1553 state_map.insert(std::make_pair(start_pair, start_state));
1557 while (!state_queue.empty()) {
1559 StatePair s = state_queue.front();
1560 StateId s1 = s.first;
1561 StateId s2 = s.second;
1565 Weight2 clat_final = clat.Final(s1);
1566 if (clat_final.Weight().Value1() !=
1567 std::numeric_limits<BaseFloat>::infinity()) {
1569 Weight1 det_fst_final = det_fst->
Final(s2);
1570 if (det_fst_final.Value() !=
1571 std::numeric_limits<BaseFloat>::infinity()) {
1576 Weight2 final_weight(
LatticeWeight(clat_final.Weight().Value1() +
1577 det_fst_final.Value(),
1578 clat_final.Weight().Value2()),
1579 clat_final.String());
1583 composed_clat->SetFinal(state_map[s], final_weight);
1588 for (fst::ArcIterator<CompactLattice> aiter(clat, s1);
1589 !aiter.Done(); aiter.Next()) {
1592 StateId next_state1 = arc1.nextstate, next_state2;
1593 bool matched =
false;
1595 if (arc1.olabel == 0) {
1602 matched = det_fst->
GetArc(s2, arc1.olabel, &arc2);
1604 next_state2 = arc2.nextstate;
1611 StatePair next_state_pair(next_state1, next_state2);
1612 IterType siter = state_map.find(next_state_pair);
1616 if (siter == state_map.end()) {
1618 next_state = composed_clat->AddState();
1619 std::pair<const StatePair, StateId> next_state_map(next_state_pair,
1621 std::pair<IterType, bool> result = state_map.insert(next_state_map);
1623 state_queue.push(next_state_pair);
1627 next_state = siter->second;
1631 if (arc1.olabel == 0) {
1632 composed_clat->AddArc(state_map[s],
1634 arc1.weight, next_state));
1636 Weight2 composed_weight(
1638 arc2.weight.Value(),
1639 arc1.weight.Weight().Value2()),
1640 arc1.weight.String());
1641 composed_clat->AddArc(state_map[s],
1643 composed_weight, next_state));
1648 fst::Connect(composed_clat);
1654 unordered_map<std::pair<int32, int32>, std::pair<BaseFloat, int32>,
1661 acoustic_scores->clear();
1663 std::vector<int32> state_times;
1668 for (StateId s = 0; s < lat.NumStates(); s++) {
1669 int32 t = state_times[s];
1670 for (fst::ArcIterator<Lattice> aiter(lat, s); !aiter.Done();
1672 const Arc &arc = aiter.Value();
1673 const LatticeWeight &weight = arc.weight;
1675 int32 tid = arc.ilabel;
1678 unordered_map<std::pair<int32, int32>, std::pair<BaseFloat, int32>,
1679 PairHasher<int32> >::iterator it = acoustic_scores->find(std::make_pair(t, tid));
1680 if (it == acoustic_scores->end()) {
1681 acoustic_scores->insert(std::make_pair(std::make_pair(t, tid),
1682 std::make_pair(weight.
Value2(), 1)));
1684 if (it->second.second == 2
1685 && it->second.first / it->second.second != weight.
Value2()) {
1686 KALDI_VLOG(2) <<
"Transitions on the same frame have different " 1687 <<
"acoustic costs for tid " << tid <<
"; " 1688 << it->second.first / it->second.second
1689 <<
" vs " << weight.
Value2();
1691 it->second.first += weight.
Value2();
1692 it->second.second++;
1700 LatticeWeight f = lat.Final(s);
1710 const unordered_map<std::pair<int32, int32>, std::pair<BaseFloat, int32>,
1720 std::vector<int32> state_times;
1725 for (StateId s = 0; s < lat->NumStates(); s++) {
1726 int32 t = state_times[s];
1727 for (fst::MutableArcIterator<Lattice> aiter(lat, s);
1728 !aiter.Done(); aiter.Next()) {
1729 Arc arc(aiter.Value());
1731 int32 tid = arc.ilabel;
1733 unordered_map<std::pair<int32, int32>, std::pair<BaseFloat, int32>,
1734 PairHasher<int32> >::const_iterator it = acoustic_scores.find(std::make_pair(t, tid));
1735 if (it == acoustic_scores.end()) {
1736 KALDI_ERR <<
"Could not find tid " << tid <<
" at time " << t
1737 <<
" in the acoustic scores map.";
1739 arc.weight.SetValue2(it->second.first / it->second.second);
1743 arc.weight.SetValue2(0.0);
1745 aiter.SetValue(arc);
1748 LatticeWeight f = lat->Final(s);
1752 lat->SetFinal(s, f);
fst::StdArc::StateId StateId
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.
fst::ArcTpl< LatticeWeight > LatticeArc
CompactLatticeArc::StateId state
virtual Weight Final(StateId s)=0
DecodableInterface provides a link between the (acoustic-modeling and feature-processing) code and th...
int32 LatticeStateTimes(const Lattice &lat, vector< int32 > *times)
This function iterates over the states of a topologically sorted lattice and counts the time instance...
double ComputeLatticeAlphasAndBetas(const LatticeType &lat, bool viterbi, vector< double > *alpha, vector< double > *beta)
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
bool WithProb(BaseFloat prob, struct RandomState *state)
void ReplaceAcousticScoresFromMap(const unordered_map< std::pair< int32, int32 >, std::pair< BaseFloat, int32 >, PairHasher< int32 > > &acoustic_scores, Lattice *lat)
This function restores acoustic scores computed using the function ComputeAcousticScoresMap into the ...
void TopSortLatticeIfNeeded(Lattice *lat)
Topologically sort the lattice if not already topologically sorted.
virtual bool IsLastFrame(int32 frame) const =0
Returns true if this is the last frame.
ClatRescoreTuple(int32 state, int32 arc, int32 tid)
void GetPerFrameAcousticCosts(const Lattice &nbest, Vector< BaseFloat > *per_frame_loglikes)
This function extracts the per-frame log likelihoods from a linear lattice (which we refer to as an '...
bool RescoreCompactLatticeSpeedup(const TransitionModel &tmodel, BaseFloat speedup_factor, DecodableInterface *decodable, CompactLattice *clat)
This function is like RescoreCompactLattice, but it is modified to avoid computing probabilities on m...
virtual StateId Start()=0
int32 TransitionIdToPdf(int32 trans_id) const
bool RescoreCompactLattice(DecodableInterface *decodable, CompactLattice *clat)
This function *adds* the negated scores obtained from the Decodable object, to the acoustic scores on...
void ConvertCompactLatticeToPhones(const TransitionModel &trans, CompactLattice *clat)
Given a lattice, and a transition model to map pdf-ids to phones, replace the sequences of transition...
fst::LatticeWeightTpl< BaseFloat > LatticeWeight
void LatticeActivePhones(const Lattice &lat, const TransitionModel &trans, const vector< int32 > &silence_phones, vector< std::set< int32 > > *active_phones)
Given a lattice, and a transition model to map pdf-ids to phones, outputs for each frame the set of p...
bool SplitToPhones(const TransitionModel &trans_model, const std::vector< int32 > &alignment, std::vector< std::vector< int32 > > *split_alignment)
SplitToPhones splits up the TransitionIds in "alignment" into their individual phones (one vector per...
void CompactLatticeShortestPath(const CompactLattice &clat, CompactLattice *shortest_path)
A form of the shortest-path/best-path algorithm that's specially coded for CompactLattice.
std::vector< std::vector< std::pair< int32, BaseFloat > > > Posterior
Posterior is a typedef for storing acoustic-state (actually, transition-id) posteriors over an uttera...
BaseFloat LatticeForwardBackwardMmi(const TransitionModel &tmodel, const Lattice &lat, const std::vector< int32 > &num_ali, bool drop_frames, bool convert_to_pdf_ids, bool cancel, Posterior *post)
This function can be used to compute posteriors for MMI, with a positive contribution for the numerat...
BaseFloat LatticeForwardBackward(const Lattice &lat, Posterior *post, double *acoustic_like_sum)
This function does the forward-backward over lattices and computes the posterior probabilities of the...
int32 NumTransitionIds() const
Returns the total number of transition-ids (note, these are one-based).
BaseFloat CompactLatticeDepth(const CompactLattice &clat, int32 *num_frames)
Returns the depth of the lattice, defined as the average number of arcs crossing any given frame...
bool ComputeCompactLatticeBetas(const CompactLattice &clat, vector< double > *beta)
double ConvertToCost(const LatticeWeightTpl< Float > &w)
int32 TransitionIdToHmmState(int32 trans_id) const
bool IsSelfLoop(int32 trans_id) const
static const LatticeWeightTpl Zero()
void ComposeCompactLatticeDeterministic(const CompactLattice &clat, fst::DeterministicOnDemandFst< fst::StdArc > *det_fst, CompactLattice *composed_clat)
This function Composes a CompactLattice format lattice with a DeterministicOnDemandFst<fst::StdFst> f...
void AlignmentToPosterior(const std::vector< int32 > &ali, Posterior *post)
Convert an alignment to a posterior (with a scale of 1.0 on each entry).
fst::VectorFst< LatticeArc > Lattice
int32 CompactLatticeStateTimes(const CompactLattice &lat, vector< int32 > *times)
As LatticeStateTimes, but in the CompactLattice format.
BaseFloat LatticeForwardBackwardMpeVariants(const TransitionModel &trans, const std::vector< int32 > &silence_phones, const Lattice &lat, const std::vector< int32 > &num_ali, std::string criterion, bool one_silence_class, Posterior *post)
This function implements either the MPFE (minimum phone frame error) or SMBR (state-level minimum bay...
bool RescoreCompactLatticeInternal(const TransitionModel *tmodel, BaseFloat speedup_factor, DecodableInterface *decodable, CompactLattice *clat)
RescoreCompactLatticeInternal is the internal code for both RescoreCompactLattice and RescoreCompatLa...
void AddWordInsPenToCompactLattice(BaseFloat word_ins_penalty, CompactLattice *clat)
This function add the word insertion penalty to graph score of each word in the compact lattice...
fst::VectorFst< CompactLatticeArc > CompactLattice
fst::StdArc::Weight Weight
bool operator<(const Int32Pair &a, const Int32Pair &b)
double LogAdd(double x, double y)
void ScalePosterior(BaseFloat scale, Posterior *post)
Scales the BaseFloat (weight) element in the posterior entries.
void ComputeAcousticScoresMap(const Lattice &lat, unordered_map< std::pair< int32, int32 >, std::pair< BaseFloat, int32 >, PairHasher< int32 > > *acoustic_scores)
This function computes the mapping from the pair (frame-index, transition-id) to the pair (sum-of-aco...
A class representing a vector.
bool PruneLattice(BaseFloat beam, LatType *lat)
#define KALDI_ASSERT(cond)
void CompactLatticeLimitDepth(int32 max_depth_per_frame, CompactLattice *clat)
This function limits the depth of the lattice, per frame: that means, it does not allow more than a s...
static const CompactLatticeWeightTpl< WeightType, IntType > Zero()
void MergePairVectorSumming(std::vector< std::pair< I, F > > *vec)
For a vector of pair<I, F> where I is an integer and F a floating-point or integer type...
bool LatticeBoost(const TransitionModel &trans, const std::vector< int32 > &alignment, const std::vector< int32 > &silence_phones, BaseFloat b, BaseFloat max_silence_error, Lattice *lat)
Boosts LM probabilities by b * [number of frame errors]; equivalently, adds -b*[number of frame error...
fst::ArcTpl< CompactLatticeWeight > CompactLatticeArc
void TopSortCompactLatticeIfNeeded(CompactLattice *clat)
Topologically sort the compact lattice if not already topologically sorted.
void CompactLatticeDepthPerFrame(const CompactLattice &clat, std::vector< int32 > *depth_per_frame)
This function returns, for each frame, the number of arcs crossing that frame.
void ConvertLatticeToPhones(const TransitionModel &trans, Lattice *lat)
Given a lattice, and a transition model to map pdf-ids to phones, replace the output symbols (presuma...
This is used in CompactLatticeLimitDepth.
void ConvertPosteriorToPdfs(const TransitionModel &tmodel, const Posterior &post_in, Posterior *post_out)
Converts a posterior over transition-ids to be a posterior over pdf-ids.
bool ComputeCompactLatticeAlphas(const CompactLattice &clat, vector< double > *alpha)
int32 MergePosteriors(const Posterior &post1, const Posterior &post2, bool merge, bool drop_frames, Posterior *post)
Merge two sets of posteriors, which must have the same length.
virtual BaseFloat LogLikelihood(int32 frame, int32 index)=0
Returns the log likelihood, which will be negated in the decoder.
bool IsSortedAndUniq(const std::vector< T > &vec)
Returns true if the vector is sorted and contains each element only once.
const double kLogZeroDouble
static double LogAddOrMax(bool viterbi, double a, double b)
bool IsFinal(int32 trans_id) const
int32 TransitionIdToPhone(int32 trans_id) const
bool RescoreLattice(DecodableInterface *decodable, Lattice *lat)
This function *adds* the negated scores obtained from the Decodable object, to the acoustic scores on...
Represents a non-allocating general vector which can be defined as a sub-vector of higher-level vecto...
static bool ApproxEqual(float a, float b, float relative_tolerance=0.001)
return abs(a - b) <= relative_tolerance * (abs(a)+abs(b)).
int32 LongestSentenceLength(const Lattice &lat)
This function returns the number of words in the longest sentence in a CompactLattice (i...
bool CompactLatticeToWordAlignment(const CompactLattice &clat, std::vector< int32 > *words, std::vector< int32 > *begin_times, std::vector< int32 > *lengths)
This function takes a CompactLattice that should only contain a single linear sequence (e...
bool CompactLatticeToWordProns(const TransitionModel &tmodel, const CompactLattice &clat, std::vector< int32 > *words, std::vector< int32 > *begin_times, std::vector< int32 > *lengths, std::vector< std::vector< int32 > > *prons, std::vector< std::vector< int32 > > *phone_lengths)
This function takes a CompactLattice that should only contain a single linear sequence (e...
void SetWeight(const W &w)
A hashing function-object for pairs of ints.