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