Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

backtrellis.c

Go to the documentation of this file.
00001 
00051 /*
00052  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00053  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00054  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology
00055  * All rights reserved
00056  */
00057 
00058 #include <julius.h>
00059 
00073 void
00074 bt_init(BACKTRELLIS *bt)
00075 {
00076   bt->num  = NULL;
00077   bt->rw   = NULL;
00078   bt->list = NULL;
00079   bt->root = NULL;
00080 }
00081 
00095 void
00096 bt_prepare(BACKTRELLIS *bt)
00097 {
00098   TRELLIS_ATOM *tre, *tmp;
00099 
00100   /* free previously allocated data */
00101   if (bt->root != NULL) free(bt->root);
00102   if (bt->rw != NULL) free(bt->rw);
00103   if (bt->num != NULL) free(bt->num);
00104   bt->num = NULL;
00105   bt->rw = NULL;
00106   bt->root = NULL;
00107 
00108   /* free actual trellis atoms previously allocated */
00109   tre = bt->list;
00110   while(tre) {
00111     tmp = tre->next;
00112     free(tre);
00113     tre = tmp;
00114   }
00115   /* reset entry point */
00116   bt->list = NULL;
00117 
00118 }  
00119 
00120 
00121 
00143 void
00144 bt_store(BACKTRELLIS *bt, TRELLIS_ATOM *tatom)
00145 {
00146 #ifdef WORD_GRAPH
00147   tatom->within_wordgraph = FALSE;
00148 #endif
00149   tatom->next = bt->list;
00150   bt->list = tatom;
00151   /*j_printf("  %3d: %15s %f < %3d %15s\n", tatom->endtime,
00152          winfo->woutput[tatom->wid], tatom->backscore,
00153          tatom->begintime, winfo->woutput[tatom->last_tre->wid]);*/
00154 }
00155 
00169 void
00170 bt_relocate_rw(BACKTRELLIS *bt)
00171 {
00172   TRELLIS_ATOM *tre;
00173   int t;
00174   int totalnum, n;
00175 
00176   if (bt->framelen == 0) {
00177     bt->num = NULL;
00178     return;
00179   }
00180 
00181   bt->num = (int *)mymalloc(sizeof(int) * bt->framelen);
00182 
00183   /* count number of trellis atom (= survived word end) for each frame */
00184   for (t=0;t<bt->framelen;t++) bt->num[t] = 0;
00185   totalnum = 0;
00186   for (tre=bt->list;tre;tre=tre->next) {
00187 #ifdef SP_BREAK_CURRENT_FRAME
00188     /* the last frame (when triggered from sp to non-sp) should be discarded */
00189     if (tre->endtime >= bt->framelen) continue;
00190 #endif      
00191     bt->num[tre->endtime]++;
00192     totalnum++;
00193   }
00194   /* if no atom found, return here with all bt->num[t] set to 0 */
00195   if (totalnum <= 0) {
00196     free(bt->num);
00197     bt->num = NULL;
00198     return;
00199   }
00200   
00201   /* allocate area */
00202   bt->root = (TRELLIS_ATOM **)mymalloc(sizeof(TRELLIS_ATOM *) * totalnum);
00203   bt->rw  = (TRELLIS_ATOM ***)mymalloc(sizeof(TRELLIS_ATOM **) * bt->framelen);
00204   n = 0;
00205   for (t=0;t<bt->framelen;t++) {
00206     if (bt->num[t] > 0) {
00207       bt->rw[t] = (TRELLIS_ATOM **)&(bt->root[n]);
00208       n += bt->num[t];
00209     }
00210   }
00211   /* then store the atoms */
00212   for (t=0;t<bt->framelen;t++) bt->num[t] = 0;
00213   for (tre=bt->list;tre;tre=tre->next) {
00214 #ifdef SP_BREAK_CURRENT_FRAME
00215     /* the last frame (when triggered from sp to non-sp) should be discarded */
00216     if (tre->endtime >= bt->framelen) continue;
00217 #endif      
00218     t = tre->endtime;
00219     
00220     bt->rw[t][bt->num[t]] = tre;
00221     bt->num[t]++;
00222   }
00223 }
00224 
00225 
00226 /* 以下の関数は bt_relocate_rw 実行後にのみ使用可能となる.*/
00227 /* functions below this line should be called after bt_relocate_rw() */
00228 
00229 #ifdef SP_BREAK_CURRENT_FRAME
00230 
00248 void
00249 set_terminal_words(BACKTRELLIS *bt)
00250 {
00251   LOGPROB maxscore;
00252   int i,t;
00253 
00254   if (bt->num == NULL) return;
00255 
00256   maxscore = LOG_ZERO;
00257   /* find last frame where a word exists */
00258   for(t=bt->framelen-1;t>=0;t--) {
00259     if (bt->num[t] > 0) break;
00260   }
00261   /* get maximum word hypothesis at that frame */
00262   for(i=0;i<bt->num[t];i++) {
00263     if (maxscore < (bt->rw[t][i])->backscore) {
00264       maxscore = (bt->rw[t][i])->backscore;
00265       sp_break_2_begin_word = (bt->rw[t][i])->wid;
00266     }
00267   }
00268   maxscore = LOG_ZERO;
00269   /* find first frame where a word exists */
00270   for(t=0;t<bt->framelen;t++) {
00271     if (bt->num[t] > 0) break;
00272   }
00273   /* get maximum word hypothesis at that frame */
00274   for(i=0;i<bt->num[t];i++) {
00275     if (maxscore < (bt->rw[t][i])->backscore) {
00276       maxscore = (bt->rw[t][i])->backscore;
00277       sp_break_2_end_word = (bt->rw[t][i])->wid;
00278     }
00279   }
00280 #ifdef SP_BREAK_DEBUG
00281   printf("2nd pass begin word: %s\n",
00282          (sp_break_2_begin_word == WORD_INVALID) ? "WORD_INVALID" : winfo->wname[sp_break_2_begin_word]);
00283   printf("2nd pass end word: %s\n",
00284          (sp_break_2_end_word == WORD_INVALID) ? "WORD_INVALID" : winfo->wname[sp_break_2_end_word]);
00285 #endif
00286 }
00287 #endif /* SP_BREAK_CURRENT_FRAME */
00288 
00289 
00290 /* the outprob on the trellis connection point should be discounted */
00314 void
00315 bt_discount_pescore(WCHMM_INFO *wchmm, BACKTRELLIS *bt, HTK_Param *param)
00316 {
00317   int t,i;
00318   TRELLIS_ATOM *tre;
00319 
00320   if (bt->num == NULL) return;
00321   
00322   for (t=0; t<bt->framelen; t++) {
00323     for (i=0; i<bt->num[t]; i++) {
00324       tre = bt->rw[t][i];
00325 #ifndef MULTIPATH_VERSION
00326       /* On normal version, both language score and the output prob. score
00327          at the connection point should removed on the trellis for the
00328          later connection.  On multi-path mode, removing only the language
00329          score is enough. */
00330       tre->backscore -= outprob_style(wchmm, wchmm->wordend[tre->wid], tre->last_tre->wid, t, param);
00331 #endif /* MULTIPATH_VERSION */
00332 #ifdef USE_NGRAM
00333 #ifdef LM_FIX_DOUBLE_SCORING
00334       /* the LM score of the last word should be subtracted, because
00335          their LM will be assigned by 3-gram on the 2nd pass.
00336       */
00337       tre->backscore -= tre->lscore;
00338 #endif
00339 #endif
00340     }
00341   }
00342 
00343 }
00344 
00363 static int
00364 compare_wid(TRELLIS_ATOM **a, TRELLIS_ATOM **b)
00365 {
00366   if ((*a)->wid > (*b)->wid) return 1;
00367   if ((*a)->wid < (*b)->wid) return -1;
00368   return 0;
00369 }
00370 
00389 void
00390 bt_sort_rw(BACKTRELLIS *bt)
00391 {
00392   int t;
00393 
00394   if (bt->num == NULL) return;
00395 
00396   for (t=0;t<bt->framelen;t++) {
00397     qsort(bt->rw[t], bt->num[t], sizeof(TRELLIS_ATOM *),
00398           (int (*)(const void *,const void *))compare_wid);
00399   }
00400 }
00401 
00402 
00403 /* 以下の関数は事前にbt_sort_rw() が呼ばれていること(第2パス用) */
00404 /* functions below should be called after bt_sort_rw() */
00405 
00427 TRELLIS_ATOM *
00428 bt_binsearch_atom(BACKTRELLIS *bt, int t, WORD_ID wkey)
00429 {
00430   /* do binary search */
00431   /* assume rw are ordered by wid */
00432   int left, right, mid;
00433   TRELLIS_ATOM *tmp;
00434 #ifdef WPAIR
00435   int i;
00436   LOGPROB maxscore;
00437   TRELLIS_ATOM *maxtre;
00438 #endif
00439   
00440   if (bt->num[t] == 0) return(NULL);
00441   
00442   left = 0;
00443   right = bt->num[t] - 1;
00444   while (left < right) {
00445     mid = (left + right) / 2;
00446     if ((bt->rw[t][mid])->wid < wkey) {
00447       left = mid + 1;
00448     } else {
00449       right = mid;
00450     }
00451   }
00452   tmp = bt->rw[t][left];
00453   if (tmp->wid == wkey) {
00454 #ifdef WPAIR
00455     /* same word with different context will be found:
00456        most likely one will be returned */
00457     maxscore = LOG_ZERO;
00458     i = left;
00459     while (i >= 0 && (tmp = bt->rw[t][i])->wid == wkey) {
00460       if (maxscore < tmp->backscore) {
00461         maxscore = tmp->backscore;
00462         maxtre = tmp;
00463       }
00464       i--;
00465     }
00466     i = left;
00467     while (i < bt->num[t] && (tmp = bt->rw[t][i])->wid == wkey) {
00468       if (maxscore < tmp->backscore) {
00469         maxscore = tmp->backscore;
00470         maxtre = tmp;
00471       }
00472       i++;
00473     }
00474 
00475     tmp = maxtre;
00476 #endif /* WORD_GRAPH */
00477 
00478     return(tmp);
00479   } else {
00480     return(NULL);
00481   }
00482 }

Generated on Tue Mar 28 16:17:42 2006 for Julius by  doxygen 1.4.2