| |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| // Copyright 2005-2010 Google, Inc. |
| // Author: krr@google.com (Kasturi Rangan Raghavan) |
| // Inspiration: shumash@google.com (Masha Maria Shugrina) |
| // \file |
| // 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_LIB_EXPECTATION_WEIGHT_H_ |
| #define FST_LIB_EXPECTATION_WEIGHT_H_ |
| |
| #include<string> |
| |
| #include <fst/pair-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; |
| |
| typedef X1 W1; |
| typedef X2 W2; |
| |
| typedef ExpectationWeight<typename X1::ReverseWeight, |
| typename X2::ReverseWeight> ReverseWeight; |
| |
| ExpectationWeight() : PairWeight<X1, X2>(Zero()) { } |
| |
| ExpectationWeight(const ExpectationWeight<X1, X2>& w) |
| : PairWeight<X1, X2> (w) { } |
| |
| ExpectationWeight(const PairWeight<X1, X2>& w) |
| : PairWeight<X1, X2> (w) { } |
| |
| ExpectationWeight(const X1& x1, const X2& x2) |
| : PairWeight<X1, X2>(x1, x2) { } |
| |
| static const ExpectationWeight<X1, X2> &Zero() { |
| static const ExpectationWeight<X1, X2> zero(X1::Zero(), X2::Zero()); |
| return zero; |
| } |
| |
| static const ExpectationWeight<X1, X2> &One() { |
| static const ExpectationWeight<X1, X2> one(X1::One(), X2::Zero()); |
| return one; |
| } |
| |
| static const ExpectationWeight<X1, X2> &NoWeight() { |
| static const ExpectationWeight<X1, X2> no_weight(X1::NoWeight(), |
| X2::NoWeight()); |
| return no_weight; |
| } |
| |
| static const string &Type() { |
| static const string type = "expectation_" + X1::Type() + "_" + X2::Type(); |
| return type; |
| } |
| |
| PairWeight<X1, X2> Quantize(float delta = kDelta) const { |
| return PairWeight<X1, X2>::Quantize(); |
| } |
| |
| ReverseWeight Reverse() const { |
| return PairWeight<X1, X2>::Reverse(); |
| } |
| |
| bool Member() const { |
| return PairWeight<X1, X2>::Member(); |
| } |
| |
| static uint64 Properties() { |
| uint64 props1 = W1::Properties(); |
| uint64 props2 = W2::Properties(); |
| return props1 & props2 & (kLeftSemiring | kRightSemiring | |
| kCommutative | kIdempotent); |
| } |
| }; |
| |
| template <class X1, class X2> |
| inline ExpectationWeight<X1, X2> Plus(const ExpectationWeight<X1, X2> &w, |
| const ExpectationWeight<X1, X2> &v) { |
| return ExpectationWeight<X1, X2>(Plus(w.Value1(), v.Value1()), |
| Plus(w.Value2(), v.Value2())); |
| } |
| |
| |
| template <class X1, class X2> |
| inline ExpectationWeight<X1, X2> Times(const ExpectationWeight<X1, X2> &w, |
| const ExpectationWeight<X1, X2> &v) { |
| return ExpectationWeight<X1, X2>(Times(w.Value1(), v.Value1()), |
| Plus(Times(w.Value1(), v.Value2()), |
| Times(w.Value2(), v.Value1()))); |
| } |
| |
| template <class X1, class X2> |
| inline ExpectationWeight<X1, X2> Divide(const ExpectationWeight<X1, X2> &w, |
| const ExpectationWeight<X1, X2> &v, |
| DivideType typ = DIVIDE_ANY) { |
| FSTERROR() << "ExpectationWeight::Divide: not implemented"; |
| return ExpectationWeight<X1, X2>::NoWeight(); |
| } |
| |
| } // namespace fst |
| |
| #endif // FST_LIB_EXPECTATION_WEIGHT_H_ |