/* * Compute the top-N closest gaussians from the chosen set (mgau,feat) * for the given input observation vector. */ static int32 compute_dist(gauden_dist_t * out_dist, int32 n_top, mfcc_t * obs, int32 featlen, mfcc_t ** mean, mfcc_t ** var, mfcc_t * det, int32 n_density) { int32 i, j, d; gauden_dist_t *worst; /* Special case optimization when n_density <= n_top */ if (n_top >= n_density) return (compute_dist_all (out_dist, obs, featlen, mean, var, det, n_density)); for (i = 0; i < n_top; i++) out_dist[i].dist = WORST_DIST; worst = &(out_dist[n_top - 1]); for (d = 0; d < n_density; d++) { mfcc_t *m; mfcc_t *v; mfcc_t dval; m = mean[d]; v = var[d]; dval = det[d]; for (i = 0; (i < featlen) && (dval >= worst->dist); i++) { mfcc_t diff; #ifdef FIXED_POINT /* Have to check for underflows here. */ mfcc_t pdval = dval; diff = obs[i] - m[i]; dval -= MFCCMUL(MFCCMUL(diff, diff), v[i]); if (dval > pdval) { dval = WORST_SCORE; break; } #else diff = obs[i] - m[i]; /* The compiler really likes this to be a single * expression, for whatever reason. */ dval -= diff * diff * v[i]; #endif } if ((i < featlen) || (dval < worst->dist)) /* Codeword d worse than worst */ continue; /* Codeword d at least as good as worst so far; insert in the ordered list */ for (i = 0; (i < n_top) && (dval < out_dist[i].dist); i++); assert(i < n_top); for (j = n_top - 1; j > i; --j) out_dist[j] = out_dist[j - 1]; out_dist[i].dist = dval; out_dist[i].id = d; } return 0; }
/* * Compute the top-N closest gaussians from the chosen set (mgau,feat) * for the given input observation vector. * NOTE: The density values computed are in log-domain, and while they are being * computed they're really the DENOMINATOR of the distance expression. */ static int32 compute_dist(dist_t * out_dist, int32 n_top, vector_t obs, int32 featlen, vector_t * mean, vector_t * var, float32 * det, int32 n_density) { int32 i, j, d; dist_t *worst; vector_t m, v; float64 dval, diff; /* Special case optimization when n_density <= n_top */ if (n_top >= n_density) return (compute_dist_all (out_dist, obs, featlen, mean, var, det, n_density)); /* * We are really computing denominators in the gaussian density expression: * sqrt(2pi * det), and (x-mean)^2*var. * To maximize the density value, we want to minimize the denominators. */ for (i = 0; i < n_top; i++) out_dist[i].dist = DBL_MAX; worst = &(out_dist[n_top - 1]); for (d = 0; d < n_density; d++) { m = mean[d]; v = var[d]; dval = det[d]; for (i = 0; (i < featlen) && (dval <= worst->dist); i++) { diff = obs[i] - m[i]; dval += diff * diff * v[i]; } if ((i < featlen) || (dval >= worst->dist)) /* Codeword d worse than worst */ continue; /* Codeword d at least as good as worst so far; insert in the ordered list */ for (i = 0; (i < n_top) && (dval >= out_dist[i].dist); i++); assert(i < n_top); for (j = n_top - 1; j > i; --j) out_dist[j] = out_dist[j - 1]; out_dist[i].dist = dval; out_dist[i].id = d; } return 0; }