sparse-matrix.h
Go to the documentation of this file.
1 // matrix/sparse-matrix.h
2 
3 // Copyright 2015 Johns Hopkins University (author: Daniel Povey)
4 // 2015 Guoguo Chen
5 // 2017 Shiyin Kang
6 
7 
8 // See ../../COPYING for clarification regarding multiple authors
9 //
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 //
14 // http://www.apache.org/licenses/LICENSE-2.0
15 //
16 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
18 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
19 // MERCHANTABLITY OR NON-INFRINGEMENT.
20 // See the Apache 2 License for the specific language governing permissions and
21 // limitations under the License.
22 
23 #ifndef KALDI_MATRIX_SPARSE_MATRIX_H_
24 #define KALDI_MATRIX_SPARSE_MATRIX_H_ 1
25 
26 #include <utility>
27 #include <vector>
28 
29 #include "matrix/matrix-common.h"
30 #include "matrix/kaldi-matrix.h"
31 #include "matrix/kaldi-vector.h"
33 
34 namespace kaldi {
35 
36 
39 
40 template <typename Real>
41 class SparseVector {
42  public:
43  MatrixIndexT Dim() const { return dim_; }
44 
45  Real Sum() const;
46 
47  template <class OtherReal>
49 
50  // *vec += alpha * *this.
51  template <class OtherReal>
52  void AddToVec(Real alpha,
53  VectorBase<OtherReal> *vec) const;
54 
55  template <class OtherReal>
56  void CopyFromSvec(const SparseVector<OtherReal> &other);
57 
59 
60  SparseVector(const SparseVector<Real> &other) { *this = other; }
61 
62  void Swap(SparseVector<Real> *other);
63 
64  // Returns the maximum value in this row and outputs the index associated with
65  // it. This is not the index into the Data() pointer, it is the index into
66  // the vector it represents, i.e. the .first value in the pair.
67  // If this vector's Dim() is zero it is an error to call this function.
68  // If all the elements stored were negative and there underlying vector had
69  // zero indexes not listed in the elements, or if no elements are stored, it
70  // will return the first un-listed index, whose value (implicitly) is zero.
71  Real Max(int32 *index) const;
72 
74  MatrixIndexT NumElements() const { return pairs_.size(); }
75 
77  const std::pair<MatrixIndexT, Real> &GetElement(MatrixIndexT i) const {
78  return pairs_[i];
79  }
80 
81  // returns pointer to element data, or NULL if empty (use with NumElements()).
82  std::pair<MatrixIndexT, Real> *Data();
83 
84  // returns pointer to element data, or NULL if empty (use with NumElements());
85  // const version
86  const std::pair<MatrixIndexT, Real> *Data() const;
87 
90  void SetRandn(BaseFloat zero_prob);
91 
92  SparseVector(): dim_(0) { }
93 
94  explicit SparseVector(MatrixIndexT dim): dim_(dim) { KALDI_ASSERT(dim >= 0); }
95 
96  // constructor from pairs; does not assume input pairs are sorted and uniq
98  const std::vector<std::pair<MatrixIndexT, Real> > &pairs);
99 
100  // constructor from a VectorBase that keeps only the nonzero elements of 'vec'.
101  explicit SparseVector(const VectorBase<Real> &vec);
102 
105  void Resize(MatrixIndexT dim, MatrixResizeType resize_type = kSetZero);
106 
107  void Write(std::ostream &os, bool binary) const;
108 
109  void Read(std::istream &os, bool binary);
110 
112  void Scale(Real alpha);
113 
114  private:
116  // pairs of (row-index, value). Stored in sorted order with no duplicates.
117  // For now we use std::vector, but we could change this.
118  std::vector<std::pair<MatrixIndexT, Real> > pairs_;
119 };
120 
121 
122 template <typename Real>
123 Real VecSvec(const VectorBase<Real> &vec,
124  const SparseVector<Real> &svec);
125 
126 
127 
128 template <typename Real>
129 class SparseMatrix {
130  public:
131  MatrixIndexT NumRows() const;
132 
133  MatrixIndexT NumCols() const;
134 
135  MatrixIndexT NumElements() const;
136 
137  Real Sum() const;
138 
139  Real FrobeniusNorm() const;
140 
141 
144  explicit SparseMatrix(const MatrixBase<Real> &mat);
145 
147  template <class OtherReal>
148  void CopyToMat(MatrixBase<OtherReal> *other,
149  MatrixTransposeType t = kNoTrans) const;
150 
153  void CopyElementsToVec(VectorBase<Real> *other) const;
154 
156  template<class OtherReal>
157  void CopyFromSmat(const SparseMatrix<OtherReal> &other,
158  MatrixTransposeType trans = kNoTrans);
159 
161  void AddToMat(BaseFloat alpha, MatrixBase<Real> *other,
162  MatrixTransposeType t = kNoTrans) const;
163 
165 
167  kNoTrans) {
168  this->CopyFromSmat(other, trans);
169  }
170 
171  void Swap(SparseMatrix<Real> *other);
172 
173  // returns pointer to element data, or NULL if empty (use with NumElements()).
175 
176  // returns pointer to element data, or NULL if empty (use with NumElements());
177  // const version
178  const SparseVector<Real> *Data() const;
179 
180  // initializer from the type that elsewhere in Kaldi is referred to as type
181  // Posterior. indexed first by row-index; the pairs are (column-index, value),
182  // and the constructor does not require them to be sorted and uniq.
183  SparseMatrix(
184  int32 dim,
185  const std::vector<std::vector<std::pair<MatrixIndexT, Real> > > &pairs);
186 
190  void SetRandn(BaseFloat zero_prob);
191 
192  void Write(std::ostream &os, bool binary) const;
193 
194  void Read(std::istream &os, bool binary);
195 
196  const SparseVector<Real> &Row(MatrixIndexT r) const;
197 
199  void SetRow(int32 r, const SparseVector<Real> &vec);
200 
205  void SelectRows(const std::vector<int32> &row_indexes,
206  const SparseMatrix<Real> &smat_other);
207 
208 
213  void AppendSparseMatrixRows(std::vector<SparseMatrix<Real> > *inputs);
214 
216 
217  SparseMatrix(int32 num_rows, int32 num_cols) { Resize(num_rows, num_cols); }
218 
229  SparseMatrix(const std::vector<int32> &indexes, int32 dim,
230  MatrixTransposeType trans = kNoTrans);
231 
242  SparseMatrix(const std::vector<int32> &indexes,
243  const VectorBase<Real> &weights, int32 dim,
244  MatrixTransposeType trans = kNoTrans);
245 
248  void Resize(MatrixIndexT rows, MatrixIndexT cols,
249  MatrixResizeType resize_type = kSetZero);
250 
252  void Scale(Real alpha);
253 
254  // Use the Matrix::CopyFromSmat() function to copy from this to Matrix. Also
255  // see Matrix::AddSmat(). There is not very extensive functionality for
256  // SparseMat just yet (e.g. no matrix multiply); we will add things as needed
257  // and as it seems necessary.
258  private:
259  // vector of SparseVectors, all of same dime (use an stl vector for now; this
260  // could change).
261  std::vector<SparseVector<Real> > rows_;
262 };
263 
264 
265 template<typename Real>
266 Real TraceMatSmat(const MatrixBase<Real> &A,
267  const SparseMatrix<Real> &B,
268  MatrixTransposeType trans = kNoTrans);
269 
270 
275 };
276 
283  public:
286  GeneralMatrixType Type() const;
287 
288  void Compress(); // If it was a full matrix, compresses, changing Type() to
289  // kCompressedMatrix; otherwise does nothing.
290 
291  void Uncompress(); // If it was a compressed matrix, uncompresses, changing
292  // Type() to kFullMatrix; otherwise does nothing.
293 
294  void Write(std::ostream &os, bool binary) const;
295 
296 
299  void Read(std::istream &is, bool binary);
300 
303  const SparseMatrix<BaseFloat> &GetSparseMatrix() const;
304 
307  void SwapSparseMatrix(SparseMatrix<BaseFloat> *smat);
308 
312  const CompressedMatrix &GetCompressedMatrix() const;
313 
316  void SwapCompressedMatrix(CompressedMatrix *cmat);
317 
320  const Matrix<BaseFloat>& GetFullMatrix() const;
321 
324  void GetMatrix(Matrix<BaseFloat> *mat) const;
325 
328  void SwapFullMatrix(Matrix<BaseFloat> *mat);
329 
332  void CopyToMat(MatrixBase<BaseFloat> *mat,
333  MatrixTransposeType trans = kNoTrans) const;
334 
337  void CopyToMat(CuMatrixBase<BaseFloat> *cu_mat,
338  MatrixTransposeType trans = kNoTrans) const;
339 
341  void AddToMat(BaseFloat alpha, MatrixBase<BaseFloat> *mat,
342  MatrixTransposeType trans = kNoTrans) const;
343 
346  void AddToMat(BaseFloat alpha, CuMatrixBase<BaseFloat> *cu_mat,
347  MatrixTransposeType trans = kNoTrans) const;
348 
350  void Scale(BaseFloat alpha);
351 
354 
357 
360 
361  MatrixIndexT NumRows() const;
362 
363  MatrixIndexT NumCols() const;
364 
365  explicit GeneralMatrix(const MatrixBase<BaseFloat> &mat) { *this = mat; }
366 
367  explicit GeneralMatrix(const CompressedMatrix &cmat) { *this = cmat; }
368 
369  explicit GeneralMatrix(const SparseMatrix<BaseFloat> &smat) { *this = smat; }
370 
372  // Assignment operator.
373  GeneralMatrix &operator =(const GeneralMatrix &other);
374  // Copy constructor
375  GeneralMatrix(const GeneralMatrix &other) { *this = other; }
376  // Sets to the empty matrix.
377  void Clear();
378  // shallow swap
379  void Swap(GeneralMatrix *other);
380  private:
381  // We don't explicitly store the type of the matrix. Rather, we make
382  // sure that only one of the matrices is ever nonempty, and the Type()
383  // returns that one, or kFullMatrix if all are empty.
387 };
388 
389 
394 void AppendGeneralMatrixRows(const std::vector<const GeneralMatrix *> &src,
395  GeneralMatrix *mat);
396 
397 
401 template <typename Real>
403  const std::vector<bool> &keep_rows,
404  SparseMatrix<Real> *out);
405 
409 template <typename Real>
410 void FilterMatrixRows(const Matrix<Real> &in,
411  const std::vector<bool> &keep_rows,
412  Matrix<Real> *out);
413 
418  const std::vector<bool> &keep_rows,
419  Matrix<BaseFloat> *out);
420 
421 
428  const std::vector<bool> &keep_rows,
429  GeneralMatrix *out);
430 
441  const GeneralMatrix &in,
442  int32 row_offset,
443  int32 num_rows,
444  GeneralMatrix *out);
445 
446 
448 
449 
450 } // namespace kaldi
451 
452 #endif // KALDI_MATRIX_SPARSE_MATRIX_H_
void CopyElementsToVec(VectorBase< OtherReal > *vec) const
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
void Scale(Real alpha)
Scale all elements of sparse vector.
This class is a wrapper that enables you to store a matrix in one of three forms: either as a Matrix<...
GeneralMatrix(const MatrixBase< BaseFloat > &mat)
MatrixResizeType
Definition: matrix-common.h:37
CompressedMatrix cmat_
void FilterMatrixRows(const Matrix< Real > &in, const std::vector< bool > &keep_rows, Matrix< Real > *out)
Outputs a Matrix<Real> containing only the rows r of "in" such that keep_keep_rows[r] == true...
SparseVector< Real > & operator=(const SparseVector< Real > &other)
Real Max(int32 *index) const
void SetRandn(BaseFloat zero_prob)
Sets elements to zero with probability zero_prob, else normally distributed.
SparseVector(MatrixIndexT dim)
Definition: sparse-matrix.h:94
Base class which provides matrix operations not involving resizing or allocation. ...
Definition: kaldi-matrix.h:49
void Read(std::istream &os, bool binary)
const std::pair< MatrixIndexT, Real > & GetElement(MatrixIndexT i) const
get an indexed element (0 <= i < NumElements()).
Definition: sparse-matrix.h:77
void AddToVec(Real alpha, VectorBase< OtherReal > *vec) const
std::vector< std::pair< MatrixIndexT, Real > > pairs_
kaldi::int32 int32
std::vector< SparseVector< Real > > rows_
GeneralMatrix(const CompressedMatrix &cmat)
SparseVector(const SparseVector< Real > &other)
Definition: sparse-matrix.h:60
SparseMatrix(int32 num_rows, int32 num_cols)
void CopyFromSvec(const SparseVector< OtherReal > &other)
void FilterGeneralMatrixRows(const GeneralMatrix &in, const std::vector< bool > &keep_rows, GeneralMatrix *out)
Outputs a GeneralMatrix containing only the rows r of "in" such that keep_rows[r] == true...
Real VecSvec(const VectorBase< Real > &vec, const SparseVector< Real > &svec)
SparseMatrix(const SparseMatrix< Real > &other, MatrixTransposeType trans=kNoTrans)
GeneralMatrix(const GeneralMatrix &other)
int32 MatrixIndexT
Definition: matrix-common.h:98
MatrixIndexT Dim() const
Definition: sparse-matrix.h:43
void FilterSparseMatrixRows(const SparseMatrix< Real > &in, const std::vector< bool > &keep_rows, SparseMatrix< Real > *out)
Outputs a SparseMatrix<Real> containing only the rows r of "in" such that keep_rows[r] == true...
void FilterCompressedMatrixRows(const CompressedMatrix &in, const std::vector< bool > &keep_rows, Matrix< BaseFloat > *out)
Outputs a Matrix<Real> containing only the rows r of "in" such that keep_rows[r] == true...
void ExtractRowRangeWithPadding(const GeneralMatrix &in, int32 row_offset, int32 num_rows, GeneralMatrix *out)
This function extracts a row-range of a GeneralMatrix and writes as a GeneralMatrix containing the sa...
MatrixIndexT NumElements() const
Returns the number of nonzero elements.
Definition: sparse-matrix.h:74
GeneralMatrixType
void AppendGeneralMatrixRows(const std::vector< const GeneralMatrix *> &src, GeneralMatrix *mat)
Appends all the matrix rows of a list of GeneralMatrixes, to get a single GeneralMatrix.
GeneralMatrix(const SparseMatrix< BaseFloat > &smat)
void Write(std::ostream &os, bool binary) const
Matrix for CUDA computing.
Definition: matrix-common.h:69
#define KALDI_ASSERT(cond)
Definition: kaldi-error.h:185
MatrixTransposeType
Definition: matrix-common.h:32
Real TraceMatSmat(const MatrixBase< Real > &A, const SparseMatrix< Real > &B, MatrixTransposeType trans)
Matrix< BaseFloat > mat_
void Resize(MatrixIndexT dim, MatrixResizeType resize_type=kSetZero)
Resizes to this dimension.
SparseMatrix< BaseFloat > smat_
Provides a vector abstraction class.
Definition: kaldi-vector.h:41
void Swap(SparseVector< Real > *other)
std::pair< MatrixIndexT, Real > * Data()