⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 viterbi.c

📁 一个通用的隐性马尔可夫C代码库 开发环境:C语言 简要说明:这是一个通用的隐性马尔可夫C代码库
💻 C
字号:
/*******************************************************************************  author       : Wasinee Rungsarityotin, Benjamin Georgi  a variant from sdviterbi()  with ordering of silent states  filename     : ghmm/ghmm/sdviterbi.c  created      : TIME: 09:07:57     DATE: April, 2003  $Id: viterbi.c,v 1.9 2004/03/18 16:30:32 cic99 Exp $Copyright (C) 1998-2001, ZAIK/ZPR, Universit鋞 zu K鰈nThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*******************************************************************************/#include "mprintf.h"#include "mes.h"#include <float.h>#include <math.h>#include <assert.h>#include <ghmm/ghmm.h>#include <ghmm/matrix.h>#include <ghmm/sdmodel.h>typedef struct local_store_t {  double **log_in_a;  double **log_b;  double *phi;  double *phi_new;  int    **psi;  int    *topo_order;  int    topo_order_length;} local_store_t;static local_store_t *viterbi_alloc(model *mo, int len);static int viterbi_free(local_store_t **v, int n,  int len);/*----------------------------------------------------------------------------*/static local_store_t *viterbi_alloc(model *mo, int len) {#define CUR_PROC "sdviterbi_alloc"  local_store_t* v = NULL;  int j;  if (!m_calloc(v, 1)) {mes_proc(); goto STOP;}  /* Allocate the log_in_a's -> individal lenghts */  if (!m_calloc(v->log_in_a, mo->N)) {mes_proc(); goto STOP;}  for (j = 0; j < mo->N; j++){    if (!m_calloc(v->log_in_a[j], mo->s[j].in_states)) {mes_proc(); goto STOP;}  }  v->log_b = matrix_d_alloc(mo->N, len);  if (!(v->log_b)) {mes_proc(); goto STOP;}  if (!m_calloc(v->phi, mo->N)) {mes_proc(); goto STOP;}  if (!m_calloc(v->phi_new, mo->N)) {mes_proc(); goto STOP;}  v->psi = matrix_i_alloc(len, mo->N);  if (!(v->psi)) {mes_proc(); goto STOP;}  v->topo_order_length = 0;  if (!m_calloc(v->topo_order, mo->N)) {mes_proc(); goto STOP;}  return(v);STOP:  viterbi_free(&v, mo->N,  len);  return(NULL);#undef CUR_PROC} /* viterbi_alloc *//*----------------------------------------------------------------------------*/static int viterbi_free(local_store_t **v, int n, int len) {#define CUR_PROC "viterbi_free"  int j;  mes_check_ptr(v, return(-1));  if( !*v ) return(0);  for (j = 0; j < n; j++)    m_free((*v)->log_in_a[j]);  m_free((*v)->log_in_a);  matrix_d_free( &((*v)->log_b), n );  m_free((*v)->phi);  m_free((*v)->phi_new);  matrix_i_free( &((*v)->psi), len );  m_free((*v)->topo_order);  m_free(*v);  return(0);#undef CUR_PROC} /* viterbi_free */static void Viterbi_precompute( model *mo, int *o, int len, local_store_t *v){#define CUR_PROC "viterbi_precompute"  int i, j, k, t;  double log_p = +1;    /* Precomputing the log(a_ij) */    for (j = 0; j < mo->N; j++)   for (i = 0; i < mo->s[j].in_states; i++)    if ( mo->s[j].in_a[i] == 0.0 )   /* DBL_EPSILON ? */ 	  v->log_in_a[j][i] = +1; /* Not used any further in the calculations */    else  	  v->log_in_a[j][i] = log( mo->s[j].in_a[i] );  /* Precomputing the log(bj(ot)) */  for (j = 0; j < mo->N; j++)    for (t = 0; t < len; t++) {      if (o[t] != mo->M){	if ( mo->s[j].b[o[t]] == 0.0 )   /* DBL_EPSILON ? */ 	  v->log_b[j][t] = +1; 	else	  v->log_b[j][t] = log( mo->s[j].b[o[t]] );      }      else{	v->log_b[j][t] = 0.0;       }    }#undef CUR_PROC}/* viterbi_precompute *//** */static void __viterbi_silent( model *mo, int t, local_store_t *v ){  int topocount;  int i, k;  double max_value, value;  for ( topocount = 0; topocount < mo->topo_order_length; topocount++) {      k = mo->topo_order[topocount];      if ( mo->silent[k] ) { /* Silent states */		  /* Determine the maximum */	  /* max_phi = phi[i] + log_in_a[j][i] ... */	  max_value = -DBL_MAX;	  v->psi[t][k] = -1;	  for (i = 0; i < mo->s[k].in_states; i++) {	    	  if ( v->phi[ mo->s[k].in_id[i] ] != +1 &&		 v->log_in_a[k][i]      != +1) {	      value = v->phi[ mo->s[k].in_id[i] ] + v->log_in_a[k][i];	      if (value > max_value) {		max_value = value;		v->psi[t][k] = mo->s[k].in_id[i];	      }	    }	  }	  	  /* No maximum found (that is, state never reached)	     or the output O[t] = 0.0: */	  if (max_value    == -DBL_MAX) {	    v->phi[k] = +1;	  } else {	    v->phi[k] = max_value;	  }	  	}  }}/** Return the log score of the sequence */int *viterbi( model *mo, int *o, int len, double *log_p){#define CUR_PROC "viterbi"  int *state_seq = NULL;  int t, j, i, k, St;  int topocount = 0;  double value, max_value;    double sum, osum = 0.0;  double dummy = 0.0;  local_store_t *v;  int len_path  = mo->N*len;  int lastemState;    // printf("---- viterbi -----\n");  if (mo->model_type == kSilentStates &&       mo->silent != NULL &&       mo->topo_order == NULL) {    model_topo_ordering( mo ); /* Should we call it here ???? */  }  /* Allocate the matrices log_in_a, log_b,Vektor phi, phi_new, Matrix psi */  v = viterbi_alloc(mo, len);  if (!v)                        { mes_proc(); goto STOP; }  if (!m_calloc(state_seq, len_path)) { mes_proc(); goto STOP; }  for(i=0; i < len_path ; i++) {    state_seq[i] = -1;  }    /* Precomputing the log(a_ij) and log(bj(ot)) */  Viterbi_precompute(mo, o, len, v);  /* Initialization, that is t = 0 */  for (j = 0; j < mo->N; j++) {    if ( mo->s[j].pi == 0.0 || v->log_b[j][0] == +1 ) /* instead of 0, DBL_EPS.? */      v->phi[j] = +1;    else      v->phi[j] = log(mo->s[j].pi) + v->log_b[j][0];  }  if ( mo->model_type == kSilentStates ) { /* could go into silent state at t=0 */    int osc;    __viterbi_silent( mo, t=0, v);  }  /*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]);  }*/    /* t > 0 */  for (t = 1; t < len; t++) {    //int osc = mo->get_class(mo->N,t);    for (j = 0; j < mo->N; j++) /** initialization of phi, psi **/    {      v->phi_new[j] = +1;      v->psi[t][j]  = -1;    }    for (k = 0; k < mo->N; k++) {	  /* Determine the maximum */      /* max_phi = phi[i] + log_in_a[j][i] ... */      if ( mo->model_type != kSilentStates || !mo->silent[k] ) {		St        = k;		max_value = -DBL_MAX;		v->psi[t][St] = -1;		for (i = 0; i < mo->s[St].in_states; i++) {		  if ( v->phi[ mo->s[St].in_id[i] ] != +1 && v->log_in_a[St][i] != +1) {		    value = v->phi[ mo->s[St].in_id[i] ] + v->log_in_a[St][i];	   	    if (value > max_value) {	      	  max_value = value;	      	  v->psi[t][St] = mo->s[St].in_id[i];	        }	    }	    else	      {;} // fprintf(stderr, " %d --> %d = %f, \n", i,St,v->log_in_a[St][i]);	  }	/* 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) */	    v->log_b[St][t] == +1 ) {	    v->phi_new[St] = +1;	}	else	  v->phi_new[St] = max_value + v->log_b[St][t];      }    } /* complete time step for emitting states */    /* First now replace the old phi with the new phi */    for (j = 0; j < mo->N; j++) {      		v->phi[j] = v->phi_new[j];		//printf("\npsi[%d],%d, phi, %f\n", t, v->psi[t][j], v->phi[j]);     }    	//last_osc = osc; /* save last transition class */    if ( mo->model_type == kSilentStates ) {       __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]);    }    ****************/  } /* Next observation , increment time-step */  /* Termination */  max_value = -DBL_MAX;  state_seq[len_path-1] = -1;  for (j = 0; j < mo->N; j++)    if ( v->phi[j] != +1 && v->phi[j] > max_value) {       max_value = v->phi[j];      state_seq[len_path-1] = j;    }  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_seq[t] = -1;      }  else {    /* Backtracing, should put DEL path nicely */    *log_p = max_value;    lastemState = state_seq[len_path-1];    for(t = len - 2, i=len_path-2; t >= 0; t--) {      if ( mo->model_type == kSilentStates &&	   mo->silent[ v->psi[t+1][ lastemState ] ]) {	St = v->psi[t+1][ lastemState ];	/* fprintf(stderr, "t=%d:  DEL St=%d\n", t+1, St ); */	while( St != -1  && mo->silent[ St ] ) { /* trace back up to the last emitting state */	  /* fprintf(stderr, "t=%d:  DEL St=%d\n", t, St ); */	  state_seq[i--] = St;	  St = v->psi[t][ St ];	}	state_seq[i--] = St;	lastemState = St;      } else {	state_seq[i--] = v->psi[t+1][ lastemState ];	lastemState    = v->psi[t+1][ lastemState ];      }    }       }  /* PRINT PATH */  /*   fprintf(stderr, "Viterbi path: " );  for(t=0; t < len_path; t++)    if (state_seq[t] >= 0) fprintf(stderr, " %d ",  state_seq[t]);  fprintf(stderr, "\n Freeing ... \n"); */   /* Free the memory space */  viterbi_free(&v, mo->N, len);  return (state_seq);STOP:  /* Free the memory space */  viterbi_free(&v, mo->N, len);  m_free(state_seq);  return NULL;#undef CUR_PROC} /* viterbi *//*============================================================================*/double viterbi_logp(model *mo, int *o, int len, int *state_seq) {#define CUR_PROC "viterbi_logp"  int t, i, j, id;  double log_p = 0.0;  int* vpath;    vpath = viterbi(mo,o,len, &log_p);    return log_p;#undef CUR_PROC} /* viterbi_logp *//*============================================================================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -