1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// random-weight.h
2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License");
4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License.
5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at
6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//     http://www.apache.org/licenses/LICENSE-2.0
8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software
10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS,
11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and
13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License.
14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc.
16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: riley@google.com (Michael Riley)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Function objects to generate random weights in various semirings
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for testing purposes.
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_RANDOM_WEIGHT_H__
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_RANDOM_WEIGHT_H__
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <cstdlib>
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <ctime>
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector>
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector;
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/float-weight.h>
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/product-weight.h>
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/string-weight.h>
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/lexicographic-weight.h>
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/power-weight.h>
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/signed-log-weight.h>
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/sparse-power-weight.h>
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The boolean 'allow_zero' below determines whether Zero() and zero
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// divisors should be returned in the random weight generation.
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns TropicalWeightTpl<T>'s that are random integers
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// chosen from [0, kNumRandomWeights).
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T>
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass TropicalWeightGenerator_ {
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef TropicalWeightTpl<T> Weight;
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  TropicalWeightGenerator_(int seed = time(0), bool allow_zero = true)
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : allow_zero_(allow_zero) {
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    srand(seed);
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int n = rand() % (kNumRandomWeights + allow_zero_);
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (allow_zero_ && n == kNumRandomWeights)
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return Weight::Zero();
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight(static_cast<T>(n));
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // The number of alternative random weights.
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kNumRandomWeights = 5;
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool allow_zero_;  // permit Zero() and zero divisors
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> const int TropicalWeightGenerator_<T>::kNumRandomWeights;
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef TropicalWeightGenerator_<float> TropicalWeightGenerator;
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns LogWeightTpl<T>'s that are random integers
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// chosen from [0, kNumRandomWeights).
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T>
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LogWeightGenerator_ {
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef LogWeightTpl<T> Weight;
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  LogWeightGenerator_(int seed = time(0), bool allow_zero = true)
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : allow_zero_(allow_zero) {
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    srand(seed);
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int n = rand() % (kNumRandomWeights + allow_zero_);
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (allow_zero_ && n == kNumRandomWeights)
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return Weight::Zero();
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight(static_cast<T>(n));
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Number of alternative random weights.
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kNumRandomWeights = 5;
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool allow_zero_;  // permit Zero() and zero divisors
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> const int LogWeightGenerator_<T>::kNumRandomWeights;
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef LogWeightGenerator_<float> LogWeightGenerator;
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns MinMaxWeightTpl<T>'s that are random integers
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// chosen from (-kNumRandomWeights, kNumRandomWeights) in addition to
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// One(), and Zero() if zero is allowed.
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T>
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass MinMaxWeightGenerator_ {
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef MinMaxWeightTpl<T> Weight;
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MinMaxWeightGenerator_(int seed = time(0), bool allow_zero = true)
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : allow_zero_(allow_zero) {
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    srand(seed);
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int n = (rand() % (2*kNumRandomWeights + allow_zero_)) - kNumRandomWeights;
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (allow_zero_ && n == kNumRandomWeights)
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return Weight::Zero();
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    else if (n == -kNumRandomWeights)
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return Weight::One();
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight(static_cast<T>(n));
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Parameters controlling the number of alternative random weights.
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kNumRandomWeights = 5;
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool allow_zero_;  // permit Zero() and zero divisors
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> const int MinMaxWeightGenerator_<T>::kNumRandomWeights;
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef MinMaxWeightGenerator_<float> MinMaxWeightGenerator;
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns StringWeights that are random integer
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// strings chosen from {1,...,kAlphabetSize}^{0,kMaxStringLength} U { Zero }
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename L, StringType S = STRING_LEFT>
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass StringWeightGenerator {
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef StringWeight<L, S> Weight;
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  StringWeightGenerator(int seed = time(0), bool allow_zero = true)
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : allow_zero_(allow_zero) {
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     srand(seed);
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int n = rand() % (kMaxStringLength + allow_zero_);
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (allow_zero_ && n == kMaxStringLength)
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return Weight::Zero();
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    vector<L> v;
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (int i = 0; i < n; ++i)
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      v.push_back(rand() % kAlphabetSize + 1);
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight(v.begin(), v.end());
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Alphabet size for random weights.
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kAlphabetSize = 5;
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Number of alternative random weights.
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kMaxStringLength = 5;
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool allow_zero_;  // permit Zero() and zero
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename L, StringType S>
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonconst int StringWeightGenerator<L, S>::kAlphabetSize;
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <typename L, StringType S>
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonconst int StringWeightGenerator<L, S>::kMaxStringLength;
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns a weight generator over the product of the
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// weights (by default) for the generators G1 and G2.
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class G1, class G2,
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  class W = ProductWeight<typename G1::Weight, typename G2::Weight> >
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass ProductWeightGenerator {
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G1::Weight W1;
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G2::Weight W2;
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef W Weight;
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ProductWeightGenerator(int seed = time(0), bool allow_zero = true)
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : generator1_(seed, allow_zero), generator2_(seed, allow_zero) {}
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W1 w1 = generator1_();
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W2 w2 = generator2_();
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight(w1, w2);
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  G1 generator1_;
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  G2 generator2_;
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns a weight generator for a lexicographic weight
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// composed out of weights for the generators G1 and G2. For lexicographic
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// weights, we cannot generate zeroes for the two subweights separately:
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// weights are members iff both members are zero or both members are non-zero.
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class G1, class G2>
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LexicographicWeightGenerator {
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G1::Weight W1;
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G2::Weight W2;
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef LexicographicWeight<W1, W2> Weight;
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  LexicographicWeightGenerator(int seed = time(0), bool allow_zero = true)
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : generator1_(seed, false), generator2_(seed, false),
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        allow_zero_(allow_zero) {}
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (allow_zero_) {
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      int n = rand() % (kNumRandomWeights + allow_zero_);
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (n == kNumRandomWeights)
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return Weight(W1::Zero(), W2::Zero());
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W1 w1 = generator1_();
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    W2 w2 = generator2_();
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return Weight(w1, w2);
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  G1 generator1_;
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  G2 generator2_;
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kNumRandomWeights = 5;
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool allow_zero_;
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class G1, class G2>
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonconst int LexicographicWeightGenerator<G1, G2>::kNumRandomWeights;
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Product generator of a string weight generator and an
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// arbitrary weight generator.
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class L, class G, StringType S = STRING_LEFT>
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass GallicWeightGenerator
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    : public ProductWeightGenerator<StringWeightGenerator<L, S>, G> {
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef ProductWeightGenerator<StringWeightGenerator<L, S>, G> PG;
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G::Weight W;
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef GallicWeight<L, W, S> Weight;
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  GallicWeightGenerator(int seed = time(0), bool allow_zero = true)
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : PG(seed, allow_zero) {}
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  GallicWeightGenerator(const PG &pg) : PG(pg) {}
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returms a weight generator over the catersian power
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// of rank n of the weights for the generator G.
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class G, unsigned int n>
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass PowerWeightGenerator {
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G::Weight W;
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef PowerWeight<W, n> Weight;
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  PowerWeightGenerator(int seed = time(0), bool allow_zero = true)
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : generator_(seed, allow_zero) {}
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator()() const {
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight w;
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (size_t i = 0; i < n; ++i) {
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      W r = generator_();
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      w.SetValue(i, r);
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return w;
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  G generator_;
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returns SignedLogWeightTpl<T>'s that are
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// random integers chosen from [0, kNumRandomWeights).
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The sign is randomly chosen as well.
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T>
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass SignedLogWeightGenerator_ {
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef SignedLogWeightTpl<T> Weight;
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SignedLogWeightGenerator_(int seed = time(0), bool allow_zero = true)
294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  : allow_zero_(allow_zero) {
295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    srand(seed);
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator() () const {
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int m = rand() % 2;
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    int n = rand() % (kNumRandomWeights + allow_zero_);
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return SignedLogWeightTpl<T>(
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      (m == 0) ?
304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        TropicalWeight(-1.0) :
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        TropicalWeight(1.0),
306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      (allow_zero_ && n == kNumRandomWeights) ?
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        LogWeightTpl<T>::Zero() :
308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        LogWeightTpl<T>(static_cast<T>(n)));
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Number of alternative random weights.
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  static const int kNumRandomWeights = 5;
314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool allow_zero_;  // permit Zero() and zero divisors
315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class T> const int SignedLogWeightGenerator_<T>::kNumRandomWeights;
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontypedef SignedLogWeightGenerator_<float> SignedLogWeightGenerator;
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This function object returms a weight generator over the catersian power
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// of rank n of the weights for the generator G.
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class G, class K, unsigned int n>
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass SparsePowerWeightGenerator {
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename G::Weight W;
327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef SparsePowerWeight<W, K> Weight;
328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  SparsePowerWeightGenerator(int seed = time(0), bool allow_zero = true)
330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : generator_(seed, allow_zero) {}
331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  Weight operator()() const {
333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    Weight w;
334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (size_t i = 1; i <= n; ++i) {
335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      W r = generator_();
336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      K p = i;
337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      w.Push(p, r, true);
338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return w;
340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  G generator_;
344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_LIB_RANDOM_WEIGHT_H__
349