Blame view
tools/openfst-1.6.7/include/fst/expectation-weight.h
4.5 KB
8dcb6dfcb first commit |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
// See www.openfst.org for extensive documentation on this weighted // finite-state transducer library. // // Expectation semiring as described by Jason Eisner: // See: doi=10.1.1.22.9398 // Multiplex semiring operations and identities: // One: <One, Zero> // Zero: <Zero, Zero> // Plus: <a1, b1> + <a2, b2> = < (a1 + a2) , (b1 + b2) > // Times: <a1, b1> * <a2, b2> = < (a1 * a2) , [(a1 * b2) + (a2 * b1)] > // Division: Undefined (currently) // // Usually used to store the pair <probability, random_variable> so that // ShortestDistance[Fst<ArcTpl<ExpectationWeight<P, V>>>] // == < PosteriorProbability, Expected_Value[V] > #ifndef FST_EXPECTATION_WEIGHT_H_ #define FST_EXPECTATION_WEIGHT_H_ #include <string> #include <fst/log.h> #include <fst/pair-weight.h> #include <fst/product-weight.h> namespace fst { // X1 is usually a probability weight like LogWeight. // X2 is usually a random variable or vector (see SignedLogWeight or // SparsePowerWeight). // // If X1 is distinct from X2, it is required that there is an external product // between X1 and X2 and if both semriring are commutative, or left or right // semirings, then result must have those properties. template <class X1, class X2> class ExpectationWeight : public PairWeight<X1, X2> { public: using PairWeight<X1, X2>::Value1; using PairWeight<X1, X2>::Value2; using PairWeight<X1, X2>::Reverse; using PairWeight<X1, X2>::Quantize; using PairWeight<X1, X2>::Member; using ReverseWeight = ExpectationWeight<typename X1::ReverseWeight, typename X2::ReverseWeight>; ExpectationWeight() : PairWeight<X1, X2>(Zero()) {} ExpectationWeight(const ExpectationWeight &weight) : PairWeight<X1, X2>(weight) {} explicit ExpectationWeight(const PairWeight<X1, X2> &weight) : PairWeight<X1, X2>(weight) {} ExpectationWeight(const X1 &x1, const X2 &x2) : PairWeight<X1, X2>(x1, x2) {} static const ExpectationWeight &Zero() { static const ExpectationWeight zero(X1::Zero(), X2::Zero()); return zero; } static const ExpectationWeight &One() { static const ExpectationWeight one(X1::One(), X2::Zero()); return one; } static const ExpectationWeight &NoWeight() { static const ExpectationWeight no_weight(X1::NoWeight(), X2::NoWeight()); return no_weight; } static const string &Type() { static const string *const type = new string("expectation_" + X1::Type() + "_" + X2::Type()); return *type; } PairWeight<X1, X2> Quantize(float delta = kDelta) const { return ExpectationWeight(PairWeight<X1, X2>::Quantize()); } ReverseWeight Reverse() const { return ReverseWeight(PairWeight<X1, X2>::Reverse()); } bool Member() const { return PairWeight<X1, X2>::Member(); } static constexpr uint64 Properties() { return X1::Properties() & X2::Properties() & (kLeftSemiring | kRightSemiring | kCommutative | kIdempotent); } }; template <class X1, class X2> inline ExpectationWeight<X1, X2> Plus(const ExpectationWeight<X1, X2> &w1, const ExpectationWeight<X1, X2> &w2) { return ExpectationWeight<X1, X2>(Plus(w1.Value1(), w2.Value1()), Plus(w1.Value2(), w2.Value2())); } template <class X1, class X2> inline ExpectationWeight<X1, X2> Times(const ExpectationWeight<X1, X2> &w1, const ExpectationWeight<X1, X2> &w2) { return ExpectationWeight<X1, X2>( Times(w1.Value1(), w2.Value1()), Plus(Times(w1.Value1(), w2.Value2()), Times(w1.Value2(), w2.Value1()))); } template <class X1, class X2> inline ExpectationWeight<X1, X2> Divide(const ExpectationWeight<X1, X2> &w1, const ExpectationWeight<X1, X2> &w2, DivideType typ = DIVIDE_ANY) { FSTERROR() << "ExpectationWeight::Divide: Not implemented"; return ExpectationWeight<X1, X2>::NoWeight(); } // This function object generates weights by calling the underlying generators // for the template weight types, like all other pair weight types. This is // intended primarily for testing. template <class X1, class X2> class WeightGenerate<ExpectationWeight<X1, X2>> : public WeightGenerate<PairWeight<X1, X2>> { public: using Weight = ExpectationWeight<X1, X2>; using Generate = WeightGenerate<PairWeight<X1, X2>>; explicit WeightGenerate(bool allow_zero = true) : Generate(allow_zero) {} Weight operator()() const { return Weight(Generate::operator()()); } }; } // namespace fst #endif // FST_EXPECTATION_WEIGHT_H_ |