| // power-weight.h |
| |
| // 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: allauzen@google.com (Cyril Allauzen) |
| // |
| // \file |
| // Cartesian power weight semiring operation definitions. |
| |
| #ifndef FST_LIB_POWER_WEIGHT_H__ |
| #define FST_LIB_POWER_WEIGHT_H__ |
| |
| #include <fst/tuple-weight.h> |
| #include <fst/weight.h> |
| |
| |
| namespace fst { |
| |
| // Cartesian power semiring: W ^ n |
| // Forms: |
| // - a left semimodule when W is a left semiring, |
| // - a right semimodule when W is a right semiring, |
| // - a bisemimodule when W is a semiring, |
| // the free semimodule of rank n over W |
| // The Times operation is overloaded to provide the |
| // left and right scalar products. |
| template <class W, unsigned int n> |
| class PowerWeight : public TupleWeight<W, n> { |
| public: |
| using TupleWeight<W, n>::Zero; |
| using TupleWeight<W, n>::One; |
| using TupleWeight<W, n>::NoWeight; |
| using TupleWeight<W, n>::Quantize; |
| using TupleWeight<W, n>::Reverse; |
| |
| typedef PowerWeight<typename W::ReverseWeight, n> ReverseWeight; |
| |
| PowerWeight() {} |
| |
| PowerWeight(const TupleWeight<W, n> &w) : TupleWeight<W, n>(w) {} |
| |
| template <class Iterator> |
| PowerWeight(Iterator begin, Iterator end) : TupleWeight<W, n>(begin, end) {} |
| |
| static const PowerWeight<W, n> &Zero() { |
| static const PowerWeight<W, n> zero(TupleWeight<W, n>::Zero()); |
| return zero; |
| } |
| |
| static const PowerWeight<W, n> &One() { |
| static const PowerWeight<W, n> one(TupleWeight<W, n>::One()); |
| return one; |
| } |
| |
| static const PowerWeight<W, n> &NoWeight() { |
| static const PowerWeight<W, n> no_weight(TupleWeight<W, n>::NoWeight()); |
| return no_weight; |
| } |
| |
| static const string &Type() { |
| static string type; |
| if (type.empty()) { |
| string power; |
| Int64ToStr(n, &power); |
| type = W::Type() + "_^" + power; |
| } |
| return type; |
| } |
| |
| static uint64 Properties() { |
| uint64 props = W::Properties(); |
| return props & (kLeftSemiring | kRightSemiring | |
| kCommutative | kIdempotent); |
| } |
| |
| PowerWeight<W, n> Quantize(float delta = kDelta) const { |
| return TupleWeight<W, n>::Quantize(delta); |
| } |
| |
| ReverseWeight Reverse() const { |
| return TupleWeight<W, n>::Reverse(); |
| } |
| }; |
| |
| |
| // Semiring plus operation |
| template <class W, unsigned int n> |
| inline PowerWeight<W, n> Plus(const PowerWeight<W, n> &w1, |
| const PowerWeight<W, n> &w2) { |
| PowerWeight<W, n> w; |
| for (size_t i = 0; i < n; ++i) |
| w.SetValue(i, Plus(w1.Value(i), w2.Value(i))); |
| return w; |
| } |
| |
| // Semiring times operation |
| template <class W, unsigned int n> |
| inline PowerWeight<W, n> Times(const PowerWeight<W, n> &w1, |
| const PowerWeight<W, n> &w2) { |
| PowerWeight<W, n> w; |
| for (size_t i = 0; i < n; ++i) |
| w.SetValue(i, Times(w1.Value(i), w2.Value(i))); |
| return w; |
| } |
| |
| // Semiring divide operation |
| template <class W, unsigned int n> |
| inline PowerWeight<W, n> Divide(const PowerWeight<W, n> &w1, |
| const PowerWeight<W, n> &w2, |
| DivideType type = DIVIDE_ANY) { |
| PowerWeight<W, n> w; |
| for (size_t i = 0; i < n; ++i) |
| w.SetValue(i, Divide(w1.Value(i), w2.Value(i), type)); |
| return w; |
| } |
| |
| // Semimodule left scalar product |
| template <class W, unsigned int n> |
| inline PowerWeight<W, n> Times(const W &s, const PowerWeight<W, n> &w) { |
| PowerWeight<W, n> sw; |
| for (size_t i = 0; i < n; ++i) |
| sw.SetValue(i, Times(s, w.Value(i))); |
| return w; |
| } |
| |
| // Semimodule right scalar product |
| template <class W, unsigned int n> |
| inline PowerWeight<W, n> Times(const PowerWeight<W, n> &w, const W &s) { |
| PowerWeight<W, n> ws; |
| for (size_t i = 0; i < n; ++i) |
| ws.SetValue(i, Times(w.Value(i), s)); |
| return w; |
| } |
| |
| // Semimodule dot product |
| template <class W, unsigned int n> |
| inline W DotProduct(const PowerWeight<W, n> &w1, |
| const PowerWeight<W, n> &w2) { |
| W w = W::Zero(); |
| for (size_t i = 0; i < n; ++i) |
| w = Plus(w, Times(w1.Value(i), w2.Value(i))); |
| return w; |
| } |
| |
| |
| } // namespace fst |
| |
| #endif // FST_LIB_POWER_WEIGHT_H__ |