Julius 4.2
libsent/src/phmm/gprune_safe.c
説明を見る。
00001 
00045 /*
00046  * Copyright (c) 1991-2011 Kawahara Lab., Kyoto University
00047  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00048  * Copyright (c) 2005-2011 Julius project team, Nagoya Institute of Technology
00049  * All rights reserved
00050  */
00051 
00052 /* gprune_safe.c --- calculate probability of Gaussian densities */
00053 /*                   with Gaussian pruning (safe) */
00054 
00055 /* $Id: gprune_safe.c,v 1.5 2011/04/29 05:09:17 sumomo Exp $ */
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   /* maximum Gaussian set size = maximum mixture size * nstream */
00112   wrk->OP_calced_maxnum = wrk->OP_hmminfo->maxmixturenum * wrk->OP_nstream;
00113   wrk->OP_calced_score = (LOGPROB *)mymalloc(sizeof(LOGPROB) * wrk->OP_calced_maxnum);
00114   wrk->OP_calced_id = (int *)mymalloc(sizeof(int) * wrk->OP_calced_maxnum);
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 
00159 void
00160 gprune_safe(HMMWork *wrk, HTK_HMM_Dens **g, int gnum, int *last_id, int lnum)
00161 {
00162   int i, j, num = 0;
00163   LOGPROB score, thres;
00164 
00165   if (last_id != NULL) {        /* compute them first to form threshold */
00166     /* 1. calculate first $OP_gprune_num and set initial threshold */
00167     for (j=0; j<lnum; j++) {
00168       i = last_id[j];
00169       score = compute_g_base(wrk, g[i]);
00170       num = cache_push(wrk, i, score, num);
00171       wrk->mixcalced[i] = TRUE;      /* mark them as calculated */
00172     }
00173     thres = wrk->OP_calced_score[num-1];
00174     /* 2. calculate the rest with pruning*/
00175     for (i = 0; i < gnum; i++) {
00176       /* skip calced ones in 1. */
00177       if (wrk->mixcalced[i]) {
00178         wrk->mixcalced[i] = FALSE;
00179         continue;
00180       }
00181       /* compute with safe pruning */
00182       score = compute_g_safe(wrk, g[i], thres);
00183       if (score <= thres) continue;
00184       num = cache_push(wrk, i, score, num);
00185       thres = wrk->OP_calced_score[num-1];
00186     }
00187   } else {                      /* in case the last_id not available */
00188     /* not tied-mixture, or at the first 0 frame */
00189     thres = LOG_ZERO;
00190     for (i = 0; i < gnum; i++) {
00191       if (num < wrk->OP_gprune_num) {
00192         score = compute_g_base(wrk, g[i]);
00193       } else {
00194         score = compute_g_safe(wrk, g[i], thres);
00195         if (score <= thres) continue;
00196       }
00197       num = cache_push(wrk, i, score, num);
00198       thres = wrk->OP_calced_score[num-1];
00199     }
00200   }
00201   wrk->OP_calced_num = num;
00202 }