47 float delta = fst::kDelta):
51 if (
clat_->Properties(kTopSorted,
true) == 0) {
52 if (!TopSort(
clat_)) {
53 KALDI_WARN <<
"Topological sorting of state-level lattice failed " 54 "(probably your lexicon has empty words or your LM has epsilon cycles; this " 66 const HashType prime = 53281;
68 HashType ans =
static_cast<HashType
>(h(vec));
69 if (ans == 0) ans = prime;
75 static void InitHashValue(
const CompactWeight &final_weight, HashType *h) {
76 const HashType prime1 = 33317, prime2 = 607;
86 HashType &next_state_hash,
88 const HashType prime1 = 1447, prime2 = 51907;
89 if (label == 0) label = prime2;
90 *h += prime1 * label *
101 for (StateId s =
clat_->NumStates() - 1; s >= 0; s--) {
104 for (ArcIterator<MutableFst<CompactArc> > aiter(*
clat_, s);
105 !aiter.Done(); aiter.Next()) {
106 const CompactArc &arc = aiter.Value();
108 if (arc.nextstate > s) {
112 "Lattice not topologically sorted [code error]");
114 KALDI_WARN <<
"Minimizing lattice with self-loops " 115 "(lattices should not have self-loops)";
118 next_hash, &this_hash);
136 bool operator () (
const CompactArc &a,
const CompactArc &b)
const {
137 if (a.ilabel < b.ilabel)
return true;
138 else if (a.ilabel > b.ilabel)
return false;
139 else if (a.nextstate < b.nextstate)
return true;
153 std::vector<CompactArc> s_arcs;
154 std::vector<CompactArc> t_arcs;
155 for (
int32 iter = 0; iter <= 1; iter++) {
156 StateId state = (iter == 0 ? s : t);
157 std::vector<CompactArc> &arcs = (iter == 0 ? s_arcs : t_arcs);
158 arcs.reserve(
clat_->NumArcs(s));
159 for (ArcIterator<MutableFst<CompactArc> > aiter(*
clat_, state);
160 !aiter.Done(); aiter.Next()) {
161 CompactArc arc = aiter.Value();
162 if (arc.nextstate == state) {
165 arc.nextstate = kNoStateId;
174 std::sort(arcs.begin(), arcs.end(), s);
177 for (
size_t i = 0;
i < s_arcs.size();
i++) {
178 if (s_arcs[
i].nextstate != t_arcs[
i].nextstate)
return false;
182 if (s_arcs[
i].ilabel != t_arcs[
i].ilabel)
return false;
184 if (s_arcs[
i].nextstate != t_arcs[
i].nextstate)
return false;
185 if (!
ApproxEqual(s_arcs[
i].weight, t_arcs[
i].weight))
return false;
194 StateId num_states =
clat_->NumStates();
195 unordered_map<HashType, std::vector<StateId> > hash_groups_;
197 for (StateId s = 0; s < num_states; s++)
201 for (StateId s = 0; s < num_states; s++)
206 typedef typename unordered_map<
HashType,
207 std::vector<StateId> >::const_iterator HashIter;
209 for (HashIter iter = hash_groups_.begin(); iter != hash_groups_.end();
211 max_size = std::max(max_size, iter->second.size());
212 if (max_size > 1000) {
213 KALDI_WARN <<
"Largest equivalence group (using hash) is " << max_size
214 <<
", minimization might be slow.";
218 for (StateId s = num_states - 1; s >= 0; s--) {
220 const std::vector<StateId> &equivalence_class = hash_groups_[hash];
222 for (
size_t i = 0;
i < equivalence_class.size();
i++) {
223 StateId t = equivalence_class[
i];
238 StateId num_removed = 0;
239 StateId num_states =
clat_->NumStates();
240 for (StateId s = 0; s < num_states; s++)
243 KALDI_VLOG(3) <<
"Removing " << num_removed <<
" of " 244 << num_states <<
" states.";
245 if (num_removed == 0)
return;
249 for (StateId s = 0; s < num_states; s++) {
252 for (MutableArcIterator<MutableFst<CompactArc> > aiter(
clat_, s);
253 !aiter.Done(); aiter.Next()) {
254 CompactArc arc = aiter.Value();
255 StateId mapped_nextstate =
state_map_[arc.nextstate];
256 if (mapped_nextstate != arc.nextstate) {
257 arc.nextstate = mapped_nextstate;
265 MutableFst<ArcTpl<CompactLatticeWeightTpl<Weight, IntType> > > *
clat_;
273 template<
class Weight,
class IntType>
283 bool MinimizeCompactLattice<kaldi::LatticeWeight, kaldi::int32>(
284 MutableFst<kaldi::CompactLatticeArc> *clat,
float delta);
fst::StdArc::StateId StateId
static void InitHashValue(const CompactWeight &final_weight, HashType *h)
static void UpdateHashValueForTransition(const CompactWeight &weight, Label label, HashType &next_state_hash, HashType *h)
A hashing function-object for vectors.
bool operator()(const CompactArc &a, const CompactArc &b) const
bool Equivalent(StateId s, StateId t) const
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
CompactArc::StateId StateId
bool ApproxEqual(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2, float delta=kDelta)
std::vector< StateId > state_map_
CompactLatticeWeightTpl< Weight, IntType > CompactWeight
bool MinimizeCompactLattice(MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *clat, float delta)
This function minimizes the compact lattice.
static HashType ConvertStringToHashValue(const std::vector< IntType > &vec)
ArcTpl< CompactWeight > CompactArc
#define KALDI_ASSERT(cond)
std::vector< HashType > state_hashes_
static const CompactLatticeWeightTpl< WeightType, IntType > Zero()
MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > * clat_
CompactLatticeMinimizer(MutableFst< CompactArc > *clat, float delta=fst::kDelta)
const std::vector< IntType > & String() const
void ComputeStateHashValues()