Blame view
tools/openfst-1.6.7/src/test/rand-fst.h
2.44 KB
8dcb6dfcb first commit |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
#ifndef FST_TEST_RAND_FST_H_ #define FST_TEST_RAND_FST_H_ #include <fst/log.h> #include <fst/mutable-fst.h> #include <fst/verify.h> namespace fst { // Generates a random FST. template <class Arc, class WeightGenerator> void RandFst(const int num_random_states, const int num_random_arcs, const int num_random_labels, const float acyclic_prob, WeightGenerator *weight_generator, MutableFst<Arc> *fst) { typedef typename Arc::Label Label; typedef typename Arc::StateId StateId; typedef typename Arc::Weight Weight; // Determines direction of the arcs wrt state numbering. This way we // can force acyclicity when desired. enum ArcDirection { ANY_DIRECTION = 0, FORWARD_DIRECTION = 1, REVERSE_DIRECTION = 2, NUM_DIRECTIONS = 3 }; ArcDirection arc_direction = ANY_DIRECTION; if (rand() / (RAND_MAX + 1.0) < acyclic_prob) arc_direction = rand() % 2 ? FORWARD_DIRECTION : REVERSE_DIRECTION; fst->DeleteStates(); StateId ns = rand() % num_random_states; if (ns == 0) return; for (StateId s = 0; s < ns; ++s) fst->AddState(); StateId start = rand() % ns; fst->SetStart(start); size_t na = rand() % num_random_arcs; for (size_t n = 0; n < na; ++n) { StateId s = rand() % ns; Arc arc; arc.ilabel = rand() % num_random_labels; arc.olabel = rand() % num_random_labels; arc.weight = (*weight_generator)(); arc.nextstate = rand() % ns; if ((arc_direction == FORWARD_DIRECTION || arc_direction == REVERSE_DIRECTION) && s == arc.nextstate) { continue; // skips self-loops } if ((arc_direction == FORWARD_DIRECTION && s > arc.nextstate) || (arc_direction == REVERSE_DIRECTION && s < arc.nextstate)) { StateId t = s; // reverses arcs s = arc.nextstate; arc.nextstate = t; } fst->AddArc(s, arc); } StateId nf = rand() % (ns + 1); for (StateId n = 0; n < nf; ++n) { StateId s = rand() % ns; Weight final = (*weight_generator)(); fst->SetFinal(s, final); } VLOG(1) << "Check FST for sanity (including property bits)."; CHECK(Verify(*fst)); // Get/compute all properties. uint64 props = fst->Properties(kFstProperties, true); // Select random set of properties to be unknown. uint64 mask = 0; for (int n = 0; n < 8; ++n) { mask |= rand() & 0xff; mask <<= 8; } mask &= ~kTrinaryProperties; fst->SetProperties(props & ~mask, mask); } } // namespace fst #endif // FST_TEST_RAND_FST_H_ |