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 30namespace 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). 37class 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). 64class 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 } 91template <typename L, StringType S = STRING_LEFT> 92class 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. 124template <class G1, class G2> 125class 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. 147template <class L, class G, StringType S = STRING_LEFT> 148class 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