/*============================================================================*/ double ighmm_rand_normal_density_trunc(double x, double mean, double u, double a) { # define CUR_PROC "ighmm_rand_normal_density_trunc" #ifndef DO_WITH_GSL double c; #endif /* DO_WITH_GSL */ if (u <= 0.0) { GHMM_LOG(LERROR, "u <= 0.0 not allowed"); goto STOP; } if (x < a) return 0.0; #ifdef DO_WITH_GSL /* move mean to the right position */ return gsl_ran_gaussian_tail_pdf(x - mean, a - mean, sqrt(u)); #else if ((c = ighmm_rand_get_1overa(a, mean, u)) == -1) { GHMM_LOG_QUEUED(LERROR); goto STOP; }; return c * ighmm_rand_normal_density(x, mean, u); #endif /* DO_WITH_GSL */ STOP: return -1.0; # undef CUR_PROC } /* double ighmm_rand_normal_density_trunc */
/*============================================================================*/ int ghmm_cmodel_logp (ghmm_cmodel * smo, double *O, int T, double *log_p) { # define CUR_PROC "ghmm_cmodel_logp" int res = -1; double **alpha, *scale = NULL; alpha = ighmm_cmatrix_stat_alloc (T, smo->N); if (!alpha) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } ARRAY_CALLOC (scale, T); /* run forward alg. */ if (ghmm_cmodel_forward (smo, O, T, NULL, alpha, scale, log_p) == -1) { /* GHMM_LOG_QUEUED(LCONVERTED); */ goto STOP; } res = 0; STOP: /* Label STOP from ARRAY_[CM]ALLOC */ ighmm_cmatrix_stat_free (&alpha); m_free (scale); return (res); # undef CUR_PROC } /* ghmm_cmodel_logp */
/*============================================================================*/ int * ghmm_dpmodel_viterbi_propagate (ghmm_dpmodel *mo, ghmm_dpseq * X, ghmm_dpseq * Y, double *log_p, int *path_length, double max_size) { #define CUR_PROC "ghmm_dpmodel_viterbi_propagate" /* Divide and conquer algorithm to reduce the memory requirement */ /* 1. Compute the alignment of X vs Y and propagate the middle point*/ /* 2. Solve recursively the two alignments X[0:len/2] vs Y[0:m] and X[len/2+1:len] vs Y[m+1:len] */ /* Break the recursion if the lengths of both sequences become tractable for the normal ghmm_dpmodel_viterbi algorithm */ /* start of the implementation */ /* give sequence length of X = 0 to ghmm_dpmodel_viterbi alloc so traceback matrix will not be allocated */ plocal_propagate_store_t * pv = pviterbi_propagate_alloc(mo, Y->length); /* check if it worked */ if (!pv) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* Precomputing the log(a_ij) and log(bj(ot)) */ pviterbi_prop_precompute(mo, pv); /* Launch the recursion */ /* double step_log; pviterbi_propagate_step(mo, X, Y, NULL, NULL, &step_log,pv); printf("step log for the whole sequence: %f\n", step_log); */ return pviterbi_propagate_recursion(mo, X, Y, log_p, path_length, NULL, NULL, max_size, pv); STOP: /* Label STOP from ARRAY_[CM]ALLOC */ /* Free the memory space */ pviterbi_propagate_free(&pv, mo->N, mo->max_offset_x, mo->max_offset_y, Y->length); return NULL; #undef CUR_PROC }
/*============================================================================*/ static plocal_propagate_store_t * pviterbi_propagate_alloc (ghmm_dpmodel *mo, int len_y) { #define CUR_PROC "pviterbi_propagate_alloc" plocal_propagate_store_t* v = NULL; int i, j, k; ARRAY_CALLOC (v, 1); v->mo = mo; v->len_y = len_y; /* Allocate the log_in_a's -> individal lenghts */ ARRAY_CALLOC (v->log_in_a, mo->N); /* first index of log_in_a: target state */ for (j = 0; j < mo->N; j++){ /* second index: source state */ ARRAY_CALLOC (v->log_in_a[j], mo->s[j].in_states); for (i=0; i<mo->s[j].in_states; i++) { /* third index: transition classes of source state */ ARRAY_CALLOC (v->log_in_a[j][i], mo->s[mo->s[j].in_id[i]].kclasses); } } ARRAY_CALLOC (v->log_b, mo->N); for (j=0; j<mo->N; j++) { ARRAY_CALLOC (v->log_b[j], ghmm_dpmodel_emission_table_size(mo, j) + 1); } if (!(v->log_b)) {GHMM_LOG_QUEUED(LCONVERTED); goto STOP;} v->phi = ighmm_cmatrix_3d_alloc(mo->max_offset_x + 1, len_y + mo->max_offset_y + 1, mo->N); if (!(v->phi)) {GHMM_LOG_QUEUED(LCONVERTED); goto STOP;} ARRAY_CALLOC (v->phi_new, mo->N); ARRAY_CALLOC (v->end_of_first, mo->max_offset_x + 1); for (j=0; j<mo->max_offset_x + 1; j++) { ARRAY_CALLOC (v->end_of_first[j], len_y + mo->max_offset_y + 1); for (i=0; i<len_y + mo->max_offset_y + 1; i++) { ARRAY_CALLOC (v->end_of_first[j][i], mo->N); for (k=0; k<mo->N; k++) v->end_of_first[j][i][k] = NULL; /*ARRAY_CALLOC (v->end_of_first[j][i][k], 1);*/ } } v->topo_order_length = 0; ARRAY_CALLOC (v->topo_order, mo->N); return(v); STOP: /* Label STOP from ARRAY_[CM]ALLOC */ pviterbi_propagate_free(&v, mo->N, mo->max_offset_x, mo->max_offset_y, len_y); return(NULL); #undef CUR_PROC }
static int smix_hmm_run(int argc, char* argv[]) { #define CUR_PROC "smix_hmm_run" int k, exitcode = -1, smo_number, sqd_fields; ghmm_cseq **sqd = NULL; ghmm_cmodel **smo = NULL; double **cp = NULL; FILE *outfile = NULL; /* read sequences and initial models */ sqd = ghmm_cseq_read(argv[1], &sqd_fields); if (!sqd) {GHMM_LOG_QUEUED(LCONVERTED); goto STOP;} if (sqd_fields > 1) printf("Warning: Seq. File contains multiple Seq. Fields; use only the first one\n"); smo = ghmm_cmodel_read(argv[2], &smo_number); if (!smo) {GHMM_LOG_QUEUED(LCONVERTED); goto STOP;} /* open output file */ if(!(outfile = ighmm_mes_fopen(argv[3], "wt"))) {GHMM_LOG_QUEUED(LCONVERTED); goto STOP;} /* matrix for component probs., */ cp = ighmm_cmatrix_alloc(sqd[0]->seq_number, smo_number); if (!cp) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP;} /* set last arg in ghmm_smixturehmm_init() : 1 = strict random partition; cp = 0/1 2. ghmm_smap_bayes from initial models 3. cp = 1 for best model, cp = 0 for other models 4. open 5. no start partition == equal cp for each model */ if (ghmm_smixturehmm_init(cp, sqd[0], smo, smo_number, 5) == -1) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* clustering */ if (ghmm_smixturehmm_cluster(outfile, cp, sqd[0], smo, smo_number) == -1) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* print trained models */ for (k = 0; k < smo_number; k++) ghmm_cmodel_print(outfile, smo[k]); if (outfile) fclose(outfile); exitcode = 0; STOP: return exitcode; # undef CUR_PROC }
ghmm_cseq *ghmm_sgenerate_extensions (ghmm_cmodel * smo, ghmm_cseq * sqd_short, int seed, int global_len, sgeneration_mode_t mode) { #define CUR_PROC "ghmm_sgenerate_extensions" ghmm_cseq *sq = NULL; int i, j, t, n, m, len = global_len, short_len, max_short_len = 0, up = 0; #ifdef bausparkasse int tilgphase = 0; #endif /* int *v_path = NULL; */ double log_p, *initial_distribution, **alpha, *scale, p, sum; /* aicj */ int class = -1; int pos; /* TEMP */ if (mode == all_viterbi || mode == viterbi_viterbi || mode == viterbi_all) { GHMM_LOG(LCONVERTED, "Error: mode not implemented yet\n"); goto STOP; } if (len <= 0) /* no global length; model should have a final state */ len = (int) GHMM_MAX_SEQ_LEN; max_short_len = ghmm_cseq_max_len (sqd_short); /*---------------alloc-------------------------------------------------*/ sq = ghmm_cseq_calloc (sqd_short->seq_number); if (!sq) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } ARRAY_CALLOC (initial_distribution, smo->N); /* is needed in cfoba_forward() */ alpha = ighmm_cmatrix_alloc (max_short_len, smo->N); if (!alpha) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } ARRAY_CALLOC (scale, max_short_len); ghmm_rng_init (); GHMM_RNG_SET (RNG, seed); /*---------------main loop over all seqs-------------------------------*/ for (n = 0; n < sqd_short->seq_number; n++) { ARRAY_CALLOC (sq->seq[n], len*(smo->dim)); short_len = sqd_short->seq_len[n]; if (len < short_len) { GHMM_LOG(LCONVERTED, "Error: given sequence is too long\n"); goto STOP; } ghmm_cseq_copy (sq->seq[n], sqd_short->seq[n], short_len); #ifdef GHMM_OBSOLETE sq->seq_label[n] = sqd_short->seq_label[n]; #endif /* GHMM_OBSOLETE */ /* Initial distribution */ /* 1. Viterbi-state */ #if 0 /* wieder aktivieren, wenn ghmm_cmodel_viterbi realisiert */ if (mode == viterbi_all || mode == viterbi_viterbi) { v_path = cviterbi (smo, sqd_short->seq[n], short_len, &log_p); if (v_path[short_len - 1] < 0 || v_path[short_len - 1] >= smo->N) { GHMM_LOG(LCONVERTED, "Warning:Error: from viterbi()\n"); sq->seq_len[n] = short_len; m_realloc (sq->seq[n], short_len); continue; } m_memset (initial_distribution, 0, smo->N); initial_distribution[v_path[short_len - 1]] = 1.0; /* all other 0 */ m_free (v_path); } #endif /* 2. Initial Distribution ??? Pi(i) = alpha_t(i)/P(O|lambda) */ if (mode == all_all || mode == all_viterbi) { if (short_len > 0) { if (ghmm_cmodel_forward (smo, sqd_short->seq[n], short_len, NULL /* ?? */ , alpha, scale, &log_p)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } sum = 0.0; for (i = 0; i < smo->N; i++) { /* alpha ist skaliert! */ initial_distribution[i] = alpha[short_len - 1][i]; sum += initial_distribution[i]; } /* nicht ok.? auf eins skalieren? */ for (i = 0; i < smo->N; i++) initial_distribution[i] /= sum; } else { for (i = 0; i < smo->N; i++) initial_distribution[i] = smo->s[i].pi; } } /* if short_len > 0: Initial state == final state from sqd_short; no output here else choose inittial state according to pi and do output */ p = GHMM_RNG_UNIFORM (RNG); sum = 0.0; for (i = 0; i < smo->N; i++) { sum += initial_distribution[i]; if (sum >= p) break; } /* error due to incorrect normalization ?? */ if (i == smo->N) { i--; while (i > 0 && initial_distribution[i] == 0.0) i--; } t = 0; pos = t * smo->dim; if (short_len == 0) { /* Output in state i */ p = GHMM_RNG_UNIFORM (RNG); sum = 0.0; for (m = 0; m < smo->M; m++) { sum += smo->s[i].c[m]; if (sum >= p) break; } /* error due to incorrect normalization ?? */ if (m == smo->M) { m--; while (m > 0 && smo->s[i].c[m] == 0.0) m--; } ghmm_cmodel_get_random_var(smo, i, m, sq->seq[n]+pos); if (smo->cos == 1) { class = 0; } else { if (!smo->class_change->get_class) { printf ("ERROR: get_class not initialized\n"); goto STOP; } /*printf("1: cos = %d, k = %d, t = %d\n",smo->cos,smo->class_change->k,t);*/ class = smo->class_change->get_class (smo, sq->seq[n], n, t); } t++; pos += smo->dim; }
int main(int argc, char* argv[]) { # define CUR_PROC "main" #ifdef GHMM_OBSOLETE int mo_number, smo_number; #ifdef CMODEL_INCLUDED int cmo_number; #endif int discrete = 0, smodelflag = 0; int T, i, j; ghmm_dmodel **mo = NULL; #ifdef CMODEL_INCLUDED cmodel **cmo = NULL; #endif ghmm_cmodel **smo = NULL; double d; /* double dangle, ddiff, s1, s2; */ if (argc != 5) { printf("Usage: main <Model File> <discrete-flag> <T> <smodel flag>\n"); exit(1); } discrete = atoi(argv[2]); T = atoi(argv[3]); smodelflag = atoi(argv[4]); ghmm_rng_init(); if (smodelflag) { smo = ghmm_cmodel_read(argv[1], &smo_number); if (!smo) {GHMM_LOG_QUEUED(LCONVERTED); return -1;} if (smo_number < 2) { printf("Need at least two HMMs to compare (read %d)\n", smo_number); return -1; } for (i = 0; i < smo_number - 1; i++) for (j = i + 1; j < smo_number; j++) { printf("#----- mo[%d], mo[%d] \n", i , j); /* syntax prob_dist: (smo1, smo2, total seqlen., symmetric, verbose) */ d = ghmm_cmodel_prob_distance(smo[i], smo[j], T, 1, 0); printf("probdist = %f\n",d); } } else if (discrete) { mo = ghmm_dmodel_read(argv[1], &mo_number); if (!mo) {GHMM_LOG_QUEUED(LCONVERTED); return -1;} if (mo_number < 2) { printf("Need at least two HMMs to compare\n"); return -1; } printf("#----- mo[0], mo[1] \n"); d = ghmm_dmodel_prob_distance(mo[0],mo[1], T, 0, 1); printf("d=%f\n",d); printf("#----- mo[1], mo[0] \n"); d = ghmm_dmodel_prob_distance(mo[1],mo[0], T, 0, 1); printf("d=%f\n",d); printf("#----- mo[0], mo[1] \n"); d = ghmm_dmodel_prob_distance(mo[0],mo[1], T, 0, 0); printf("d=%f\n",d); printf("#----- mo[1], mo[0] \n"); d = ghmm_dmodel_prob_distance(mo[1],mo[0], T, 0, 0); printf("d=%f\n",d); printf("#----- mo[0], mo[1] \n"); d = ghmm_dmodel_prob_distance(mo[0],mo[1], T, 1, 1); printf("d=%f\n",d); printf("#----- mo[0], mo[1] \n"); d = ghmm_dmodel_prob_distance(mo[0],mo[1], T, 1, 0); printf("d=%f\n",d); } #ifdef CMODEL_INCLUDED else { cmo = cmodel_read(argv[1], &cmo_number); if (!cmo) {GHMM_LOG_QUEUED(LCONVERTED); return -1;} if (cmo_number < 2) { printf("Need at least two CHMMs to compare\n"); return -1; } printf("#----- cmo[0], cmo[1] \n"); d = cmodel_prob_distance(cmo[0], cmo[1], T, 0, 1); printf("d=%f\n",d); printf("#----- cmo[1], cmo[0] \n"); d = cmodel_prob_distance(cmo[1], cmo[0], T, 0, 1); printf("d=%f\n",d); printf("#----- cmo[0], cmo[1] \n"); d = cmodel_prob_distance(cmo[0], cmo[1], T, 0, 0); printf("d=%f\n",d); printf("#----- cmo[1], cmo[0] \n"); d = cmodel_prob_distance(cmo[1], cmo[0], T, 0, 0); printf("d=%f\n",d); printf("#----- cmo[0], cmo[1] \n"); d = cmodel_prob_distance(cmo[0], cmo[1], T, 1, 1); printf("d=%f\n",d); printf("#----- cmo[0], cmo[1] \n"); d = cmodel_prob_distance(cmo[0], cmo[1], T, 1, 0); printf("d=%f\n",d); /* coemission likelihood */ printf("#----- cmo[0]/cmo[1] \n"); if (cmodel_coemission_likelihood(cmo[0], cmo[1], &d) == -1) d = -1; printf("Coemission Likelihood = %e\n",d); printf("#----- cmo[0]/cmo[0] \n"); if (cmodel_coemission_likelihood(cmo[0], cmo[0], &d) == -1) d = -1; printf("Coemission Likelihood = %e\n",d); printf("#----- cmo[1]/cmo[1] \n"); if (cmodel_coemission_likelihood(cmo[1], cmo[1], &d) == -1) d = -1; printf("Coemission Likelihood = %e\n",d); printf("#----- D_angle, D_diff, S1, S2\n"); cmodel_measures(cmo[0], cmo[1], &dangle, &ddiff, &s1, &s2); printf("D_angle = %e\n", dangle); printf("D_diff = %e\n", ddiff); printf("S1 = %e\n", s1); printf("S2 = %e\n", s2); } #endif /* CMODEL_INCLUDED*/ #else /* GHMM_OBSOLETE */ fprintf (stderr, "probdist is obsolete. If you need it rebuild the GHMM with \"GHMM_OBSOLETE\".\n"); #endif /* GHMM_OBSOLETE */ return 0; }
/*============================================================================*/ int *ghmm_dpmodel_viterbi_variable_tb(ghmm_dpmodel *mo, ghmm_dpseq * X, ghmm_dpseq * Y, double *log_p, int *path_length, int start_traceback_with) { #define CUR_PROC "ghmm_dpmodel_viterbi" int u, v, j, i, off_x, off_y, current_state_index; double value, max_value, previous_prob; plocal_store_t *pv; int *state_seq = NULL; int emission; double log_b_i, log_in_a_ij; double (*log_in_a)(plocal_store_t*, int, int, ghmm_dpseq*, ghmm_dpseq*, int, int); /* printf("---- viterbi -----\n"); */ i_list * state_list; state_list = ighmm_list_init_list(); log_in_a = &sget_log_in_a; /* int len_path = mo->N*len; the length of the path is not known apriori */ /* if (mo->model_type & kSilentStates && */ /* mo->silent != NULL && */ /* mo->topo_order == NULL) { */ /* ghmm_dmodel_topo_order( mo ); */ /* } */ /* Allocate the matrices log_in_a, log_b,Vektor phi, phi_new, Matrix psi */ pv = pviterbi_alloc(mo, X->length, Y->length); if (!pv) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* Precomputing the log(a_ij) and log(bj(ot)) */ pviterbi_precompute(mo, pv); /* Initialize the lookback matrix (for positions [-offsetX,0], [-1, len_y]*/ init_phi(pv, X, Y); /* u > max_offset_x , v starts -1 to allow states with offset_x == 0 which corresponds to a series of gap states before reading the first character of x at position x=0, y=v */ /** THIS IS THE MAIN RECURRENCE **/ for (u = mo->max_offset_x + 1; u < X->length; u++) { for (v = -mo->max_offset_y; v < Y->length; v++) { for (j = 0; j < mo->N; j++) { /** initialization of phi (lookback matrix), psi (traceback) **/ set_phi(pv, u, v, j, +1); set_psi(pv, u, v, j, -1); } for (i = 0; i < mo->N; i++) { /* Determine the maximum */ /* max_phi = phi[i] + log_in_a[j][i] ... */ if (!(mo->model_type & GHMM_kSilentStates) || !mo->silent[i] ) { max_value = -DBL_MAX; set_psi(pv, u, v, i, -1); for (j = 0; j < mo->s[i].in_states; j++) { /* look back in the phi matrix at the offsets */ previous_prob = get_phi(pv, u, v, mo->s[i].offset_x, mo->s[i].offset_y, mo->s[i].in_id[j]); log_in_a_ij = (*log_in_a)(pv, i, j, X, Y, u, v); if ( previous_prob != +1 && log_in_a_ij != +1) { value = previous_prob + log_in_a_ij; if (value > max_value) { max_value = value; set_psi(pv, u, v, i, mo->s[i].in_id[j]); } } else {;} /* fprintf(stderr, " %d --> %d = %f, \n", i,i,v->log_in_a[i][i]); */ } emission = ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y); #ifdef DEBUG if (emission > ghmm_dpmodel_emission_table_size(mo, i)){ printf("State %i\n", i); ghmm_dpmodel_state_print(&(mo->s[i])); printf("charX: %i charY: %i alphabet size: %i emission table: %i emission index: %i\n", ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], ghmm_dpmodel_emission_table_size(mo, i), emission); } #endif log_b_i = log_b(pv, i, ghmm_dpmodel_pair(ghmm_dpseq_get_char(X, mo->s[i].alphabet, u), ghmm_dpseq_get_char(Y, mo->s[i].alphabet, v), mo->size_of_alphabet[mo->s[i].alphabet], mo->s[i].offset_x, mo->s[i].offset_y)); /* No maximum found (that is, state never reached) or the output O[t] = 0.0: */ if (max_value == -DBL_MAX ||/* and then also: (v->psi[t][j] == -1) */ log_b_i == +1 ) { set_phi(pv, u, v, i, +1); } else set_phi(pv, u, v, i, max_value + log_b_i); } } /* complete time step for emitting states */ /* last_osc = osc; */ /* save last transition class */ /*if (mo->model_type & kSilentStates) { p__viterbi_silent( mo, t, v ); }*/ /* complete time step for silent states */ /************** for (j = 0; j < mo->N; j++) { printf("\npsi[%d],in:%d, phi=%f\n", t, v->psi[t][j], v->phi[j]); } for (i = 0; i < mo->N; i++){ printf("%d\t", former_matchcount[i]); } for (i = 0; i < mo->N; i++){ printf("%d\t", recent_matchcount[i]); } ****************/ } /* End for v in Y */ /* Next character in X */ push_back_phi(pv, Y->length); } /* End for u in X */ /* Termination */ max_value = -DBL_MAX; ighmm_list_append(state_list, -1); /* if start_traceback_with is -1 (it is by default) search for the most likely state at the end of both sequences */ if (start_traceback_with == -1) { for (j = 0; j < mo->N; j++){ #ifdef DEBUG printf("phi(len_x)(len_y)(%i)=%f\n", j, get_phi(pv, u, Y->length-1, 0, 0, j)); #endif if ( get_phi(pv, u, Y->length-1, 0, 0, j) != +1 && get_phi(pv, u, Y->length-1, 0, 0, j) > max_value) { max_value = get_phi(pv, X->length-1, Y->length-1, 0, 0, j); state_list->last->val = j; } } } /* this is the special traceback mode for the d & c algorithm that also connects the traceback to the first state of the rest of the path */ else { #ifdef DEBUG printf("D & C traceback from state %i!\n", start_traceback_with); printf("Last characters emitted X: %i, Y: %i\n", ghmm_dpseq_get_char(X, mo->s[start_traceback_with].alphabet, X->length-1), ghmm_dpseq_get_char(Y, mo->s[start_traceback_with].alphabet, Y->length-1)); for (j = 0; j < mo->N; j++){ printf("phi(len_x)(len_y)(%i)=%f\n", j, get_phi(pv, X->length-1, Y->length-1, 0, 0, j)); } #endif max_value = get_phi(pv, X->length-1, Y->length-1, 0, 0, start_traceback_with); if (max_value != 1 && max_value > -DBL_MAX) state_list->last->val = start_traceback_with; } if (max_value == -DBL_MAX) { /* Sequence can't be generated from the model! */ *log_p = +1; /* Backtracing doesn't work, because state_seq[*] allocated with -1 */ /* for (t = len - 2; t >= 0; t--) state_list->last->val = -1; */ } else { /* Backtracing, should put DEL path nicely */ *log_p = max_value; /* removed the handling of silent states here */ /* start trace back at the end of both sequences */ u = X->length - 1; v = Y->length - 1; current_state_index = state_list->first->val; off_x = mo->s[current_state_index].offset_x; off_y = mo->s[current_state_index].offset_y; while (u - off_x >= -1 && v - off_y >= -1 && current_state_index != -1) { /* while (u > 0 && v > 0) { */ /* look up the preceding state and save it in the first position of the state list */ /* printf("Current state %i at (%i,%i) -> preceding state %i\n", current_state_index, u, v, get_psi(pv, u, v, current_state_index)); */ /* update the current state */ current_state_index = get_psi(pv, u, v, current_state_index); if (current_state_index != -1) ighmm_list_insert(state_list, current_state_index); /* move in the alignment matrix */ u -= off_x; v -= off_y; /* get the next offsets */ off_x = mo->s[current_state_index].offset_x; off_y = mo->s[current_state_index].offset_y; } } /* Free the memory space */ pviterbi_free(&pv, mo->N, X->length, Y->length, mo->max_offset_x , mo->max_offset_y); /* printf("After traceback: last state = %i\n", state_list->last->val); */ state_seq = ighmm_list_to_array(state_list); *path_length = state_list->length; /* PRINT PATH */ /* fprintf(stderr, "Viterbi path: " ); */ /* int t; */ /* for(t=0; t < *path_length; t++) */ /* if (state_seq[t] >= 0) fprintf(stderr, " %d ", state_seq[t]); */ /* fprintf(stderr, "\n Freeing ... \n"); */ return (state_seq); STOP: /* Label STOP from ARRAY_[CM]ALLOC */ /* Free the memory space */ pviterbi_free(&pv, mo->N, X->length, Y->length, mo->max_offset_x, mo->max_offset_y); m_free(state_seq); ighmm_list_free(state_list); return NULL; #undef CUR_PROC } /* viterbi */