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 }