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