online-feat-input.cc
Go to the documentation of this file.
1 // online/online-feat-input.cc
2 
3 // Copyright 2012 Cisco Systems (author: Matthias Paulik)
4 
5 // Modifications to the original contribution by Cisco Systems made by:
6 // Vassil Panayotov
7 // Johns Hopkins University (author: Daniel Povey)
8 
9 // See ../../COPYING for clarification regarding multiple authors
10 //
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 //
15 // http://www.apache.org/licenses/LICENSE-2.0
16 //
17 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
19 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
20 // MERCHANTABLITY OR NON-INFRINGEMENT.
21 // See the Apache 2 License for the specific language governing permissions and
22 // limitations under the License.
23 
24 #include "online-feat-input.h"
25 
26 namespace kaldi {
27 
28 
29 // This is a wrapper for ComputeInternal. It behaves exactly the
30 // same as ComputeInternal, except that at the start of the file,
31 // ComputeInternal may return empty output multiple times in a row.
32 // This function prevents those initial non-productive calls, which
33 // may otherwise confuse decoder code into thinking there is
34 // a problem with the stream (too many timeouts), and cause it to fail.
36 
37  int32 orig_nr = output->NumRows(), orig_nc = output->NumCols();
38  int32 initial_t_in = t_in_;
39  bool ans;
40  while ((ans = ComputeInternal(output))) {
41  if (output->NumRows() == 0 &&
42  t_in_ != initial_t_in) {
43  // we produced no output but added to our internal buffer.
44  // Call ComputeInternal again.
45  initial_t_in = t_in_;
46  output->Resize(orig_nr, orig_nc); // make the same request.
47  } else {
48  return ans;
49  }
50  }
51  return ans;
52  // ans = false. If ComputeInternal returned false,
53  // it means we are done, so no point calling it again.
54 }
55 
56 
58  bool more_data) const {
59  // Tells the caller, assuming we get given "num_new_frames" of input (and
60  // given knowledge of whether there is more data coming), how many frames
61  // would we be able to output?
62 
63  int32 max_t = t_in_ + num_new_frames;
64  if (max_t >= min_window_ || !more_data) {
65  // If this takes us to "min_window_" frames, we'll output all we have.
66  return num_new_frames + t_in_ - t_out_;
67  } else {
68  return 0; // We'll wait till we have at least "min_window_" frames.
69  }
70 }
71 
72 
73 // What happens at the start of the utterance is not really ideal, it would be
74 // better to have some "fake stats" extracted from typical data from this domain,
75 // to start with. We'll have to do this later.
77  KALDI_ASSERT(output->NumRows() > 0 && output->NumCols() == Dim());
78 
79  Matrix<BaseFloat> input;
80  input.Swap(output);
81 
82  bool more_data = input_->Compute(&input);
83 
84  int32 num_input_frames = input.NumRows();
85 
86  int32 output_frames = NumOutputFrames(num_input_frames,
87  more_data);
88  output->Resize(output_frames,
89  output_frames == 0 ? 0 : Dim());
90 
91  int32 output_counter = 0;
92  for (int32 i = 0; i < num_input_frames; i++) {
93  AcceptFrame(input.Row(i));
94  while (t_in_ >= cmn_window_ && t_out_ < t_in_) {
95  // We must output a frame now or we'll overwrite
96  // frames we need in the buffer.
97  SubVector<BaseFloat> this_frame(*output, output_counter);
98  OutputFrame(&this_frame);
99  output_counter++;
100  }
101  }
102  for (; output_counter < output_frames; output_counter++) {
103  SubVector<BaseFloat> this_frame(*output, output_counter);
104  OutputFrame(&this_frame);
105  }
106  return more_data;
107 }
108 
111  history_.Row(t_in_ % (cmn_window_ + 1)).CopyFromVec(input);
112  t_in_++;
113 }
114 
115 // Output the frame indexed "t_out_".
117  KALDI_ASSERT(t_out_ < t_in_); // or there is nothing to output.
118  // First set "sum_".
119  if (t_out_ == 0) { // This is the first request for an output frame,
120  // so in general we need to set sum_ to the sum of the first "min_window_"
121  // frames. We will have less than min_window_ frames if the input finished
122  // before then (if the input were not finished, we'd not have reached this
123  // code).
124  int32 num_frames = t_in_ < min_window_ ? t_in_ : min_window_;
125  for (int32 i = 0; i < num_frames; i++)
126  sum_.AddVec(1.0, history_.Row(i));
127  }
128  int32 num_history_frames;
129  if (t_out_ >= cmn_window_) num_history_frames = cmn_window_;
130  else if (t_out_ < min_window_)
131  num_history_frames = (t_in_ < min_window_ ? t_in_ : min_window_);
132  else
133  num_history_frames = t_out_;
134 
135  SubVector<BaseFloat> input_frame(history_, t_out_ % (cmn_window_ + 1));
136  output->CopyFromVec(input_frame);
137  output->AddVec(-1.0 / num_history_frames, sum_); // Apply CMN to the output.
138 
139  // Update sum.
140  if (t_out_ >= min_window_)
141  sum_.AddVec(1.0, input_frame);
142  if (t_out_ >= cmn_window_) { // Remove the frame from "cmn_window_" frames ago.
143  sum_.AddVec(-1.0, history_.Row((t_out_ - cmn_window_) % (cmn_window_ + 1)));
144  KALDI_ASSERT(t_in_ == t_out_ + 1); // or else the frame indexed t_out_ -
145  // cmn_window_ would not be the right one.
146  }
147  t_out_++;
148 }
149 
150 #if !defined(_MSC_VER)
151 
153  feature_dim_(feature_dim) {
154  server_addr_.sin_family = AF_INET; // IPv4
155  server_addr_.sin_addr.s_addr = INADDR_ANY; // listen on all interfaces
156  server_addr_.sin_port = htons(port);
157  sock_desc_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
158  if (sock_desc_ == -1)
159  KALDI_ERR << "socket() call failed!";
160  int32 rcvbuf_size = 30000;
161  if (setsockopt(sock_desc_, SOL_SOCKET, SO_RCVBUF,
162  &rcvbuf_size, sizeof(rcvbuf_size)) == -1)
163  KALDI_ERR << "setsockopt() failed to set receive buffer size!";
164  if (bind(sock_desc_,
165  reinterpret_cast<sockaddr*>(&server_addr_),
166  sizeof(server_addr_)) == -1)
167  KALDI_ERR << "bind() call failed!";
168 }
169 
170 
172  char buf[65535];
173  socklen_t caddr_len = sizeof(client_addr_);
174  ssize_t nrecv = recvfrom(sock_desc_, buf, sizeof(buf), 0,
175  reinterpret_cast<sockaddr*>(&client_addr_),
176  &caddr_len);
177  if (nrecv == -1) {
178  KALDI_WARN << "recvfrom() call error!";
179  output->Resize(0, 0);
180  return false;
181  }
182  std::stringstream ss(std::stringstream::in | std::stringstream::out);
183  ss.write(buf, nrecv);
184  output->Read(ss, true);
185  return true;
186 }
187 
188 #endif
189 
190 
192  const Matrix<BaseFloat> &transform,
193  int32 left_context,
194  int32 right_context):
195  input_(input), input_dim_(input->Dim()),
196  left_context_(left_context), right_context_(right_context) {
197 
198  int32 tot_context = left_context + 1 + right_context;
199  if (transform.NumCols() == input_dim_ * tot_context) {
200  linear_transform_ = transform;
201  // and offset_ stays empty.
202  } else if (transform.NumCols() == input_dim_ * tot_context + 1) {
203  linear_transform_.Resize(transform.NumRows(), transform.NumCols() - 1);
204  linear_transform_.CopyFromMat(transform.Range(0, transform.NumRows(),
205  0, transform.NumCols() - 1));
206  offset_.Resize(transform.NumRows());
207  offset_.CopyColFromMat(transform, transform.NumCols() - 1);
208  } else {
209  KALDI_ERR << "Invalid parameters supplied to OnlineLdaInput";
210  }
211 }
212 
213 // static
215  const MatrixBase<BaseFloat> &input2,
216  const MatrixBase<BaseFloat> &input3,
217  int32 context_window,
218  Matrix<BaseFloat> *output) {
219  KALDI_ASSERT(context_window > 0);
220  const int32 size1 = input1.NumRows(), size2 = input2.NumRows(),
221  size3 = input3.NumRows();
222  int32 num_frames_in = size1 + size2 + size3,
223  num_frames_out = num_frames_in - (context_window - 1),
224  dim = std::max(input1.NumCols(), std::max(input2.NumCols(), input3.NumCols()));
225  // do std::max in case one or more of the input matrices is empty.
226 
227  if (num_frames_out <= 0) {
228  output->Resize(0, 0);
229  return;
230  }
231  output->Resize(num_frames_out, dim * context_window);
232  for (int32 t_out = 0; t_out < num_frames_out; t_out++) {
233  for (int32 pos = 0; pos < context_window; pos++) {
234  int32 t_in = t_out + pos;
235  SubVector<BaseFloat> vec_out(output->Row(t_out), pos * dim, dim);
236  if (t_in < size1)
237  vec_out.CopyFromVec(input1.Row(t_in));
238  else if (t_in < size1 + size2)
239  vec_out.CopyFromVec(input2.Row(t_in - size1));
240  else
241  vec_out.CopyFromVec(input3.Row(t_in - size1 - size2));
242  }
243  }
244 }
245 
247  Matrix<BaseFloat> *output) {
248  if (spliced_feats.NumRows() == 0) {
249  output->Resize(0, 0);
250  } else {
251  output->Resize(spliced_feats.NumRows(), linear_transform_.NumRows());
252  output->AddMatMat(1.0, spliced_feats, kNoTrans,
253  linear_transform_, kTrans, 0.0);
254  if (offset_.Dim() != 0)
255  output->AddVecToRows(1.0, offset_);
256  }
257 }
258 
260  KALDI_ASSERT(output->NumRows() > 0 &&
261  output->NumCols() == linear_transform_.NumRows());
262  // If output->NumRows() == 0, it corresponds to a request for zero frames,
263  // which makes no sense.
264 
265  // We request the same number of frames of data that we were requested.
266  Matrix<BaseFloat> input(output->NumRows(), input_dim_);
267  bool ans = input_->Compute(&input);
268  // If we got no input (timed out) and we're not at the end, we return
269  // empty output.
270 
271  if (input.NumRows() == 0 && ans) {
272  output->Resize(0, 0);
273  return ans;
274  } else if (input.NumRows() == 0 && !ans) {
275  // The end of the input stream, but no input this time.
276  if (remainder_.NumRows() == 0) {
277  output->Resize(0, 0);
278  return ans;
279  }
280  }
281 
282  // If this is the first segment of the utterance, we put in the
283  // initial duplicates of the first frame, numbered "left_context".
284  if (remainder_.NumRows() == 0 && input.NumRows() != 0 && left_context_ != 0) {
286  for (int32 i = 0; i < left_context_; i++)
287  remainder_.Row(i).CopyFromVec(input.Row(0));
288  }
289 
290  // If this is the last segment, we put in the final duplicates of the
291  // last frame, numbered "right_context".
292  Matrix<BaseFloat> tail;
293  if (!ans && right_context_ > 0) {
295  for (int32 i = 0; i < right_context_; i++) {
296  if (input.NumRows() > 0)
297  tail.Row(i).CopyFromVec(input.Row(input.NumRows() - 1));
298  else
299  tail.Row(i).CopyFromVec(remainder_.Row(remainder_.NumRows() - 1));
300  }
301  }
302 
303  Matrix<BaseFloat> spliced_feats;
304  int32 context_window = left_context_ + 1 + right_context_;
305  // The next line is a call to a member function.
306  SpliceFrames(remainder_, input, tail, context_window, &spliced_feats);
307  TransformToOutput(spliced_feats, output);
308  ComputeNextRemainder(input);
309  return ans;
310 }
311 
313  // The size of the remainder that we propagate to the next frame is
314  // context_window - 1, if available.
315  int32 context_window = left_context_ + 1 + right_context_;
316  int32 next_remainder_len = std::min(context_window - 1,
317  remainder_.NumRows() + input.NumRows());
318  if (next_remainder_len == 0) {
319  remainder_.Resize(0, 0);
320  return;
321  }
322  Matrix<BaseFloat> next_remainder(next_remainder_len, input_dim_);
323  int32 rsize = remainder_.NumRows(), isize = input.NumRows();
324  for (int32 i = 0; i < next_remainder_len; i++) {
325  SubVector<BaseFloat> dest(next_remainder, i);
326  int32 t = (rsize + isize) - next_remainder_len + i;
327  // Here, t is an offset into a numbering of the frames where we first have
328  // the old "remainder" frames, then the regular frames.
329  if (t < rsize) dest.CopyFromVec(remainder_.Row(t));
330  else dest.CopyFromVec(input.Row(t - rsize));
331  }
332  remainder_ = next_remainder;
333 }
334 
335 
337  bool ans = input_->Compute(output);
338  if (output->NumRows() != 0)
339  data_.push_back(new Matrix<BaseFloat>(*output));
340  return ans;
341 }
342 
344  int32 num_frames = 0, dim = 0;
345  for (size_t i = 0; i < data_.size(); i++) {
346  num_frames += data_[i]->NumRows();
347  dim = data_[i]->NumCols();
348  }
349  output->Resize(num_frames, dim);
350  int32 frame_offset = 0;
351  for (size_t i = 0; i < data_.size(); i++) {
352  int32 this_frames = data_[i]->NumRows();
353  output->Range(frame_offset, this_frames, 0, dim).CopyFromMat(*data_[i]);
354  frame_offset += this_frames;
355  }
356  KALDI_ASSERT(frame_offset == num_frames);
357 }
358 
360  for (size_t i = 0; i < data_.size(); i++) delete data_[i];
361  data_.clear();
362 }
363 
364 
366  OnlineFeatInputItf *input):
367  input_(input), opts_(delta_opts), input_dim_(input_->Dim()) { }
368 
369 
370 // static
372  const MatrixBase<BaseFloat> &input2,
373  const MatrixBase<BaseFloat> &input3,
374  Matrix<BaseFloat> *output) {
375  const int32 size1 = input1.NumRows(), size2 = input2.NumRows(),
376  size3 = input3.NumRows(), size_out = size1 + size2 + size3;
377  if (size_out == 0) {
378  output->Resize(0, 0);
379  return;
380  }
381  // do std::max in case one or more of the input matrices is empty.
382  int32 dim = std::max(input1.NumCols(),
383  std::max(input2.NumCols(), input3.NumCols()));
384 
385  output->Resize(size_out, dim);
386  if (size1 != 0)
387  output->Range(0, size1, 0, dim).CopyFromMat(input1);
388  if (size2 != 0)
389  output->Range(size1, size2, 0, dim).CopyFromMat(input2);
390  if (size3 != 0)
391  output->Range(size1 + size2, size3, 0, dim).CopyFromMat(input3);
392 }
393 
395  Matrix<BaseFloat> *output,
396  Matrix<BaseFloat> *remainder) const {
397  int32 input_rows = input.NumRows(),
398  output_rows = std::max(0, input_rows - Context() * 2),
399  remainder_rows = std::min(input_rows, Context() * 2),
400  input_dim = input_dim_,
401  output_dim = Dim();
402  if (remainder_rows > 0) {
403  remainder->Resize(remainder_rows, input_dim);
404  remainder->CopyFromMat(input.Range(input_rows - remainder_rows,
405  remainder_rows, 0, input_dim));
406  } else {
407  remainder->Resize(0, 0);
408  }
409  if (output_rows > 0) {
410  output->Resize(output_rows, output_dim);
411  DeltaFeatures delta(opts_);
412  for (int32 output_frame = 0; output_frame < output_rows; output_frame++) {
413  int32 input_frame = output_frame + Context();
414  SubVector<BaseFloat> output_row(*output, output_frame);
415  delta.Process(input, input_frame, &output_row);
416  }
417  } else {
418  output->Resize(0, 0);
419  }
420 }
421 
423  KALDI_ASSERT(output->NumRows() > 0 &&
424  output->NumCols() == Dim());
425  // If output->NumRows() == 0, it corresponds to a request for zero frames,
426  // which makes no sense.
427 
428  // We request the same number of frames of data that we were requested.
429  Matrix<BaseFloat> input(output->NumRows(), input_dim_);
430  bool ans = input_->Compute(&input);
431 
432  // If we got no input (timed out) and we're not at the end, we return
433  // empty output.
434  if (input.NumRows() == 0 && ans) {
435  output->Resize(0, 0);
436  return ans;
437  } else if (input.NumRows() == 0 && !ans) {
438  // The end of the input stream, but no input this time.
439  if (remainder_.NumRows() == 0) {
440  output->Resize(0, 0);
441  return ans;
442  }
443  }
444 
445  // If this is the first segment of the utterance, we put in the
446  // initial duplicates of the first frame, numbered "Context()"
447  if (remainder_.NumRows() == 0 && input.NumRows() != 0 && Context() != 0) {
449  for (int32 i = 0; i < Context(); i++)
450  remainder_.Row(i).CopyFromVec(input.Row(0));
451  }
452 
453  // If this is the last segment, we put in the final duplicates of the
454  // last frame, numbered "Context()".
455  Matrix<BaseFloat> tail;
456  if (!ans && Context() > 0) {
457  tail.Resize(Context(), input_dim_);
458  for (int32 i = 0; i < Context(); i++) {
459  if (input.NumRows() > 0)
460  tail.Row(i).CopyFromVec(input.Row(input.NumRows() - 1));
461  else
462  tail.Row(i).CopyFromVec(remainder_.Row(remainder_.NumRows() - 1));
463  }
464  }
465 
466  Matrix<BaseFloat> appended_feats;
467  AppendFrames(remainder_, input, tail, &appended_feats);
468  DeltaComputation(appended_feats, output, &remainder_);
469  return ans;
470 }
471 
472 
473 
475  if (finished_) return; // Nothing to do.
476 
477  // We always keep the most recent frame of features, if present,
478  // in case it is needed (this may happen when someone calls
479  // IsLastFrame(), which requires us to get the next frame, while
480  // they're still processing this frame.
481  bool have_last_frame = (feat_matrix_.NumRows() != 0);
482  Vector<BaseFloat> last_frame;
483  if (have_last_frame)
484  last_frame = feat_matrix_.Row(feat_matrix_.NumRows() - 1);
485 
486  int32 iter;
487  for (iter = 0; iter < opts_.num_tries; iter++) {
488  Matrix<BaseFloat> next_features(opts_.batch_size, feat_dim_);
489  finished_ = ! input_->Compute(&next_features);
490  if (next_features.NumRows() == 0 && ! finished_) {
491  // It timed out. Try again.
492  continue;
493  }
494  if (next_features.NumRows() > 0) {
495  int32 new_size = (have_last_frame ? 1 : 0) +
496  next_features.NumRows();
497  feat_offset_ += feat_matrix_.NumRows() -
498  (have_last_frame ? 1 : 0); // we're discarding this many
499  // frames.
500  feat_matrix_.Resize(new_size, feat_dim_, kUndefined);
501  if (have_last_frame) {
502  feat_matrix_.Row(0).CopyFromVec(last_frame);
503  feat_matrix_.Range(1, next_features.NumRows(), 0, feat_dim_).
504  CopyFromMat(next_features);
505  } else {
506  feat_matrix_.CopyFromMat(next_features);
507  }
508  }
509  break;
510  }
511  if (iter == opts_.num_tries) { // we fell off the loop
512  KALDI_WARN << "After " << opts_.num_tries << ", got no features, giving up.";
513  finished_ = true; // We set finished_ to true even though the stream
514  // doesn't say it's finished, because the delay is too much-- we gave up.
515  }
516 }
517 
518 
520  KALDI_ASSERT(frame >= feat_offset_ &&
521  "You are attempting to get expired frames.");
522  if (frame < feat_offset_ + feat_matrix_.NumRows())
523  return true;
524  else {
525  GetNextFeatures();
526  if (frame < feat_offset_ + feat_matrix_.NumRows())
527  return true;
528  else {
529  if (finished_) return false;
530  else {
531  KALDI_WARN << "Unexpected point reached in code: "
532  << "possibly you are skipping frames?";
533  return false;
534  }
535  }
536  }
537 }
538 
540  if (frame < feat_offset_)
541  KALDI_ERR << "Attempting to get a discarded frame.";
542  if (frame >= feat_offset_ + feat_matrix_.NumRows())
543  KALDI_ERR << "Attempt get frame without check its validity.";
544  return feat_matrix_.Row(frame - feat_offset_);
545 }
546 
547 
548 } // namespace kaldi
549 
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
OnlineFeatInputItf * input_
virtual bool Compute(Matrix< BaseFloat > *output)
void OutputFrame(VectorBase< BaseFloat > *output)
Matrix< BaseFloat > remainder_
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Definition: kaldi-matrix.h:67
OnlineFeatInputItf * input_
Base class which provides matrix operations not involving resizing or allocation. ...
Definition: kaldi-matrix.h:49
kaldi::int32 int32
void Swap(Matrix< Real > *other)
Swaps the contents of *this and *other. Shallow swap.
void CopyFromMat(const MatrixBase< OtherReal > &M, MatrixTransposeType trans=kNoTrans)
Copy given matrix. (no resize is done).
Matrix< BaseFloat > history_
static void SpliceFrames(const MatrixBase< BaseFloat > &input1, const MatrixBase< BaseFloat > &input2, const MatrixBase< BaseFloat > &input3, int32 context_window, Matrix< BaseFloat > *output)
uint64 data_
Matrix< BaseFloat > remainder_
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
void ComputeNextRemainder(const MatrixBase< BaseFloat > &input)
void Read(std::istream &in, bool binary, bool add=false)
read from stream.
virtual bool Compute(Matrix< BaseFloat > *output)
const SubVector< Real > Row(MatrixIndexT i) const
Return specific row of matrix [const].
Definition: kaldi-matrix.h:188
void TransformToOutput(const MatrixBase< BaseFloat > &spliced_feats, Matrix< BaseFloat > *output)
virtual int32 Dim() const
void AddVecToRows(const Real alpha, const VectorBase< OtherReal > &v)
[each row of *this] += alpha * v
void DeltaComputation(const MatrixBase< BaseFloat > &input, Matrix< BaseFloat > *output, Matrix< BaseFloat > *remainder) const
void Process(const MatrixBase< BaseFloat > &input_feats, int32 frame, VectorBase< BaseFloat > *output_frame) const
virtual int32 Dim() const
void AddMatMat(const Real alpha, const MatrixBase< Real > &A, MatrixTransposeType transA, const MatrixBase< Real > &B, MatrixTransposeType transB, const Real beta)
#define KALDI_ERR
Definition: kaldi-error.h:147
virtual bool Compute(Matrix< BaseFloat > *output)
#define KALDI_WARN
Definition: kaldi-error.h:150
OnlineUdpInput(int32 port, int32 feature_dim)
OnlineDeltaInput(const DeltaFeaturesOptions &delta_opts, OnlineFeatInputItf *input)
void GetCachedData(Matrix< BaseFloat > *output)
static void AppendFrames(const MatrixBase< BaseFloat > &input1, const MatrixBase< BaseFloat > &input2, const MatrixBase< BaseFloat > &input3, Matrix< BaseFloat > *output)
OnlineFeatInputItf * input_
bool ComputeInternal(Matrix< BaseFloat > *output)
virtual bool Compute(Matrix< BaseFloat > *output)
void AcceptFrame(const VectorBase< BaseFloat > &input)
OnlineLdaInput(OnlineFeatInputItf *input, const Matrix< BaseFloat > &transform, int32 left_context, int32 right_context)
A class representing a vector.
Definition: kaldi-vector.h:406
SubVector< BaseFloat > GetFrame(int32 frame)
Vector< BaseFloat > offset_
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
Definition: kaldi-matrix.h:64
DeltaFeaturesOptions opts_
SubMatrix< Real > Range(const MatrixIndexT row_offset, const MatrixIndexT num_rows, const MatrixIndexT col_offset, const MatrixIndexT num_cols) const
Return a sub-part of matrix.
Definition: kaldi-matrix.h:202
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).
virtual bool Compute(Matrix< BaseFloat > *output)=0
Matrix< BaseFloat > linear_transform_
Provides a vector abstraction class.
Definition: kaldi-vector.h:41
int32 NumOutputFrames(int32 num_new_frames, bool more_data) const
void AddVec(const Real alpha, const VectorBase< OtherReal > &v)
Add vector : *this = *this + alpha * rv (with casting between floats and doubles) ...
Represents a non-allocating general vector which can be defined as a sub-vector of higher-level vecto...
Definition: kaldi-vector.h:501
virtual int32 Dim() const
virtual int32 Dim() const
virtual bool Compute(Matrix< BaseFloat > *output)