コード例 #1
0
ファイル: randvar.c プロジェクト: tempbottle/ghmm
/*============================================================================*/
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 */
コード例 #2
0
ファイル: sfoba.c プロジェクト: T-R0D/Past-Courses
/*============================================================================*/
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 */
コード例 #3
0
/*============================================================================*/
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
}
コード例 #4
0
/*============================================================================*/
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
}
コード例 #5
0
ファイル: smix_hmm.c プロジェクト: amremam2004/ghmm
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
}
コード例 #6
0
ファイル: sgenerate.c プロジェクト: dunghand/msrds
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;
    }
コード例 #7
0
ファイル: probdist.c プロジェクト: amremam2004/ghmm
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;
}
コード例 #8
0
ファイル: pviterbi.c プロジェクト: tempbottle/ghmm
/*============================================================================*/
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 */