00001
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <sent/stddefs.h>
00058 #include <sent/htk_hmm.h>
00059 #include <sent/htk_param.h>
00060 #include <sent/hmm.h>
00061 #include <sent/hmm_calc.h>
00062
00075 LOGPROB
00076 compute_g_safe(HMMWork *wrk, HTK_HMM_Dens *binfo, LOGPROB thres)
00077 {
00078 VECT tmp, x;
00079 VECT *mean;
00080 VECT *var;
00081 VECT *vec = wrk->OP_vec;
00082 short veclen = wrk->OP_veclen;
00083 VECT fthres = thres * (-2.0);
00084
00085 if (binfo == NULL) return(LOG_ZERO);
00086 mean = binfo->mean;
00087 var = binfo->var->vec;
00088 tmp = binfo->gconst;
00089 for (; veclen > 0; veclen--) {
00090 x = *(vec++) - *(mean++);
00091 tmp += x * x * *(var++);
00092 if (tmp > fthres) return LOG_ZERO;
00093 }
00094 return(tmp * -0.5);
00095 }
00096
00097
00098
00106 boolean
00107 gprune_safe_init(HMMWork *wrk)
00108 {
00109 int i;
00110
00111
00112 wrk->OP_calced_maxnum = wrk->OP_hmminfo->maxmixturenum;
00113 wrk->OP_calced_score = (LOGPROB *)mymalloc(sizeof(LOGPROB) * wrk->OP_gprune_num);
00114 wrk->OP_calced_id = (int *)mymalloc(sizeof(int) * wrk->OP_gprune_num);
00115 wrk->mixcalced = (boolean *)mymalloc(sizeof(int) * wrk->OP_calced_maxnum);
00116 for(i=0;i<wrk->OP_calced_maxnum;i++) wrk->mixcalced[i] = FALSE;
00117 return TRUE;
00118 }
00119
00126 void
00127 gprune_safe_free(HMMWork *wrk)
00128 {
00129 free(wrk->OP_calced_score);
00130 free(wrk->OP_calced_id);
00131 free(wrk->mixcalced);
00132 }
00133
00158 void
00159 gprune_safe(HMMWork *wrk, HTK_HMM_Dens **g, int gnum, int *last_id)
00160 {
00161 int i, j, num = 0;
00162 LOGPROB score, thres;
00163
00164 if (last_id != NULL) {
00165
00166 for (j=0; j<wrk->OP_gprune_num; j++) {
00167 i = last_id[j];
00168 score = compute_g_base(wrk, g[i]);
00169 num = cache_push(wrk, i, score, num);
00170 wrk->mixcalced[i] = TRUE;
00171 }
00172 thres = wrk->OP_calced_score[num-1];
00173
00174 for (i = 0; i < gnum; i++) {
00175
00176 if (wrk->mixcalced[i]) {
00177 wrk->mixcalced[i] = FALSE;
00178 continue;
00179 }
00180
00181 score = compute_g_safe(wrk, g[i], thres);
00182 if (score <= thres) continue;
00183 num = cache_push(wrk, i, score, num);
00184 thres = wrk->OP_calced_score[num-1];
00185 }
00186 } else {
00187
00188 thres = LOG_ZERO;
00189 for (i = 0; i < gnum; i++) {
00190 if (num < wrk->OP_gprune_num) {
00191 score = compute_g_base(wrk, g[i]);
00192 } else {
00193 score = compute_g_safe(wrk, g[i], thres);
00194 if (score <= thres) continue;
00195 }
00196 num = cache_push(wrk, i, score, num);
00197 thres = wrk->OP_calced_score[num-1];
00198 }
00199 }
00200 wrk->OP_calced_num = num;
00201 }