libsent/src/phmm/gprune_beam.c

Go to the documentation of this file.
00001 
00046 /*
00047  * Copyright (c) 1991-2007 Kawahara Lab., Kyoto University
00048  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00049  * Copyright (c) 2005-2007 Julius project team, Nagoya Institute of Technology
00050  * All rights reserved
00051  */
00052 
00053 #include <sent/stddefs.h>
00054 #include <sent/htk_hmm.h>
00055 #include <sent/htk_param.h>
00056 #include <sent/hmm.h>
00057 #include <sent/hmm_calc.h>
00058 
00059 #define TEST2
00060 
00061 /*
00062 
00063   best_mixtures_on_last_frame[]
00064   
00065   dim:  0 1 2 3 4 .... veclen-1    -> sum up
00066  ================================
00067   thres
00068  --------------------------------
00069   mix1  | |
00070   mix2  | |
00071   mix3  v v
00072   ...
00073   mixN  
00074  ================================
00075          \_\_ vecprob[0],vecprob[1]
00076 
00077   algorithm 1:
00078          
00079   foreach dim {
00080      foreach all_mixtures in best_mixtures_on_last_frame {
00081         compute score
00082      }
00083      threshold = the current lowest score + beam_width?
00084      foreach rest_mixtures {
00085         if (already marked as pruned at previous dim) {
00086            skip
00087         }
00088         compute score
00089         if (score < threshold) {
00090            mark as pruned
00091            skip
00092         }
00093         if (score > threshold) {
00094            update threshold
00095         }
00096      }
00097   }
00098 
00099   algorithm 2:
00100 
00101   foreach all_mixtures in best_mixtures_on_last_frame {
00102      foreach dim {
00103        compute score
00104        if (threshold[dim] < score) update
00105      }
00106      threshold[dim] += beam_width
00107   }
00108   foreach rest_mixtures {
00109      foreach dim {
00110         compute score
00111         if (score < threshold[dim]) skip this mixture
00112         update thres
00113      }
00114   }
00115      
00116 */
00117 
00124 static void
00125 clear_dimthres(HMMWork *wrk)
00126 {
00127   int i;
00128   for(i=0;i<wrk->dimthres_num;i++) wrk->dimthres[i] = 0.0;
00129 }
00130 
00138 static void
00139 set_dimthres(HMMWork *wrk)
00140 {
00141   int i;
00142   for(i=0;i<wrk->dimthres_num;i++) wrk->dimthres[i] += TMBEAMWIDTH;
00143 }
00144 
00158 static LOGPROB
00159 compute_g_beam_updating(HMMWork *wrk, HTK_HMM_Dens *binfo)
00160 {
00161   VECT tmp, x;
00162   VECT *mean;
00163   VECT *var;
00164   VECT *th = wrk->dimthres;
00165   VECT *vec = wrk->OP_vec;
00166   short veclen = wrk->OP_veclen;
00167 
00168 #ifndef TEST2
00169   if (binfo == NULL) return(LOG_ZERO);
00170 #endif
00171 
00172   mean = binfo->mean;
00173   var = binfo->var->vec;
00174 
00175   tmp = 0.0;
00176   for (; veclen > 0; veclen--) {
00177     x = *(vec++) - *(mean++);
00178     tmp += x * x * *(var++);
00179     if ( *th < tmp) *th = tmp;
00180     th++;
00181   }
00182   return((tmp + binfo->gconst) * -0.5);
00183 }
00184 
00198 static LOGPROB
00199 compute_g_beam_pruning(HMMWork *wrk, HTK_HMM_Dens *binfo)
00200 {
00201   VECT tmp, x;
00202   VECT *mean;
00203   VECT *var;
00204   VECT *th = wrk->dimthres;
00205   VECT *vec = wrk->OP_vec;
00206   short veclen = wrk->OP_veclen;
00207 
00208 #ifndef TEST2
00209   if (binfo == NULL) return(LOG_ZERO);
00210 #endif
00211   mean = binfo->mean;
00212   var = binfo->var->vec;
00213 
00214   tmp = 0.0;
00215   for (; veclen > 0; veclen--) {
00216     x = *(vec++) - *(mean++);
00217     tmp += x * x * *(var++);
00218     if ( tmp > *(th++)) {
00219       return LOG_ZERO;
00220     }
00221   }
00222   return((tmp + binfo->gconst) * -0.5);
00223 }
00224 
00225 
00233 boolean
00234 gprune_beam_init(HMMWork *wrk)
00235 {
00236   int i;
00237   /* maximum Gaussian set size = maximum mixture size */
00238   wrk->OP_calced_maxnum = wrk->OP_hmminfo->maxmixturenum;
00239   wrk->OP_calced_score = (LOGPROB *)mymalloc(sizeof(LOGPROB) * wrk->OP_gprune_num);
00240   wrk->OP_calced_id = (int *)mymalloc(sizeof(int) * wrk->OP_gprune_num);
00241   wrk->mixcalced = (boolean *)mymalloc(sizeof(int) * wrk->OP_calced_maxnum);
00242   for(i=0;i<wrk->OP_calced_maxnum;i++) wrk->mixcalced[i] = FALSE;
00243   wrk->dimthres_num = wrk->OP_hmminfo->opt.vec_size;
00244   wrk->dimthres = (LOGPROB *)mymalloc(sizeof(LOGPROB) * wrk->dimthres_num);
00245 
00246   return TRUE;
00247 }
00248 
00255 void
00256 gprune_beam_free(HMMWork *wrk)
00257 {
00258   free(wrk->OP_calced_score);
00259   free(wrk->OP_calced_id);
00260   free(wrk->mixcalced);
00261   free(wrk->dimthres);
00262 }
00263 
00288 void
00289 gprune_beam(HMMWork *wrk, HTK_HMM_Dens **g, int gnum, int *last_id)
00290 {
00291   int i, j, num = 0;
00292   LOGPROB score, thres;
00293 
00294   if (last_id != NULL) {        /* compute them first to form thresholds */
00295     /* 1. clear dimthres */
00296     clear_dimthres(wrk);
00297     /* 2. calculate first $OP_gprune_num and set initial thresholds */
00298     for (j=0; j<wrk->OP_gprune_num; j++) {
00299       i = last_id[j];
00300 #ifdef TEST2
00301       if (!g[i]) {
00302         score = LOG_ZERO;
00303       } else {
00304         score = compute_g_beam_updating(wrk, g[i]);
00305       }
00306       num = cache_push(wrk, i, score, num);
00307 #else
00308       score = compute_g_beam_updating(wrk, g[i]);
00309       num = cache_push(wrk, i, score, num);
00310 #endif
00311       wrk->mixcalced[i] = TRUE;      /* mark them as calculated */
00312     }
00313     /* 3. set pruning thresholds for each dimension */
00314     set_dimthres(wrk);
00315 
00316     /* 4. calculate the rest with pruning*/
00317     for (i = 0; i < gnum; i++) {
00318       /* skip calced ones in 1. */
00319       if (wrk->mixcalced[i]) {
00320         wrk->mixcalced[i] = FALSE;
00321         continue;
00322       }
00323 #ifdef TEST2
00324       /* compute with safe pruning */
00325       if (!g[i]) continue;
00326       score = compute_g_beam_pruning(wrk, g[i]);
00327       if (score > LOG_ZERO) {
00328         num = cache_push(wrk, i, score, num);
00329       }
00330 #else
00331       /* compute with safe pruning */
00332       score = compute_g_beam_pruning(wrk, g[i]);
00333       if (score > LOG_ZERO) {
00334         num = cache_push(wrk, i, score, num);
00335       }
00336 #endif
00337     }
00338   } else {                      /* in case the last_id not available */
00339     /* at the first 0 frame */
00340     /* calculate with safe pruning */
00341     thres = LOG_ZERO;
00342     for (i = 0; i < gnum; i++) {
00343       if (num < wrk->OP_gprune_num) {
00344         score = compute_g_base(wrk, g[i]);
00345       } else {
00346         score = compute_g_safe(wrk, g[i], thres);
00347         if (score <= thres) continue;
00348       }
00349       num = cache_push(wrk, i, score, num);
00350       thres = wrk->OP_calced_score[num-1];
00351     }
00352   }
00353   wrk->OP_calced_num = num;
00354 }

Generated on Tue Dec 18 15:59:56 2007 for Julius by  doxygen 1.5.4