101 template<
typename Real>
112 Real max_x = std::numeric_limits<Real>::min();
114 max_x = std::max(max_x, (x[
i] < 0 ? -x[
i] : x[
i]));
120 sigma += (x[
i] * s) * (x[
i] * s);
124 "Tridiagonalizing matrix that is too large or has NaNs.");
125 if (sigma == 0.0) *beta = 0.0;
127 Real x1 = x[dim-1] * s, mu = std::sqrt(x1 * x1 + sigma);
131 v[dim-1] = -sigma / (x1 + mu);
136 *beta = 2 * v1sq / (sigma + v1sq);
137 Real inv_v1 = 1.0 / v1;
146 KALDI_ERR <<
"NaN encountered in HouseBackward";
164 template<
typename Real>
170 Real *data = this->Data();
171 Real *qdata = (Q == NULL ? NULL : Q->
Data());
174 Real beta, *v = tmp_v.Data(), *p = tmp_p.
Data(), *w = p, *x = p;
179 Real *Arow = data + ksize;
183 Real minus_half_beta_pv = -0.5 * beta *
cblas_Xdot(k, p, 1, v, 1);
188 data[ksize + k - 1] = std::sqrt(
cblas_Xdot(k, Arow, 1, Arow, 1));
204 cblas_Xgemv(
kTrans, k, n, -beta, qdata, qstride, v, 1, 0.0, x, 1);
207 cblas_Xger(k, n, 1.0, v, 1, x, 1, qdata, qstride);
220 template<
typename Real>
221 inline void Givens(Real a, Real b, Real *c, Real *s) {
226 if (std::abs(b) > std::abs(a)) {
228 *s = 1 / std::sqrt(1 + tau*tau);
232 *c = 1 / std::sqrt(1 + tau*tau);
244 template <
typename Real>
252 Real
d = (diag[n-2] - diag[n-1]) / 2.0,
254 inv_scale = std::max(std::max(std::abs(d), std::abs(t)),
255 std::numeric_limits<Real>::min()),
256 scale = 1.0 / inv_scale,
257 d_scaled = d * scale,
258 off_diag_n2_scaled = off_diag[n-2] * scale,
259 t2_n_n1_scaled = off_diag_n2_scaled * off_diag_n2_scaled,
260 sgn_d = (d > 0.0 ? 1.0 : -1.0),
261 mu = diag[n-1] - inv_scale * t2_n_n1_scaled /
262 (d_scaled + sgn_d * std::sqrt(d_scaled * d_scaled + t2_n_n1_scaled)),
266 Real *Qdata = (Q == NULL ? NULL : Q->
Data());
268 Qcols = (Q == NULL ? 0 : Q->
NumCols());
283 Real p = diag[k], q = off_diag[k], r = diag[k+1];
286 diag[k] = c * (c*p - s*q) - s * (c*q - s*r);
287 off_diag[k] = s * (c*p - s*q) + c * (c*q - s*r);
288 diag[k+1] = s * (s*p + c*q) + c * (s*q + c*r);
299 Real &elem_k_km1 = off_diag[k-1],
301 elem_k_km1 = c*elem_k_km1 - s*elem_kp1_km1;
308 Qdata + (k+1)*Qstride, 1, c, -s);
312 Real &elem_kp2_k = z,
313 &elem_kp2_kp1 = off_diag[k+1];
318 elem_kp2_k = - s * elem_kp2_kp1;
319 elem_kp2_kp1 = c * elem_kp2_kp1;
330 template <
typename Real>
339 large_iters = 100 + 2*
n;
340 Real epsilon = (pow(2.0,
sizeof(Real) == 4 ? -23.0 : -52.0));
342 for (; counter < max_iters; counter++) {
345 if (counter == large_iters ||
346 (counter > large_iters && (counter - large_iters) % 50 == 0)) {
348 <<
" iterations in QR (dim is " << n <<
"), doubling epsilon.";
350 KALDI_WARN <<
"Diag, off-diag are " <<
d <<
" and " << o;
354 if (std::abs(off_diag[
i]) <= epsilon *
355 (std::abs(diag[i]) + std::abs(diag[i+1])))
366 while (q < n && (n-q < 2 || off_diag[n-2-q] == 0.0))
374 while (npq + q < n && (n-q-npq-1 < 0 || off_diag[n-q-npq-1] != 0.0))
391 QrStep(npq, diag + p, off_diag + p, &Qpart);
393 QrStep(npq, diag + p, off_diag + p,
397 if (counter == max_iters) {
398 KALDI_WARN <<
"Failure to converge in QR algorithm. " 399 <<
"Exiting with partial output.";
408 template <
typename Real>
421 if (i > 0) off_diag(i-1) = (*this)(
i, i-1);
428 if (i > 0) (*this)(
i, i-1) = off_diag(i-1);
432 template<
typename Real>
453 template<
typename Real>
458 if (lanczos_dim <= 0)
459 lanczos_dim = std::max(eig_dim + 50, eig_dim + eig_dim/2);
461 if (lanczos_dim >= dim) {
466 this->Eig(&s_tmp, &P_tmp);
487 Q.Row(0).Scale(1.0 / Q.Row(0).Norm(2));
499 Real start_prod =
VecVec(r, r);
502 Real prod =
VecVec(r, q_e);
503 if (counter == 0 && static_cast<MatrixIndexT>(e) + 1 >=
d)
507 if (
d+1 == lanczos_dim)
break;
509 if (end_prod <= 0.1 * start_prod) {
517 KALDI_ERR <<
"Loop detected in Lanczos iteration.";
522 if (
d+1 != lanczos_dim) {
526 r.
Scale(1.0 / std::sqrt(end_prod));
527 Q.Row(
d+1).CopyFromVec(r);
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
void Givens(Real a, Real b, Real *c, Real *s)
Create Givens rotations, as in Golub and Van Loan 3rd ed., page 216.
Packed symetric matrix class.
void QrInternal(MatrixIndexT n, Real *diag, Real *off_diag, MatrixBase< Real > *Q)
void HouseBackward(MatrixIndexT dim, const Real *x, Real *v, Real *beta)
void cblas_Xspr2(MatrixIndexT dim, float alpha, const float *Xdata, MatrixIndexT incX, const float *Ydata, MatrixIndexT incY, float *Adata)
void Qr(MatrixBase< Real > *Q)
The symmetric QR algorithm.
MatrixIndexT NumCols() const
Returns number of columns (or zero for empty matrix).
Base class which provides matrix operations not involving resizing or allocation. ...
const Real * Data() const
Gives pointer to raw data (const).
#define KALDI_ISFINITE(x)
void Eig(VectorBase< Real > *s, MatrixBase< Real > *P=NULL) const
Solves the symmetric eigenvalue problem: at end we should have (*this) = P * diag(s) * P^T...
A class for storing matrices.
void AddSpVec(const Real alpha, const SpMatrix< Real > &M, const VectorBase< Real > &v, const Real beta)
Add symmetric positive definite matrix times vector: this <– beta*this + alpha*M*v.
void CopyFromMat(const MatrixBase< OtherReal > &M, MatrixTransposeType trans=kNoTrans)
Copy given matrix. (no resize is done).
void SetUnit()
Sets to zero, except ones along diagonal [for non-square matrices too].
void Tridiagonalize(MatrixBase< Real > *Q)
Tridiagonalize the matrix with an orthogonal transformation.
float cblas_Xdot(const int N, const float *const X, const int incX, const float *const Y, const int incY)
void CopyFromVec(const VectorBase< Real > &v)
Copy data from another vector (must match own size).
void CopyDiagFromPacked(const PackedMatrix< Real > &M)
Extracts the diagonal of a packed matrix M; works for Sp or Tp.
MatrixIndexT Stride() const
Stride (distance in memory between each row). Will be >= NumCols.
void cblas_Xscal(const int N, const float alpha, float *data, const int inc)
void Transpose()
Transpose the matrix.
void AddMatMat(const Real alpha, const MatrixBase< Real > &A, MatrixTransposeType transA, const MatrixBase< Real > &B, MatrixTransposeType transB, const Real beta)
void TopEigs(VectorBase< Real > *s, MatrixBase< Real > *P, MatrixIndexT lanczos_dim=0) const
This function gives you, approximately, the largest eigenvalues of the symmetric matrix and the corre...
Real * Data()
Returns a pointer to the start of the vector's data.
MatrixIndexT Dim() const
Returns the dimension of the vector.
void Scale(Real alpha)
Multiplies all elements by this constant.
void SetRandn()
Set vector to random normally-distributed noise.
A class representing a vector.
void cblas_Xaxpy(const int N, const float alpha, const float *X, const int incX, float *Y, const int incY)
#define KALDI_ASSERT(cond)
MatrixIndexT NumRows() const
Returns number of rows (or zero for empty matrix).
void QrStep(MatrixIndexT n, Real *diag, Real *off_diag, MatrixBase< Real > *Q)
void cblas_Xgemv(MatrixTransposeType trans, MatrixIndexT num_rows, MatrixIndexT num_cols, float alpha, const float *Mdata, MatrixIndexT stride, const float *xdata, MatrixIndexT incX, float beta, float *ydata, MatrixIndexT incY)
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.
void cblas_Xspmv(const float alpha, const int num_rows, const float *Mdata, const float *v, const int v_inc, const float beta, float *y, const int y_inc)
Provides a vector abstraction class.
void cblas_Xger(MatrixIndexT num_rows, MatrixIndexT num_cols, float alpha, const float *xdata, MatrixIndexT incX, const float *ydata, MatrixIndexT incY, float *Mdata, MatrixIndexT stride)
Real VecVec(const VectorBase< Real > &a, const VectorBase< Real > &b)
Returns dot product between v1 and v2.
void AddVec(const Real alpha, const VectorBase< OtherReal > &v)
Add vector : *this = *this + alpha * rv (with casting between floats and doubles) ...
void CopyDiagFromSp(const SpMatrix< Real > &M)
Extracts the diagonal of a symmetric matrix.
Sub-matrix representation.
Represents a non-allocating general vector which can be defined as a sub-vector of higher-level vecto...
void cblas_Xrot(const int N, float *X, const int incX, float *Y, const int incY, const float c, const float s)
void SortSvd(VectorBase< Real > *s, MatrixBase< Real > *U, MatrixBase< Real > *Vt, bool sort_on_absolute_value)
Function to ensure that SVD is sorted.
SubVector< Real > Range(const MatrixIndexT o, const MatrixIndexT l)
Returns a sub-vector of a vector (a range of elements).