foba.c

来自「General Hidden Markov Model Library 一个通用」· C语言 代码 · 共 1,035 行 · 第 1/3 页

C
1,035
字号
/*********************************************************************************       This file is part of the General Hidden Markov Model Library,*       GHMM version 0.8_beta1, see http://ghmm.org**       Filename: ghmm/ghmm/foba.c*       Authors:  Utz J. Pape, Benjamin Georgi, Janne Grunau**       Copyright (C) 1998-2004 Alexander Schliep*       Copyright (C) 1998-2001 ZAIK/ZPR, Universitaet zu Koeln*       Copyright (C) 2002-2004 Max-Planck-Institut fuer Molekulare Genetik,*                               Berlin**       Contact: schliep@ghmm.org**       This library is free software; you can redistribute it and/or*       modify it under the terms of the GNU Library General Public*       License as published by the Free Software Foundation; either*       version 2 of the License, or (at your option) any later version.**       This library is distributed in the hope that it will be useful,*       but WITHOUT ANY WARRANTY; without even the implied warranty of*       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU*       Library General Public License for more details.**       You should have received a copy of the GNU Library General Public*       License along with this library; if not, write to the Free*       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA***       This file is version $Revision: 1932 $*                       from $Date: 2007-11-01 19:24:29 +0100 (Thu, 01 Nov 2007) $*             last change by $Author: grunau $.********************************************************************************/#ifdef HAVE_CONFIG_H#  include "../config.h"#endif#include <assert.h>#include "ghmm.h"#include "model.h"#include "math.h"#include "matrix.h"#include "mes.h"#include "mprintf.h"#include "foba.h"#include "ghmm_internals.h"int ghmm_dmodel_forward_init (ghmm_dmodel * mo, double *alpha_1, int symb, double *scale){# define CUR_PROC "ghmm_dmodel_forward_init"  int res = -1;  int i, j, id, in_id;  double c_0;  scale[0] = 0.0;  /*printf(" *** foba_initforward\n");*/  /*iterate over non-silent states*/  /*printf(" *** iterate over non-silent states \n");*/  for (i = 0; i < mo->N; i++) {    if (!(mo->model_type & GHMM_kSilentStates) || !(mo->silent[i])) {      /*no starting in states with order > 0 !!!*/      if (!(mo->model_type & GHMM_kHigherOrderEmissions) || mo->order[i] == 0) {        alpha_1[i] = mo->s[i].pi * mo->s[i].b[symb];        /*printf("\nalpha1[%i]=%f\n",i,alpha_1[i]);*/        scale[0] += alpha_1[i];      }      else {        alpha_1[i] = 0;      }    }  }  /*iterate over silent states*/  /*printf(" *** iterate over silent states \n");*/  if (mo->model_type & GHMM_kSilentStates) {    for (i = 0; i < mo->topo_order_length; i++) {      id = mo->topo_order[i];      alpha_1[id] = mo->s[id].pi;      /*printf("\nsilent_start alpha1[%i]=%f\n",id,alpha_1[id]);*/      for (j = 0; j < mo->s[id].in_states; j++) {        in_id = mo->s[id].in_id[j];        alpha_1[id] += mo->s[id].in_a[j] * alpha_1[in_id];        /*printf("\n\tsilent_run alpha1[%i]=%f\n",id,alpha_1[id]);*/      }      scale[0] += alpha_1[id];    }  }  /* printf("\nwo label: scale[0] = %f\n",scale[0]); */  if (scale[0] >= GHMM_EPS_PREC) {    c_0 = 1 / scale[0];    for (i = 0; i < mo->N; i++)      alpha_1[i] *= c_0;  }  res = 0;  return (0);                   /* attention: scale[0] might be 0 */# undef CUR_PROC}                               /* ghmm_dmodel_forward_init *//*----------------------------------------------------------------------------*//** modified by Casillux to improve performance */double ghmm_dmodel_forward_step (ghmm_dstate * s, double *alpha_t, const double b_symb){  int i, id;  double value = 0.0;  if (b_symb < GHMM_EPS_PREC)    return 0.;  /*printf(" *** foba_stepforward\n");*/  for (i = 0; i < s->in_states; i++) {    id = s->in_id[i];    value += s->in_a[i] * alpha_t[id];    /*printf("    state %d, value %f, p_symb %f\n",id, value, b_symb); */  }  value *= b_symb;  return (value);}                               /* ghmm_dmodel_forward_step *//*============================================================================*/int ghmm_dmodel_forward (ghmm_dmodel * mo, const int *O, int len, double **alpha,                  double *scale, double *log_p){# define CUR_PROC "ghmm_dmodel_forward"  char * str;  int res = -1;  int i, t, id;  int e_index;  double c_t;  double log_scale_sum = 0.0;  double non_silent_salpha_sum = 0.0;  double salpha_log = 0.0;  if (mo->model_type & GHMM_kSilentStates)    ghmm_dmodel_order_topological(mo);  ghmm_dmodel_forward_init (mo, alpha[0], O[0], scale);  if (scale[0] < GHMM_EPS_PREC) {    /* means: first symbol can't be generated by hmm */    /*printf("\nscale kleiner als eps (line_no: 123)\n");*/    *log_p = +1;  }  else {    *log_p = -log (1 / scale[0]);    for (t = 1; t < len; t++) {      scale[t] = 0.0;      update_emission_history (mo, O[t - 1]);      /* printf("\n\nStep t=%i mit len=%i, O[i]=%i\n",t,len,O[t]);         printf("iterate over non-silent state\n"); */      /* iterate over non-silent states */      for (i = 0; i < mo->N; i++) {        if (!(mo->model_type & GHMM_kSilentStates) || !(mo->silent[i])) {          e_index = get_emission_index (mo, i, O[t], t);          if (e_index != -1) {            alpha[t][i] =              ghmm_dmodel_forward_step (&mo->s[i], alpha[t - 1], mo->s[i].b[e_index]);            scale[t] += alpha[t][i];          }          else {            alpha[t][i] = 0;          }        }      }      /* iterate over silent states */      /* printf("iterate over silent state\n"); */      if (mo->model_type & GHMM_kSilentStates) {        for (i = 0; i < mo->topo_order_length; i++) {          /*printf("\nget id\n");*/          id = mo->topo_order[i];          /*printf("  akt_ state %d\n",id);*/          /*printf("\nin stepforward\n");*/          alpha[t][id] = ghmm_dmodel_forward_step (&mo->s[id], alpha[t], 1);          /*printf("\nnach stepforward\n");*/          scale[t] += alpha[t][id];        }      }      if (scale[t] < GHMM_EPS_PREC) {        /* O-string  can't be generated by hmm */        str = ighmm_mprintf(NULL, 0, "scale smaller than epsilon (%g < %g) in position %d. Can't generate symbol %d\n", scale[t], GHMM_EPS_PREC, t, O[t]);	GHMM_LOG(LCONVERTED, str);	m_free (str);        *log_p = +1.0;        break;      }      c_t = 1 / scale[t];      for (i = 0; i < mo->N; i++) {        alpha[t][i] *= c_t;      }      if (!(mo->model_type & GHMM_kSilentStates) && *log_p != +1) {        /* sum log(c[t]) scaling values to get  log( P(O|lambda) ) */        /*printf("log_p %f -= log(%f) = ",*log_p,c_t);*/        *log_p -= log (c_t);        /*printf(" %f\n",*log_p); */      }    }    if (mo->model_type & GHMM_kSilentStates && *log_p != +1) {      /*printf("silent model\n");*/      for (i = 0; i < len; i++) {        log_scale_sum += log (scale[i]);      }      for (i = 0; i < mo->N; i++) {        if (!(mo->silent[i])) {          non_silent_salpha_sum += alpha[len - 1][i];        }      }      salpha_log = log (non_silent_salpha_sum);      *log_p = log_scale_sum + salpha_log;    }  }  /*printf("\nin forward: log_p = %f\n",*log_p);*/  if (*log_p == 1.0) {    res = -1;  }  else {    res = 0;  }  return res;# undef CUR_PROC}                               /* ghmm_dmodel_forward *//*============================================================================*/int ghmm_dmodel_forward_descale (double **alpha, double *scale, int t, int n,                  double **newalpha){# define CUR_PROC "ghmm_dmodel_forward_descale"  int i, j, k;  /*printf("\nAngekommen, t=%i, n=%i\n",t,n);*/  for (i = 0; i < t; i++) {    /*printf("i=%i\n",i);*/    for (j = 0; j < n; j++) {      /*printf("\tj=%i\n",j);*/      newalpha[i][j] = alpha[i][j];      /*newalpha[i][j] *= scale[j];*/      /*printf(".");*/      for (k = 0; k <= i; k++) {        /*printf(",");*/        newalpha[i][j] *= scale[k];      }    }  }  /*printf("\ndescale geschafft\n");*/  return 0;# undef CUR_PROC}                               /* ghmm_dmodel_forward_descale *//***************************** Backward Algorithm ******************************/int ghmm_dmodel_backward (ghmm_dmodel * mo, const int *O, int len, double **beta,                   const double *scale){# define CUR_PROC "ghmm_dmodel_backward"  /* beta_tmp holds beta-variables for silent states */  double *beta_tmp=NULL;  double sum, emission;  int i, j, j_id, t, k, id;  int res = -1;  int e_index;  for (t = 0; t < len; t++)    mes_check_0 (scale[t], goto STOP);  /* topological ordering for models with silent states and allocating     temporary array needed for silent states */  if (mo->model_type & GHMM_kSilentStates) {    ARRAY_CALLOC (beta_tmp, mo->N);    ghmm_dmodel_order_topological(mo);  }  /* initialize all states */  for (i = 0; i < mo->N; i++) {    beta[len - 1][i] = 1.0;  }  if (!(mo->model_type & GHMM_kHigherOrderEmissions)) {    mo->maxorder = 0;  }  /* initialize emission history */  for (t = len - (mo->maxorder); t < len; t++) {    update_emission_history (mo, O[t]);  }    /* Backward Step for t = T-1, ..., 0 */  /* loop over reverse topological ordering of silent states, non-silent states  */  for (t = len - 2; t >= 0; t--) {    /* printf(" ----------- *** t = %d ***  ---------- \n",t); */    /* printf("\n*** O(%d) = %d\n",t+1,O[t+1]); */    /* updating of emission_history with O[t] such that emission_history memorizes       O[t - maxorder ... t] */    if (0 <= t - mo->maxorder + 1)      update_emission_history_front (mo, O[t - mo->maxorder + 1]);    /* iterating over the the silent states and filling beta_tmp */    if (mo->model_type & GHMM_kSilentStates) {      for (k = mo->topo_order_length - 1; k >= 0; k--) {        id = mo->topo_order[k];        /* printf("  silent[%d] = %d\n",id,mo->silent[id]); */        assert (mo->silent[id] == 1);        sum = 0.0;        for (j = 0; j < mo->s[id].out_states; j++) {          j_id = mo->s[id].out_id[j];	  /* out_state is not silent */	  if (!mo->silent[j_id]) {	    e_index = get_emission_index (mo, j_id, O[t + 1], t + 1);	    if (e_index != -1) {	      sum += mo->s[id].out_a[j] * mo->s[j_id].b[e_index] * beta[t+1][j_id];	    }	  }	  /* out_state is silent, beta_tmp[j_id] is useful since we go through	     the silent states in reversed topological order */	  else {	    sum += mo->s[id].out_a[j] * beta_tmp[j_id];	  }	}	/* setting beta_tmp for the silent state	   don't scale the betas for silent states now 	   wait until the betas for non-silent states are complete to avoid

⌨️ 快捷键说明

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