00001 
00041 
00042 
00043 
00044 
00045 
00046 
00047    
00048 #include <julius.h>
00049 
00050 #ifdef USE_NGRAM
00051 
00070 static int
00071 compare_nw(NEXTWORD **a, NEXTWORD **b)
00072 {
00073   if ((*a)->id > (*b)->id) return 1;
00074   if ((*a)->id < (*b)->id) return -1;
00075   return 0;
00076 }
00077 
00099 
00100 static NEXTWORD *
00101 search_nw(NEXTWORD **nw, WORD_ID w, int num)
00102 {
00103   int left,right,mid;
00104   NEXTWORD *tmp;
00105 
00106   if (num == 0) return NULL;
00107   left = 0;
00108   right = num - 1;
00109   while (left < right) {
00110     mid = (left + right) / 2;
00111     if ((nw[mid])->id < w) {
00112       left = mid + 1;
00113     } else {
00114       right = mid;
00115     }
00116   }
00117   tmp = nw[left];
00118   if (tmp->id == w) {
00119     return tmp;
00120   } else {
00121     return NULL;
00122   }
00123 }
00124 
00125 
00126 static WORD_ID cnword[2];       
00127 static int cnnum;               
00128 static int last_trans;          
00129 
00146 static void
00147 set_word_context(WORD_ID *cseq, int n, WORD_INFO *winfo)
00148 {
00149   int i;
00150 
00151   cnnum = 0;
00152   last_trans = 0;
00153   for(i=n-1;i>=0;i--) {
00154     if (! winfo->is_transparent[cseq[i]]) {
00155       cnword[cnnum++] = winfo->wton[cseq[i]];
00156       if (cnnum >= 2) break;
00157     } else {
00158       last_trans++;
00159     }
00160   }
00161 }
00162 
00163 
00164 
00165 
00166 
00204 static int
00205 pick_backtrellis_words(BACKTRELLIS *bt, WORD_INFO *winfo, NGRAM_INFO *ngram, NEXTWORD **nw, int oldnum, NODE *hypo, short t)
00206 {
00207   int i;
00208   WORD_ID w;
00209   LOGPROB rawscore;
00210 #ifdef WPAIR
00211   int w_old = WORD_INVALID;
00212 #endif
00213   int num;
00214 
00215   num = oldnum;
00216   
00217   set_word_context(hypo->seq, hypo->seqnum, winfo);
00218   
00219   for (i=0;i<bt->num[t];i++) {
00220     w = (bt->rw[t][i])->wid;
00221 #ifdef WORD_GRAPH
00222     
00223     if (!(bt->rw[t][i])->within_wordgraph) continue;
00224 #endif 
00225 #ifdef WPAIR
00226     
00227 
00228 
00229     if (w == w_old) continue;   
00230     else w_old = w;
00231 #endif 
00232     
00233     if (search_nw(nw, w, oldnum) != NULL) continue;
00234     switch(cnnum) {             
00235     case 0:                     
00236       rawscore = uni_prob(ngram, winfo->wton[w]);
00237       break;
00238     case 1:                     
00239       rawscore = bi_prob_rl(ngram, winfo->wton[w], cnword[0]);
00240       break;
00241     default:                    
00242       rawscore = tri_prob_rl(ngram, winfo->wton[w], cnword[0], cnword[1]);
00243       break;
00244     }
00245 #ifdef CLASS_NGRAM
00246     rawscore += winfo->cprob[w];
00247 #endif
00248     nw[num]->tre   = bt->rw[t][i];
00249     nw[num]->id    = w;
00250     nw[num]->lscore = lm_weight2 * rawscore + lm_penalty2;
00251     if (winfo->is_transparent[w]) {
00252       
00253       if (winfo->is_transparent[hypo->seq[hypo->seqnum-1]]) {
00254         nw[num]->lscore += lm_penalty_trans;
00255       }
00256     }
00257     
00258     
00259     num++;
00260   }
00261   return num;
00262 }
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00308 int
00309 get_backtrellis_words(BACKTRELLIS *bt, WORD_INFO *winfo, NGRAM_INFO *ngram, NEXTWORD **nw, NODE *hypo, short tm, short t_end)
00310 {
00311   int num = 0;
00312   int t, t_step;
00313   int oldnum=0;
00314 
00315   if (tm < 0) return(0);
00316 
00317 #ifdef PREFER_CENTER_ON_TRELLIS_LOOKUP
00318   
00319   
00320   for (t_step = 0; t_step < lookup_range; t_step++) {
00321     
00322     t = tm - t_step;
00323     if (t < 0 || t > bt->framelen - 1 || t >= t_end) continue;
00324     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00325     if (num > oldnum) {
00326       qsort(nw, num, sizeof(NEXTWORD *),
00327             (int (*)(const void *,const void *))compare_nw);
00328       oldnum = num;
00329     }
00330     if (t_step == 0) continue;  
00331     
00332     t = tm + t_step;
00333     if (t < 0 || t > bt->framelen - 1 || t >= t_end) continue;
00334     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00335     if (num > oldnum) {
00336       qsort(nw, num, sizeof(NEXTWORD *),
00337             (int (*)(const void *,const void *))compare_nw);
00338       oldnum = num;
00339     }
00340   }
00341 
00342 #else
00343 
00344   
00345   for(t = tm; t >= tm - lookup_range; t--) {
00346     if (t < 0) break;
00347     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00348     if (num > oldnum) {
00349       qsort(nw, num, sizeof(NEXTWORD *),
00350             (int (*)(const void *,const void *))compare_nw);
00351       oldnum = num;
00352     }
00353   }
00354   
00355   for(t = tm + 1; t < tm + lookup_range; t++) {
00356     if (t > bt->framelen - 1) break;
00357     if (t >= t_end) break;
00358     num = pick_backtrellis_words(bt, winfo, ngram, nw, oldnum, hypo, t);
00359     if (num > oldnum) {
00360       qsort(nw, num, sizeof(NEXTWORD *),
00361             (int (*)(const void *,const void *))compare_nw);
00362       oldnum = num;
00363     }
00364   }
00365 #endif
00366 
00367   return num;
00368 }
00369 
00390 int
00391 limit_nw(NEXTWORD **nw, NODE *hypo, int num)
00392 {
00393   int src,dst;
00394   int newnum;
00395 
00396   
00397   
00398   if (hypo->seq[hypo->seqnum-1] == winfo->head_silwid) {
00399     return(0);
00400   }
00401 
00402   dst = 0;
00403   for (src=0; src<num; src++) {
00404     if (nw[src]->id == winfo->tail_silwid) {
00405       
00406       
00407       continue;
00408     }
00409 #ifdef FIX_35_INHIBIT_SAME_WORD_EXPANSION
00410     
00411     
00412     if (nw[src]->tre == hypo->tre) continue;
00413 #endif
00414     
00415     if (src != dst) memcpy(nw[dst], nw[src], sizeof(NEXTWORD));
00416     dst++;
00417   }
00418   newnum = dst;
00419 
00420   return newnum;
00421 }
00422         
00423 
00424 
00425 
00426 
00427 
00461 int
00462 ngram_firstwords(NEXTWORD **nw, int peseqlen, int maxnw, WORD_INFO *winfo, BACKTRELLIS *bt)
00463 {
00464 #ifdef SP_BREAK_CURRENT_FRAME
00465   if (rest_param != NULL) {
00466     
00467     
00468 
00469     nw[0]->id = sp_break_2_begin_word;
00470   } else {
00471     
00472     
00473     nw[0]->id = winfo->tail_silwid;
00474   }
00475 #else
00476   
00477   nw[0]->id = winfo->tail_silwid;
00478 #endif
00479 #ifdef FIX_PENALTY
00480   nw[0]->lscore = 0.0;
00481 #else
00482   nw[0]->lscore = lm_penalty2;
00483 #endif
00484 
00485   return 1;                     
00486 }
00487 
00488 
00489 
00490 
00530 int
00531 ngram_nextwords(
00532                 NODE *hypo,
00533                 NEXTWORD **nw,
00534                 int maxnw,      
00535                 NGRAM_INFO *ngram, 
00536                 WORD_INFO *winfo, 
00537                 BACKTRELLIS *bt) 
00538 {
00539   int num, num2;
00540 
00541   if (hypo->seqnum == 0) {
00542     j_error("gs_get_next_words: hypo contains no word\n");
00543   }
00544 
00545   
00546   
00547   num = get_backtrellis_words(bt, winfo, ngram, nw, hypo, hypo->estimated_next_t, hypo->bestt);
00548 
00549   if (debug2_flag) j_printf("%d",num);
00550 
00551   
00552   
00553   num2 = limit_nw(nw, hypo, num);
00554 
00555   if (debug2_flag) j_printf("-%d=%d unfolded\n",num-num2,num2);
00556 
00557   return(num2);
00558 }
00559 
00560 
00583 boolean
00584 ngram_acceptable(NODE *hypo, WORD_INFO *winfo)
00585 {
00586   if (
00587 #ifdef SP_BREAK_CURRENT_FRAME
00588       
00589       
00590       hypo->seq[hypo->seqnum-1] == sp_break_2_end_word
00591 #else
00592       
00593       
00594       hypo->seq[hypo->seqnum-1] == winfo->head_silwid
00595 #endif
00596       ) {
00597     return TRUE;
00598   } else {
00599     return FALSE;
00600   }
00601 }
00602 
00603 #endif