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

check_hmm_restriction.c

Go to the documentation of this file.
00001 
00039 /*
00040  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00041  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00042  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology
00043  * All rights reserved
00044  */
00045 
00046 #include <sent/stddefs.h>
00047 #include <sent/htk_hmm.h>
00048 #include <sent/htk_param.h>
00049 #include <sent/hmm.h>
00050 
00051 #define GOOD 0                  
00052 #define FIXED 1                 
00053 #define BAD 3                   
00054 
00055 /* transition allowance matrix on normal version */
00056 /* G=good,F=fixed,B=bad */
00057 /*  |G|F|B */
00058 /* -+-+-+- */
00059 /* G|G|F|B */
00060 /* F|F|F|B */
00061 /* B|B|B|B */
00062 
00063 /* transition probability is not loganized yet */
00064 
00074 static int
00075 trans_ok_p(HTK_HMM_Trans *t)
00076 {
00077 #ifdef MULTIPATH_VERSION
00078   int i;
00079   int tflag;
00080   int retflag = GOOD;
00081 
00082   /* no arc to initial state */
00083   tflag = GOOD;
00084   for (i=0;i<t->statenum;i++) {
00085     if (t->a[i][0] != (PROB)0.0) {
00086       tflag = BAD;
00087       break;
00088     }
00089   }
00090   if (tflag == BAD) {
00091     j_printerr("Error: transition to initial state not allowed\n");
00092     retflag = BAD;
00093   }
00094   /* no arc from final state */
00095   tflag = GOOD;
00096   for (i=0;i<t->statenum;i++) {
00097     if (t->a[t->statenum-1][i] != (PROB)0.0) {
00098       tflag = BAD;
00099       break;
00100     }
00101   }
00102   if (tflag == BAD) {
00103     j_printerr("Error: transition from final state not allowed\n");
00104     retflag = BAD;
00105   }
00106     
00107   return(retflag);
00108   
00109 #else  /* ~MULTIPATH_VERSION */
00110   
00111   int i, j;
00112   int tflag = BAD;
00113   int retflag = BAD;
00114   PROB maxprob;
00115   int maxid = -1;
00116   
00117   /* allow only one arc from initial state */
00118   tflag = BAD;
00119   for (i=0;i<t->statenum;i++) {
00120     if (t->a[0][i] != (PROB)0.0) {
00121       if (tflag == BAD) {
00122         tflag = GOOD;
00123       } else {                  /* 2nd time */
00124         j_printerr("Warning: initial state has more than one arc\n");
00125         tflag = BAD;
00126         break;
00127       }
00128     }
00129   }
00130   if (tflag == BAD) {           /* unacceptable transition found */
00131     if (i >= t->statenum) {     /* no arc */
00132       j_printerr("Error: initial state has no arc\n");
00133     } else {
00134       /* modify the transition: gather them to an arc with best probability */
00135       maxprob = 0.0; maxid = -1;
00136       for (j=0;j<t->statenum;j++) {
00137         if (maxprob < t->a[0][j]) {
00138           maxprob = t->a[0][j];
00139           maxid = j;
00140         }
00141       }
00142       if (maxid == -1) {
00143         j_error("Error: trans_ok_p: no transition in a state?\n");
00144       }
00145       t->a[0][maxid] = 1.0;
00146       for (j=0;j<t->statenum;j++) {
00147         if (j == maxid) continue;
00148         t->a[0][j] = 0.0;
00149       }
00150       tflag = FIXED;
00151     }
00152   }
00153 
00154   retflag = tflag;
00155   
00156   /* allow only one arc to final state */
00157   tflag = BAD;
00158   for (i=0;i<t->statenum;i++) {
00159     if (t->a[i][t->statenum-1] != (PROB)0.0) {
00160       if (tflag == BAD) {
00161         tflag = GOOD;
00162       } else {                  /* 2nd time */
00163         j_printerr("Warning: more than one arc to end state\n");
00164         tflag = BAD;
00165         break;
00166       }
00167     }
00168   }
00169   if (tflag == BAD) {
00170     if (i >= t->statenum) {     /* no arc */
00171       j_printerr("Error: no arc to end state\n");
00172     } else {
00173       /* modify the transition: gather them to an arc with best probability */
00174       maxprob = (PROB)0.0;
00175       for (j=0;j<t->statenum;j++) {
00176         if (maxprob < t->a[j][t->statenum-1]) {
00177           maxprob = t->a[j][t->statenum-1];
00178           maxid = j;
00179         }
00180       }
00181       for (i=0;i<t->statenum;i++) {
00182         if (t->a[i][t->statenum-1] == (PROB)0.0) continue;
00183         if (i == maxid) continue;
00184         for (j=t->statenum-2;j>=0;j--) {
00185           if (t->a[i][j] != (PROB)0.0) {
00186             t->a[i][j] += t->a[i][t->statenum-1];
00187             t->a[i][t->statenum-1] = (PROB)0.0;
00188             break;
00189           }
00190         }
00191       }
00192       tflag = FIXED;
00193     }
00194   }
00195     
00196   return(retflag | tflag);
00197 
00198 #endif /* MULTIPATH_VERSION */
00199 }
00200 
00208 boolean
00209 check_hmm_limit(HTK_HMM_Data *dt)
00210 {
00211   boolean return_flag = TRUE;
00212   int tflag;
00213 
00214   tflag = trans_ok_p(dt->tr);
00215   if (tflag == BAD) {
00216     return_flag = FALSE;
00217     j_printerr("Limit: HMM \"%s\" has unsupported arc.\n", dt->name);
00218     put_htk_trans(dt->tr);
00219   } else if (tflag == FIXED) {
00220     j_printerr("Warning: HMM \"%s\" has unsupported arc.\n", dt->name);
00221     j_printerr("SERIOUS WARNING: Transition arc has been modified as below\n");
00222     j_printerr("SERIOUS WARNING: This may cause unintended recognition result\n");
00223     put_htk_trans(dt->tr);
00224   }
00225 #ifdef MULTIPATH_VERSION
00226   if (dt->tr->statenum < 3) {
00227     return_flag = FALSE;
00228     j_printerr("Limit: HMM \"%s\" has no output state (statenum=%d)\n", dt->name, dt->tr->statenum);
00229   }
00230 #endif
00231   return(return_flag);
00232 }
00233 
00241 boolean
00242 check_all_hmm_limit(HTK_HMM_INFO *hmminfo)
00243 {
00244   HTK_HMM_Data *dt;
00245   boolean return_flag = TRUE;
00246 
00247   for (dt = hmminfo->start; dt; dt = dt->next) {
00248     if (check_hmm_limit(dt) == FALSE) {
00249       return_flag = FALSE;
00250     }
00251   }
00252   return(return_flag);
00253 }
00254 
00255 
00256 #ifdef MULTIPATH_VERSION
00257 
00276 boolean
00277 is_skippable_model(HTK_HMM_Data *d)
00278 {
00279   if (d->tr->a[0][d->tr->statenum-1] != LOG_ZERO) {
00280     return TRUE;
00281   }
00282   return FALSE;
00283 }
00284 #endif

Generated on Tue Mar 28 16:01:39 2006 for Julius by  doxygen 1.4.2