tp-matrix.cc
Go to the documentation of this file.
1 // matrix/tp-matrix.cc
2 
3 // Copyright 2009-2011 Ondrej Glembek; Lukas Burget; Microsoft Corporation
4 // Saarland University; Yanmin Qian; Haihua Xu
5 
6 // See ../../COPYING for clarification regarding multiple authors
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 
12 // http://www.apache.org/licenses/LICENSE-2.0
13 
14 // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 // MERCHANTABLITY OR NON-INFRINGEMENT.
18 // See the Apache 2 License for the specific language governing permissions and
19 // limitations under the License.
20 
21 #include "matrix/tp-matrix.h"
22 #include "matrix/sp-matrix.h"
23 #include "matrix/kaldi-matrix.h"
24 #include "matrix/cblas-wrappers.h"
25 
26 
27 namespace kaldi {
28 
29 #ifndef HAVE_ATLAS
30 template<typename Real>
32  // these are CLAPACK types
33  KaldiBlasInt result;
34  KaldiBlasInt rows = static_cast<int>(this->num_rows_);
35 
36  // clapack call
37  // NOTE: Even though "U" is for upper, lapack assumes column-wise storage
38  // of the data. We have a row-wise storage, therefore, we need to "invert"
39  clapack_Xtptri(&rows, this->data_, &result);
40 
41  if (result < 0) {
42  KALDI_ERR << "Call to CLAPACK stptri_ function failed";
43  } else if (result > 0) {
44  KALDI_ERR << "Matrix is singular";
45  }
46 }
47 #else
48 template<typename Real>
50  // ATLAS doesn't implement triangular matrix inversion in packed
51  // format, so we temporarily put in non-packed format.
52  Matrix<Real> tmp(*this);
53  int rows = static_cast<int>(this->num_rows_);
54 
55  // ATLAS call. It's really row-major ordering and a lower triangular matrix,
56  // but there is some weirdness with Fortran-style indexing that we need to
57  // take account of, so everything gets swapped.
58  int result = clapack_Xtrtri( rows, tmp.Data(), tmp.Stride());
59  // Let's hope ATLAS has the same return value conventions as clapack.
60  // I couldn't find any documentation online.
61  if (result < 0) {
62  KALDI_ERR << "Call to ATLAS strtri function failed";
63  } else if (result > 0) {
64  KALDI_ERR << "Matrix is singular";
65  }
66  (*this).CopyFromMat(tmp);
67 }
68 #endif
69 
70 template<typename Real>
72  double det = 1.0;
73  for (MatrixIndexT i = 0; i<this->NumRows(); i++) {
74  det *= (*this)(i, i);
75  }
76  return static_cast<Real>(det);
77 }
78 
79 
80 template<typename Real>
82  std::swap(this->data_, other->data_);
83  std::swap(this->num_rows_, other->num_rows_);
84 }
85 
86 
87 template<typename Real>
89  KALDI_ASSERT(orig.NumRows() == this->NumRows());
90  MatrixIndexT n = this->NumRows();
91  this->SetZero();
92  Real *data = this->data_, *jdata = data; // start of j'th row of matrix.
93  const Real *orig_jdata = orig.Data(); // start of j'th row of matrix.
94  for (MatrixIndexT j = 0; j < n; j++, jdata += j, orig_jdata += j) {
95  Real *kdata = data; // start of k'th row of matrix.
96  Real d(0.0);
97  for (MatrixIndexT k = 0; k < j; k++, kdata += k) {
98  Real s = cblas_Xdot(k, kdata, 1, jdata, 1);
99  // (*this)(j, k) = s = (orig(j, k) - s)/(*this)(k, k);
100  jdata[k] = s = (orig_jdata[k] - s)/kdata[k];
101  d = d + s*s;
102  }
103  // d = orig(j, j) - d;
104  d = orig_jdata[j] - d;
105 
106  if (d >= 0.0) {
107  // (*this)(j, j) = std::sqrt(d);
108  jdata[j] = std::sqrt(d);
109  } else {
110  KALDI_ERR << "Cholesky decomposition failed. Maybe matrix "
111  "is not positive definite.";
112  }
113  }
114 }
115 
116 template<typename Real>
118  MatrixTransposeType Trans) {
119  if (Trans == kNoTrans) {
120  KALDI_ASSERT(this->NumRows() == M.NumRows() && M.NumRows() == M.NumCols());
121  MatrixIndexT D = this->NumRows();
122  const Real *in_i = M.Data();
123  MatrixIndexT stride = M.Stride();
124  Real *out_i = this->data_;
125  for (MatrixIndexT i = 0; i < D; i++, in_i += stride, out_i += i)
126  for (MatrixIndexT j = 0; j <= i; j++)
127  out_i[j] = in_i[j];
128  } else {
129  KALDI_ASSERT(this->NumRows() == M.NumRows() && M.NumRows() == M.NumCols());
130  MatrixIndexT D = this->NumRows();
131  const Real *in_i = M.Data();
132  MatrixIndexT stride = M.Stride();
133  Real *out_i = this->data_;
134  for (MatrixIndexT i = 0; i < D; i++, in_i++, out_i += i) {
135  for (MatrixIndexT j = 0; j <= i; j++)
136  out_i[j] = in_i[stride*j];
137  }
138  }
139 }
140 
141 
142 template class TpMatrix<float>;
143 template class TpMatrix<double>;
144 
145 } // namespace kaldi
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
Definition: chain.dox:20
Packed symetric matrix class.
Definition: matrix-common.h:62
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Definition: kaldi-matrix.h:67
Base class which provides matrix operations not involving resizing or allocation. ...
Definition: kaldi-matrix.h:49
const Real * Data() const
Gives pointer to raw data (const).
Definition: kaldi-matrix.h:79
void swap(basic_filebuf< CharT, Traits > &x, basic_filebuf< CharT, Traits > &y)
A class for storing matrices.
Definition: kaldi-matrix.h:823
MatrixIndexT NumRows() const
uint64 data_
MatrixIndexT num_rows_
Real Determinant()
Returns the determinant of the matrix (product of diagonals)
Definition: tp-matrix.cc:71
float cblas_Xdot(const int N, const float *const X, const int incX, const float *const Y, const int incY)
void Cholesky(const SpMatrix< Real > &orig)
Definition: tp-matrix.cc:88
MatrixIndexT Stride() const
Stride (distance in memory between each row). Will be >= NumCols.
Definition: kaldi-matrix.h:70
void clapack_Xtptri(KaldiBlasInt *num_rows, float *Mdata, KaldiBlasInt *result)
int32 MatrixIndexT
Definition: matrix-common.h:98
struct rnnlm::@11::@12 n
#define KALDI_ERR
Definition: kaldi-error.h:147
Packed symetric matrix class.
Definition: matrix-common.h:63
#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
MatrixTransposeType
Definition: matrix-common.h:32
void CopyFromMat(const MatrixBase< Real > &M, MatrixTransposeType Trans=kNoTrans)
CopyFromMat copies the lower triangle of M into *this (or the upper triangle, if Trans == kTrans)...
Definition: tp-matrix.cc:117
void Swap(TpMatrix< Real > *other)
Shallow swap.
Definition: tp-matrix.cc:81