Julius 4.2
|
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 }