compare-int-vector.cc
Go to the documentation of this file.
1 // bin/compare-int-vector.cc
2 
3 // Copyright 2018 Johns Hopkins University (Author: Daniel Povey)
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 #include "base/kaldi-common.h"
21 #include "util/common-utils.h"
22 #include "matrix/kaldi-vector.h"
24 #include <iomanip>
25 
26 
27 namespace kaldi {
28 void AddToCount(int32 location_to_add,
29  double value_to_add,
30  std::vector<double> *counts) {
31  if (location_to_add < 0)
32  KALDI_ERR << "Contents of vectors cannot be "
33  "negative if --write-tot-counts or --write-diff-counts "
34  "options are provided.";
35  if (counts->size() <= static_cast<size_t>(location_to_add))
36  counts->resize(location_to_add + 1, 0.0);
37  (*counts)[location_to_add] += value_to_add;
38 }
39 
40 void AddToConfusionMatrix(int32 phone1, int32 phone2,
41  Matrix<double> *counts) {
42  if (phone1 < 0 || phone2 < 0)
43  KALDI_ERR << "Contents of vectors cannot be "
44  "negative if --write-confusion-matrix option is "
45  "provided.";
46  int32 max_size = std::max<int32>(phone1, phone2) + 1;
47  if (counts->NumRows() < max_size)
48  counts->Resize(max_size, max_size, kCopyData);
49  (*counts)(phone1, phone2) += 1.0;
50 }
51 
52 
53 void WriteAsKaldiVector(const std::vector<double> &counts,
54  std::string &wxfilename,
55  bool binary) {
56  Vector<BaseFloat> counts_vec(counts.size());
57  for (size_t i = 0; i < counts.size(); i++)
58  counts_vec(i) = counts[i];
59  WriteKaldiObject(counts_vec, wxfilename, binary);
60 }
61 
62 } // namespace kaldi
63 
64 int main(int argc, char *argv[]) {
65  try {
66  using namespace kaldi;
67 
68  const char *usage =
69  "Compare vectors of integers (e.g. phone alignments)\n"
70  "Prints to stdout fields of the form:\n"
71  "<utterance-id> <num-frames-in-utterance> <num-frames-that-differ>\n"
72  "\n"
73  "e.g.:\n"
74  " SWB1_A_31410_32892 420 36\n"
75  "\n"
76  "Usage:\n"
77  "compare-int-vector [options] <vector1-rspecifier> <vector2-rspecifier>\n"
78  "\n"
79  "e.g. compare-int-vector scp:foo.scp scp:bar.scp > comparison\n"
80  "E.g. the inputs might come from ali-to-phones.\n"
81  "Warnings are printed if the vector lengths differ for a given utterance-id,\n"
82  "and in those cases, the number of frames printed will be the smaller of the\n"
83  "\n"
84  "See also: ali-to-phones, copy-int-vector\n";
85 
86 
87  ParseOptions po(usage);
88 
89  std::string tot_wxfilename,
90  diff_wxfilename,
91  confusion_matrix_wxfilename;
92  bool binary = true;
93 
94  po.Register("binary", &binary, "If true, write in binary mode (only applies "
95  "if --write-tot-counts or --write-diff-counts options are supplied).");
96  po.Register("write-tot-counts", &tot_wxfilename, "Filename to write "
97  "vector of total counts. These may be summed with 'vector-sum'.");
98  po.Register("write-diff-counts", &diff_wxfilename, "Filename to write "
99  "vector of counts of phones (or whatever is in the inputs) "
100  "that differ from one vector to the other. Each time a pair differs, "
101  "0.5 will be added to each one's location.");
102  po.Register("write-confusion-matrix", &confusion_matrix_wxfilename,
103  "Filename to write confusion matrix, indexed by [phone1][phone2]."
104  "These may be summed by 'matrix-sum'.");
105 
106  po.Read(argc, argv);
107 
108  if (po.NumArgs() != 2) {
109  po.PrintUsage();
110  exit(1);
111  }
112 
113  std::string vector1_rspecifier = po.GetArg(1),
114  vector2_rspecifier = po.GetArg(2);
115 
116  int64 num_done = 0,
117  num_not_found = 0,
118  num_mismatched_lengths = 0,
119  tot_frames = 0, tot_difference = 0;
120 
121  std::vector<double> diff_counts;
122  std::vector<double> tot_counts;
123  Matrix<double> confusion_matrix;
124 
125  SequentialInt32VectorReader reader1(vector1_rspecifier);
126  RandomAccessInt32VectorReader reader2(vector2_rspecifier);
127 
128  for (; !reader1.Done(); reader1.Next(), num_done++) {
129  const std::string &key = reader1.Key();
130  if (!reader2.HasKey(key)) {
131  KALDI_WARN << "No key " << key << " found in second input.";
132  num_not_found++;
133  continue;
134  }
135  const std::vector<int32> &value1 = reader1.Value(),
136  &value2 = reader2.Value(key);
137  size_t len1 = value1.size(), len2 = value2.size();
138  if (len1 != len2) {
139  KALDI_WARN << "For utterance " << key << ", lengths differ "
140  << len1 << " vs. " << len2;
141  num_mismatched_lengths++;
142  }
143  size_t len = std::min(len1, len2),
144  difference = 0;
145  for (size_t i = 0; i < len; i++) {
146  int32 phone1 = value1[i], phone2 = value2[i];
147  if (phone1 != phone2) {
148  difference++;
149  if (!diff_wxfilename.empty()) {
150  AddToCount(phone1, 0.5, &diff_counts);
151  AddToCount(phone2, 0.5, &diff_counts);
152  }
153  }
154  if (!tot_wxfilename.empty())
155  AddToCount(phone1, 1.0, &tot_counts);
156  if (!confusion_matrix_wxfilename.empty())
157  AddToConfusionMatrix(phone1, phone2, &confusion_matrix);
158  }
159  num_done++;
160  std::cout << key << " " << len << " " << difference << "\n";
161  tot_frames += len;
162  tot_difference += difference;
163  }
164 
165  BaseFloat difference_percent = tot_difference * 100.0 / tot_frames;
166  KALDI_LOG << "Computed difference for " << num_done << " utterances, of which "
167  << num_mismatched_lengths << " had mismatched lengths; corresponding "
168  "utterance not found for " << num_not_found;
169  KALDI_LOG << "Average p(different) is " << std::setprecision(4) << difference_percent
170  << "%, over " << tot_frames << " frames.";
171 
172  if (!tot_wxfilename.empty())
173  WriteAsKaldiVector(tot_counts, tot_wxfilename, binary);
174  if (!diff_wxfilename.empty())
175  WriteAsKaldiVector(diff_counts, diff_wxfilename, binary);
176  if (!confusion_matrix_wxfilename.empty())
177  WriteKaldiObject(confusion_matrix, confusion_matrix_wxfilename, binary);
178 
179  return (num_done != 0 ? 0 : 1);
180  } catch(const std::exception &e) {
181  std::cerr << e.what();
182  return -1;
183  }
184 }
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void PrintUsage(bool print_command_line=false)
Prints the usage documentation [provided in the constructor].
kaldi::int32 int32
void Register(const std::string &name, bool *ptr, const std::string &doc)
Allows random access to a collection of objects in an archive or script file; see The Table concept...
Definition: kaldi-table.h:233
void WriteAsKaldiVector(const std::vector< double > &counts, std::string &wxfilename, bool binary)
float BaseFloat
Definition: kaldi-types.h:29
The class ParseOptions is for parsing command-line options; see Parsing command-line options for more...
Definition: parse-options.h:36
const T & Value(const std::string &key)
A templated class for reading objects sequentially from an archive or script file; see The Table conc...
Definition: kaldi-table.h:287
int Read(int argc, const char *const *argv)
Parses the command line options and fills the ParseOptions-registered variables.
#define KALDI_ERR
Definition: kaldi-error.h:147
#define KALDI_WARN
Definition: kaldi-error.h:150
std::string GetArg(int param) const
Returns one of the positional parameters; 1-based indexing for argc/argv compatibility.
bool HasKey(const std::string &key)
int NumArgs() const
Number of positional parameters (c.f. argc-1).
A class representing a vector.
Definition: kaldi-vector.h:406
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
Definition: kaldi-matrix.h:64
void WriteKaldiObject(const C &c, const std::string &filename, bool binary)
Definition: kaldi-io.h:257
void Resize(const MatrixIndexT r, const MatrixIndexT c, MatrixResizeType resize_type=kSetZero, MatrixStrideType stride_type=kDefaultStride)
Sets matrix to a specified size (zero is OK as long as both r and c are zero).
int main(int argc, char *argv[])
#define KALDI_LOG
Definition: kaldi-error.h:153
void AddToCount(int32 location_to_add, double value_to_add, std::vector< double > *counts)
void AddToConfusionMatrix(int32 phone1, int32 phone2, Matrix< double > *counts)