1 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 // 14 // Copyright 2005-2010 Google, Inc. 15 // Author: krr (at) google.com (Kasturi Rangan Raghavan) 16 // Inspiration: shumash (at) google.com (Masha Maria Shugrina) 17 // \file 18 // Expectation semiring as described by Jason Eisner: 19 // See: doi=10.1.1.22.9398 20 // Multiplex semiring operations and identities: 21 // One: <One, Zero> 22 // Zero: <Zero, Zero> 23 // Plus: <a1, b1> + <a2, b2> = < (a1 + a2) , (b1 + b2) > 24 // Times: <a1, b1> * <a2, b2> = < (a1 * a2) , [(a1 * b2) + (a2 * b1)] > 25 // Division: Undefined (currently) 26 // 27 // Usually used to store the pair <probability, random_variable> so that 28 // ShortestDistance[Fst<ArcTpl<ExpectationWeight<P, V> > >] 29 // == < PosteriorProbability, Expected_Value[V] > 30 31 #ifndef FST_LIB_EXPECTATION_WEIGHT_H_ 32 #define FST_LIB_EXPECTATION_WEIGHT_H_ 33 34 #include<string> 35 36 #include <fst/pair-weight.h> 37 38 39 namespace fst { 40 41 // X1 is usually a probability weight like LogWeight 42 // X2 is usually a random variable or vector 43 // see SignedLogWeight or SparsePowerWeight 44 // 45 // If X1 is distinct from X2, it is required that there is an external 46 // product between X1 and X2 and if both semriring are commutative, or 47 // left or right semirings, then result must have those properties. 48 template <class X1, class X2> 49 class ExpectationWeight : public PairWeight<X1, X2> { 50 public: 51 using PairWeight<X1, X2>::Value1; 52 using PairWeight<X1, X2>::Value2; 53 54 using PairWeight<X1, X2>::Reverse; 55 using PairWeight<X1, X2>::Quantize; 56 using PairWeight<X1, X2>::Member; 57 58 typedef X1 W1; 59 typedef X2 W2; 60 61 typedef ExpectationWeight<typename X1::ReverseWeight, 62 typename X2::ReverseWeight> ReverseWeight; 63 64 ExpectationWeight() : PairWeight<X1, X2>(Zero()) { } 65 66 ExpectationWeight(const ExpectationWeight<X1, X2>& w) 67 : PairWeight<X1, X2> (w) { } 68 69 ExpectationWeight(const PairWeight<X1, X2>& w) 70 : PairWeight<X1, X2> (w) { } 71 72 ExpectationWeight(const X1& x1, const X2& x2) 73 : PairWeight<X1, X2>(x1, x2) { } 74 75 static const ExpectationWeight<X1, X2> &Zero() { 76 static const ExpectationWeight<X1, X2> zero(X1::Zero(), X2::Zero()); 77 return zero; 78 } 79 80 static const ExpectationWeight<X1, X2> &One() { 81 static const ExpectationWeight<X1, X2> one(X1::One(), X2::Zero()); 82 return one; 83 } 84 85 static const ExpectationWeight<X1, X2> &NoWeight() { 86 static const ExpectationWeight<X1, X2> no_weight(X1::NoWeight(), 87 X2::NoWeight()); 88 return no_weight; 89 } 90 91 static const string &Type() { 92 static const string type = "expectation_" + X1::Type() + "_" + X2::Type(); 93 return type; 94 } 95 96 PairWeight<X1, X2> Quantize(float delta = kDelta) const { 97 return PairWeight<X1, X2>::Quantize(); 98 } 99 100 ReverseWeight Reverse() const { 101 return PairWeight<X1, X2>::Reverse(); 102 } 103 104 bool Member() const { 105 return PairWeight<X1, X2>::Member(); 106 } 107 108 static uint64 Properties() { 109 uint64 props1 = W1::Properties(); 110 uint64 props2 = W2::Properties(); 111 return props1 & props2 & (kLeftSemiring | kRightSemiring | 112 kCommutative | kIdempotent); 113 } 114 }; 115 116 template <class X1, class X2> 117 inline ExpectationWeight<X1, X2> Plus(const ExpectationWeight<X1, X2> &w, 118 const ExpectationWeight<X1, X2> &v) { 119 return ExpectationWeight<X1, X2>(Plus(w.Value1(), v.Value1()), 120 Plus(w.Value2(), v.Value2())); 121 } 122 123 124 template <class X1, class X2> 125 inline ExpectationWeight<X1, X2> Times(const ExpectationWeight<X1, X2> &w, 126 const ExpectationWeight<X1, X2> &v) { 127 return ExpectationWeight<X1, X2>(Times(w.Value1(), v.Value1()), 128 Plus(Times(w.Value1(), v.Value2()), 129 Times(w.Value2(), v.Value1()))); 130 } 131 132 template <class X1, class X2> 133 inline ExpectationWeight<X1, X2> Divide(const ExpectationWeight<X1, X2> &w, 134 const ExpectationWeight<X1, X2> &v, 135 DivideType typ = DIVIDE_ANY) { 136 FSTERROR() << "ExpectationWeight::Divide: not implemented"; 137 return ExpectationWeight<X1, X2>::NoWeight(); 138 } 139 140 } // namespace fst 141 142 #endif // FST_LIB_EXPECTATION_WEIGHT_H_ 143