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) allow_zero_(allow_zero)42 : allow_zero_(allow_zero) { 43 srand(seed); 44 } 45 operator()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) allow_zero_(allow_zero)69 : allow_zero_(allow_zero) { 70 srand(seed); 71 } 72 operator()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) allow_zero_(allow_zero)97 : allow_zero_(allow_zero) { 98 srand(seed); 99 } 100 operator()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) generator1_(seed,allow_zero)132 : generator1_(seed, allow_zero), generator2_(seed, allow_zero) {} 133 operator()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) PG(seed,allow_zero)157 : PG(seed, allow_zero) {} 158 GallicWeightGenerator(const PG & pg)159 GallicWeightGenerator(const PG &pg) : PG(pg) {} 160 }; 161 162 } // namespace fst; 163 164 #endif // FST_LIB_RANDOM_WEIGHT_H__ 165