/** * @brief Compute a set of Gaussians with no pruning * * The calculated scores will be stored to OP_calced_score, with its * corresponding mixture id to OP_calced_id. * 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 num [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_none(HMMWork *wrk, HTK_HMM_Dens **g, int num, int *last_id, int lnum) { int i; HTK_HMM_Dens *dens; LOGPROB *prob = wrk->OP_calced_score; int *id = wrk->OP_calced_id; #ifdef ENABLE_MSD int valid_dim; int calced_num; #endif #ifdef ENABLE_MSD valid_dim = 0; for(i=0; i<wrk->OP_veclen; i++) { if (wrk->OP_vec[i] != LZERO) valid_dim++; } calced_num = 0; for(i=0; i<num; i++) { dens = *(g++); if (dens->meanlen != valid_dim) continue; if (dens->meanlen == 0) { *(prob++) = 0.0; } else { *(prob++) = compute_g_base(wrk, dens); } *(id++) = i; calced_num++; } if (calced_num == 0) { jlog("Error: MSD: input data dim = %d / %d, but no Gaussian defined for it\n", valid_dim, wrk->OP_veclen); jlog("Error: MSD: Gaussian dimensions in this mixture:"); for(i=0;i<num;i++) { jlog(" %d", g[i]->meanlen); } jlog("\n"); } wrk->OP_calced_num = calced_num; #else for(i=0; i<num; i++) { dens = *(g++); *(prob++) = compute_g_base(wrk, dens); *(id++) = i; } wrk->OP_calced_num = num; #endif }
/** * @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; }
/** * Main function to compute all the GMS %HMM states in a frame * with the input vectore specified by OP_vec. This function assumes * that this will be called for sequencial frame, since it utilizes the * result of previous frame for faster pruning. * * @param wrk [i/o] HMM computation work area * */ void compute_gs_scores(HMMWork *wrk) { int i; for (i=0;i<wrk->gsset_num;i++) { #ifdef GS_MAX_PROB #ifdef LAST_BEST /* compute only the maximum with pruning (last best first) */ wrk->t_fs[i] = compute_g_max(wrk, wrk->gsset[i].state, wrk->gms_last_max_id_list[i]); #else wrk->t_fs[i] = compute_g_max(wrk, wrk->gsset[i].state); #endif /* LAST_BEST */ #else /* compute all mixture */ wrk->t_fs[i] = compute_g_base(wrk, wrk->gsset[i].state); #endif /*printf("%d:%s:%f\n",i,gsset[i].book->name,t_fs[i]);*/ } }
/** * @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; }