// 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.
//
//
// \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 "fst/lib/float-weight.h"
#include "fst/lib/product-weight.h"
#include "fst/lib/string-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 TropicalWeights that are random integers
// chosen from [0, kNumRandomWeights).
class TropicalWeightGenerator {
public:
typedef TropicalWeight 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<float>(n));
}
private:
// The number of alternative random weights.
static const int kNumRandomWeights = 5;
bool allow_zero_; // permit Zero() and zero divisors
};
// This function object returns LogWeights that are random integers
// chosen from [0, kNumRandomWeights).
class LogWeightGenerator {
public:
typedef LogWeight 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<float>(n));
}
private:
// Number of alternative random weights.
static const int kNumRandomWeights = 5;
bool allow_zero_; // permit Zero() and zero divisors
};
// 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 divisors
};
// This function object returns a weight generator over the product of the
// weights for the generators G1 and G2.
template <class G1, class G2>
class ProductWeightGenerator {
public:
typedef typename G1::Weight W1;
typedef typename G2::Weight W2;
typedef ProductWeight<W1, W2> 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_;
};
// 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) {}
};
} // namespace fst;
#endif // FST_LIB_RANDOM_WEIGHT_H__