1 // power-weight.h
2
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Copyright 2005-2010 Google, Inc.
16 // Author: allauzen@google.com (Cyril Allauzen)
17 //
18 // \file
19 // Cartesian power weight semiring operation definitions.
20
21 #ifndef FST_LIB_POWER_WEIGHT_H__
22 #define FST_LIB_POWER_WEIGHT_H__
23
24 #include <fst/tuple-weight.h>
25 #include <fst/weight.h>
26
27
28 namespace fst {
29
30 // Cartesian power semiring: W ^ n
31 // Forms:
32 // - a left semimodule when W is a left semiring,
33 // - a right semimodule when W is a right semiring,
34 // - a bisemimodule when W is a semiring,
35 // the free semimodule of rank n over W
36 // The Times operation is overloaded to provide the
37 // left and right scalar products.
38 template <class W, unsigned int n>
39 class PowerWeight : public TupleWeight<W, n> {
40 public:
41 using TupleWeight<W, n>::Zero;
42 using TupleWeight<W, n>::One;
43 using TupleWeight<W, n>::NoWeight;
44 using TupleWeight<W, n>::Quantize;
45 using TupleWeight<W, n>::Reverse;
46
47 typedef PowerWeight<typename W::ReverseWeight, n> ReverseWeight;
48
PowerWeight()49 PowerWeight() {}
50
PowerWeight(const TupleWeight<W,n> & w)51 PowerWeight(const TupleWeight<W, n> &w) : TupleWeight<W, n>(w) {}
52
53 template <class Iterator>
PowerWeight(Iterator begin,Iterator end)54 PowerWeight(Iterator begin, Iterator end) : TupleWeight<W, n>(begin, end) {}
55
Zero()56 static const PowerWeight<W, n> &Zero() {
57 static const PowerWeight<W, n> zero(TupleWeight<W, n>::Zero());
58 return zero;
59 }
60
One()61 static const PowerWeight<W, n> &One() {
62 static const PowerWeight<W, n> one(TupleWeight<W, n>::One());
63 return one;
64 }
65
NoWeight()66 static const PowerWeight<W, n> &NoWeight() {
67 static const PowerWeight<W, n> no_weight(TupleWeight<W, n>::NoWeight());
68 return no_weight;
69 }
70
Type()71 static const string &Type() {
72 static string type;
73 if (type.empty()) {
74 string power;
75 Int64ToStr(n, &power);
76 type = W::Type() + "_^" + power;
77 }
78 return type;
79 }
80
Properties()81 static uint64 Properties() {
82 uint64 props = W::Properties();
83 return props & (kLeftSemiring | kRightSemiring |
84 kCommutative | kIdempotent);
85 }
86
87 PowerWeight<W, n> Quantize(float delta = kDelta) const {
88 return TupleWeight<W, n>::Quantize(delta);
89 }
90
Reverse()91 ReverseWeight Reverse() const {
92 return TupleWeight<W, n>::Reverse();
93 }
94 };
95
96
97 // Semiring plus operation
98 template <class W, unsigned int n>
Plus(const PowerWeight<W,n> & w1,const PowerWeight<W,n> & w2)99 inline PowerWeight<W, n> Plus(const PowerWeight<W, n> &w1,
100 const PowerWeight<W, n> &w2) {
101 PowerWeight<W, n> w;
102 for (size_t i = 0; i < n; ++i)
103 w.SetValue(i, Plus(w1.Value(i), w2.Value(i)));
104 return w;
105 }
106
107 // Semiring times operation
108 template <class W, unsigned int n>
Times(const PowerWeight<W,n> & w1,const PowerWeight<W,n> & w2)109 inline PowerWeight<W, n> Times(const PowerWeight<W, n> &w1,
110 const PowerWeight<W, n> &w2) {
111 PowerWeight<W, n> w;
112 for (size_t i = 0; i < n; ++i)
113 w.SetValue(i, Times(w1.Value(i), w2.Value(i)));
114 return w;
115 }
116
117 // Semiring divide operation
118 template <class W, unsigned int n>
119 inline PowerWeight<W, n> Divide(const PowerWeight<W, n> &w1,
120 const PowerWeight<W, n> &w2,
121 DivideType type = DIVIDE_ANY) {
122 PowerWeight<W, n> w;
123 for (size_t i = 0; i < n; ++i)
124 w.SetValue(i, Divide(w1.Value(i), w2.Value(i), type));
125 return w;
126 }
127
128 // Semimodule left scalar product
129 template <class W, unsigned int n>
Times(const W & s,const PowerWeight<W,n> & w)130 inline PowerWeight<W, n> Times(const W &s, const PowerWeight<W, n> &w) {
131 PowerWeight<W, n> sw;
132 for (size_t i = 0; i < n; ++i)
133 sw.SetValue(i, Times(s, w.Value(i)));
134 return w;
135 }
136
137 // Semimodule right scalar product
138 template <class W, unsigned int n>
Times(const PowerWeight<W,n> & w,const W & s)139 inline PowerWeight<W, n> Times(const PowerWeight<W, n> &w, const W &s) {
140 PowerWeight<W, n> ws;
141 for (size_t i = 0; i < n; ++i)
142 ws.SetValue(i, Times(w.Value(i), s));
143 return w;
144 }
145
146 // Semimodule dot product
147 template <class W, unsigned int n>
DotProduct(const PowerWeight<W,n> & w1,const PowerWeight<W,n> & w2)148 inline W DotProduct(const PowerWeight<W, n> &w1,
149 const PowerWeight<W, n> &w2) {
150 W w = W::Zero();
151 for (size_t i = 0; i < n; ++i)
152 w = Plus(w, Times(w1.Value(i), w2.Value(i)));
153 return w;
154 }
155
156
157 } // namespace fst
158
159 #endif // FST_LIB_POWER_WEIGHT_H__
160