event-map.h
Go to the documentation of this file.
1 // tree/event-map.h
2 
3 // Copyright 2009-2011 Microsoft Corporation; Haihua Xu
4 
5 // See ../../COPYING for clarification regarding multiple authors
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 // http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16 // MERCHANTABLITY OR NON-INFRINGEMENT.
17 // See the Apache 2 License for the specific language governing permissions and
18 // limitations under the License.
19 
20 #ifndef KALDI_TREE_EVENT_MAP_H_
21 #define KALDI_TREE_EVENT_MAP_H_
22 
23 #include <vector>
24 #include <map>
25 #include <algorithm>
26 #include "base/kaldi-common.h"
27 #include "util/stl-utils.h"
28 #include "util/const-integer-set.h"
29 
30 namespace kaldi {
31 
35 
36 
37 // Note RE negative values: some of this code will not work if things of type
38 // EventValueType are negative. In particular, TableEventMap can't be used if
39 // things of EventValueType are negative, and additionally TableEventMap won't
40 // be efficient if things of EventValueType take on extremely large values. The
41 // EventKeyType can be negative though.
42 
46 
52 
57 
58 typedef std::vector<std::pair<EventKeyType, EventValueType> > EventType;
59 // It is required to be sorted and have unique keys-- i.e. functions assume this when called
60 // with this type.
61 
62 inline std::pair<EventKeyType, EventValueType> MakeEventPair (EventKeyType k, EventValueType v) {
63  return std::pair<EventKeyType, EventValueType>(k, v);
64 }
65 
66 void WriteEventType(std::ostream &os, bool binary, const EventType &vec);
67 void ReadEventType(std::istream &is, bool binary, EventType *vec);
68 
69 std::string EventTypeToString(const EventType &evec); // so we can print events out in error messages.
70 
71 struct EventMapVectorHash { // Hashing object for EventMapVector. Works for both pointers and references.
72  // Not used in event-map.{h, cc}
73  size_t operator () (const EventType &vec);
74  size_t operator () (const EventType *ptr) { return (*this)(*ptr); }
75 };
76 struct EventMapVectorEqual { // Equality object for EventType pointers-- test equality of underlying vector.
77  // Not used in event-map.{h, cc}
78  size_t operator () (const EventType *p1, const EventType *p2) { return (*p1 == *p2); }
79 };
80 
81 
86 class EventMap {
87  public:
88  static void Check(const EventType &event); // will crash if not sorted and unique on key.
89  static bool Lookup(const EventType &event, EventKeyType key, EventValueType *ans);
90 
91  // Maps events to the answer type. input must be sorted.
92  virtual bool Map(const EventType &event, EventAnswerType *ans) const = 0;
93 
94  // MultiMap maps a partially specified set of events to the set of answers it might
95  // map to. It appends these to "ans". "ans" is
96  // **not guaranteed unique at output** if the
97  // tree contains duplicate answers at leaves -- you should sort & uniq afterwards.
98  // e.g.: SortAndUniq(ans).
99  virtual void MultiMap(const EventType &event, std::vector<EventAnswerType> *ans) const = 0;
100 
101  // GetChildren() returns the EventMaps that are immediate children of this
102  // EventMap (if they exist), by putting them in *out. Useful for
103  // determining the structure of the event map.
104  virtual void GetChildren(std::vector<EventMap*> *out) const = 0;
105 
106  // This Copy() does a deep copy of the event map.
107  // If new_leaves is nonempty when it reaches a leaf with value l s.t. new_leaves[l] != NULL,
108  // it replaces it with a copy of that EventMap. This makes it possible to extend and modify
109  // It's the way we do splits of trees, and clustering of trees. Think about this carefully, because
110  // the EventMap structure does not support modification of an existing tree. Do not be tempted
111  // to do this differently, because other kinds of mechanisms would get very messy and unextensible.
112  // Copy() is the only mechanism to modify a tree. It's similar to a kind of function composition.
113  // Copy() does not take ownership of the pointers in new_leaves (it uses the Copy() function of those
114  // EventMaps).
115  virtual EventMap *Copy(const std::vector<EventMap*> &new_leaves) const = 0;
116 
117  EventMap *Copy() const { std::vector<EventMap*> new_leaves; return Copy(new_leaves); }
118 
119  // The function MapValues() is intended to be used to map phone-sets between
120  // different integer representations. For all the keys in the set
121  // "keys_to_map", it will map the corresponding values using the map
122  // "value_map". Note: these values are the values in the key->value pairs of
123  // the EventMap, which really correspond to phones in the usual case; they are
124  // not the "answers" of the EventMap which correspond to clustered states. In
125  // case multiple values are mapped to the same value, it will try to deal with
126  // it gracefully where it can, but will crash if, for example, this would
127  // cause problems with the TableEventMap. It will also crash if any values
128  // used for keys in "keys_to_map" are not mapped by "value_map". This
129  // function is not currently used.
130  virtual EventMap *MapValues(
131  const unordered_set<EventKeyType> &keys_to_map,
132  const unordered_map<EventValueType,EventValueType> &value_map) const = 0;
133 
134  // The function Prune() is like Copy(), except it removes parts of the tree
135  // that return only -1 (it will return NULL if this EventMap returns only -1).
136  // This is a mechanism to remove parts of the tree-- you would first use the
137  // Copy() function with a vector of EventMap*, and for the parts you don't
138  // want, you'd put a ConstantEventMap with -1; you'd then call
139  // Prune() on the result. This function is not currently used.
140  virtual EventMap *Prune() const = 0;
141 
142  virtual EventAnswerType MaxResult() const { // child classes may override this for efficiency; here is basic version.
143  // returns -1 if nothing found.
144  std::vector<EventAnswerType> tmp; EventType empty_event;
145  MultiMap(empty_event, &tmp);
146  if (tmp.empty()) {
147  KALDI_WARN << "EventMap::MaxResult(), empty result";
148  return std::numeric_limits<EventAnswerType>::min();
149  }
150  else { return * std::max_element(tmp.begin(), tmp.end()); }
151  }
152 
154  virtual void Write(std::ostream &os, bool binary) = 0;
155 
156  virtual ~EventMap() {}
157 
159  static void Write(std::ostream &os, bool binary, EventMap *emap);
162  static EventMap *Read(std::istream &is, bool binary);
163 };
164 
165 
166 class ConstantEventMap: public EventMap {
167  public:
168  virtual bool Map(const EventType &event, EventAnswerType *ans) const {
169  *ans = answer_;
170  return true;
171  }
172 
173  virtual void MultiMap(const EventType &,
174  std::vector<EventAnswerType> *ans) const {
175  ans->push_back(answer_);
176  }
177 
178  virtual void GetChildren(std::vector<EventMap*> *out) const { out->clear(); }
179 
180  virtual EventMap *Copy(const std::vector<EventMap*> &new_leaves) const {
181  if (answer_ < 0 || answer_ >= (EventAnswerType)new_leaves.size() ||
182  new_leaves[answer_] == NULL)
183  return new ConstantEventMap(answer_);
184  else return new_leaves[answer_]->Copy();
185  }
186 
187  virtual EventMap *MapValues(
188  const unordered_set<EventKeyType> &keys_to_map,
189  const unordered_map<EventValueType,EventValueType> &value_map) const {
190  return new ConstantEventMap(answer_);
191  }
192 
193  virtual EventMap *Prune() const {
194  return (answer_ == -1 ? NULL : new ConstantEventMap(answer_));
195  }
196 
197  explicit ConstantEventMap(EventAnswerType answer): answer_(answer) { }
198 
199  virtual void Write(std::ostream &os, bool binary);
200  static ConstantEventMap *Read(std::istream &is, bool binary);
201  private:
202  EventAnswerType answer_;
204 };
205 
206 class TableEventMap: public EventMap {
207  public:
208 
209  virtual bool Map(const EventType &event, EventAnswerType *ans) const {
210  EventValueType tmp; *ans = -1; // means no answer
211  if (Lookup(event, key_, &tmp) && tmp >= 0
212  && tmp < (EventValueType)table_.size() && table_[tmp] != NULL) {
213  return table_[tmp]->Map(event, ans);
214  }
215  return false;
216  }
217 
218  virtual void GetChildren(std::vector<EventMap*> *out) const {
219  out->clear();
220  for (size_t i = 0; i<table_.size(); i++)
221  if (table_[i] != NULL) out->push_back(table_[i]);
222  }
223 
224  virtual void MultiMap(const EventType &event, std::vector<EventAnswerType> *ans) const {
225  EventValueType tmp;
226  if (Lookup(event, key_, &tmp)) {
227  if (tmp >= 0 && tmp < (EventValueType)table_.size() && table_[tmp] != NULL)
228  return table_[tmp]->MultiMap(event, ans);
229  // else no answers.
230  } else { // all answers are possible if no such key.
231  for (size_t i = 0;i < table_.size();i++)
232  if (table_[i] != NULL) table_[i]->MultiMap(event, ans); // append.
233  }
234  }
235 
236  virtual EventMap *Prune() const;
237 
238  virtual EventMap *MapValues(
239  const unordered_set<EventKeyType> &keys_to_map,
240  const unordered_map<EventValueType,EventValueType> &value_map) const;
241 
243  explicit TableEventMap(EventKeyType key, const std::vector<EventMap*> &table): key_(key), table_(table) {}
245  explicit TableEventMap(EventKeyType key, const std::map<EventValueType, EventMap*> &map_in);
247  explicit TableEventMap(EventKeyType key, const std::map<EventValueType, EventAnswerType> &map_in);
248 
249  virtual void Write(std::ostream &os, bool binary);
250  static TableEventMap *Read(std::istream &is, bool binary);
251 
252  virtual EventMap *Copy(const std::vector<EventMap*> &new_leaves) const {
253  std::vector<EventMap*> new_table_(table_.size(), NULL);
254  for (size_t i = 0;i<table_.size();i++) if (table_[i]) new_table_[i]=table_[i]->Copy(new_leaves);
255  return new TableEventMap(key_, new_table_);
256  }
257  virtual ~TableEventMap() {
258  DeletePointers(&table_);
259  }
260  private:
261  EventKeyType key_;
262  std::vector<EventMap*> table_;
264 };
265 
266 
267 
268 
269 class SplitEventMap: public EventMap { // A decision tree [non-leaf] node.
270  public:
271 
272  virtual bool Map(const EventType &event, EventAnswerType *ans) const {
273  EventValueType value;
274  if (Lookup(event, key_, &value)) {
275  // if (std::binary_search(yes_set_.begin(), yes_set_.end(), value)) {
276  if (yes_set_.count(value)) {
277  return yes_->Map(event, ans);
278  }
279  return no_->Map(event, ans);
280  }
281  return false;
282  }
283 
284  virtual void MultiMap(const EventType &event, std::vector<EventAnswerType> *ans) const {
285  EventValueType tmp;
286  if (Lookup(event, key_, &tmp)) {
287  if (std::binary_search(yes_set_.begin(), yes_set_.end(), tmp))
288  yes_->MultiMap(event, ans);
289  else
290  no_->MultiMap(event, ans);
291  } else { // both yes and no contribute.
292  yes_->MultiMap(event, ans);
293  no_->MultiMap(event, ans);
294  }
295  }
296 
297  virtual void GetChildren(std::vector<EventMap*> *out) const {
298  out->clear();
299  out->push_back(yes_);
300  out->push_back(no_);
301  }
302 
303  virtual EventMap *Copy(const std::vector<EventMap*> &new_leaves) const {
304  return new SplitEventMap(key_, yes_set_, yes_->Copy(new_leaves), no_->Copy(new_leaves));
305  }
306 
307  virtual void Write(std::ostream &os, bool binary);
308  static SplitEventMap *Read(std::istream &is, bool binary);
309 
310  virtual EventMap *Prune() const;
311 
312  virtual EventMap *MapValues(
313  const unordered_set<EventKeyType> &keys_to_map,
314  const unordered_map<EventValueType,EventValueType> &value_map) const;
315 
316  virtual ~SplitEventMap() { Destroy(); }
317 
319  SplitEventMap(EventKeyType key, const std::vector<EventValueType> &yes_set,
320  EventMap *yes, EventMap *no): key_(key), yes_set_(yes_set), yes_(yes), no_(no) {
322  KALDI_ASSERT(yes_ != NULL && no_ != NULL);
323  }
324 
325 
326  private:
328  SplitEventMap(EventKeyType key, const ConstIntegerSet<EventValueType> &yes_set,
329  EventMap *yes, EventMap *no): key_(key), yes_set_(yes_set), yes_(yes), no_(no) {
330  KALDI_ASSERT(yes_ != NULL && no_ != NULL);
331  }
332  void Destroy() {
333  delete yes_; delete no_;
334  }
335  EventKeyType key_;
336  // std::vector<EventValueType> yes_set_;
337  ConstIntegerSet<EventValueType> yes_set_; // more efficient Map function.
338  EventMap *yes_; // owned here.
339  EventMap *no_; // owned here.
340  SplitEventMap &operator = (const SplitEventMap &other); // Disallow.
341 };
342 
356 bool GetTreeStructure(const EventMap &map,
357  int32 *num_leaves,
358  std::vector<int32> *parents);
359 
360 
362 
363 }
364 
365 #endif
bool GetTreeStructure(const EventMap &map, int32 *num_leaves, std::vector< int32 > *parents)
This function gets the tree structure of the EventMap "map" in a convenient form. ...
Definition: event-map.cc:429
EventKeyType key_
Definition: event-map.h:335
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
virtual EventMap * Copy(const std::vector< EventMap *> &new_leaves) const
Definition: event-map.h:180
void DeletePointers(std::vector< A *> *v)
Deletes any non-NULL pointers in the vector v, and sets the corresponding entries of v to NULL...
Definition: stl-utils.h:184
virtual void GetChildren(std::vector< EventMap *> *out) const
Definition: event-map.h:178
std::pair< EventKeyType, EventValueType > MakeEventPair(EventKeyType k, EventValueType v)
Definition: event-map.h:62
virtual bool Map(const EventType &event, EventAnswerType *ans) const
Definition: event-map.h:168
virtual void GetChildren(std::vector< EventMap *> *out) const
Definition: event-map.h:218
virtual ~SplitEventMap()
Definition: event-map.h:316
ConstantEventMap(EventAnswerType answer)
Definition: event-map.h:197
virtual EventAnswerType MaxResult() const
Definition: event-map.h:142
std::string EventTypeToString(const EventType &evec)
Definition: event-map.cc:253
virtual bool Map(const EventType &event, EventAnswerType *ans) const
Definition: event-map.h:209
kaldi::int32 int32
virtual EventMap * Prune() const
Definition: event-map.h:193
#define KALDI_DISALLOW_COPY_AND_ASSIGN(type)
Definition: kaldi-utils.h:121
virtual bool Map(const EventType &event, EventAnswerType *ans) const
Definition: event-map.h:272
EventKeyType key_
Definition: event-map.h:261
virtual ~TableEventMap()
Definition: event-map.h:257
virtual void MultiMap(const EventType &, std::vector< EventAnswerType > *ans) const
Definition: event-map.h:173
std::vector< EventMap * > table_
Definition: event-map.h:262
void WriteEventType(std::ostream &os, bool binary, const EventType &evec)
Definition: event-map.cc:228
virtual EventMap * Copy(const std::vector< EventMap *> &new_leaves) const
Definition: event-map.h:303
std::vector< std::pair< EventKeyType, EventValueType > > EventType
Definition: event-map.h:58
virtual EventMap * MapValues(const unordered_set< EventKeyType > &keys_to_map, const unordered_map< EventValueType, EventValueType > &value_map) const
Definition: event-map.h:187
SplitEventMap(EventKeyType key, const std::vector< EventValueType > &yes_set, EventMap *yes, EventMap *no)
This constructor takes ownership of the "yes" and "no" arguments.
Definition: event-map.h:319
EventAnswerType answer_
Definition: event-map.h:202
virtual void MultiMap(const EventType &event, std::vector< EventAnswerType > *ans) const
Definition: event-map.h:284
SplitEventMap(EventKeyType key, const ConstIntegerSet< EventValueType > &yes_set, EventMap *yes, EventMap *no)
This constructor used in the Copy() function.
Definition: event-map.h:328
size_t operator()(const EventType &vec)
Definition: event-map.cc:264
int32 EventKeyType
Things of type EventKeyType can take any value.
Definition: event-map.h:45
void ReadEventType(std::istream &is, bool binary, EventType *evec)
Definition: event-map.cc:239
#define KALDI_PARANOID_ASSERT(cond)
Definition: kaldi-error.h:206
virtual void MultiMap(const EventType &event, std::vector< EventAnswerType > *ans) const
Definition: event-map.h:224
virtual void GetChildren(std::vector< EventMap *> *out) const
Definition: event-map.h:297
#define KALDI_WARN
Definition: kaldi-error.h:150
virtual EventMap * Copy(const std::vector< EventMap *> &new_leaves) const =0
ConstIntegerSet< EventValueType > yes_set_
Definition: event-map.h:337
EventMap * Copy() const
Definition: event-map.h:117
virtual ~EventMap()
Definition: event-map.h:156
A class that is capable of representing a generic mapping from EventType (which is a vector of (key...
Definition: event-map.h:86
bool IsSorted(const std::vector< T > &vec)
Returns true if the vector is sorted.
Definition: stl-utils.h:47
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
TableEventMap(EventKeyType key, const std::vector< EventMap *> &table)
Takes ownership of pointers.
Definition: event-map.h:243
int32 EventAnswerType
As far as the event-map code itself is concerned, things of type EventAnswerType may take any value e...
Definition: event-map.h:56
int32 EventValueType
Given current code, things of type EventValueType should generally be nonnegative and in a reasonably...
Definition: event-map.h:51
virtual EventMap * Copy(const std::vector< EventMap *> &new_leaves) const
Definition: event-map.h:252
void Copy(const CuMatrixBase< Real > &src, const CuArray< int32 > &copy_from_indices, CuMatrixBase< Real > *tgt)
Copies elements from src into tgt as given by copy_from_indices.
Definition: cu-math.cc:173