Home | History | Annotate | Download | only in fst
      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