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 / -2.0);
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 
00141 void
00142 gprune_safe(HTK_HMM_Dens **g, int gnum, int *last_id)
00143 {
00144   int i, j, num = 0;
00145   LOGPROB score, thres;
00146 
00147   if (last_id != NULL) {        
00148     
00149     for (j=0; j<OP_gprune_num; j++) {
00150       i = last_id[j];
00151       score = compute_g_base(g[i]);
00152       num = cache_push(i, score, num);
00153       mixcalced[i] = TRUE;      
00154     }
00155     thres = OP_calced_score[num-1];
00156     
00157     for (i = 0; i < gnum; i++) {
00158       
00159       if (mixcalced[i]) {
00160         mixcalced[i] = FALSE;
00161         continue;
00162       }
00163       
00164       score = compute_g_safe(g[i], thres);
00165       if (score <= thres) continue;
00166       num = cache_push(i, score, num);
00167       thres = OP_calced_score[num-1];
00168     }
00169   } else {                      
00170     
00171     thres = LOG_ZERO;
00172     for (i = 0; i < gnum; i++) {
00173       if (num < OP_gprune_num) {
00174         score = compute_g_base(g[i]);
00175       } else {
00176         score = compute_g_safe(g[i], thres);
00177         if (score <= thres) continue;
00178       }
00179       num = cache_push(i, score, num);
00180       thres = OP_calced_score[num-1];
00181     }
00182   }
00183   OP_calced_num = num;
00184 }