// 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 #include 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 PowerWeight : public TupleWeight { public: using TupleWeight::Zero; using TupleWeight::One; using TupleWeight::NoWeight; using TupleWeight::Quantize; using TupleWeight::Reverse; typedef PowerWeight ReverseWeight; PowerWeight() {} PowerWeight(const TupleWeight &w) : TupleWeight(w) {} template PowerWeight(Iterator begin, Iterator end) : TupleWeight(begin, end) {} static const PowerWeight &Zero() { static const PowerWeight zero(TupleWeight::Zero()); return zero; } static const PowerWeight &One() { static const PowerWeight one(TupleWeight::One()); return one; } static const PowerWeight &NoWeight() { static const PowerWeight no_weight(TupleWeight::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 Quantize(float delta = kDelta) const { return TupleWeight::Quantize(delta); } ReverseWeight Reverse() const { return TupleWeight::Reverse(); } }; // Semiring plus operation template inline PowerWeight Plus(const PowerWeight &w1, const PowerWeight &w2) { PowerWeight 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 inline PowerWeight Times(const PowerWeight &w1, const PowerWeight &w2) { PowerWeight 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 inline PowerWeight Divide(const PowerWeight &w1, const PowerWeight &w2, DivideType type = DIVIDE_ANY) { PowerWeight 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 inline PowerWeight Times(const W &s, const PowerWeight &w) { PowerWeight sw; for (size_t i = 0; i < n; ++i) sw.SetValue(i, Times(s, w.Value(i))); return w; } // Semimodule right scalar product template inline PowerWeight Times(const PowerWeight &w, const W &s) { PowerWeight ws; for (size_t i = 0; i < n; ++i) ws.SetValue(i, Times(w.Value(i), s)); return w; } // Semimodule dot product template inline W DotProduct(const PowerWeight &w1, const PowerWeight &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__