28 #ifndef KALDI_MATRIX_JAMA_SVD_H_ 29 #define KALDI_MATRIX_JAMA_SVD_H_ 1 38 #if defined(HAVE_ATLAS) || defined(USE_KALDI_SVD) 64 template<
typename Real>
65 bool MatrixBase<Real>::JamaSvd(VectorBase<Real> *s_in,
66 MatrixBase<Real> *U_in,
67 MatrixBase<Real> *V_in) {
68 KALDI_ASSERT(s_in != NULL && U_in !=
this && V_in !=
this);
69 int wantu = (U_in != NULL), wantv = (V_in != NULL);
70 Matrix<Real> Utmp, Vtmp;
71 MatrixBase<Real> &U = (U_in ? *U_in : Utmp), &V = (V_in ? *V_in : Vtmp);
72 VectorBase<Real> &s = *s_in;
74 int m = num_rows_,
n = num_cols_;
76 if (wantu)
KALDI_ASSERT((
int)U.num_rows_ == m && (
int)U.num_cols_ == n);
77 if (wantv)
KALDI_ASSERT((
int)V.num_rows_ == n && (
int)V.num_cols_ == n);
84 MatrixBase<Real> &A(*
this);
85 Real *adata = A.Data(), *workdata = work.Data(), *edata = e.Data(),
86 *udata = U.Data(), *vdata = V.Data();
87 int astride =
static_cast<int>(A.Stride()),
88 ustride = static_cast<int>(U.Stride()),
89 vstride = static_cast<int>(V.Stride());
90 int i = 0,
j = 0, k = 0;
95 int nct = std::min(m-1, n);
96 int nrt = std::max(0, std::min(n-2, m));
97 for (k = 0; k < std::max(nct, nrt); k++) {
104 for (i = k; i < m; i++) {
105 s(k) = hypot(s(k), A(i, k));
111 for (i = k; i < m; i++) {
118 for (
j = k+1;
j <
n;
j++) {
119 if ((k < nct) && (s(k) != 0.0)) {
123 Real t =
cblas_Xdot(m - k, adata + astride*k + k, astride,
124 adata + astride*k +
j, astride);
129 cblas_Xaxpy(m - k, t, adata + k*astride + k, astride,
130 adata + k*astride +
j, astride);
141 if (wantu & (k < nct)) {
146 for (i = k; i < m; i++) {
156 for (i = k+1; i <
n; i++) {
157 e(k) = hypot(e(k), e(i));
163 for (i = k+1; i <
n; i++) {
169 if ((k+1 < m) & (e(k) != 0.0)) {
173 for (i = k+1; i < m; i++) {
176 for (
j = k+1;
j <
n;
j++) {
177 for (i = k+1; i < m; i++) {
178 workdata[
i] += edata[
j] * adata[i*astride +
j];
181 for (
j = k+1;
j <
n;
j++) {
182 Real t(-e(
j)/e(k+1));
184 adata + (k+1)*astride +
j, astride);
196 for (i = k+1; i <
n; i++) {
205 int p = std::min(n, m+1);
207 s(nct) = A(nct, nct);
213 e(nrt) = A(nrt, p-1);
220 for (
j = nct;
j < nu;
j++) {
221 for (i = 0; i < m; i++) {
226 for (k = nct-1; k >= 0; k--) {
228 for (
j = k+1;
j < nu;
j++) {
229 Real t =
cblas_Xdot(m - k, udata + k*ustride + k, ustride, udata + k*ustride +
j, ustride);
234 cblas_Xaxpy(m - k, t, udata + ustride*k + k, ustride,
235 udata + k*ustride +
j, ustride);
240 for (i = k; i < m; i++ ) {
243 U(k, k) = 1.0 + U(k, k);
244 for (i = 0; i < k-1; i++) {
248 for (i = 0; i < m; i++) {
259 for (k = n-1; k >= 0; k--) {
260 if ((k < nrt) & (e(k) != 0.0)) {
261 for (
j = k+1;
j < nu;
j++) {
262 Real t =
cblas_Xdot(n - (k+1), vdata + (k+1)*vstride + k, vstride,
263 vdata + (k+1)*vstride +
j, vstride);
269 cblas_Xaxpy(n - (k+1), t, vdata + (k+1)*vstride + k, vstride,
270 vdata + (k+1)*vstride +
j, vstride);
276 for (i = 0; i <
n; i++) {
290 Real eps(pow(2.0,
sizeof(Real) == 4 ? -23.0 : -52.0));
298 Real tiny(pow(2.0,
sizeof(Real) == 4 ? -120.0: -966.0 ));
304 if (iter == 500 || iter == 750) {
305 KALDI_WARN <<
"Svd taking a long time: making convergence criterion less exact.";
306 eps = pow(static_cast<Real>(0.8), eps);
307 tiny = pow(static_cast<Real>(0.8), tiny);
310 KALDI_WARN <<
"Svd not converging on matrix of size " << m <<
" by " <<
n;
324 for (k = p-2; k >= -1; k--) {
328 if (std::abs(e(k)) <=
329 tiny + eps*(std::abs(s(k)) + std::abs(s(k+1)))) {
338 for (ks = p-1; ks >= k; ks--) {
342 Real t( (ks != p ? std::abs(e(ks)) : 0.) +
343 (ks != k+1 ? std::abs(e(ks-1)) : 0.));
344 if (std::abs(s(ks)) <= tiny + eps*t) {
351 }
else if (ks == p-1) {
369 for (
j = p-2;
j >= k;
j--) {
370 Real t( hypot(s(
j), f));
379 for (i = 0; i <
n; i++) {
380 t = cs*V(i,
j) + sn*V(i, p-1);
381 V(i, p-1) = -sn*V(i,
j) + cs*V(i, p-1);
394 for (
j = k;
j < p;
j++) {
395 Real t(hypot(s(
j), f));
402 for (i = 0; i < m; i++) {
403 t = cs*U(i,
j) + sn*U(i, k-1);
404 U(i, k-1) = -sn*U(i,
j) + cs*U(i, k-1);
418 Real scale = std::max(std::max(std::max(std::max(
419 std::abs(s(p-1)), std::abs(s(p-2))), std::abs(e(p-2))),
420 std::abs(s(k))), std::abs(e(k)));
421 Real sp = s(p-1)/scale;
422 Real spm1 = s(p-2)/scale;
423 Real epm1 = e(p-2)/scale;
424 Real sk = s(k)/scale;
425 Real ek = e(k)/scale;
426 Real b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/2.0;
427 Real c = (sp*epm1)*(sp*epm1);
429 if ((b != 0.0) || (c != 0.0)) {
430 shift = std::sqrt(b*b + c);
434 shift = c/(b + shift);
436 Real f = (sk + sp)*(sk - sp) + shift;
441 for (
j = k;
j < p-1;
j++) {
442 Real t = hypot(f, g);
448 f = cs*s(
j) + sn*e(
j);
449 e(
j) = cs*e(
j) - sn*s(
j);
453 cblas_Xrot(n, vdata +
j, vstride, vdata +
j+1, vstride, cs, sn);
464 f = cs*e(
j) + sn*s(
j+1);
465 s(
j+1) = -sn*e(
j) + cs*s(
j+1);
468 if (wantu && (
j < m-1)) {
469 cblas_Xrot(m, udata +
j, ustride, udata +
j+1, ustride, cs, sn);
489 s(k) = (s(k) < 0.0 ? -s(k) : 0.0);
491 for (i = 0; i <= pp; i++) {
500 if (s(k) >= s(k+1)) {
506 if (wantv && (k < n-1)) {
507 for (i = 0; i <
n; i++) {
508 t = V(i, k+1); V(i, k+1) = V(i, k); V(i, k) = t;
511 if (wantu && (k < m-1)) {
512 for (i = 0; i < m; i++) {
513 t = U(i, k+1); U(i, k+1) = U(i, k); U(i, k) = t;
527 #endif // defined(HAVE_ATLAS) || defined(USE_KALDI_SVD) 531 #endif // KALDI_MATRIX_JAMA_SVD_H_ This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
float cblas_Xdot(const int N, const float *const X, const int incX, const float *const Y, const int incY)
void cblas_Xaxpy(const int N, const float alpha, const float *X, const int incX, float *Y, const int incY)
#define KALDI_ASSERT(cond)
void cblas_Xrot(const int N, float *X, const int incX, float *Y, const int incY, const float c, const float s)