14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// random-weight.h
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License");
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License.
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//      http://www.apache.org/licenses/LICENSE-2.0
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS,
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License.
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Function objects to generate random weights in various semirings
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for testing purposes.
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_RANDOM_WEIGHT_H__
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_RANDOM_WEIGHT_H__
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <cstdlib>
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <ctime>
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/float-weight.h"
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/product-weight.h"
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/string-weight.h"
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst {
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// The boolean 'allow_zero' below determines whether Zero() and zero
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// divisors should be returned in the random weight generation.
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This function object returns TropicalWeights that are random integers
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// chosen from [0, kNumRandomWeights).
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass TropicalWeightGenerator {
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef TropicalWeight Weight;
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  TropicalWeightGenerator(int seed = time(0), bool allow_zero = true)
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : allow_zero_(allow_zero) {
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    srand(seed);
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight operator() () const {
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int n = rand() % (kNumRandomWeights + allow_zero_);
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (allow_zero_ && n == kNumRandomWeights)
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Weight::Zero();
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Weight(static_cast<float>(n));
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // The number of alternative random weights.
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kNumRandomWeights = 5;
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool allow_zero_;  // permit Zero() and zero divisors
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This function object returns LogWeights that are random integers
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// chosen from [0, kNumRandomWeights).
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass LogWeightGenerator {
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef LogWeight Weight;
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LogWeightGenerator(int seed = time(0), bool allow_zero = true)
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : allow_zero_(allow_zero) {
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    srand(seed);
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight operator() () const {
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int n = rand() % (kNumRandomWeights + allow_zero_);
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (allow_zero_ && n == kNumRandomWeights)
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Weight::Zero();
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Weight(static_cast<float>(n));
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Number of alternative random weights.
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kNumRandomWeights = 5;
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool allow_zero_;  // permit Zero() and zero divisors
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This function object returns StringWeights that are random integer
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// strings chosen from {1,...,kAlphabetSize}^{0,kMaxStringLength} U { Zero }
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <typename L, StringType S = STRING_LEFT>
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass StringWeightGenerator {
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef StringWeight<L, S> Weight;
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  StringWeightGenerator(int seed = time(0), bool allow_zero = true)
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : allow_zero_(allow_zero) {
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project     srand(seed);
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight operator() () const {
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int n = rand() % (kMaxStringLength + allow_zero_);
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (allow_zero_ && n == kMaxStringLength)
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return Weight::Zero();
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    vector<L> v;
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (int i = 0; i < n; ++i)
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      v.push_back(rand() % kAlphabetSize + 1);
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Weight(v.begin(), v.end());
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Alphabet size for random weights.
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kAlphabetSize = 5;
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  // Number of alternative random weights.
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  static const int kMaxStringLength = 5;
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  bool allow_zero_;  // permit Zero() and zero divisors
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This function object returns a weight generator over the product of the
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// weights for the generators G1 and G2.
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class G1, class G2>
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass ProductWeightGenerator {
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename G1::Weight W1;
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename G2::Weight W2;
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef ProductWeight<W1, W2> Weight;
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ProductWeightGenerator(int seed = time(0), bool allow_zero = true)
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : generator1_(seed, allow_zero), generator2_(seed, allow_zero) {}
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Weight operator() () const {
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    W1 w1 = generator1_();
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    W2 w2 = generator2_();
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return Weight(w1, w2);
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project private:
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  G1 generator1_;
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  G2 generator2_;
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Product generator of a string weight generator and an
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// arbitrary weight generator.
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate <class L, class G, StringType S = STRING_LEFT>
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectclass GallicWeightGenerator
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    : public ProductWeightGenerator<StringWeightGenerator<L, S>, G> {
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project public:
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef ProductWeightGenerator<StringWeightGenerator<L, S>, G> PG;
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef typename G::Weight W;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  typedef GallicWeight<L, W, S> Weight;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  GallicWeightGenerator(int seed = time(0), bool allow_zero = true)
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      : PG(seed, allow_zero) {}
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  GallicWeightGenerator(const PG &pg) : PG(pg) {}
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project};
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}  // namespace fst;
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif  // FST_LIB_RANDOM_WEIGHT_H__
165