Home | History | Annotate | Download | only in lib
      1 // random-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 //
     16 // \file
     17 // Function objects to generate random weights in various semirings
     18 // for testing purposes.
     19 
     20 #ifndef FST_LIB_RANDOM_WEIGHT_H__
     21 #define FST_LIB_RANDOM_WEIGHT_H__
     22 
     23 #include <cstdlib>
     24 #include <ctime>
     25 
     26 #include "fst/lib/float-weight.h"
     27 #include "fst/lib/product-weight.h"
     28 #include "fst/lib/string-weight.h"
     29 
     30 namespace fst {
     31 
     32 // The boolean 'allow_zero' below determines whether Zero() and zero
     33 // divisors should be returned in the random weight generation.
     34 
     35 // This function object returns TropicalWeights that are random integers
     36 // chosen from [0, kNumRandomWeights).
     37 class TropicalWeightGenerator {
     38  public:
     39   typedef TropicalWeight Weight;
     40 
     41   TropicalWeightGenerator(int seed = time(0), bool allow_zero = true)
     42       : allow_zero_(allow_zero) {
     43     srand(seed);
     44   }
     45 
     46   Weight operator() () const {
     47     int n = rand() % (kNumRandomWeights + allow_zero_);
     48     if (allow_zero_ && n == kNumRandomWeights)
     49       return Weight::Zero();
     50 
     51     return Weight(static_cast<float>(n));
     52   }
     53 
     54  private:
     55   // The number of alternative random weights.
     56   static const int kNumRandomWeights = 5;
     57 
     58   bool allow_zero_;  // permit Zero() and zero divisors
     59 };
     60 
     61 
     62 // This function object returns LogWeights that are random integers
     63 // chosen from [0, kNumRandomWeights).
     64 class LogWeightGenerator {
     65  public:
     66   typedef LogWeight Weight;
     67 
     68   LogWeightGenerator(int seed = time(0), bool allow_zero = true)
     69       : allow_zero_(allow_zero) {
     70     srand(seed);
     71   }
     72 
     73   Weight operator() () const {
     74     int n = rand() % (kNumRandomWeights + allow_zero_);
     75     if (allow_zero_ && n == kNumRandomWeights)
     76       return Weight::Zero();
     77 
     78     return Weight(static_cast<float>(n));
     79   }
     80 
     81  private:
     82   // Number of alternative random weights.
     83   static const int kNumRandomWeights = 5;
     84 
     85   bool allow_zero_;  // permit Zero() and zero divisors
     86 };
     87 
     88 
     89 // This function object returns StringWeights that are random integer
     90 // strings chosen from {1,...,kAlphabetSize}^{0,kMaxStringLength} U { Zero }
     91 template <typename L, StringType S = STRING_LEFT>
     92 class StringWeightGenerator {
     93  public:
     94   typedef StringWeight<L, S> Weight;
     95 
     96   StringWeightGenerator(int seed = time(0), bool allow_zero = true)
     97       : allow_zero_(allow_zero) {
     98      srand(seed);
     99   }
    100 
    101   Weight operator() () const {
    102     int n = rand() % (kMaxStringLength + allow_zero_);
    103     if (allow_zero_ && n == kMaxStringLength)
    104       return Weight::Zero();
    105 
    106     vector<L> v;
    107     for (int i = 0; i < n; ++i)
    108       v.push_back(rand() % kAlphabetSize + 1);
    109     return Weight(v.begin(), v.end());
    110   }
    111 
    112  private:
    113   // Alphabet size for random weights.
    114   static const int kAlphabetSize = 5;
    115   // Number of alternative random weights.
    116   static const int kMaxStringLength = 5;
    117 
    118   bool allow_zero_;  // permit Zero() and zero divisors
    119 };
    120 
    121 
    122 // This function object returns a weight generator over the product of the
    123 // weights for the generators G1 and G2.
    124 template <class G1, class G2>
    125 class ProductWeightGenerator {
    126  public:
    127   typedef typename G1::Weight W1;
    128   typedef typename G2::Weight W2;
    129   typedef ProductWeight<W1, W2> Weight;
    130 
    131   ProductWeightGenerator(int seed = time(0), bool allow_zero = true)
    132       : generator1_(seed, allow_zero), generator2_(seed, allow_zero) {}
    133 
    134   Weight operator() () const {
    135     W1 w1 = generator1_();
    136     W2 w2 = generator2_();
    137     return Weight(w1, w2);
    138   }
    139 
    140  private:
    141   G1 generator1_;
    142   G2 generator2_;
    143 };
    144 
    145 // Product generator of a string weight generator and an
    146 // arbitrary weight generator.
    147 template <class L, class G, StringType S = STRING_LEFT>
    148 class GallicWeightGenerator
    149     : public ProductWeightGenerator<StringWeightGenerator<L, S>, G> {
    150 
    151  public:
    152   typedef ProductWeightGenerator<StringWeightGenerator<L, S>, G> PG;
    153   typedef typename G::Weight W;
    154   typedef GallicWeight<L, W, S> Weight;
    155 
    156   GallicWeightGenerator(int seed = time(0), bool allow_zero = true)
    157       : PG(seed, allow_zero) {}
    158 
    159   GallicWeightGenerator(const PG &pg) : PG(pg) {}
    160 };
    161 
    162 }  // namespace fst;
    163 
    164 #endif  // FST_LIB_RANDOM_WEIGHT_H__
    165