| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| #include <assert.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <limits.h> |
|
|
| #include <pocketsphinx/err.h> |
|
|
| #include "util/ckd_alloc.h" |
| #include "hmm.h" |
|
|
| hmm_context_t * |
| hmm_context_init(int32 n_emit_state, |
| uint8 ** const *tp, |
| int16 const *senscore, |
| uint16 * const *sseq) |
| { |
| hmm_context_t *ctx; |
|
|
| assert(n_emit_state > 0); |
| if (n_emit_state > HMM_MAX_NSTATE) { |
| E_ERROR("Number of emitting states must be <= %d\n", HMM_MAX_NSTATE); |
| return NULL; |
| } |
|
|
| ctx = ckd_calloc(1, sizeof(*ctx)); |
| ctx->n_emit_state = n_emit_state; |
| ctx->tp = tp; |
| ctx->senscore = senscore; |
| ctx->sseq = sseq; |
| ctx->st_sen_scr = ckd_calloc(n_emit_state, sizeof(*ctx->st_sen_scr)); |
|
|
| return ctx; |
| } |
|
|
| void |
| hmm_context_free(hmm_context_t *ctx) |
| { |
| if (ctx == NULL) |
| return; |
| ckd_free(ctx->st_sen_scr); |
| ckd_free(ctx); |
| } |
|
|
| void |
| hmm_init(hmm_context_t *ctx, hmm_t *hmm, int mpx, int ssid, int tmatid) |
| { |
| hmm->ctx = ctx; |
| hmm->mpx = mpx; |
| hmm->n_emit_state = ctx->n_emit_state; |
| if (mpx) { |
| int i; |
| hmm->ssid = BAD_SSID; |
| hmm->senid[0] = ssid; |
| for (i = 1; i < hmm_n_emit_state(hmm); ++i) { |
| hmm->senid[i] = BAD_SSID; |
| } |
| } |
| else { |
| hmm->ssid = ssid; |
| memcpy(hmm->senid, ctx->sseq[ssid], hmm->n_emit_state * sizeof(*hmm->senid)); |
| } |
| hmm->tmatid = tmatid; |
| hmm_clear(hmm); |
| } |
|
|
| void |
| hmm_deinit(hmm_t *hmm) |
| { |
| (void)hmm; |
| } |
|
|
| void |
| hmm_dump(hmm_t * hmm, |
| FILE * fp) |
| { |
| int32 i; |
|
|
| if (hmm_is_mpx(hmm)) { |
| fprintf(fp, "MPX "); |
| for (i = 0; i < hmm_n_emit_state(hmm); i++) |
| fprintf(fp, " %11d", hmm_senid(hmm, i)); |
| fprintf(fp, " ( "); |
| for (i = 0; i < hmm_n_emit_state(hmm); i++) |
| fprintf(fp, "%d ", hmm_ssid(hmm, i)); |
| fprintf(fp, ")\n"); |
| } |
| else { |
| fprintf(fp, "SSID "); |
| for (i = 0; i < hmm_n_emit_state(hmm); i++) |
| fprintf(fp, " %11d", hmm_senid(hmm, i)); |
| fprintf(fp, " (%d)\n", hmm_ssid(hmm, 0)); |
| } |
|
|
| if (hmm->ctx->senscore) { |
| fprintf(fp, "SENSCR"); |
| for (i = 0; i < hmm_n_emit_state(hmm); i++) |
| fprintf(fp, " %11d", hmm_senscr(hmm, i)); |
| fprintf(fp, "\n"); |
| } |
|
|
| fprintf(fp, "SCORES %11d", hmm_in_score(hmm)); |
| for (i = 1; i < hmm_n_emit_state(hmm); i++) |
| fprintf(fp, " %11d", hmm_score(hmm, i)); |
| fprintf(fp, " %11d", hmm_out_score(hmm)); |
| fprintf(fp, "\n"); |
|
|
| fprintf(fp, "HISTID %11d", hmm_in_history(hmm)); |
| for (i = 1; i < hmm_n_emit_state(hmm); i++) |
| fprintf(fp, " %11d", hmm_history(hmm, i)); |
| fprintf(fp, " %11d", hmm_out_history(hmm)); |
| fprintf(fp, "\n"); |
|
|
| if (hmm_in_score(hmm) > 0) |
| fprintf(fp, |
| "ALERT!! The input score %d is large than 0. Probably wrap around.\n", |
| hmm_in_score(hmm)); |
| if (hmm_out_score(hmm) > 0) |
| fprintf(fp, |
| "ALERT!! The output score %d is large than 0. Probably wrap around\n.", |
| hmm_out_score(hmm)); |
|
|
| fflush(fp); |
| } |
|
|
|
|
| void |
| hmm_clear_scores(hmm_t * h) |
| { |
| int32 i; |
|
|
| hmm_in_score(h) = WORST_SCORE; |
| for (i = 1; i < hmm_n_emit_state(h); i++) |
| hmm_score(h, i) = WORST_SCORE; |
| hmm_out_score(h) = WORST_SCORE; |
|
|
| h->bestscore = WORST_SCORE; |
| } |
|
|
| void |
| hmm_clear(hmm_t * h) |
| { |
| int32 i; |
|
|
| hmm_in_score(h) = WORST_SCORE; |
| hmm_in_history(h) = -1; |
| for (i = 1; i < hmm_n_emit_state(h); i++) { |
| hmm_score(h, i) = WORST_SCORE; |
| hmm_history(h, i) = -1; |
| } |
| hmm_out_score(h) = WORST_SCORE; |
| hmm_out_history(h) = -1; |
|
|
| h->bestscore = WORST_SCORE; |
| h->frame = -1; |
| } |
|
|
| void |
| hmm_enter(hmm_t *h, int32 score, int32 histid, int frame) |
| { |
| hmm_in_score(h) = score; |
| hmm_in_history(h) = histid; |
| hmm_frame(h) = frame; |
| } |
|
|
| void |
| hmm_normalize(hmm_t *h, int32 bestscr) |
| { |
| int32 i; |
|
|
| for (i = 0; i < hmm_n_emit_state(h); i++) { |
| if (hmm_score(h, i) BETTER_THAN WORST_SCORE) |
| hmm_score(h, i) -= bestscr; |
| } |
| if (hmm_out_score(h) BETTER_THAN WORST_SCORE) |
| hmm_out_score(h) -= bestscr; |
| } |
|
|
| #define hmm_tprob_5st(i, j) (-tp[(i)*6+(j)]) |
| #define nonmpx_senscr(i) (-senscore[sseq[i]]) |
|
|
| static int32 |
| hmm_vit_eval_5st_lr(hmm_t * hmm) |
| { |
| int16 const *senscore = hmm->ctx->senscore; |
| uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; |
| uint16 const *sseq = hmm->senid; |
| int32 s5, s4, s3, s2, s1, s0, t2, t1, t0, bestScore; |
|
|
| |
| bestScore = WORST_SCORE; |
|
|
| |
| s4 = hmm_score(hmm, 4) + nonmpx_senscr(4); |
| s3 = hmm_score(hmm, 3) + nonmpx_senscr(3); |
| |
| if (s3 BETTER_THAN WORST_SCORE) { |
| t1 = s4 + hmm_tprob_5st(4, 5); |
| t2 = s3 + hmm_tprob_5st(3, 5); |
| if (t1 BETTER_THAN t2) { |
| s5 = t1; |
| hmm_out_history(hmm) = hmm_history(hmm, 4); |
| } else { |
| s5 = t2; |
| hmm_out_history(hmm) = hmm_history(hmm, 3); |
| } |
| if (s5 WORSE_THAN WORST_SCORE) s5 = WORST_SCORE; |
| hmm_out_score(hmm) = s5; |
| bestScore = s5; |
| } |
|
|
| s2 = hmm_score(hmm, 2) + nonmpx_senscr(2); |
| |
| if (s2 BETTER_THAN WORST_SCORE) { |
| t0 = s4 + hmm_tprob_5st(4, 4); |
| t1 = s3 + hmm_tprob_5st(3, 4); |
| t2 = s2 + hmm_tprob_5st(2, 4); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s4 = t2; |
| hmm_history(hmm, 4) = hmm_history(hmm, 2); |
| } else |
| s4 = t0; |
| } else { |
| if (t2 BETTER_THAN t1) { |
| s4 = t2; |
| hmm_history(hmm, 4) = hmm_history(hmm, 2); |
| } else { |
| s4 = t1; |
| hmm_history(hmm, 4) = hmm_history(hmm, 3); |
| } |
| } |
| if (s4 WORSE_THAN WORST_SCORE) s4 = WORST_SCORE; |
| if (s4 BETTER_THAN bestScore) bestScore = s4; |
| hmm_score(hmm, 4) = s4; |
| } |
|
|
| s1 = hmm_score(hmm, 1) + nonmpx_senscr(1); |
| |
| if (s1 BETTER_THAN WORST_SCORE) { |
| t0 = s3 + hmm_tprob_5st(3, 3); |
| t1 = s2 + hmm_tprob_5st(2, 3); |
| t2 = s1 + hmm_tprob_5st(1, 3); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s3 = t2; |
| hmm_history(hmm, 3) = hmm_history(hmm, 1); |
| } else |
| s3 = t0; |
| } else { |
| if (t2 BETTER_THAN t1) { |
| s3 = t2; |
| hmm_history(hmm, 3) = hmm_history(hmm, 1); |
| } else { |
| s3 = t1; |
| hmm_history(hmm, 3) = hmm_history(hmm, 2); |
| } |
| } |
| if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; |
| if (s3 BETTER_THAN bestScore) bestScore = s3; |
| hmm_score(hmm, 3) = s3; |
| } |
|
|
| s0 = hmm_in_score(hmm) + nonmpx_senscr(0); |
| |
| t0 = s2 + hmm_tprob_5st(2, 2); |
| t1 = s1 + hmm_tprob_5st(1, 2); |
| t2 = s0 + hmm_tprob_5st(0, 2); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| } else |
| s2 = t0; |
| } else { |
| if (t2 BETTER_THAN t1) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| } else { |
| s2 = t1; |
| hmm_history(hmm, 2) = hmm_history(hmm, 1); |
| } |
| } |
| if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; |
| if (s2 BETTER_THAN bestScore) bestScore = s2; |
| hmm_score(hmm, 2) = s2; |
|
|
|
|
| |
| t0 = s1 + hmm_tprob_5st(1, 1); |
| t1 = s0 + hmm_tprob_5st(0, 1); |
| if (t0 BETTER_THAN t1) { |
| s1 = t0; |
| } else { |
| s1 = t1; |
| hmm_history(hmm, 1) = hmm_in_history(hmm); |
| } |
| if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; |
| if (s1 BETTER_THAN bestScore) bestScore = s1; |
| hmm_score(hmm, 1) = s1; |
|
|
| |
| s0 = s0 + hmm_tprob_5st(0, 0); |
| if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; |
| if (s0 BETTER_THAN bestScore) bestScore = s0; |
| hmm_in_score(hmm) = s0; |
|
|
| hmm_bestscore(hmm) = bestScore; |
| return bestScore; |
| } |
|
|
| #define mpx_senid(st) sseq[ssid[st]][st] |
| #define mpx_senscr(st) (-senscore[mpx_senid(st)]) |
|
|
| static int32 |
| hmm_vit_eval_5st_lr_mpx(hmm_t * hmm) |
| { |
| uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; |
| int16 const *senscore = hmm->ctx->senscore; |
| uint16 * const *sseq = hmm->ctx->sseq; |
| uint16 *ssid = hmm->senid; |
| int32 bestScore; |
| int32 s5, s4, s3, s2, s1, s0, t2, t1, t0; |
|
|
| |
| if (ssid[4] == BAD_SSID) |
| s4 = t1 = WORST_SCORE; |
| else { |
| s4 = hmm_score(hmm, 4) + mpx_senscr(4); |
| t1 = s4 + hmm_tprob_5st(4, 5); |
| } |
| if (ssid[3] == BAD_SSID) |
| s3 = t2 = WORST_SCORE; |
| else { |
| s3 = hmm_score(hmm, 3) + mpx_senscr(3); |
| t2 = s3 + hmm_tprob_5st(3, 5); |
| } |
| if (t1 BETTER_THAN t2) { |
| s5 = t1; |
| hmm_out_history(hmm) = hmm_history(hmm, 4); |
| } |
| else { |
| s5 = t2; |
| hmm_out_history(hmm) = hmm_history(hmm, 3); |
| } |
| if (s5 WORSE_THAN WORST_SCORE) s5 = WORST_SCORE; |
| hmm_out_score(hmm) = s5; |
| bestScore = s5; |
|
|
| |
| if (ssid[2] == BAD_SSID) |
| s2 = t2 = WORST_SCORE; |
| else { |
| s2 = hmm_score(hmm, 2) + mpx_senscr(2); |
| t2 = s2 + hmm_tprob_5st(2, 4); |
| } |
|
|
| t0 = t1 = WORST_SCORE; |
| if (s4 != WORST_SCORE) |
| t0 = s4 + hmm_tprob_5st(4, 4); |
| if (s3 != WORST_SCORE) |
| t1 = s3 + hmm_tprob_5st(3, 4); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s4 = t2; |
| hmm_history(hmm, 4) = hmm_history(hmm, 2); |
| ssid[4] = ssid[2]; |
| } |
| else |
| s4 = t0; |
| } |
| else { |
| if (t2 BETTER_THAN t1) { |
| s4 = t2; |
| hmm_history(hmm, 4) = hmm_history(hmm, 2); |
| ssid[4] = ssid[2]; |
| } |
| else { |
| s4 = t1; |
| hmm_history(hmm, 4) = hmm_history(hmm, 3); |
| ssid[4] = ssid[3]; |
| } |
| } |
| if (s4 WORSE_THAN WORST_SCORE) s4 = WORST_SCORE; |
| if (s4 BETTER_THAN bestScore) |
| bestScore = s4; |
| hmm_score(hmm, 4) = s4; |
|
|
| |
| if (ssid[1] == BAD_SSID) |
| s1 = t2 = WORST_SCORE; |
| else { |
| s1 = hmm_score(hmm, 1) + mpx_senscr(1); |
| t2 = s1 + hmm_tprob_5st(1, 3); |
| } |
| t0 = t1 = WORST_SCORE; |
| if (s3 != WORST_SCORE) |
| t0 = s3 + hmm_tprob_5st(3, 3); |
| if (s2 != WORST_SCORE) |
| t1 = s2 + hmm_tprob_5st(2, 3); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s3 = t2; |
| hmm_history(hmm, 3) = hmm_history(hmm, 1); |
| ssid[3] = ssid[1]; |
| } |
| else |
| s3 = t0; |
| } |
| else { |
| if (t2 BETTER_THAN t1) { |
| s3 = t2; |
| hmm_history(hmm, 3) = hmm_history(hmm, 1); |
| ssid[3] = ssid[1]; |
| } |
| else { |
| s3 = t1; |
| hmm_history(hmm, 3) = hmm_history(hmm, 2); |
| ssid[3] = ssid[2]; |
| } |
| } |
| if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; |
| if (s3 BETTER_THAN bestScore) bestScore = s3; |
| hmm_score(hmm, 3) = s3; |
|
|
| |
| s0 = hmm_in_score(hmm) + mpx_senscr(0); |
|
|
| |
| t0 = t1 = WORST_SCORE; |
| if (s2 != WORST_SCORE) |
| t0 = s2 + hmm_tprob_5st(2, 2); |
| if (s1 != WORST_SCORE) |
| t1 = s1 + hmm_tprob_5st(1, 2); |
| t2 = s0 + hmm_tprob_5st(0, 2); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| ssid[2] = ssid[0]; |
| } |
| else |
| s2 = t0; |
| } |
| else { |
| if (t2 BETTER_THAN t1) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| ssid[2] = ssid[0]; |
| } |
| else { |
| s2 = t1; |
| hmm_history(hmm, 2) = hmm_history(hmm, 1); |
| ssid[2] = ssid[1]; |
| } |
| } |
| if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; |
| if (s2 BETTER_THAN bestScore) bestScore = s2; |
| hmm_score(hmm, 2) = s2; |
|
|
| |
| t0 = WORST_SCORE; |
| if (s1 != WORST_SCORE) |
| t0 = s1 + hmm_tprob_5st(1, 1); |
| t1 = s0 + hmm_tprob_5st(0, 1); |
| if (t0 BETTER_THAN t1) { |
| s1 = t0; |
| } |
| else { |
| s1 = t1; |
| hmm_history(hmm, 1) = hmm_in_history(hmm); |
| ssid[1] = ssid[0]; |
| } |
| if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; |
| if (s1 BETTER_THAN bestScore) bestScore = s1; |
| hmm_score(hmm, 1) = s1; |
|
|
| s0 += hmm_tprob_5st(0, 0); |
| if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; |
| if (s0 BETTER_THAN bestScore) bestScore = s0; |
| hmm_in_score(hmm) = s0; |
|
|
| hmm_bestscore(hmm) = bestScore; |
| return bestScore; |
| } |
|
|
| #define hmm_tprob_3st(i, j) (-tp[(i)*4+(j)]) |
|
|
| static int32 |
| hmm_vit_eval_3st_lr(hmm_t * hmm) |
| { |
| int16 const *senscore = hmm->ctx->senscore; |
| uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; |
| uint16 const *sseq = hmm->senid; |
| int32 s3, s2, s1, s0, t2, t1, t0, bestScore; |
|
|
| s2 = hmm_score(hmm, 2) + nonmpx_senscr(2); |
| s1 = hmm_score(hmm, 1) + nonmpx_senscr(1); |
| s0 = hmm_in_score(hmm) + nonmpx_senscr(0); |
|
|
| |
| bestScore = WORST_SCORE; |
| t2 = INT_MIN; |
|
|
| |
| if (s1 BETTER_THAN WORST_SCORE) { |
| t1 = s2 + hmm_tprob_3st(2, 3); |
| if (hmm_tprob_3st(1,3) BETTER_THAN TMAT_WORST_SCORE) |
| t2 = s1 + hmm_tprob_3st(1, 3); |
| if (t1 BETTER_THAN t2) { |
| s3 = t1; |
| hmm_out_history(hmm) = hmm_history(hmm, 2); |
| } else { |
| s3 = t2; |
| hmm_out_history(hmm) = hmm_history(hmm, 1); |
| } |
| if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; |
| hmm_out_score(hmm) = s3; |
| bestScore = s3; |
| } |
|
|
| |
| t0 = s2 + hmm_tprob_3st(2, 2); |
| t1 = s1 + hmm_tprob_3st(1, 2); |
| if (hmm_tprob_3st(0, 2) BETTER_THAN TMAT_WORST_SCORE) |
| t2 = s0 + hmm_tprob_3st(0, 2); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| } else |
| s2 = t0; |
| } else { |
| if (t2 BETTER_THAN t1) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| } else { |
| s2 = t1; |
| hmm_history(hmm, 2) = hmm_history(hmm, 1); |
| } |
| } |
| if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; |
| if (s2 BETTER_THAN bestScore) bestScore = s2; |
| hmm_score(hmm, 2) = s2; |
|
|
| |
| t0 = s1 + hmm_tprob_3st(1, 1); |
| t1 = s0 + hmm_tprob_3st(0, 1); |
| if (t0 BETTER_THAN t1) { |
| s1 = t0; |
| } else { |
| s1 = t1; |
| hmm_history(hmm, 1) = hmm_in_history(hmm); |
| } |
| if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; |
| if (s1 BETTER_THAN bestScore) bestScore = s1; |
| hmm_score(hmm, 1) = s1; |
|
|
| |
| s0 = s0 + hmm_tprob_3st(0, 0); |
| if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; |
| if (s0 BETTER_THAN bestScore) bestScore = s0; |
| hmm_in_score(hmm) = s0; |
|
|
| hmm_bestscore(hmm) = bestScore; |
| return bestScore; |
| } |
|
|
| static int32 |
| hmm_vit_eval_3st_lr_mpx(hmm_t * hmm) |
| { |
| uint8 const *tp = hmm->ctx->tp[hmm->tmatid][0]; |
| int16 const *senscore = hmm->ctx->senscore; |
| uint16 * const *sseq = hmm->ctx->sseq; |
| uint16 *ssid = hmm->senid; |
| int32 bestScore; |
| int32 s3, s2, s1, s0, t2, t1, t0; |
|
|
| |
| t2 = INT_MIN; |
| if (ssid[2] == BAD_SSID) |
| s2 = t1 = WORST_SCORE; |
| else { |
| s2 = hmm_score(hmm, 2) + mpx_senscr(2); |
| t1 = s2 + hmm_tprob_3st(2, 3); |
| } |
| if (ssid[1] == BAD_SSID) |
| s1 = t2 = WORST_SCORE; |
| else { |
| s1 = hmm_score(hmm, 1) + mpx_senscr(1); |
| if (hmm_tprob_3st(1,3) BETTER_THAN TMAT_WORST_SCORE) |
| t2 = s1 + hmm_tprob_3st(1, 3); |
| } |
| if (t1 BETTER_THAN t2) { |
| s3 = t1; |
| hmm_out_history(hmm) = hmm_history(hmm, 2); |
| } |
| else { |
| s3 = t2; |
| hmm_out_history(hmm) = hmm_history(hmm, 1); |
| } |
| if (s3 WORSE_THAN WORST_SCORE) s3 = WORST_SCORE; |
| hmm_out_score(hmm) = s3; |
| bestScore = s3; |
|
|
| |
| s0 = hmm_in_score(hmm) + mpx_senscr(0); |
|
|
| |
| t0 = t1 = WORST_SCORE; |
| if (s2 != WORST_SCORE) |
| t0 = s2 + hmm_tprob_3st(2, 2); |
| if (s1 != WORST_SCORE) |
| t1 = s1 + hmm_tprob_3st(1, 2); |
| if (hmm_tprob_3st(0,2) BETTER_THAN TMAT_WORST_SCORE) |
| t2 = s0 + hmm_tprob_3st(0, 2); |
| if (t0 BETTER_THAN t1) { |
| if (t2 BETTER_THAN t0) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| ssid[2] = ssid[0]; |
| } |
| else |
| s2 = t0; |
| } |
| else { |
| if (t2 BETTER_THAN t1) { |
| s2 = t2; |
| hmm_history(hmm, 2) = hmm_in_history(hmm); |
| ssid[2] = ssid[0]; |
| } |
| else { |
| s2 = t1; |
| hmm_history(hmm, 2) = hmm_history(hmm, 1); |
| ssid[2] = ssid[1]; |
| } |
| } |
| if (s2 WORSE_THAN WORST_SCORE) s2 = WORST_SCORE; |
| if (s2 BETTER_THAN bestScore) bestScore = s2; |
| hmm_score(hmm, 2) = s2; |
|
|
| |
| t0 = WORST_SCORE; |
| if (s1 != WORST_SCORE) |
| t0 = s1 + hmm_tprob_3st(1, 1); |
| t1 = s0 + hmm_tprob_3st(0, 1); |
| if (t0 BETTER_THAN t1) { |
| s1 = t0; |
| } |
| else { |
| s1 = t1; |
| hmm_history(hmm, 1) = hmm_in_history(hmm); |
| ssid[1] = ssid[0]; |
| } |
| if (s1 WORSE_THAN WORST_SCORE) s1 = WORST_SCORE; |
| if (s1 BETTER_THAN bestScore) bestScore = s1; |
| hmm_score(hmm, 1) = s1; |
|
|
| |
| s0 += hmm_tprob_3st(0, 0); |
| if (s0 WORSE_THAN WORST_SCORE) s0 = WORST_SCORE; |
| if (s0 BETTER_THAN bestScore) bestScore = s0; |
| hmm_in_score(hmm) = s0; |
|
|
| hmm_bestscore(hmm) = bestScore; |
| return bestScore; |
| } |
|
|
| static int32 |
| hmm_vit_eval_anytopo(hmm_t * hmm) |
| { |
| hmm_context_t *ctx = hmm->ctx; |
| int32 to, from, bestfrom; |
| int32 newscr, scr, bestscr; |
| int final_state; |
|
|
| |
| ctx->st_sen_scr[0] = hmm_in_score(hmm) + hmm_senscr(hmm, 0); |
| for (from = 1; from < hmm_n_emit_state(hmm); ++from) { |
| if ((ctx->st_sen_scr[from] = |
| hmm_score(hmm, from) + hmm_senscr(hmm, from)) WORSE_THAN WORST_SCORE) |
| ctx->st_sen_scr[from] = WORST_SCORE; |
| } |
|
|
| |
| |
| final_state = hmm_n_emit_state(hmm); |
| to = final_state; |
| scr = WORST_SCORE; |
| bestfrom = -1; |
| for (from = to - 1; from >= 0; --from) { |
| if ((hmm_tprob(hmm, from, to) BETTER_THAN TMAT_WORST_SCORE) && |
| ((newscr = ctx->st_sen_scr[from] |
| + hmm_tprob(hmm, from, to)) BETTER_THAN scr)) { |
| scr = newscr; |
| bestfrom = from; |
| } |
| } |
| hmm_out_score(hmm) = scr; |
| if (bestfrom >= 0) |
| hmm_out_history(hmm) = hmm_history(hmm, bestfrom); |
| bestscr = scr; |
|
|
| |
| for (to = final_state - 1; to >= 0; --to) { |
| |
| scr = |
| (hmm_tprob(hmm, to, to) BETTER_THAN TMAT_WORST_SCORE) |
| ? ctx->st_sen_scr[to] + hmm_tprob(hmm, to, to) |
| : WORST_SCORE; |
|
|
| |
| bestfrom = -1; |
| for (from = to - 1; from >= 0; --from) { |
| if ((hmm_tprob(hmm, from, to) BETTER_THAN TMAT_WORST_SCORE) && |
| ((newscr = ctx->st_sen_scr[from] |
| + hmm_tprob(hmm, from, to)) BETTER_THAN scr)) { |
| scr = newscr; |
| bestfrom = from; |
| } |
| } |
|
|
| |
| if (to == 0) { |
| hmm_in_score(hmm) = scr; |
| if (bestfrom >= 0) |
| hmm_in_history(hmm) = hmm_history(hmm, bestfrom); |
| } |
| else { |
| hmm_score(hmm, to) = scr; |
| if (bestfrom >= 0) |
| hmm_history(hmm, to) = hmm_history(hmm, bestfrom); |
| } |
| |
| if (bestfrom >= 0 && hmm_is_mpx(hmm)) |
| hmm->senid[to] = hmm->senid[bestfrom]; |
|
|
| if (bestscr WORSE_THAN scr) |
| bestscr = scr; |
| } |
|
|
| hmm_bestscore(hmm) = bestscr; |
| return bestscr; |
| } |
|
|
| int32 |
| hmm_vit_eval(hmm_t * hmm) |
| { |
| if (hmm_is_mpx(hmm)) { |
| if (hmm_n_emit_state(hmm) == 5) |
| return hmm_vit_eval_5st_lr_mpx(hmm); |
| else if (hmm_n_emit_state(hmm) == 3) |
| return hmm_vit_eval_3st_lr_mpx(hmm); |
| else |
| return hmm_vit_eval_anytopo(hmm); |
| } |
| else { |
| if (hmm_n_emit_state(hmm) == 5) |
| return hmm_vit_eval_5st_lr(hmm); |
| else if (hmm_n_emit_state(hmm) == 3) |
| return hmm_vit_eval_3st_lr(hmm); |
| else |
| return hmm_vit_eval_anytopo(hmm); |
| } |
| } |
|
|
| int32 |
| hmm_dump_vit_eval(hmm_t * hmm, FILE * fp) |
| { |
| int32 bs = 0; |
|
|
| if (fp) { |
| fprintf(fp, "BEFORE:\n"); |
| hmm_dump(hmm, fp); |
| } |
| bs = hmm_vit_eval(hmm); |
| if (fp) { |
| fprintf(fp, "AFTER:\n"); |
| hmm_dump(hmm, fp); |
| } |
|
|
| return bs; |
| } |
|
|