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 (at) 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 49 PowerWeight() {} 50 51 PowerWeight(const TupleWeight<W, n> &w) : TupleWeight<W, n>(w) {} 52 53 template <class Iterator> 54 PowerWeight(Iterator begin, Iterator end) : TupleWeight<W, n>(begin, end) {} 55 56 static const PowerWeight<W, n> &Zero() { 57 static const PowerWeight<W, n> zero(TupleWeight<W, n>::Zero()); 58 return zero; 59 } 60 61 static const PowerWeight<W, n> &One() { 62 static const PowerWeight<W, n> one(TupleWeight<W, n>::One()); 63 return one; 64 } 65 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 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 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 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> 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> 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> 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> 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> 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