ContextDependency Class Reference

#include <context-dep.h>

Inheritance diagram for ContextDependency:
Collaboration diagram for ContextDependency:

Public Member Functions

virtual int32 ContextWidth () const
 ContextWidth() returns the value N (e.g. More...
 
virtual int32 CentralPosition () const
 Central position P of the phone context, in 0-based numbering, e.g. More...
 
virtual bool Compute (const std::vector< int32 > &phoneseq, int32 pdf_class, int32 *pdf_id) const
 returns success or failure; outputs pdf to pdf_id For positions that were outside the sequence (due to end effects), put zero. More...
 
virtual int32 NumPdfs () const
 NumPdfs() returns the number of acoustic pdfs (they are numbered 0.. NumPdfs()-1). More...
 
virtual ContextDependencyInterfaceCopy () const
 Returns pointer to new object which is copy of current one. More...
 
void Read (std::istream &is, bool binary)
 Read context-dependency object from disk; throws on error. More...
 
 ContextDependency ()
 
 ContextDependency (int32 N, int32 P, EventMap *to_pdf)
 
void Write (std::ostream &os, bool binary) const
 
 ~ContextDependency ()
 
const EventMapToPdfMap () const
 
virtual void GetPdfInfo (const std::vector< int32 > &phones, const std::vector< int32 > &num_pdf_classes, std::vector< std::vector< std::pair< int32, int32 > > > *pdf_info) const
 GetPdfInfo returns a vector indexed by pdf-id, saying for each pdf which pairs of (phone, pdf-class) it can correspond to. More...
 
virtual void GetPdfInfo (const std::vector< int32 > &phones, const std::vector< std::vector< std::pair< int32, int32 > > > &pdf_class_pairs, std::vector< std::vector< std::vector< std::pair< int32, int32 > > > > *pdf_info) const
 This function outputs information about what possible pdf-ids can be generated for HMM-states; it covers the general case where the self-loop pdf-class may be different from the forward-transition pdf-class, so we are asking not about the set of possible pdf-ids for a given (phone, pdf-class), but the set of possible ordered pairs (forward-transition-pdf, self-loop-pdf) for a given (phone, forward-transition-pdf-class, self-loop-pdf-class). More...
 
- Public Member Functions inherited from ContextDependencyInterface
virtual ~ContextDependencyInterface ()
 
 ContextDependencyInterface ()
 

Private Member Functions

void EnumeratePairs (const std::vector< int32 > &phones, int32 self_loop_pdf_class, int32 forward_pdf_class, const std::vector< int32 > &context, unordered_set< std::pair< int32, int32 >, PairHasher< int32 > > *pairs) const
 
 KALDI_DISALLOW_COPY_AND_ASSIGN (ContextDependency)
 

Private Attributes

int32 N_
 
int32 P_
 
EventMapto_pdf_
 

Detailed Description

Definition at line 59 of file context-dep.h.

Constructor & Destructor Documentation

◆ ContextDependency() [1/2]

◆ ContextDependency() [2/2]

ContextDependency ( int32  N,
int32  P,
EventMap to_pdf 
)
inline

Definition at line 91 of file context-dep.h.

References ContextDependency::Write().

92  :
93  N_(N), P_(P), to_pdf_(to_pdf) { }

◆ ~ContextDependency()

~ContextDependency ( )
inline

Definition at line 96 of file context-dep.h.

References ContextDependency::to_pdf_.

96 { delete to_pdf_; }

Member Function Documentation

◆ CentralPosition()

virtual int32 CentralPosition ( ) const
inlinevirtual

Central position P of the phone context, in 0-based numbering, e.g.

P = 1 for typical triphone system. We have to see if we can do without this function.

Implements ContextDependencyInterface.

Definition at line 62 of file context-dep.h.

References ContextDependency::Compute(), and ContextDependency::P_.

Referenced by TrainingGraphCompiler::CompileGraph(), TrainingGraphCompiler::CompileGraphs(), kaldi::InitAmGmmFromOld(), main(), and TrainingGraphCompiler::TrainingGraphCompiler().

62 { return P_; }

◆ Compute()

bool Compute ( const std::vector< int32 > &  phoneseq,
int32  pdf_class,
int32 pdf_id 
) const
virtual

returns success or failure; outputs pdf to pdf_id For positions that were outside the sequence (due to end effects), put zero.

Naturally phoneseq[CentralPosition()] must be nonzero.

Implements ContextDependencyInterface.

Definition at line 26 of file context-dep.cc.

References rnnlm::i, KALDI_ASSERT, KALDI_COMPILE_TIME_ASSERT, kaldi::kPdfClass, EventMap::Map(), ContextDependency::N_, and ContextDependency::to_pdf_.

Referenced by ContextDependency::CentralPosition().

28  {
29  KALDI_ASSERT(static_cast<int32>(phoneseq.size()) == N_);
30  EventType event_vec;
31  event_vec.reserve(N_+1);
32  event_vec.push_back(std::make_pair
33  (static_cast<EventKeyType>(kPdfClass), // -1
34  static_cast<EventValueType>(pdf_class)));
35  KALDI_COMPILE_TIME_ASSERT(kPdfClass < 0); // or it would not be sorted.
36  for (int32 i = 0;i < N_;i++) {
37  event_vec.push_back(std::make_pair
38  (static_cast<EventKeyType>(i),
39  static_cast<EventValueType>(phoneseq[i])));
40  KALDI_ASSERT(static_cast<EventAnswerType>(phoneseq[i]) >= 0);
41  }
42  KALDI_ASSERT(pdf_id != NULL);
43  return to_pdf_->Map(event_vec, pdf_id);
44 }
kaldi::int32 int32
virtual bool Map(const EventType &event, EventAnswerType *ans) const =0
static const EventKeyType kPdfClass
Definition: context-dep.h:39
std::vector< std::pair< EventKeyType, EventValueType > > EventType
Definition: event-map.h:58
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
#define KALDI_COMPILE_TIME_ASSERT(b)
Definition: kaldi-utils.h:131

◆ ContextWidth()

virtual int32 ContextWidth ( ) const
inlinevirtual

ContextWidth() returns the value N (e.g.

3 for triphone models) that says how many phones are considered for computing context.

Implements ContextDependencyInterface.

Definition at line 61 of file context-dep.h.

References ContextDependency::N_.

Referenced by TrainingGraphCompiler::CompileGraph(), TrainingGraphCompiler::CompileGraphs(), kaldi::InitAmGmmFromOld(), main(), and TrainingGraphCompiler::TrainingGraphCompiler().

61 { return N_; }

◆ Copy()

virtual ContextDependencyInterface* Copy ( ) const
inlinevirtual

Returns pointer to new object which is copy of current one.

Implements ContextDependencyInterface.

Definition at line 79 of file context-dep.h.

References ContextDependency::ContextDependency(), EventMap::Copy(), ContextDependency::N_, ContextDependency::P_, ContextDependency::Read(), and ContextDependency::to_pdf_.

79  {
80  return new ContextDependency(N_, P_, to_pdf_->Copy());
81  }
virtual EventMap * Copy(const std::vector< EventMap *> &new_leaves) const =0

◆ EnumeratePairs()

void EnumeratePairs ( const std::vector< int32 > &  phones,
int32  self_loop_pdf_class,
int32  forward_pdf_class,
const std::vector< int32 > &  context,
unordered_set< std::pair< int32, int32 >, PairHasher< int32 > > *  pairs 
) const
private

Definition at line 181 of file context-dep.cc.

References rnnlm::i, KALDI_ASSERT, kaldi::kPdfClass, EventMap::MultiMap(), rnnlm::n, ContextDependency::N_, ContextDependency::P_, kaldi::SortAndUniq(), and ContextDependency::to_pdf_.

Referenced by ContextDependency::GetPdfInfo().

185  {
186  std::vector<int32> new_phone_window(phone_window);
187  EventType vec;
188 
189  std::vector<EventAnswerType> forward_pdfs, self_loop_pdfs;
190 
191  // get list of possible forward pdfs
192  vec.clear();
193  for (size_t i = 0; i < N_; i++)
194  if (phone_window[i] >= 0)
195  vec.push_back(std::make_pair(static_cast<EventKeyType>(i),
196  static_cast<EventValueType>(phone_window[i])));
197  vec.push_back(std::make_pair(kPdfClass, static_cast<EventValueType>(forward_pdf_class)));
198  std::sort(vec.begin(), vec.end());
199  to_pdf_->MultiMap(vec, &forward_pdfs);
200  SortAndUniq(&forward_pdfs);
201 
202  if (self_loop_pdf_class < 0) {
203  // Invalid pdf-class because there was no self-loop. Return pairs
204  // where the self-loop pdf-id is -1.
205  for (int32 forward_pdf: forward_pdfs) {
206  pairs->insert(std::pair<int32,int32>(forward_pdf, -1));
207  }
208  return;
209  }
210 
211  // get list of possible self-loop pdfs
212  vec.clear();
213  for (size_t i = 0; i < N_; i++)
214  if (phone_window[i] >= 0)
215  vec.push_back(std::make_pair(static_cast<EventKeyType>(i),
216  static_cast<EventValueType>(phone_window[i])));
217  vec.push_back(std::make_pair(kPdfClass, static_cast<EventValueType>(self_loop_pdf_class)));
218  std::sort(vec.begin(), vec.end());
219  to_pdf_->MultiMap(vec, &self_loop_pdfs);
220  SortAndUniq(&self_loop_pdfs);
221 
222  if (forward_pdfs.size() == 1 || self_loop_pdfs.size() == 1) {
223  for (size_t m = 0; m < forward_pdfs.size(); m++)
224  for (size_t n = 0; n < self_loop_pdfs.size(); n++)
225  pairs->insert(std::make_pair(forward_pdfs[m], self_loop_pdfs[n]));
226  } else {
227  // Choose 'position' as a phone position in 'context' that's currently
228  // -1, and that is as close as possible to the central position P.
229  int32 position = 0;
230  int32 min_dist = N_ - 1;
231  for (int32 i = 0; i < N_; i++) {
232  int32 dist = (P_ - i > 0) ? (P_ - i) : (i - P_);
233  if (phone_window[i] == -1 && dist < min_dist) {
234  position = i;
235  min_dist = dist;
236  }
237  }
238  KALDI_ASSERT(min_dist < N_);
239  KALDI_ASSERT(position != P_);
240 
241  // The next two lines have to do with how BOS/EOS effects are handled in
242  // phone context. Zero phone value in a non-central position (i.e. not
243  // position P_... and 'position' will never equal P_) means 'there is no
244  // phone here because we're at BOS or EOS'.
245  new_phone_window[position] = 0;
246  EnumeratePairs(phones, self_loop_pdf_class, forward_pdf_class,
247  new_phone_window, pairs);
248 
249  for (size_t i = 0 ; i < phones.size(); i++) {
250  new_phone_window[position] = phones[i];
251  EnumeratePairs(phones, self_loop_pdf_class, forward_pdf_class,
252  new_phone_window, pairs);
253  }
254  }
255 }
kaldi::int32 int32
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq&#39;s (removes duplicates) from a vector.
Definition: stl-utils.h:39
void EnumeratePairs(const std::vector< int32 > &phones, int32 self_loop_pdf_class, int32 forward_pdf_class, const std::vector< int32 > &context, unordered_set< std::pair< int32, int32 >, PairHasher< int32 > > *pairs) const
Definition: context-dep.cc:181
static const EventKeyType kPdfClass
Definition: context-dep.h:39
std::vector< std::pair< EventKeyType, EventValueType > > EventType
Definition: event-map.h:58
struct rnnlm::@11::@12 n
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
virtual void MultiMap(const EventType &event, std::vector< EventAnswerType > *ans) const =0

◆ GetPdfInfo() [1/2]

void GetPdfInfo ( const std::vector< int32 > &  phones,
const std::vector< int32 > &  num_pdf_classes,
std::vector< std::vector< std::pair< int32, int32 > > > *  pdf_info 
) const
virtual

GetPdfInfo returns a vector indexed by pdf-id, saying for each pdf which pairs of (phone, pdf-class) it can correspond to.

(Usually just one). c.f. hmm/hmm-topology.h for meaning of pdf-class. This is the old, simpler interface of GetPdfInfo(), and that this one can only be called if the HmmTopology object's IsHmm() function call returns true.

Implements ContextDependencyInterface.

Definition at line 287 of file context-dep.cc.

References rnnlm::i, kaldi::IsSortedAndUniq(), rnnlm::j, KALDI_ASSERT, KALDI_WARN, kaldi::kPdfClass, EventMap::MultiMap(), ContextDependency::NumPdfs(), ContextDependency::P_, kaldi::SortAndUniq(), and ContextDependency::to_pdf_.

Referenced by kaldi::TestGenRandContextDependency(), kaldi::TestMonophoneContextDependency(), and ContextDependency::ToPdfMap().

290  {
291 
292  EventType vec;
293  KALDI_ASSERT(pdf_info != NULL);
294  pdf_info->resize(NumPdfs());
295  for (size_t i = 0 ; i < phones.size(); i++) {
296  int32 phone = phones[i];
297  vec.clear();
298  vec.push_back(std::make_pair(static_cast<EventKeyType>(P_),
299  static_cast<EventValueType>(phone)));
300  // Now get length.
301  KALDI_ASSERT(static_cast<size_t>(phone) < num_pdf_classes.size());
302  EventAnswerType len = num_pdf_classes[phone];
303 
304  for (int32 pos = 0; pos < len; pos++) {
305  vec.resize(2);
306  vec[0] = std::make_pair(static_cast<EventKeyType>(P_),
307  static_cast<EventValueType>(phone));
308  vec[1] = std::make_pair(kPdfClass, static_cast<EventValueType>(pos));
309  std::sort(vec.begin(), vec.end());
310  std::vector<EventAnswerType> pdfs; // pdfs that can be at this pos as this phone.
311  to_pdf_->MultiMap(vec, &pdfs);
312  SortAndUniq(&pdfs);
313  if (pdfs.empty()) {
314  KALDI_WARN << "ContextDependency::GetPdfInfo, no pdfs returned for position "<< pos << " of phone " << phone << ". Continuing but this is a serious error.";
315  }
316  for (size_t j = 0; j < pdfs.size(); j++) {
317  KALDI_ASSERT(static_cast<size_t>(pdfs[j]) < pdf_info->size());
318  (*pdf_info)[pdfs[j]].push_back(std::make_pair(phone, pos));
319  }
320  }
321  }
322  for (size_t i = 0; i < pdf_info->size(); i++) {
323  std::sort( ((*pdf_info)[i]).begin(), ((*pdf_info)[i]).end());
324  KALDI_ASSERT(IsSortedAndUniq( ((*pdf_info)[i]))); // should have no dups.
325  }
326 }
kaldi::int32 int32
void SortAndUniq(std::vector< T > *vec)
Sorts and uniq&#39;s (removes duplicates) from a vector.
Definition: stl-utils.h:39
static const EventKeyType kPdfClass
Definition: context-dep.h:39
virtual int32 NumPdfs() const
NumPdfs() returns the number of acoustic pdfs (they are numbered 0.. NumPdfs()-1).
Definition: context-dep.h:71
std::vector< std::pair< EventKeyType, EventValueType > > EventType
Definition: event-map.h:58
#define KALDI_WARN
Definition: kaldi-error.h:150
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
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
virtual void MultiMap(const EventType &event, std::vector< EventAnswerType > *ans) const =0
bool IsSortedAndUniq(const std::vector< T > &vec)
Returns true if the vector is sorted and contains each element only once.
Definition: stl-utils.h:63

◆ GetPdfInfo() [2/2]

void GetPdfInfo ( const std::vector< int32 > &  phones,
const std::vector< std::vector< std::pair< int32, int32 > > > &  pdf_class_pairs,
std::vector< std::vector< std::vector< std::pair< int32, int32 > > > > *  pdf_info 
) const
virtual

This function outputs information about what possible pdf-ids can be generated for HMM-states; it covers the general case where the self-loop pdf-class may be different from the forward-transition pdf-class, so we are asking not about the set of possible pdf-ids for a given (phone, pdf-class), but the set of possible ordered pairs (forward-transition-pdf, self-loop-pdf) for a given (phone, forward-transition-pdf-class, self-loop-pdf-class).

Note: 'phones' is a list of integer ids of phones, and 'pdf-class-pairs', indexed by phone, is a list of pairs (forward-transition-pdf-class, self-loop-pdf-class) that we can have for that phone. The output 'pdf_info' is indexed first by phone and then by the same index that indexes each element of 'pdf_class_pairs', and tells us for each pair in 'pdf_class_pairs', what is the list of possible (forward-transition-pdf-id, self-loop-pdf-id) that we can have. This is less efficient than the other version of GetPdfInfo(). Note: if there is no self-loop, the corresponding entry (.second) in pdf_class_pairs and the output pdf_info would be -1.

Implements ContextDependencyInterface.

Definition at line 257 of file context-dep.cc.

References ContextDependency::EnumeratePairs(), rnnlm::i, rnnlm::j, KALDI_ASSERT, ContextDependency::N_, and ContextDependency::P_.

260  {
261 
262  KALDI_ASSERT(pdf_info != NULL);
263  pdf_info->resize(1 + *std::max_element(phones.begin(), phones.end()));
264  std::vector<int32> phone_window(N_, -1);
265  EventType vec;
266  for (size_t i = 0 ; i < phones.size(); i++) {
267  // loop over phones
268  int32 phone = phones[i];
269  (*pdf_info)[phone].resize(pdf_class_pairs[phone].size());
270  for (size_t j = 0; j < pdf_class_pairs[phone].size(); j++) {
271  // loop over pdf_class pairs
272  int32 pdf_class = pdf_class_pairs[phone][j].first,
273  self_loop_pdf_class = pdf_class_pairs[phone][j].second;
274  phone_window[P_] = phone;
275 
276  unordered_set<std::pair<int32, int32>, PairHasher<int32> > pairs;
277  EnumeratePairs(phones, self_loop_pdf_class, pdf_class, phone_window, &pairs);
278  unordered_set<std::pair<int32, int32>, PairHasher<int32> >::iterator iter = pairs.begin(),
279  end = pairs.end();
280  for (; iter != end; ++iter)
281  (*pdf_info)[phone][j].push_back(*iter);
282  std::sort( ((*pdf_info)[phone][j]).begin(), ((*pdf_info)[phone][j]).end());
283  }
284  }
285 }
kaldi::int32 int32
void EnumeratePairs(const std::vector< int32 > &phones, int32 self_loop_pdf_class, int32 forward_pdf_class, const std::vector< int32 > &context, unordered_set< std::pair< int32, int32 >, PairHasher< int32 > > *pairs) const
Definition: context-dep.cc:181
std::vector< std::pair< EventKeyType, EventValueType > > EventType
Definition: event-map.h:58
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185

◆ KALDI_DISALLOW_COPY_AND_ASSIGN()

KALDI_DISALLOW_COPY_AND_ASSIGN ( ContextDependency  )
private

◆ NumPdfs()

virtual int32 NumPdfs ( ) const
inlinevirtual

NumPdfs() returns the number of acoustic pdfs (they are numbered 0.. NumPdfs()-1).

Implements ContextDependencyInterface.

Definition at line 71 of file context-dep.h.

References EventMap::MaxResult(), and ContextDependency::to_pdf_.

Referenced by ContextDependency::GetPdfInfo(), and main().

71  {
72  // this routine could be simplified to return to_pdf_->MaxResult()+1. we're a
73  // bit more paranoid than that.
74  if (!to_pdf_) return 0;
75  EventAnswerType max_result = to_pdf_->MaxResult();
76  if (max_result < 0 ) return 0;
77  else return (int32) max_result+1;
78  }
virtual EventAnswerType MaxResult() const
Definition: event-map.h:142
kaldi::int32 int32
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

◆ Read()

void Read ( std::istream &  is,
bool  binary 
)

Read context-dependency object from disk; throws on error.

Definition at line 155 of file context-dep.cc.

References kaldi::ExpectToken(), KALDI_ERR, ContextDependency::N_, ContextDependency::P_, EventMap::Read(), kaldi::ReadBasicType(), kaldi::ReadToken(), and ContextDependency::to_pdf_.

Referenced by ContextDependency::Copy(), kaldi::InitAmGmmFromOld(), main(), and kaldi::TestGenRandContextDependency().

155  {
156  if (to_pdf_) {
157  delete to_pdf_;
158  to_pdf_ = NULL;
159  }
160  ExpectToken(is, binary, "ContextDependency");
161  ReadBasicType(is, binary, &N_);
162  ReadBasicType(is, binary, &P_);
163  EventMap *to_pdf = NULL;
164  std::string token;
165  ReadToken(is, binary, &token);
166  if (token == "ToLength") { // back-compat.
167  EventMap *to_num_pdf_classes = EventMap::Read(is, binary);
168  delete to_num_pdf_classes;
169  ReadToken(is, binary, &token);
170  }
171  if (token == "ToPdf") {
172  to_pdf = EventMap::Read(is , binary);
173  } else {
174  KALDI_ERR << "Got unexpected token " << token
175  << " reading context-dependency object.";
176  }
177  ExpectToken(is, binary, "EndContextDependency");
178  to_pdf_ = to_pdf;
179 }
void ReadBasicType(std::istream &is, bool binary, T *t)
ReadBasicType is the name of the read function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:55
void ReadToken(std::istream &is, bool binary, std::string *str)
ReadToken gets the next token and puts it in str (exception on failure).
Definition: io-funcs.cc:154
static EventMap * Read(std::istream &is, bool binary)
a Read function that reads an arbitrary EventMap; also works for NULL pointers.
Definition: event-map.cc:36
void ExpectToken(std::istream &is, bool binary, const char *token)
ExpectToken tries to read in the given token, and throws an exception on failure. ...
Definition: io-funcs.cc:191
#define KALDI_ERR
Definition: kaldi-error.h:147

◆ ToPdfMap()

const EventMap& ToPdfMap ( ) const
inline

Definition at line 98 of file context-dep.h.

References ContextDependency::GetPdfInfo(), and ContextDependency::to_pdf_.

Referenced by kaldi::InitAmGmmFromOld(), and main().

98 { return *to_pdf_; }

◆ Write()

void Write ( std::ostream &  os,
bool  binary 
) const

Definition at line 145 of file context-dep.cc.

References ContextDependency::N_, ContextDependency::P_, ContextDependency::to_pdf_, EventMap::Write(), kaldi::WriteBasicType(), and kaldi::WriteToken().

Referenced by ContextDependency::ContextDependency(), main(), and kaldi::TestGenRandContextDependency().

145  {
146  WriteToken(os, binary, "ContextDependency");
147  WriteBasicType(os, binary, N_);
148  WriteBasicType(os, binary, P_);
149  WriteToken(os, binary, "ToPdf");
150  to_pdf_->Write(os, binary);
151  WriteToken(os, binary, "EndContextDependency");
152 }
void WriteToken(std::ostream &os, bool binary, const char *token)
The WriteToken functions are for writing nonempty sequences of non-space characters.
Definition: io-funcs.cc:134
void WriteBasicType(std::ostream &os, bool binary, T t)
WriteBasicType is the name of the write function for bool, integer types, and floating-point types...
Definition: io-funcs-inl.h:34
virtual void Write(std::ostream &os, bool binary)=0
Write to stream.

Member Data Documentation

◆ N_

◆ P_

◆ to_pdf_


The documentation for this class was generated from the following files: