00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00042
00043 #include <assert.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <limits.h>
00047
00048
00049 #include <ckd_alloc.h>
00050 #include <err.h>
00051
00052
00053 #include "hmm.h"
00054
00055 hmm_context_t *
00056 hmm_context_init(int32 n_emit_state,
00057 int32 ** const *tp,
00058 int16 const *senscore,
00059 int16 * const *sseq)
00060 {
00061 hmm_context_t *ctx;
00062
00063 assert(n_emit_state > 0);
00064 if (n_emit_state > HMM_MAX_NSTATE) {
00065 E_ERROR("Number of emitting states must be <= 5\n");
00066 return NULL;
00067 }
00068
00069 ctx = ckd_calloc(1, sizeof(*ctx));
00070 ctx->n_emit_state = n_emit_state;
00071 ctx->tp = tp;
00072 ctx->senscore = senscore;
00073 ctx->sseq = sseq;
00074 ctx->st_sen_scr = ckd_calloc(n_emit_state, sizeof(*ctx->st_sen_scr));
00075 ctx->mpx_ssid_alloc = listelem_alloc_init(sizeof(int32) * ctx->n_emit_state);
00076
00077 return ctx;
00078 }
00079
00080 void
00081 hmm_context_free(hmm_context_t *ctx)
00082 {
00083 listelem_alloc_free(ctx->mpx_ssid_alloc);
00084 ckd_free(ctx->st_sen_scr);
00085 ckd_free(ctx);
00086 }
00087
00088 void
00089 hmm_init(hmm_context_t *ctx, hmm_t *hmm, int mpx, int ssid, int tmatid)
00090 {
00091
00092 assert(ssid >= -1);
00093 hmm->ctx = ctx;
00094 hmm->mpx = mpx;
00095 hmm->n_emit_state = ctx->n_emit_state;
00096 if (mpx) {
00097 hmm->s.mpx_ssid = listelem_malloc(ctx->mpx_ssid_alloc);
00098 memset(hmm->s.mpx_ssid, -1, sizeof(*hmm->s.mpx_ssid) * hmm_n_emit_state(hmm));
00099 hmm->s.mpx_ssid[0] = ssid;
00100 }
00101 else {
00102 hmm->s.ssid = ssid;
00103 }
00104 hmm->tmatid = tmatid;
00105 hmm_clear(hmm);
00106 }
00107
00108 void
00109 hmm_deinit(hmm_t *hmm)
00110 {
00111 hmm_context_t *ctx = hmm->ctx;
00112
00113 if (hmm->mpx)
00114 listelem_free(ctx->mpx_ssid_alloc, hmm->s.mpx_ssid);
00115 }
00116
00117 void
00118 hmm_dump(hmm_t * hmm,
00119 FILE * fp)
00120 {
00121 int32 i;
00122
00123 if (hmm_is_mpx(hmm)) {
00124 fprintf(fp, "MPX ");
00125 for (i = 0; i < hmm_n_emit_state(hmm); i++)
00126 fprintf(fp, " %11d", hmm_senid(hmm, i));
00127 fprintf(fp, " ( ");
00128 for (i = 0; i < hmm_n_emit_state(hmm); i++)
00129 fprintf(fp, "%d ", hmm_ssid(hmm, i));
00130 fprintf(fp, ")\n");
00131 }
00132 else {
00133 fprintf(fp, "SSID ");
00134 for (i = 0; i < hmm_n_emit_state(hmm); i++)
00135 fprintf(fp, " %11d", hmm_senid(hmm, i));
00136 fprintf(fp, " (%d)\n", hmm_ssid(hmm, 0));
00137 }
00138
00139 if (hmm->ctx->senscore) {
00140 fprintf(fp, "SENSCR");
00141 for (i = 0; i < hmm_n_emit_state(hmm); i++)
00142 fprintf(fp, " %11d", hmm_senscr(hmm, i));
00143 fprintf(fp, "\n");
00144 }
00145
00146 fprintf(fp, "SCORES %11d", hmm_in_score(hmm));
00147 for (i = 1; i < hmm_n_emit_state(hmm); i++)
00148 fprintf(fp, " %11d", hmm_score(hmm, i));
00149 fprintf(fp, " %11d", hmm_out_score(hmm));
00150 fprintf(fp, "\n");
00151
00152 fprintf(fp, "HISTID %11d", hmm_in_history(hmm));
00153 for (i = 1; i < hmm_n_emit_state(hmm); i++)
00154 fprintf(fp, " %11d", hmm_history(hmm, i));
00155 fprintf(fp, " %11d", hmm_out_history(hmm));
00156 fprintf(fp, "\n");
00157
00158 if (hmm_in_score(hmm) > 0)
00159 fprintf(fp,
00160 "ALERT!! The input score %d is large than 0. Probably wrap around.\n",
00161 hmm_in_score(hmm));
00162 if (hmm_out_score(hmm) > 0)
00163 fprintf(fp,
00164 "ALERT!! The output score %d is large than 0. Probably wrap around\n.",
00165 hmm_out_score(hmm));
00166
00167 fflush(fp);
00168 }
00169
00170
00171 void
00172 hmm_clear_scores(hmm_t * h)
00173 {
00174 int32 i;
00175
00176 hmm_in_score(h) = WORST_SCORE;
00177 for (i = 1; i < hmm_n_emit_state(h); i++)
00178 hmm_score(h, i) = WORST_SCORE;
00179 hmm_out_score(h) = WORST_SCORE;
00180
00181 h->bestscore = WORST_SCORE;
00182 }
00183
00184 void
00185 hmm_clear(hmm_t * h)
00186 {
00187 int32 i;
00188
00189 hmm_in_score(h) = WORST_SCORE;
00190 hmm_in_history(h) = -1;
00191 for (i = 1; i < hmm_n_emit_state(h); i++) {
00192 hmm_score(h, i) = WORST_SCORE;
00193 hmm_history(h, i) = -1;
00194 }
00195 hmm_out_score(h) = WORST_SCORE;
00196 hmm_out_history(h) = -1;
00197
00198 h->bestscore = WORST_SCORE;
00199 h->frame = -1;
00200 }
00201
00202 void
00203 hmm_enter(hmm_t *h, int32 score, int32 histid, int frame)
00204 {
00205 hmm_in_score(h) = score;
00206 hmm_in_history(h) = histid;
00207 hmm_frame(h) = frame;
00208 }
00209
00210 void
00211 hmm_normalize(hmm_t *h, int32 bestscr)
00212 {
00213 int32 i;
00214
00215 for (i = 0; i < hmm_n_emit_state(h); i++) {
00216 if (hmm_score(h, i) > WORST_SCORE)
00217 hmm_score(h, i) -= bestscr;
00218 }
00219 if (hmm_out_score(h) > WORST_SCORE)
00220 hmm_out_score(h) -= bestscr;
00221 }
00222
00223 #define hmm_tprob_5st(i, j) (tp[(i)*6+(j)])
00224 #define nonmpx_senscr(i) (-senscore[sseq[i]] << 10)
00225
00226 static int32
00227 hmm_vit_eval_5st_lr(hmm_t * hmm)
00228 {
00229 int16 const *senscore = hmm->ctx->senscore;
00230 int32 const *tp = hmm->ctx->tp[hmm->tmatid][0];
00231
00232 int16 const *sseq = hmm->ctx->sseq[hmm_ssid(hmm, 0)];
00233 int32 s5, s4, s3, s2, s1, s0, t2, t1, t0, bestScore;
00234
00235
00236 bestScore = WORST_SCORE;
00237
00238
00239 s4 = hmm_score(hmm, 4) + nonmpx_senscr(4);
00240 s3 = hmm_score(hmm, 3) + nonmpx_senscr(3);
00241
00242 if (s3 > WORST_SCORE) {
00243 t1 = s4 + hmm_tprob_5st(4, 5);
00244 t2 = s3 + hmm_tprob_5st(3, 5);
00245 if (t1 > t2) {
00246 s5 = t1;
00247 hmm_out_history(hmm) = hmm_history(hmm, 4);
00248 } else {
00249 s5 = t2;
00250 hmm_out_history(hmm) = hmm_history(hmm, 3);
00251 }
00252 if (s5 < WORST_SCORE) s5 = WORST_SCORE;
00253 hmm_out_score(hmm) = s5;
00254 bestScore = s5;
00255 }
00256
00257 s2 = hmm_score(hmm, 2) + nonmpx_senscr(2);
00258
00259 if (s2 > WORST_SCORE) {
00260 t0 = s4 + hmm_tprob_5st(4, 4);
00261 t1 = s3 + hmm_tprob_5st(3, 4);
00262 t2 = s2 + hmm_tprob_5st(2, 4);
00263 if (t0 > t1) {
00264 if (t2 > t0) {
00265 s4 = t2;
00266 hmm_history(hmm, 4) = hmm_history(hmm, 2);
00267 } else
00268 s4 = t0;
00269 } else {
00270 if (t2 > t1) {
00271 s4 = t2;
00272 hmm_history(hmm, 4) = hmm_history(hmm, 2);
00273 } else {
00274 s4 = t1;
00275 hmm_history(hmm, 4) = hmm_history(hmm, 3);
00276 }
00277 }
00278 if (s4 < WORST_SCORE) s4 = WORST_SCORE;
00279 if (s4 > bestScore) bestScore = s4;
00280 hmm_score(hmm, 4) = s4;
00281 }
00282
00283 s1 = hmm_score(hmm, 1) + nonmpx_senscr(1);
00284
00285 if (s1 > WORST_SCORE) {
00286 t0 = s3 + hmm_tprob_5st(3, 3);
00287 t1 = s2 + hmm_tprob_5st(2, 3);
00288 t2 = s1 + hmm_tprob_5st(1, 3);
00289 if (t0 > t1) {
00290 if (t2 > t0) {
00291 s3 = t2;
00292 hmm_history(hmm, 3) = hmm_history(hmm, 1);
00293 } else
00294 s3 = t0;
00295 } else {
00296 if (t2 > t1) {
00297 s3 = t2;
00298 hmm_history(hmm, 3) = hmm_history(hmm, 1);
00299 } else {
00300 s3 = t1;
00301 hmm_history(hmm, 3) = hmm_history(hmm, 2);
00302 }
00303 }
00304 if (s3 < WORST_SCORE) s3 = WORST_SCORE;
00305 if (s3 > bestScore) bestScore = s3;
00306 hmm_score(hmm, 3) = s3;
00307 }
00308
00309 s0 = hmm_in_score(hmm) + nonmpx_senscr(0);
00310
00311 t0 = s2 + hmm_tprob_5st(2, 2);
00312 t1 = s1 + hmm_tprob_5st(1, 2);
00313 t2 = s0 + hmm_tprob_5st(0, 2);
00314 if (t0 > t1) {
00315 if (t2 > t0) {
00316 s2 = t2;
00317 hmm_history(hmm, 2) = hmm_in_history(hmm);
00318 } else
00319 s2 = t0;
00320 } else {
00321 if (t2 > t1) {
00322 s2 = t2;
00323 hmm_history(hmm, 2) = hmm_in_history(hmm);
00324 } else {
00325 s2 = t1;
00326 hmm_history(hmm, 2) = hmm_history(hmm, 1);
00327 }
00328 }
00329 if (s2 < WORST_SCORE) s2 = WORST_SCORE;
00330 if (s2 > bestScore) bestScore = s2;
00331 hmm_score(hmm, 2) = s2;
00332
00333
00334
00335 t0 = s1 + hmm_tprob_5st(1, 1);
00336 t1 = s0 + hmm_tprob_5st(0, 1);
00337 if (t0 > t1) {
00338 s1 = t0;
00339 } else {
00340 s1 = t1;
00341 hmm_history(hmm, 1) = hmm_in_history(hmm);
00342 }
00343 if (s1 < WORST_SCORE) s1 = WORST_SCORE;
00344 if (s1 > bestScore) bestScore = s1;
00345 hmm_score(hmm, 1) = s1;
00346
00347
00348 s0 = s0 + hmm_tprob_5st(0, 0);
00349 if (s0 < WORST_SCORE) s0 = WORST_SCORE;
00350 if (s0 > bestScore) bestScore = s0;
00351 hmm_in_score(hmm) = s0;
00352
00353 hmm_bestscore(hmm) = bestScore;
00354 return bestScore;
00355 }
00356
00357 #define mpx_senid(st) sseq[ssid[st]][st]
00358 #define mpx_senscr(st) (-senscore[mpx_senid(st)] << 10)
00359
00360 static int32
00361 hmm_vit_eval_5st_lr_mpx(hmm_t * hmm)
00362 {
00363 const int32 *tp = hmm->ctx->tp[hmm->tmatid][0];
00364 const int16 *senscore = hmm->ctx->senscore;
00365 int16 * const *sseq = hmm->ctx->sseq;
00366 int32 *ssid = hmm->s.mpx_ssid;
00367 int32 bestScore;
00368 int32 s5, s4, s3, s2, s1, s0, t2, t1, t0;
00369
00370
00371 if (ssid[4] == -1)
00372 s4 = t1 = WORST_SCORE;
00373 else {
00374 s4 = hmm_score(hmm, 4) + mpx_senscr(4);
00375 t1 = s4 + hmm_tprob_5st(4, 5);
00376 }
00377 if (ssid[3] == -1)
00378 s3 = t2 = WORST_SCORE;
00379 else {
00380 s3 = hmm_score(hmm, 3) + mpx_senscr(3);
00381 t2 = s3 + hmm_tprob_5st(3, 5);
00382 }
00383 if (t1 > t2) {
00384 s5 = t1;
00385 hmm_out_history(hmm) = hmm_history(hmm, 4);
00386 }
00387 else {
00388 s5 = t2;
00389 hmm_out_history(hmm) = hmm_history(hmm, 3);
00390 }
00391 if (s5 < WORST_SCORE) s5 = WORST_SCORE;
00392 hmm_out_score(hmm) = s5;
00393 bestScore = s5;
00394
00395
00396 if (ssid[2] == -1)
00397 s2 = t2 = WORST_SCORE;
00398 else {
00399 s2 = hmm_score(hmm, 2) + mpx_senscr(2);
00400 t2 = s2 + hmm_tprob_5st(2, 4);
00401 }
00402
00403 t0 = t1 = WORST_SCORE;
00404 if (s4 != WORST_SCORE)
00405 t0 = s4 + hmm_tprob_5st(4, 4);
00406 if (s3 != WORST_SCORE)
00407 t1 = s3 + hmm_tprob_5st(3, 4);
00408 if (t0 > t1) {
00409 if (t2 > t0) {
00410 s4 = t2;
00411 hmm_history(hmm, 4) = hmm_history(hmm, 2);
00412 ssid[4] = ssid[2];
00413 }
00414 else
00415 s4 = t0;
00416 }
00417 else {
00418 if (t2 > t1) {
00419 s4 = t2;
00420 hmm_history(hmm, 4) = hmm_history(hmm, 2);
00421 ssid[4] = ssid[2];
00422 }
00423 else {
00424 s4 = t1;
00425 hmm_history(hmm, 4) = hmm_history(hmm, 3);
00426 ssid[4] = ssid[3];
00427 }
00428 }
00429 if (s4 < WORST_SCORE) s4 = WORST_SCORE;
00430 if (s4 > bestScore)
00431 bestScore = s4;
00432 hmm_score(hmm, 4) = s4;
00433
00434
00435 if (ssid[1] == -1)
00436 s1 = t2 = WORST_SCORE;
00437 else {
00438 s1 = hmm_score(hmm, 1) + mpx_senscr(1);
00439 t2 = s1 + hmm_tprob_5st(1, 3);
00440 }
00441 t0 = t1 = WORST_SCORE;
00442 if (s3 != WORST_SCORE)
00443 t0 = s3 + hmm_tprob_5st(3, 3);
00444 if (s2 != WORST_SCORE)
00445 t1 = s2 + hmm_tprob_5st(2, 3);
00446 if (t0 > t1) {
00447 if (t2 > t0) {
00448 s3 = t2;
00449 hmm_history(hmm, 3) = hmm_history(hmm, 1);
00450 ssid[3] = ssid[1];
00451 }
00452 else
00453 s3 = t0;
00454 }
00455 else {
00456 if (t2 > t1) {
00457 s3 = t2;
00458 hmm_history(hmm, 3) = hmm_history(hmm, 1);
00459 ssid[3] = ssid[1];
00460 }
00461 else {
00462 s3 = t1;
00463 hmm_history(hmm, 3) = hmm_history(hmm, 2);
00464 ssid[3] = ssid[2];
00465 }
00466 }
00467 if (s3 < WORST_SCORE) s3 = WORST_SCORE;
00468 if (s3 > bestScore) bestScore = s3;
00469 hmm_score(hmm, 3) = s3;
00470
00471
00472 s0 = hmm_in_score(hmm) + mpx_senscr(0);
00473
00474
00475 t0 = t1 = WORST_SCORE;
00476 if (s2 != WORST_SCORE)
00477 t0 = s2 + hmm_tprob_5st(2, 2);
00478 if (s1 != WORST_SCORE)
00479 t1 = s1 + hmm_tprob_5st(1, 2);
00480 t2 = s0 + hmm_tprob_5st(0, 2);
00481 if (t0 > t1) {
00482 if (t2 > t0) {
00483 s2 = t2;
00484 hmm_history(hmm, 2) = hmm_in_history(hmm);
00485 ssid[2] = ssid[0];
00486 }
00487 else
00488 s2 = t0;
00489 }
00490 else {
00491 if (t2 > t1) {
00492 s2 = t2;
00493 hmm_history(hmm, 2) = hmm_in_history(hmm);
00494 ssid[2] = ssid[0];
00495 }
00496 else {
00497 s2 = t1;
00498 hmm_history(hmm, 2) = hmm_history(hmm, 1);
00499 ssid[2] = ssid[1];
00500 }
00501 }
00502 if (s2 < WORST_SCORE) s2 = WORST_SCORE;
00503 if (s2 > bestScore) bestScore = s2;
00504 hmm_score(hmm, 2) = s2;
00505
00506
00507 t0 = WORST_SCORE;
00508 if (s1 != WORST_SCORE)
00509 t0 = s1 + hmm_tprob_5st(1, 1);
00510 t1 = s0 + hmm_tprob_5st(0, 1);
00511 if (t0 > t1) {
00512 s1 = t0;
00513 }
00514 else {
00515 s1 = t1;
00516 hmm_history(hmm, 1) = hmm_in_history(hmm);
00517 ssid[1] = ssid[0];
00518 }
00519 if (s1 < WORST_SCORE) s1 = WORST_SCORE;
00520 if (s1 > bestScore) bestScore = s1;
00521 hmm_score(hmm, 1) = s1;
00522
00523 s0 += hmm_tprob_5st(0, 0);
00524 if (s0 < WORST_SCORE) s0 = WORST_SCORE;
00525 if (s0 > bestScore) bestScore = s0;
00526 hmm_in_score(hmm) = s0;
00527
00528 hmm_bestscore(hmm) = bestScore;
00529 return bestScore;
00530 }
00531
00532 #define hmm_tprob_3st(i, j) (tp[(i)*4+(j)])
00533
00534 static int32
00535 hmm_vit_eval_3st_lr(hmm_t * hmm)
00536 {
00537 const int16 *senscore = hmm->ctx->senscore;
00538 const int32 *tp = hmm->ctx->tp[hmm->tmatid][0];
00539 const int16 *sseq = hmm->ctx->sseq[hmm_ssid(hmm, 0)];
00540 int32 s3, s2, s1, s0, t2, t1, t0, bestScore;
00541
00542 s2 = hmm_score(hmm, 2) + nonmpx_senscr(2);
00543 s1 = hmm_score(hmm, 1) + nonmpx_senscr(1);
00544 s0 = hmm_in_score(hmm) + nonmpx_senscr(0);
00545
00546
00547 bestScore = WORST_SCORE;
00548 t2 = INT_MIN;
00549
00550
00551 if (s1 > WORST_SCORE) {
00552 t1 = s2 + hmm_tprob_3st(2, 3);
00553 if (hmm_tprob_3st(1,3) > WORST_SCORE)
00554 t2 = s1 + hmm_tprob_3st(1, 3);
00555 if (t1 > t2) {
00556 s3 = t1;
00557 hmm_out_history(hmm) = hmm_history(hmm, 2);
00558 } else {
00559 s3 = t2;
00560 hmm_out_history(hmm) = hmm_history(hmm, 1);
00561 }
00562 if (s3 < WORST_SCORE) s3 = WORST_SCORE;
00563 hmm_out_score(hmm) = s3;
00564 bestScore = s3;
00565 }
00566
00567
00568 t0 = s2 + hmm_tprob_3st(2, 2);
00569 t1 = s1 + hmm_tprob_3st(1, 2);
00570 if (hmm_tprob_3st(0, 2) > WORST_SCORE)
00571 t2 = s0 + hmm_tprob_3st(0, 2);
00572 if (t0 > t1) {
00573 if (t2 > t0) {
00574 s2 = t2;
00575 hmm_history(hmm, 2) = hmm_in_history(hmm);
00576 } else
00577 s2 = t0;
00578 } else {
00579 if (t2 > t1) {
00580 s2 = t2;
00581 hmm_history(hmm, 2) = hmm_in_history(hmm);
00582 } else {
00583 s2 = t1;
00584 hmm_history(hmm, 2) = hmm_history(hmm, 1);
00585 }
00586 }
00587 if (s2 < WORST_SCORE) s2 = WORST_SCORE;
00588 if (s2 > bestScore) bestScore = s2;
00589 hmm_score(hmm, 2) = s2;
00590
00591
00592 t0 = s1 + hmm_tprob_3st(1, 1);
00593 t1 = s0 + hmm_tprob_3st(0, 1);
00594 if (t0 > t1) {
00595 s1 = t0;
00596 } else {
00597 s1 = t1;
00598 hmm_history(hmm, 1) = hmm_in_history(hmm);
00599 }
00600 if (s1 < WORST_SCORE) s1 = WORST_SCORE;
00601 if (s1 > bestScore) bestScore = s1;
00602 hmm_score(hmm, 1) = s1;
00603
00604
00605 s0 = s0 + hmm_tprob_3st(0, 0);
00606 if (s0 < WORST_SCORE) s0 = WORST_SCORE;
00607 if (s0 > bestScore) bestScore = s0;
00608 hmm_in_score(hmm) = s0;
00609
00610 hmm_bestscore(hmm) = bestScore;
00611 return bestScore;
00612 }
00613
00614 static int32
00615 hmm_vit_eval_3st_lr_mpx(hmm_t * hmm)
00616 {
00617 int32 const *tp = hmm->ctx->tp[hmm->tmatid][0];
00618 int16 const *senscore = hmm->ctx->senscore;
00619 int16 * const *sseq = hmm->ctx->sseq;
00620 int32 *ssid = hmm->s.mpx_ssid;
00621 int32 bestScore;
00622 int32 s3, s2, s1, s0, t2, t1, t0;
00623
00624
00625 t2 = INT_MIN;
00626 if (ssid[2] == -1)
00627 s2 = t1 = WORST_SCORE;
00628 else {
00629 s2 = hmm_score(hmm, 2) + mpx_senscr(2);
00630 t1 = s2 + hmm_tprob_3st(2, 3);
00631 }
00632 if (ssid[1] == -1)
00633 s1 = WORST_SCORE;
00634 else {
00635 s1 = hmm_score(hmm, 1) + mpx_senscr(1);
00636 t2 = s1 + hmm_tprob_3st(1, 3);
00637 }
00638 if (t1 > t2) {
00639 s3 = t1;
00640 hmm_out_history(hmm) = hmm_history(hmm, 2);
00641 }
00642 else {
00643 s3 = t2;
00644 hmm_out_history(hmm) = hmm_history(hmm, 1);
00645 }
00646 if (s3 < WORST_SCORE) s3 = WORST_SCORE;
00647 hmm_out_score(hmm) = s3;
00648 bestScore = s3;
00649
00650
00651 s0 = hmm_in_score(hmm) + mpx_senscr(0);
00652
00653
00654 t0 = t1 = WORST_SCORE;
00655 if (s2 != WORST_SCORE)
00656 t0 = s2 + hmm_tprob_3st(2, 2);
00657 if (s1 != WORST_SCORE)
00658 t1 = s1 + hmm_tprob_3st(1, 2);
00659 if (hmm_tprob_3st(0,2) > WORST_SCORE)
00660 t2 = s0 + hmm_tprob_3st(0, 2);
00661 if (t0 > t1) {
00662 if (t2 > t0) {
00663 s2 = t2;
00664 hmm_history(hmm, 2) = hmm_in_history(hmm);
00665 ssid[2] = ssid[0];
00666 }
00667 else
00668 s2 = t0;
00669 }
00670 else {
00671 if (t2 > t1) {
00672 s2 = t2;
00673 hmm_history(hmm, 2) = hmm_in_history(hmm);
00674 ssid[2] = ssid[0];
00675 }
00676 else {
00677 s2 = t1;
00678 hmm_history(hmm, 2) = hmm_history(hmm, 1);
00679 ssid[2] = ssid[1];
00680 }
00681 }
00682 if (s2 < WORST_SCORE) s2 = WORST_SCORE;
00683 if (s2 > bestScore) bestScore = s2;
00684 hmm_score(hmm, 2) = s2;
00685
00686
00687 t0 = WORST_SCORE;
00688 if (s1 != WORST_SCORE)
00689 t0 = s1 + hmm_tprob_3st(1, 1);
00690 t1 = s0 + hmm_tprob_3st(0, 1);
00691 if (t0 > t1) {
00692 s1 = t0;
00693 }
00694 else {
00695 s1 = t1;
00696 hmm_history(hmm, 1) = hmm_in_history(hmm);
00697 ssid[1] = ssid[0];
00698 }
00699 if (s1 < WORST_SCORE) s1 = WORST_SCORE;
00700 if (s1 > bestScore) bestScore = s1;
00701 hmm_score(hmm, 1) = s1;
00702
00703
00704 s0 += hmm_tprob_3st(0, 0);
00705 if (s0 < WORST_SCORE) s0 = WORST_SCORE;
00706 if (s0 > bestScore) bestScore = s0;
00707 hmm_in_score(hmm) = s0;
00708
00709 hmm_bestscore(hmm) = bestScore;
00710 return bestScore;
00711 }
00712
00713 static int32
00714 hmm_vit_eval_anytopo(hmm_t * hmm)
00715 {
00716 hmm_context_t *ctx = hmm->ctx;
00717 int32 to, from, bestfrom;
00718 int32 newscr, scr, bestscr;
00719 int final_state;
00720
00721
00722 ctx->st_sen_scr[0] = hmm_in_score(hmm) + hmm_senscr(hmm, 0);
00723 for (from = 1; from < hmm_n_emit_state(hmm); ++from) {
00724 if ((ctx->st_sen_scr[from] =
00725 hmm_score(hmm, from) + hmm_senscr(hmm, from)) < WORST_SCORE)
00726 ctx->st_sen_scr[from] = WORST_SCORE;
00727 }
00728
00729
00730
00731 final_state = hmm_n_emit_state(hmm);
00732 to = final_state;
00733 scr = WORST_SCORE;
00734 bestfrom = -1;
00735 for (from = to - 1; from >= 0; --from) {
00736 if ((hmm_tprob(hmm, from, to) > WORST_SCORE) &&
00737 ((newscr = ctx->st_sen_scr[from]
00738 + hmm_tprob(hmm, from, to)) > scr)) {
00739 scr = newscr;
00740 bestfrom = from;
00741 }
00742 }
00743 hmm_out_score(hmm) = scr;
00744 if (bestfrom >= 0)
00745 hmm_out_history(hmm) = hmm_history(hmm, bestfrom);
00746 bestscr = scr;
00747
00748
00749 for (to = final_state - 1; to >= 0; --to) {
00750
00751 scr =
00752 (hmm_tprob(hmm, to, to) > WORST_SCORE)
00753 ? ctx->st_sen_scr[to] + hmm_tprob(hmm, to, to)
00754 : WORST_SCORE;
00755
00756
00757 bestfrom = -1;
00758 for (from = to - 1; from >= 0; --from) {
00759 if ((hmm_tprob(hmm, from, to) > WORST_SCORE) &&
00760 ((newscr = ctx->st_sen_scr[from]
00761 + hmm_tprob(hmm, from, to)) > scr)) {
00762 scr = newscr;
00763 bestfrom = from;
00764 }
00765 }
00766
00767
00768 if (to == 0) {
00769 hmm_in_score(hmm) = scr;
00770 if (bestfrom >= 0)
00771 hmm_in_history(hmm) = hmm_history(hmm, bestfrom);
00772 }
00773 else {
00774 hmm_score(hmm, to) = scr;
00775 if (bestfrom >= 0)
00776 hmm_history(hmm, to) = hmm_history(hmm, bestfrom);
00777 }
00778 if (bestfrom >= 0 && hmm_is_mpx(hmm))
00779 hmm->s.mpx_ssid[to] = hmm->s.mpx_ssid[bestfrom];
00780
00781 if (bestscr < scr)
00782 bestscr = scr;
00783 }
00784
00785 hmm_bestscore(hmm) = bestscr;
00786 return bestscr;
00787 }
00788
00789 int32
00790 hmm_vit_eval(hmm_t * hmm)
00791 {
00792 if (hmm_is_mpx(hmm)) {
00793 if (hmm_n_emit_state(hmm) == 5)
00794 return hmm_vit_eval_5st_lr_mpx(hmm);
00795 else if (hmm_n_emit_state(hmm) == 3)
00796 return hmm_vit_eval_3st_lr_mpx(hmm);
00797 else
00798 return hmm_vit_eval_anytopo(hmm);
00799 }
00800 else {
00801 if (hmm_n_emit_state(hmm) == 5)
00802 return hmm_vit_eval_5st_lr(hmm);
00803 else if (hmm_n_emit_state(hmm) == 3)
00804 return hmm_vit_eval_3st_lr(hmm);
00805 else
00806 return hmm_vit_eval_anytopo(hmm);
00807 }
00808 }
00809
00810 int32
00811 hmm_dump_vit_eval(hmm_t * hmm, FILE * fp)
00812 {
00813 int32 bs = 0;
00814
00815 if (fp) {
00816 fprintf(fp, "BEFORE:\n");
00817 hmm_dump(hmm, fp);
00818 }
00819 bs = hmm_vit_eval(hmm);
00820 if (fp) {
00821 fprintf(fp, "AFTER:\n");
00822 hmm_dump(hmm, fp);
00823 }
00824
00825 return bs;
00826 }