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