/** * @brief Compute a set of Gaussians with safe pruning. * * If the N-best mixtures in the previous frame is specified in @a last_id, * They are first computed to set the initial threshold. * After that, the rest of the Gaussians will be computed with the thresholds * to drop unpromising Gaussians from computation at early stage * of likelihood computation. If the computation of a Gaussian reached to * the end, the threshold will be updated to always hold the likelihood of * current N-best score. * * The calculated scores will be stored to OP_calced_score, with its * corresponding mixture id to OP_calced_id. These are done by calling * cache_push(). * The number of calculated mixtures is also stored in OP_calced_num. * * This can be called from calc_tied_mix() or calc_mix(). * * @param wrk [i/o] HMM computation work area * @param g [in] set of Gaussian densities to compute the output probability * @param gnum [in] length of above * @param last_id [in] ID list of N-best mixture in previous input frame, * or NULL if not exist * @param lnum [in] length of last_id */ void gprune_safe(HMMWork *wrk, HTK_HMM_Dens **g, int gnum, int *last_id, int lnum) { int i, j, num = 0; LOGPROB score, thres; if (last_id != NULL) { /* compute them first to form threshold */ /* 1. calculate first $OP_gprune_num and set initial threshold */ for (j=0; j<lnum; j++) { i = last_id[j]; score = compute_g_base(wrk, g[i]); num = cache_push(wrk, i, score, num); wrk->mixcalced[i] = TRUE; /* mark them as calculated */ } thres = wrk->OP_calced_score[num-1]; /* 2. calculate the rest with pruning*/ for (i = 0; i < gnum; i++) { /* skip calced ones in 1. */ if (wrk->mixcalced[i]) { wrk->mixcalced[i] = FALSE; continue; } /* compute with safe pruning */ score = compute_g_safe(wrk, g[i], thres); if (score <= thres) continue; num = cache_push(wrk, i, score, num); thres = wrk->OP_calced_score[num-1]; } } else { /* in case the last_id not available */ /* not tied-mixture, or at the first 0 frame */ thres = LOG_ZERO; for (i = 0; i < gnum; i++) { if (num < wrk->OP_gprune_num) { score = compute_g_base(wrk, g[i]); } else { score = compute_g_safe(wrk, g[i], thres); if (score <= thres) continue; } num = cache_push(wrk, i, score, num); thres = wrk->OP_calced_score[num-1]; } } wrk->OP_calced_num = num; }
/** * @brief Compute a set of Gaussians with heuristic pruning. * * If the N-best mixtures in the previous frame is specified in @a last_id, * They are first computed to get the maximum value for each dimension. * After that, the rest of the Gaussians will be computed using the maximum * values as heuristics of uncomputed dimensions to drop unpromising * Gaussians from computation at early stage * of likelihood computation. If the @a last_id is not specified (typically * at the first frame of the input), a safe pruning as same as one in * gprune_safe.c will be applied. * * The calculated scores will be stored to OP_calced_score, with its * corresponding mixture id to OP_calced_id. These are done by calling * cache_push(). * The number of calculated mixtures is also stored in OP_calced_num. * * This can be called from calc_tied_mix() or calc_mix(). * * @param wrk [i/o] HMM computation work area * @param g [in] set of Gaussian densities to compute the output probability * @param gnum [in] length of above * @param last_id [in] ID list of N-best mixture in previous input frame, * or NULL if not exist * @param lnum [in] length of last_id */ void gprune_heu(HMMWork *wrk, HTK_HMM_Dens **g, int gnum, int *last_id, int lnum) { int i, j, num = 0; LOGPROB score, thres; if (last_id != NULL) { /* compute them first to form thresholds */ /* 1. clear backmax */ init_backmax(wrk); /* 2. calculate first $OP_gprune_num with setting max for each dimension */ for (j=0; j<lnum; j++) { i = last_id[j]; score = compute_g_heu_updating(wrk, g[i]); num = cache_push(wrk, i, score, num); wrk->mixcalced[i] = TRUE; /* mark them as calculated */ } /* 3. set backmax for each dimension */ make_backmax(wrk); /* 4. calculate the rest with pruning*/ thres = wrk->OP_calced_score[num-1]; for (i = 0; i < gnum; i++) { /* skip calced ones in 1. */ if (wrk->mixcalced[i]) { wrk->mixcalced[i] = FALSE; continue; } /* compute with safe pruning */ score = compute_g_heu_pruning(wrk, g[i], thres); if (score > LOG_ZERO) { num = cache_push(wrk, i, score, num); thres = wrk->OP_calced_score[num-1]; } } } else { /* in case the last_id not available */ /* at the first 0 frame */ /* calculate with safe pruning */ thres = LOG_ZERO; for (i = 0; i < gnum; i++) { if (num < wrk->OP_gprune_num) { score = compute_g_base(wrk, g[i]); } else { score = compute_g_safe(wrk, g[i], thres); if (score <= thres) continue; } num = cache_push(wrk, i, score, num); thres = wrk->OP_calced_score[num-1]; } } wrk->OP_calced_num = num; }
/** * @brief Compute a set of Gaussians with beam pruning. * * If the N-best mixtures in the previous frame is specified in @a last_id, * They are first computed to set the thresholds for each dimension. * After that, the rest of the Gaussians will be computed with those dimension * thresholds to drop unpromising Gaussians from computation at early stage * of likelihood computation. If the @a last_id is not specified (typically * at the first frame of the input), a safe pruning as same as one in * gprune_safe.c will be applied. * * The calculated scores will be stored to OP_calced_score, with its * corresponding mixture id to OP_calced_id. These are done by calling * cache_push(). * The number of calculated mixtures is also stored in OP_calced_num. * * This can be called from calc_tied_mix() or calc_mix(). * * @param wrk [i/o] HMM computation work area * @param g [in] set of Gaussian densities to compute the output probability * @param gnum [in] length of above * @param last_id [in] ID list of N-best mixture in previous input frame, * or NULL if not exist * @param lnum [in] length of last_id */ void gprune_beam(HMMWork *wrk, HTK_HMM_Dens **g, int gnum, int *last_id, int lnum) { int i, j, num = 0; LOGPROB score, thres; if (last_id != NULL) { /* compute them first to form thresholds */ /* 1. clear dimthres */ clear_dimthres(wrk); /* 2. calculate first $OP_gprune_num and set initial thresholds */ for (j=0; j<lnum; j++) { i = last_id[j]; #ifdef TEST2 if (!g[i]) { score = LOG_ZERO; } else { score = compute_g_beam_updating(wrk, g[i]); } num = cache_push(wrk, i, score, num); #else score = compute_g_beam_updating(wrk, g[i]); num = cache_push(wrk, i, score, num); #endif wrk->mixcalced[i] = TRUE; /* mark them as calculated */ } /* 3. set pruning thresholds for each dimension */ set_dimthres(wrk); /* 4. calculate the rest with pruning*/ for (i = 0; i < gnum; i++) { /* skip calced ones in 1. */ if (wrk->mixcalced[i]) { wrk->mixcalced[i] = FALSE; continue; } #ifdef TEST2 /* compute with safe pruning */ if (!g[i]) continue; score = compute_g_beam_pruning(wrk, g[i]); if (score > LOG_ZERO) { num = cache_push(wrk, i, score, num); } #else /* compute with safe pruning */ score = compute_g_beam_pruning(wrk, g[i]); if (score > LOG_ZERO) { num = cache_push(wrk, i, score, num); } #endif } } else { /* in case the last_id not available */ /* at the first 0 frame */ /* calculate with safe pruning */ thres = LOG_ZERO; for (i = 0; i < gnum; i++) { if (num < wrk->OP_gprune_num) { score = compute_g_base(wrk, g[i]); } else { score = compute_g_safe(wrk, g[i], thres); if (score <= thres) continue; } num = cache_push(wrk, i, score, num); thres = wrk->OP_calced_score[num-1]; } } wrk->OP_calced_num = num; }