00001
00039
00040
00041
00042
00043
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
00056
00057
00058
00059
00060
00061
00062
00063
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
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
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
00110
00111 int i, j;
00112 int tflag = BAD;
00113 int retflag = BAD;
00114 PROB maxprob;
00115 int maxid = -1;
00116
00117
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 {
00124 j_printerr("Warning: initial state has more than one arc\n");
00125 tflag = BAD;
00126 break;
00127 }
00128 }
00129 }
00130 if (tflag == BAD) {
00131 if (i >= t->statenum) {
00132 j_printerr("Error: initial state has no arc\n");
00133 } else {
00134
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
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 {
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) {
00171 j_printerr("Error: no arc to end state\n");
00172 } else {
00173
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
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