| // random-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: riley@google.com (Michael Riley) |
| // |
| // \file |
| // Function objects to generate random weights in various semirings |
| // for testing purposes. |
| |
| #ifndef FST_LIB_RANDOM_WEIGHT_H__ |
| #define FST_LIB_RANDOM_WEIGHT_H__ |
| |
| #include <cstdlib> |
| #include <ctime> |
| #include <vector> |
| using std::vector; |
| |
| |
| #include <fst/float-weight.h> |
| #include <fst/product-weight.h> |
| #include <fst/string-weight.h> |
| #include <fst/lexicographic-weight.h> |
| #include <fst/power-weight.h> |
| #include <fst/signed-log-weight.h> |
| #include <fst/sparse-power-weight.h> |
| |
| |
| namespace fst { |
| |
| // The boolean 'allow_zero' below determines whether Zero() and zero |
| // divisors should be returned in the random weight generation. |
| |
| // This function object returns TropicalWeightTpl<T>'s that are random integers |
| // chosen from [0, kNumRandomWeights). |
| template <class T> |
| class TropicalWeightGenerator_ { |
| public: |
| typedef TropicalWeightTpl<T> Weight; |
| |
| TropicalWeightGenerator_(int seed = time(0), bool allow_zero = true) |
| : allow_zero_(allow_zero) { |
| srand(seed); |
| } |
| |
| Weight operator() () const { |
| int n = rand() % (kNumRandomWeights + allow_zero_); |
| if (allow_zero_ && n == kNumRandomWeights) |
| return Weight::Zero(); |
| |
| return Weight(static_cast<T>(n)); |
| } |
| |
| private: |
| // The number of alternative random weights. |
| static const int kNumRandomWeights = 5; |
| |
| bool allow_zero_; // permit Zero() and zero divisors |
| }; |
| |
| template <class T> const int TropicalWeightGenerator_<T>::kNumRandomWeights; |
| |
| typedef TropicalWeightGenerator_<float> TropicalWeightGenerator; |
| |
| |
| // This function object returns LogWeightTpl<T>'s that are random integers |
| // chosen from [0, kNumRandomWeights). |
| template <class T> |
| class LogWeightGenerator_ { |
| public: |
| typedef LogWeightTpl<T> Weight; |
| |
| LogWeightGenerator_(int seed = time(0), bool allow_zero = true) |
| : allow_zero_(allow_zero) { |
| srand(seed); |
| } |
| |
| Weight operator() () const { |
| int n = rand() % (kNumRandomWeights + allow_zero_); |
| if (allow_zero_ && n == kNumRandomWeights) |
| return Weight::Zero(); |
| |
| return Weight(static_cast<T>(n)); |
| } |
| |
| private: |
| // Number of alternative random weights. |
| static const int kNumRandomWeights = 5; |
| |
| bool allow_zero_; // permit Zero() and zero divisors |
| }; |
| |
| template <class T> const int LogWeightGenerator_<T>::kNumRandomWeights; |
| |
| typedef LogWeightGenerator_<float> LogWeightGenerator; |
| |
| |
| // This function object returns MinMaxWeightTpl<T>'s that are random integers |
| // chosen from (-kNumRandomWeights, kNumRandomWeights) in addition to |
| // One(), and Zero() if zero is allowed. |
| template <class T> |
| class MinMaxWeightGenerator_ { |
| public: |
| typedef MinMaxWeightTpl<T> Weight; |
| |
| MinMaxWeightGenerator_(int seed = time(0), bool allow_zero = true) |
| : allow_zero_(allow_zero) { |
| srand(seed); |
| } |
| |
| Weight operator() () const { |
| int n = (rand() % (2*kNumRandomWeights + allow_zero_)) - kNumRandomWeights; |
| if (allow_zero_ && n == kNumRandomWeights) |
| return Weight::Zero(); |
| else if (n == -kNumRandomWeights) |
| return Weight::One(); |
| |
| return Weight(static_cast<T>(n)); |
| } |
| |
| private: |
| // Parameters controlling the number of alternative random weights. |
| static const int kNumRandomWeights = 5; |
| |
| bool allow_zero_; // permit Zero() and zero divisors |
| }; |
| |
| template <class T> const int MinMaxWeightGenerator_<T>::kNumRandomWeights; |
| |
| typedef MinMaxWeightGenerator_<float> MinMaxWeightGenerator; |
| |
| |
| // This function object returns StringWeights that are random integer |
| // strings chosen from {1,...,kAlphabetSize}^{0,kMaxStringLength} U { Zero } |
| template <typename L, StringType S = STRING_LEFT> |
| class StringWeightGenerator { |
| public: |
| typedef StringWeight<L, S> Weight; |
| |
| StringWeightGenerator(int seed = time(0), bool allow_zero = true) |
| : allow_zero_(allow_zero) { |
| srand(seed); |
| } |
| |
| Weight operator() () const { |
| int n = rand() % (kMaxStringLength + allow_zero_); |
| if (allow_zero_ && n == kMaxStringLength) |
| return Weight::Zero(); |
| |
| vector<L> v; |
| for (int i = 0; i < n; ++i) |
| v.push_back(rand() % kAlphabetSize + 1); |
| return Weight(v.begin(), v.end()); |
| } |
| |
| private: |
| // Alphabet size for random weights. |
| static const int kAlphabetSize = 5; |
| // Number of alternative random weights. |
| static const int kMaxStringLength = 5; |
| |
| bool allow_zero_; // permit Zero() and zero |
| }; |
| |
| template <typename L, StringType S> |
| const int StringWeightGenerator<L, S>::kAlphabetSize; |
| template <typename L, StringType S> |
| const int StringWeightGenerator<L, S>::kMaxStringLength; |
| |
| |
| // This function object returns a weight generator over the product of the |
| // weights (by default) for the generators G1 and G2. |
| template <class G1, class G2, |
| class W = ProductWeight<typename G1::Weight, typename G2::Weight> > |
| class ProductWeightGenerator { |
| public: |
| typedef typename G1::Weight W1; |
| typedef typename G2::Weight W2; |
| typedef W Weight; |
| |
| ProductWeightGenerator(int seed = time(0), bool allow_zero = true) |
| : generator1_(seed, allow_zero), generator2_(seed, allow_zero) {} |
| |
| Weight operator() () const { |
| W1 w1 = generator1_(); |
| W2 w2 = generator2_(); |
| return Weight(w1, w2); |
| } |
| |
| private: |
| G1 generator1_; |
| G2 generator2_; |
| }; |
| |
| |
| // This function object returns a weight generator for a lexicographic weight |
| // composed out of weights for the generators G1 and G2. For lexicographic |
| // weights, we cannot generate zeroes for the two subweights separately: |
| // weights are members iff both members are zero or both members are non-zero. |
| template <class G1, class G2> |
| class LexicographicWeightGenerator { |
| public: |
| typedef typename G1::Weight W1; |
| typedef typename G2::Weight W2; |
| typedef LexicographicWeight<W1, W2> Weight; |
| |
| LexicographicWeightGenerator(int seed = time(0), bool allow_zero = true) |
| : generator1_(seed, false), generator2_(seed, false), |
| allow_zero_(allow_zero) {} |
| |
| Weight operator() () const { |
| if (allow_zero_) { |
| int n = rand() % (kNumRandomWeights + allow_zero_); |
| if (n == kNumRandomWeights) |
| return Weight(W1::Zero(), W2::Zero()); |
| } |
| W1 w1 = generator1_(); |
| W2 w2 = generator2_(); |
| return Weight(w1, w2); |
| } |
| |
| private: |
| G1 generator1_; |
| G2 generator2_; |
| static const int kNumRandomWeights = 5; |
| bool allow_zero_; |
| }; |
| |
| template <class G1, class G2> |
| const int LexicographicWeightGenerator<G1, G2>::kNumRandomWeights; |
| |
| |
| // Product generator of a string weight generator and an |
| // arbitrary weight generator. |
| template <class L, class G, StringType S = STRING_LEFT> |
| class GallicWeightGenerator |
| : public ProductWeightGenerator<StringWeightGenerator<L, S>, G> { |
| |
| public: |
| typedef ProductWeightGenerator<StringWeightGenerator<L, S>, G> PG; |
| typedef typename G::Weight W; |
| typedef GallicWeight<L, W, S> Weight; |
| |
| GallicWeightGenerator(int seed = time(0), bool allow_zero = true) |
| : PG(seed, allow_zero) {} |
| |
| GallicWeightGenerator(const PG &pg) : PG(pg) {} |
| }; |
| |
| // This function object returms a weight generator over the catersian power |
| // of rank n of the weights for the generator G. |
| template <class G, unsigned int n> |
| class PowerWeightGenerator { |
| public: |
| typedef typename G::Weight W; |
| typedef PowerWeight<W, n> Weight; |
| |
| PowerWeightGenerator(int seed = time(0), bool allow_zero = true) |
| : generator_(seed, allow_zero) {} |
| |
| Weight operator()() const { |
| Weight w; |
| for (size_t i = 0; i < n; ++i) { |
| W r = generator_(); |
| w.SetValue(i, r); |
| } |
| return w; |
| } |
| |
| private: |
| G generator_; |
| }; |
| |
| // This function object returns SignedLogWeightTpl<T>'s that are |
| // random integers chosen from [0, kNumRandomWeights). |
| // The sign is randomly chosen as well. |
| template <class T> |
| class SignedLogWeightGenerator_ { |
| public: |
| typedef SignedLogWeightTpl<T> Weight; |
| |
| SignedLogWeightGenerator_(int seed = time(0), bool allow_zero = true) |
| : allow_zero_(allow_zero) { |
| srand(seed); |
| } |
| |
| Weight operator() () const { |
| int m = rand() % 2; |
| int n = rand() % (kNumRandomWeights + allow_zero_); |
| |
| return SignedLogWeightTpl<T>( |
| (m == 0) ? |
| TropicalWeight(-1.0) : |
| TropicalWeight(1.0), |
| (allow_zero_ && n == kNumRandomWeights) ? |
| LogWeightTpl<T>::Zero() : |
| LogWeightTpl<T>(static_cast<T>(n))); |
| } |
| |
| private: |
| // Number of alternative random weights. |
| static const int kNumRandomWeights = 5; |
| bool allow_zero_; // permit Zero() and zero divisors |
| }; |
| |
| template <class T> const int SignedLogWeightGenerator_<T>::kNumRandomWeights; |
| |
| typedef SignedLogWeightGenerator_<float> SignedLogWeightGenerator; |
| |
| // This function object returms a weight generator over the catersian power |
| // of rank n of the weights for the generator G. |
| template <class G, class K, unsigned int n> |
| class SparsePowerWeightGenerator { |
| public: |
| typedef typename G::Weight W; |
| typedef SparsePowerWeight<W, K> Weight; |
| |
| SparsePowerWeightGenerator(int seed = time(0), bool allow_zero = true) |
| : generator_(seed, allow_zero) {} |
| |
| Weight operator()() const { |
| Weight w; |
| for (size_t i = 1; i <= n; ++i) { |
| W r = generator_(); |
| K p = i; |
| w.Push(p, r, true); |
| } |
| return w; |
| } |
| |
| private: |
| G generator_; |
| }; |
| |
| } // namespace fst |
| |
| #endif // FST_LIB_RANDOM_WEIGHT_H__ |