17 #ifndef NLP_GRM2_SFST_NORMALIZE_H_ 18 #define NLP_GRM2_SFST_NORMALIZE_H_ 20 #include <sys/types.h> 29 #include <fst/float-weight.h> 31 #include <fst/matcher.h> 32 #include <fst/mutable-fst.h> 34 #include <fst/weight.h> 41 #include <fst/compat.h> 53 typename Arc::StateId s,
54 typename Arc::Label phi_label,
55 fst::Log64Weight *high_sum,
56 fst::Log64Weight *low_sum,
57 fst::Log64Weight *phi_weight,
58 ssize_t *phi_position) {
60 typedef typename Arc::StateId StateId;
61 typedef typename Arc::Label Label;
62 typedef typename Arc::Weight Weight;
63 typedef f::ArcIterator<f::Fst<Arc>> ArcItr;
64 typedef f::ExplicitMatcher<f::Matcher<f::Fst<Arc>>> Matr;
66 f::WeightConvert<Weight, f::Log64Weight> to_log64;
67 f::Adder<f::Log64Weight> high_adder(to_log64(fst.Final(s)));
68 f::Adder<f::Log64Weight> low_adder;
69 *phi_weight = f::Log64Weight::Zero();
75 Weight fail_weight = Weight::One();
76 for (
size_t i = 0; i < failpath.
Length(); ++i) {
78 *phi_weight = to_log64(failpath.
GetWeight(i));
80 if (high_adder.Sum() == f::Log64Weight::Zero())
break;
85 if (
final != Weight::Zero()) {
86 low_adder.Reset(to_log64(
f::Times(fail_weight,
final)));
91 Matr matcher(fst, f::MATCH_INPUT);
92 Label prev_label = f::kNoLabel;
93 for (ArcItr aiter(fst, s); !aiter.Done(); aiter.Next()) {
94 const Arc &high_arc = aiter.Value();
95 Label label = high_arc.ilabel;
96 if (label != phi_label) {
97 f::Log64Weight high_weight = to_log64(high_arc.weight);
98 high_adder.Add(high_weight);
100 fail_weight = Weight::One();
101 bool matched = label == prev_label;
102 for (
size_t i = 0; i < failpath.
Length() && !matched; ++i) {
106 for (matcher.Find(label); !matcher.Done(); matcher.Next()) {
107 const Arc &low_arc = matcher.Value();
108 f::Log64Weight low_weight =
109 to_log64(
Times(fail_weight, low_arc.weight));
110 low_adder.Add(low_weight);
118 *high_sum = high_adder.Sum();
119 *low_sum = low_adder.Sum();
125 typename Arc::StateId s,
126 typename Arc::Label phi_label,
129 f::Log64Weight high_sum, low_sum, phi_weight;
130 ssize_t phi_position;
131 StateSums(fst, s, phi_label, &high_sum, &low_sum,
132 &phi_weight, &phi_position);
134 bool high_sum_le_one =
Less(high_sum, f::Log64Weight::One()) ||
135 ApproxEqual(high_sum, f::Log64Weight::One(), delta);
138 bool phi_norm = f::ApproxEqual(f::Plus(high_sum, phi_weight),
139 f::Plus(
f::Times(phi_weight, low_sum),
140 f::Log64Weight::One()),
142 bool ret = high_sum_le_one && phi_norm;
144 VLOG(1) <<
"IsNormalized: State not normalized: " << s
145 <<
" high_sum: " << high_sum
146 <<
" low_sum: " << low_sum
147 <<
" phi_weight: " << phi_weight;
160 typename Arc::Label phi_label = fst::kNoLabel,
161 float delta = fst::kDelta) {
163 typedef typename Arc::StateId StateId;
164 typedef f::StateIterator<f::Fst<Arc>> StateItr;
167 for (StateItr siter(fst); !siter.Done(); siter.Next()) {
168 StateId s = siter.Value();
184 typename Arc::Label phi_label = fst::kNoLabel,
185 float delta = fst::kDelta) {
187 typedef typename Arc::Weight Weight;
190 LOG(ERROR) <<
"GlobalNormalize: input is not a canonical stochastic FST";
194 std::vector<Weight> distance;
195 const auto total_weight =
197 if (!total_weight.Member())
199 f::Reweight(fst, distance, f::REWEIGHT_TO_INITIAL);
200 f::RemoveWeight(fst, total_weight,
false);
214 fst::MutableFst<Arc> *
fst) {
216 typedef typename Arc::Weight Weight;
218 f::WeightConvert<Weight, f::Log64Weight> to_log64;
219 f::WeightConvert<f::Log64Weight, Weight> from_log64;
220 if (s < 0 || s >= fst->NumStates()) {
223 Weight
final = fst->Final(s);
225 f::Adder<f::Log64Weight> adder(to_log64(
final));
226 for (f::ArcIterator<f::MutableFst<Arc>> aiter(*fst, s); !aiter.Done();
228 const Arc &arc = aiter.Value();
229 f::Log64Weight weight = to_log64(arc.weight);
234 Weight sum = from_log64(adder.Sum());
235 if (
final != Weight::Zero()) fst->SetFinal(s, Divide(
final, sum));
236 for (f::MutableArcIterator<f::MutableFst<Arc>> aiter(fst, s); !aiter.Done();
238 Arc arc = aiter.Value();
239 arc.weight = Divide(arc.weight, sum);
256 typedef typename Arc::StateId StateId;
259 LOG(ERROR) <<
"LocalNormalize: input is not a canonical stochastic FST";
263 for (StateId s = 0; s < fst->NumStates(); ++s) {
276 typename Arc::Label phi_label = fst::kNoLabel) {
278 typedef typename Arc::StateId StateId;
279 typedef typename Arc::Weight Weight;
280 typedef f::MutableArcIterator<f::MutableFst<Arc>> MArcItr;
282 f::WeightConvert<f::Log64Weight, Weight> from_log64;
283 f::WeightConvert<Weight, f::Log64Weight> to_log64;
284 if (s < 0 || s >= fst->NumStates()) {
287 MArcItr aiter(fst, s);
288 f::Log64Weight high_sum, low_sum, phi_weight;
289 ssize_t phi_position;
290 StateSums(*fst, s, phi_label, &high_sum, &low_sum, &phi_weight,
295 if (
ApproxZero(high_sum) && (phi_position == -1 || fst->NumArcs(s) != 1)) {
299 bool low_sum_ge_one =
300 Less(f::Log64Weight::One(), low_sum) ||
301 ApproxEqual(low_sum, f::Log64Weight::One(), kNormDelta);
302 bool high_sum_eq_one =
303 ApproxEqual(high_sum, f::Log64Weight::One(), kNormDelta);
304 bool high_sum_gt_one =
Less(f::Log64Weight::One(), high_sum);
307 if (low_sum_ge_one || high_sum_gt_one ||
308 (high_sum_eq_one && phi_position != -1) ||
309 (!high_sum_eq_one && phi_position == -1)) {
310 for (; !aiter.Done(); aiter.Next()) {
311 Arc arc = aiter.Value();
312 if (arc.ilabel != phi_label) {
313 arc.weight = from_log64(Divide(to_log64(arc.weight), high_sum));
317 Weight
final = fst->Final(s);
318 if (
final != Weight::Zero()) {
319 final = from_log64(Divide(to_log64(
final), high_sum));
320 fst->SetFinal(s,
final);
322 high_sum = f::Log64Weight::One();
325 if (phi_position != -1) {
326 if (high_sum == f::Log64Weight::One()) {
329 f::Log64Weight numer =
Minus(f::Log64Weight::One(), high_sum);
330 f::Log64Weight denom =
Minus(f::Log64Weight::One(), low_sum);
331 phi_weight = f::Divide(numer, denom);
333 aiter.Seek(phi_position);
334 Arc arc = aiter.Value();
335 arc.weight = from_log64(phi_weight);
349 typename Arc::Label phi_label = fst::kNoLabel) {
351 typedef typename Arc::StateId StateId;
352 typedef typename Arc::Weight Weight;
354 std::vector<StateId> top_order;
355 if (phi_label == f::kNoLabel)
return true;
357 LOG(ERROR) <<
"PhiNormalize: input is not a canonical stochastic FST";
361 for (StateId i = top_order.size() - 1; i >= 0; --i) {
362 StateId s = top_order[i];
377 "Use `NORM_KL_MIN_APPROXIMATED` instead.") = 2,
392 using ArcItr = fst::ArcIterator<fst::Fst<Arc>>;
393 using MArcItr = fst::MutableArcIterator<fst::MutableFst<Arc>>;
394 using Matr = fst::ExplicitMatcher<fst::Matcher<fst::Fst<Arc>>>;
400 : phi_label_(phi_label),
403 effective_zero_(1.0, effective_zero),
404 maxiters_(maxiters) { }
421 : count(SLWeight::Zero()),
422 fail_count(SLWeight::Zero()),
423 denom(SLWeight::Zero()) { }
430 std::vector<StateId> hi_states;
434 void InitStates(
const fst::ExpandedFst<Arc> &fst);
439 fst::MutableFst<Arc> *fst);
444 bool ComputeNormFactor(
const fst::ExpandedFst<Arc> &fst,
445 StateId s, std::vector<SLWeight> *norm_factor)
const;
454 const std::vector<SLWeight> &norm_factor,
456 std::vector<SLWeight> *arc_weights)
const;
461 bool LambdaSearch(
const fst::ExpandedFst<Arc> &fst,
463 const std::vector<SLWeight> &norm_factor,
464 std::vector<SLWeight> *arc_weights)
const;
468 bool InitArcWeights(
const fst::ExpandedFst<Arc> &fst,
469 StateId s, std::vector<SLWeight> *arc_weights)
const;
473 bool ComputeDenom(
const fst::ExpandedFst<Arc> &fst,
StateId s,
474 const std::vector<SLWeight> &arc_weights);
478 size_t NumNonPhiArcs(
const fst::Fst<Arc> &fst,
StateId s)
const {
479 size_t narcs = fst.NumArcs(s);
480 if (fst.Final(s) != Weight::Zero()) ++narcs;
481 if (backoff_->GetBackoffPosition(s) != -1) --narcs;
486 bool IsEffectiveZero(
SLWeight w)
const {
487 return ApproxZero(w, effective_zero_.Value2());
490 const Label phi_label_;
494 const size_t maxiters_;
496 std::unique_ptr<Backoff<Arc>> backoff_;
497 std::vector<NormState> norm_states_;
498 fst::WeightConvert<SLWeight, Weight> from_log_;
499 fst::WeightConvert<Weight, SLWeight> to_log_;
507 fst::MutableFst<Arc> *
fst) {
513 LOG(ERROR) <<
"CountNormalize: backoff summation failed";
522 const Weight trim_weight = from_log_(effective_zero_);
530 if (fst->Properties(f::kError,
false))
return false;
534 if (phi_label_ == f::kNoLabel || norm_type ==
NORM_SUMMED) {
536 LOG(ERROR) <<
"CountNormalizer: local normalization failed";
542 for (
StateId i = 0; i < fst->NumStates(); ++i) {
543 StateId s = backoff_->GetPhiTopOrder(i);
544 if (!KLMinimizeState(s, norm_type, fst))
return false;
548 if (phi_label_ != f::kNoLabel && !
PhiNormalize(fst, phi_label_)) {
549 LOG(ERROR) <<
"CountNormalizer: phi normalization failed";
557 const fst::ExpandedFst<Arc> &
fst) {
559 backoff_ = std::make_unique<Backoff<Arc>>(fst, phi_label_);
561 norm_states_.clear();
562 norm_states_.resize(fst.NumStates());
563 for (
StateId i = fst.NumStates() - 1; i >= 0; --i) {
564 const StateId s = backoff_->GetPhiTopOrder(i);
565 NormState &state = norm_states_[s];
566 f::Adder<SLWeight> adder(to_log_(fst.Final(s)));
567 for (
ArcItr aiter(fst, s); !aiter.Done(); aiter.Next()) {
568 const Arc &arc = aiter.Value();
569 if (arc.ilabel == phi_label_)
570 state.fail_count = to_log_(arc.weight);
571 adder.Add(to_log_(arc.weight));
573 state.count = adder.Sum();
574 const StateId bos = backoff_->GetBackoffState(s);
575 if (bos != f::kNoStateId) {
576 NormState &bo_state = norm_states_[bos];
578 bo_state.hi_states.push_back(s);
590 std::vector<SLWeight> arc_weights(fst->NumArcs(s) + 1, SLWeight::Zero());
591 std::vector<SLWeight> prev_arc_weights;
592 std::vector<SLWeight> norm_factor(fst->NumArcs(s) + 1, SLWeight::Zero());
594 if (InitArcWeights(*fst, s, &arc_weights)) {
595 if (!ComputeDenom(*fst, s, arc_weights))
599 prev_arc_weights = arc_weights;
600 if (!ComputeNormFactor(*fst, s, &norm_factor))
603 if (!LambdaSearch(*fst, s, norm_type, norm_factor, &arc_weights)) {
604 LOG(ERROR) <<
"CountNormalizer: lambda iterations failed";
607 if (!ComputeDenom(*fst, s, arc_weights))
609 if (++iters > maxiters_) {
610 LOG(WARNING) <<
"CountNormalizer: max DC iterations exceeded:" 621 f::Adder<SLWeight> adder;
622 for (
MArcItr aiter(fst, s); !aiter.Done(); aiter.Next(), ++pos) {
623 Arc arc = aiter.Value();
624 if (
Less(arc_weights[pos], SLWeight::Zero())) {
625 LOG(ERROR) <<
"CountNormalizer: bad arc weight: " << arc_weights[pos];
628 arc.weight = from_log_(arc_weights[pos]);
630 adder.Add(arc_weights[pos]);
633 if (
Less(arc_weights[pos], SLWeight::Zero())) {
634 LOG(ERROR) <<
"CountNormalizer: bad final weight: " << arc_weights[pos];
637 fst->SetFinal(s, from_log_(arc_weights[pos]));
638 adder.Add(arc_weights[pos]);
641 if (
Less(SLWeight::One(), adder.Sum()) &&
642 !ApproxEqual(SLWeight::One(), adder.Sum())) {
643 LOG(ERROR) <<
"CountNormalizer: bad state sum: " << adder.Sum();
651 const fst::ExpandedFst<Arc> &fst,
StateId s,
652 std::vector<SLWeight> *norm_factor)
const {
656 const NormState &state = norm_states_[s];
658 std::fill(norm_factor->begin(), norm_factor->end(), SLWeight::Zero());
660 for (
auto his : state.hi_states) {
662 if (NumNonPhiArcs(fst, s) == NumNonPhiArcs(fst, his))
664 const NormState &hi_state = norm_states_[his];
666 const SLWeight hi_weight = Divide(hi_state.fail_count, hi_state.denom);
667 for (
size_t hipos = 0; hipos < fst.NumArcs(his); ++hipos) {
668 const ssize_t pos = backoff_->GetBackedOffArc(his, hipos);
671 (*norm_factor)[pos] = Plus((*norm_factor)[pos], hi_weight);
675 if (fst.Final(his) != Weight::Zero()) {
676 const ssize_t pos = fst.NumArcs(s);
677 (*norm_factor)[pos] = Plus((*norm_factor)[pos], hi_weight);
686 const std::vector<SLWeight> &norm_factor,
SLWeight lambda,
687 std::vector<SLWeight> *arc_weights)
const {
692 f::Adder<SLWeight> adder;
693 for (
ArcItr aiter(fst, s); !aiter.Done(); aiter.Next(), ++pos) {
694 const Arc &arc = aiter.Value();
700 const SLWeight arc_weight = to_log_(arc.weight);
701 if (IsEffectiveZero(arc_weight)) {
703 (*arc_weights)[pos] = effective_zero_;
707 (*arc_weights)[pos] = Divide(arc_weight, norm);
708 if (IsEffectiveZero((*arc_weights)[pos])) {
710 (*arc_weights)[pos] = effective_zero_;
714 adder.Add((*arc_weights)[pos]);
717 if (fst.Final(s) != Weight::Zero()) {
719 const SLWeight final_weight = to_log_(fst.Final(s));
722 if (IsEffectiveZero(final_weight)) {
724 (*arc_weights)[pos] = effective_zero_;
727 (*arc_weights)[pos] = Divide(final_weight, norm);
729 if (IsEffectiveZero((*arc_weights)[pos]))
730 (*arc_weights)[pos] = effective_zero_;
732 adder.Add((*arc_weights)[pos]);
739 const fst::ExpandedFst<Arc> &fst,
StateId s,
740 CountNormType norm_type,
const std::vector<SLWeight> &norm_factor,
741 std::vector<SLWeight> *arc_weights)
const {
746 SLWeight lambda_low = SLWeight::Zero();
747 SLWeight lambda_hi = SLWeight::Zero();
748 for (
ArcItr aiter(fst, s); !aiter.Done(); aiter.Next(), ++pos) {
749 SLWeight cx = to_log_(aiter.Value().weight);
752 if (
Less(maxfx, fx)) maxfx = fx;
753 if (
Less(lambda_low, cfx)) lambda_low = cfx;
754 lambda_hi = Plus(lambda_hi, cx);
756 const SLWeight final_cx = to_log_(fst.Final(s));
757 const SLWeight final_fx = norm_factor[pos];
758 const SLWeight final_cfx = Plus(final_fx, final_cx);
759 if (
Less(maxfx, final_fx)) maxfx = final_fx;
760 if (
Less(lambda_low, final_cfx)) lambda_low = final_cfx;
761 lambda_hi = Plus(Plus(lambda_hi, final_cx), maxfx);
763 if (
Less(lambda_hi, lambda_low)) {
764 if (ApproxEqual(lambda_low, lambda_hi,
kNormDelta)) {
765 lambda_low = lambda_hi;
767 LOG(ERROR) <<
"CountNormalizer: bad lambda parameter limits:" 769 <<
" lambda_low: " << lambda_low
770 <<
" lambda_hi: " << lambda_hi;
775 const SLWeight two = Plus(SLWeight::One(), SLWeight::One());
778 const SLWeight lambda = Divide(Plus(lambda_hi, lambda_low), two);
780 NormArcWeights(fst, s, norm_type, norm_factor, lambda, arc_weights);
781 if (ApproxEqual(arc_sum, SLWeight::One(), delta_) ||
782 ApproxEqual(lambda_low, lambda_hi,
kNormDelta)) {
784 }
else if (
Less(arc_sum, SLWeight::One())) {
789 if (++iters > maxiters_) {
790 LOG(ERROR) <<
"CountNormalizer: max (lambda) iterations exceeded:" 792 <<
" lambda_low: " << lambda_low
793 <<
" lambda_hi: " << lambda_hi
794 <<
" arc_sum: " << arc_sum;
802 const fst::ExpandedFst<Arc> &fst,
803 StateId s, std::vector<SLWeight> *arc_weights)
const {
804 const NormState &state = norm_states_[s];
807 std::fill(arc_weights->begin(), arc_weights->end(), SLWeight::Zero());
810 ssize_t num_arcs = fst.NumArcs(s);
811 if (fst.Final(s) != Weight::Zero())
814 to_log_(-std::log(static_cast<double>(num_arcs)));
816 if (IsEffectiveZero(state.count)) {
819 for (
size_t pos = 0; pos < num_arcs; ++pos)
820 (*arc_weights)[pos] = Divide(SLWeight::One(), num_arcs_weight);
826 Times(num_arcs_weight, effective_zero_));
828 for (
ArcItr aiter(fst, s);
830 aiter.Next(), ++pos) {
831 const Arc &arc = aiter.Value();
832 const SLWeight arc_weight = Divide(to_log_(arc.weight), state.count);
833 (*arc_weights)[pos] = Plus(
Times(arc_weight, arc_mult), effective_zero_);
835 if (fst.Final(s) != Weight::Zero()) {
836 const SLWeight final_weight = Divide(to_log_(fst.Final(s)), state.count);
837 (*arc_weights)[pos] =
838 Plus(
Times(final_weight, arc_mult), effective_zero_);
846 const fst::ExpandedFst<Arc> &fst,
StateId s,
847 const std::vector<SLWeight> &arc_weights) {
849 NormState &state = norm_states_[s];
850 for (
auto his : state.hi_states) {
851 NormState &hi_state = norm_states_[his];
852 f::Adder<SLWeight> adder;
854 for (
size_t hipos = 0; hipos < fst.NumArcs(his); ++hipos) {
855 const ssize_t pos = backoff_->GetBackedOffArc(his, hipos);
857 adder.Add(arc_weights[pos]);
859 if (fst.Final(his) != Weight::Zero()) {
860 const ssize_t pos = fst.NumArcs(s);
861 adder.Add(arc_weights[pos]);
863 hi_state.denom =
Minus(SLWeight::One(), adder.Sum());
865 if (
Less(hi_state.denom, effective_zero_)) {
871 Matr matcher(fst, f::MATCH_INPUT);
872 matcher.SetState(his);
874 for (
ArcItr aiter(fst, s); !aiter.Done(); aiter.Next(), ++pos) {
875 const Arc &arc = aiter.Value();
876 if (arc.ilabel == phi_label_ || !matcher.Find(arc.ilabel))
877 adder.Add(arc_weights[pos]);
879 if (fst.Final(his) == Weight::Zero())
880 adder.Add(arc_weights[pos]);
881 hi_state.denom = adder.Sum();
884 if (IsEffectiveZero(hi_state.denom)) {
889 hi_state.denom = effective_zero_;
890 }
else if (
Less(hi_state.denom, SLWeight::Zero())) {
891 LOG(ERROR) <<
"CountNormalizer: bad backoff denominator: " 893 <<
" state: " << s <<
" high state: " << his;
929 fst::MutableFst<Arc> *
fst,
930 typename Arc::Label phi_label,
937 effective_zero, maxiters);
938 return normalizer.
Normalize(norm_type, fst);
948 typename Arc::Label phi_label = fst::kNoLabel,
949 float delta = fst::kDelta) {
951 typedef typename Arc::StateId
StateId;
952 typedef typename Arc::Weight
Weight;
955 LOG(ERROR) <<
"Condition: conditioning delta is negative";
959 f::WeightConvert<f::Log64Weight, Weight> from_log64;
960 Weight weight = from_log64(delta);
963 for (StateId s = 0; s < fst->NumStates(); ++s) {
964 for (f::MutableArcIterator<f::MutableFst<Arc>> aiter(fst, s);
967 Arc arc = aiter.Value();
969 if (arc.ilabel == phi_label || arc.ilabel == 0)
971 arc.weight =
Times(arc.weight, weight);
980 #endif // NLP_GRM2_SFST_NORMALIZE_H_
bool Less(fst::LogWeightTpl< T > weight1, fst::LogWeightTpl< T > weight2)
bool LocalNormalizeState(typename Arc::StateId s, fst::MutableFst< Arc > *fst)
static constexpr size_t kMaxNormIters
void StateSums(const fst::Fst< Arc > &fst, typename Arc::StateId s, typename Arc::Label phi_label, fst::Log64Weight *high_sum, fst::Log64Weight *low_sum, fst::Log64Weight *phi_weight, ssize_t *phi_position)
Weight GetWeight(size_t i) const
Entropy64Weight Minus(Entropy64Weight w1, Entropy64Weight w2)
bool CountNormalize(fst::MutableFst< Arc > *fst, typename Arc::Label phi_label, CountNormType norm_type=NORM_SUMMED, bool trim=false, float delta=internal::CountNormalizer< Arc >::kNormDelta, double effective_zero=internal::CountNormalizer< Arc >::kEffectiveZero, size_t maxiters=internal::CountNormalizer< Arc >::kMaxNormIters)
fst::SignedLog64Weight SLWeight
bool ApproxZero(fst::Log64Weight weight, fst::Log64Weight approx_zero=kApproxZeroWeight)
bool SumBackoff(fst::MutableFst< Arc > *fst, typename Arc::Label phi_label)
bool Condition(fst::MutableFst< Arc > *fst, typename Arc::Label phi_label=fst::kNoLabel, float delta=fst::kDelta)
bool Normalize(CountNormType norm_type, fst::MutableFst< Arc > *fst)
bool LocalNormalize(fst::MutableFst< Arc > *fst)
bool IsCanonical(const fst::Fst< Arc > &fst, typename Arc::Label phi_label, std::vector< typename Arc::StateId > *top_order)
Arc::Weight ShortestDistance(const fst::Fst< Arc > &fst, std::vector< typename Arc::Weight > *distance, typename Arc::Label phi_label=fst::kNoLabel, bool reverse=false, float delta=fst::kShortestDelta)
StateId GetNextState(size_t i) const
bool IsNormalizedState(const fst::Fst< Arc > &fst, typename Arc::StateId s, typename Arc::Label phi_label, float delta)
void WeightTrim(bool include_phi, Weight approx_zero=ApproxZeroWeight())
fst::ArcIterator< fst::Fst< Arc >> ArcItr
size_t GetPosition(size_t i) const
bool IsNormalized(const fst::Fst< Arc > &fst, typename Arc::Label phi_label=fst::kNoLabel, float delta=fst::kDelta)
CountNormalizer(Label phi_label, bool trim=false, float delta=kNormDelta, double effective_zero=kEffectiveZero, size_t maxiters=kMaxNormIters)
bool PhiNormalize(fst::MutableFst< Arc > *fst, typename Arc::Label phi_label=fst::kNoLabel)
const fst::Log64Weight kApproxZeroWeight
fst::MutableArcIterator< fst::MutableFst< Arc >> MArcItr
typename Arc::StateId StateId
void SumWeightTrim(bool include_phi, Weight approx_zero=ApproxZeroWeight())
fst::ExplicitMatcher< fst::Matcher< fst::Fst< Arc >>> Matr
typename Arc::Weight Weight
constexpr double kNormDelta
void NormWeights(std::vector< Weight > *weights)
bool GlobalNormalize(fst::MutableFst< Arc > *fst, typename Arc::Label phi_label=fst::kNoLabel, float delta=fst::kDelta)
static constexpr float kNormDelta
bool ApproxEqualWeights(const std::vector< Weight > &weights1, const std::vector< Weight > &weights2, float delta=fst::kDelta, Weight approx_zero=Weight::NoWeight())
static constexpr double kEffectiveZero
Real64Weight Times(SignedLog64Weight w1, Real64Weight w2)
bool PhiNormalizeState(typename Arc::StateId s, fst::MutableFst< Arc > *fst, typename Arc::Label phi_label=fst::kNoLabel)
typename Arc::Label Label