sreestimate.c
来自「General Hidden Markov Model Library 一个通用」· C语言 代码 · 共 907 行 · 第 1/2 页
C
907 行
/********************************************************************************* This file is part of the General Hidden Markov Model Library,* GHMM version 0.8_beta1, see http://ghmm.org** Filename: ghmm/ghmm/sreestimate.c* Authors: Bernhard Knab, Benjamin Georgi** 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: 1713 $* from $Date: 2006-10-16 16:06:28 +0200 (Mon, 16 Oct 2006) $* last change by $Author: grunau $.********************************************************************************/#ifdef HAVE_CONFIG_H# include "../config.h"#endif#include <math.h>#include <float.h>#include "ghmm.h"#include "mprintf.h"#include "mes.h"#include "sreestimate.h"#include "smodel.h"#include "sfoba.h"#include "matrix.h"#include "vector.h"#include "randvar.h"#include "ghmm_internals.h"/* switch: turn off (0) MESCONTR and MESINFO */#define MCI 1/* set control output (MES_WIN, MES_FILE, MES_FILE_WIN, ...) */#define MESCONTR MES_FILE/* set info output (logP, ...) */#define MESINFO MES_FILEtypedef struct local_store_t { int cos; double *pi_num; double pi_denom; double ***a_num; double **a_denom; double **c_num; double *c_denom; double **mue_num; double **u_num; double **mue_u_denom; /* mue-denom. = u-denom. for sym. normal density */ double **sum_gt_otot; /* for truncated normal density */ double **sum_gt_logb; /* Control according to Q-function */} local_store_t;/** needed for normaldensitypos (truncated normal density) */#define ACC 1E-8static double C_PHI;static double CC_PHI;/***/static local_store_t *sreestimate_alloc (const ghmm_cmodel * smo);static int sreestimate_free (local_store_t ** r, int N);static int sreestimate_init (local_store_t * r, const ghmm_cmodel * smo);static int sreestimate_alloc_matvek (double ***alpha, double ***beta, double **scale, double ****b, int T, int N, int M);static int sreestimate_precompute_b (ghmm_cmodel * smo, double *O, int T, double ***b);static int sreestimate_free_matvec (double **alpha, double **beta, double *scale, double ***b, int T, int N);static int sreestimate_setlambda (local_store_t * r, ghmm_cmodel * smo);static int sreestimate_one_step (ghmm_cmodel * smo, local_store_t * r, int seq_number, int *T, double **O, double *log_p, double *seq_w);/*----------------------------------------------------------------------------*//* various allocations */static local_store_t *sreestimate_alloc (const ghmm_cmodel * smo){# define CUR_PROC "sreestimate_alloc" int i; local_store_t *r = NULL; ARRAY_CALLOC (r, 1); r->cos = smo->cos; ARRAY_CALLOC (r->pi_num, smo->N); ARRAY_CALLOC (r->a_num, smo->N); for (i = 0; i < smo->N; i++) { r->a_num[i] = ighmm_cmatrix_stat_alloc (smo->cos, smo->s[i].out_states); if (!r->a_num[i]) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } } r->a_denom = ighmm_cmatrix_stat_alloc (smo->N, smo->cos); if (!r->a_denom) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* For sacke of simplicity, a NXmax(M) is being allocated, even though not all emissins components are of size max(M) */ ARRAY_CALLOC (r->c_denom, smo->N); r->c_num = ighmm_cmatrix_stat_alloc (smo->N, smo->M); if (!(r->c_num)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } r->mue_num = ighmm_cmatrix_stat_alloc (smo->N, smo->M); if (!(r->mue_num)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } r->u_num = ighmm_cmatrix_stat_alloc (smo->N, smo->M); if (!(r->u_num)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } r->mue_u_denom = ighmm_cmatrix_stat_alloc (smo->N, smo->M); if (!(r->mue_u_denom)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } r->sum_gt_otot = ighmm_cmatrix_stat_alloc (smo->N, smo->M); if (!(r->sum_gt_otot)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } r->sum_gt_logb = ighmm_cmatrix_stat_alloc (smo->N, smo->M); if (!(r->sum_gt_logb)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } return (r);STOP: /* Label STOP from ARRAY_[CM]ALLOC */ sreestimate_free (&r, smo->N); return 0;# undef CUR_PROC} /* sreestimate_alloc *//*----------------------------------------------------------------------------*/static int sreestimate_free (local_store_t ** r, int N){# define CUR_PROC "sreestimate_free" int i; mes_check_ptr (r, return (-1)); if (!*r) return (0); m_free ((*r)->pi_num); for (i = 0; i < N; i++) ighmm_cmatrix_stat_free (&((*r)->a_num[i])); m_free ((*r)->a_num); ighmm_cmatrix_stat_free (&((*r)->a_denom)); /***/ m_free ((*r)->c_denom); ighmm_cmatrix_stat_free (&((*r)->c_num)); ighmm_cmatrix_stat_free (&((*r)->mue_num)); ighmm_cmatrix_stat_free (&((*r)->u_num)); ighmm_cmatrix_stat_free (&((*r)->mue_u_denom)); ighmm_cmatrix_stat_free (&((*r)->sum_gt_otot)); ighmm_cmatrix_stat_free (&((*r)->sum_gt_logb)); m_free (*r); return (0);# undef CUR_PROC} /* sreestimate_free *//*----------------------------------------------------------------------------*/static int sreestimate_init (local_store_t * r, const ghmm_cmodel * smo){# define CUR_PROC "sreestimate_init" int i, j, m, osc; r->pi_denom = 0.0; for (i = 0; i < smo->N; i++) { r->pi_num[i] = 0.0; for (osc = 0; osc < smo->cos; osc++) { r->a_denom[i][osc] = 0.0; for (j = 0; j < smo->s[i].out_states; j++) r->a_num[i][osc][j] = 0.0; } r->c_denom[i] = 0.0; for (m = 0; m < smo->M; m++) { r->c_num[i][m] = 0.0; r->mue_num[i][m] = 0.0; r->u_num[i][m] = 0.0; r->mue_u_denom[i][m] = 0.0; r->sum_gt_otot[i][m] = 0.0; r->sum_gt_logb[i][m] = 0.0; } } return (0);# undef CUR_PROC} /* sreestimate_init *//*----------------------------------------------------------------------------*/static int sreestimate_alloc_matvek (double ***alpha, double ***beta, double **scale, double ****b, int T, int N, int M){# define CUR_PROC "sreestimate_alloc_matvek" int t, res = -1; *alpha = ighmm_cmatrix_stat_alloc (T, N); if (!(*alpha)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } *beta = ighmm_cmatrix_stat_alloc (T, N); if (!(*beta)) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } ARRAY_CALLOC (*scale, T); /* 3-dim. matrix for b[t][i][m] with m = 1..M(!): */ ARRAY_CALLOC (*b, T); for (t = 0; t < T; t++) { (*b)[t] = ighmm_cmatrix_stat_alloc (N, M + 1); if (!((*b)[t])) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } } res = 0;STOP: /* Label STOP from ARRAY_[CM]ALLOC */ return (res);# undef CUR_PROC} /* sreestimate_alloc_matvek *//*----------------------------------------------------------------------------*/static int sreestimate_free_matvec (double **alpha, double **beta, double *scale, double ***b, int T, int N){# define CUR_PROC "sreestimate_free_matvec" int t; ighmm_cmatrix_stat_free (&alpha); ighmm_cmatrix_stat_free (&beta); m_free (scale); if (!b) return (0); for (t = 0; t < T; t++) ighmm_cmatrix_stat_free (&b[t]); m_free (b); return (0);# undef CUR_PROC} /* sreestimate_free_matvec *//*----------------------------------------------------------------------------*/static int sreestimate_precompute_b (ghmm_cmodel * smo, double *O, int T, double ***b){# define CUR_PROC "sreestimate_precompute_b" int t, i, m; /* save sum (c_im * b_im(O_t)) in b[t][i][smo->M] */ for (t = 0; t < T; t++) for (i = 0; i < smo->N; i++) b[t][i][smo->M] = 0.0; /* save c_im * b_im(O_t) directly in b[t][i][m] */ for (t = 0; t < T; t++) for (i = 0; i < smo->N; i++) for (m = 0; m < smo->s[i].M; m++) { b[t][i][m] = ghmm_cmodel_calc_cmbm (smo, i, m, O[t]); b[t][i][smo->s[i].M] += b[t][i][m]; } return (0);# undef CUR_PROC} /* sreestimate_precompute_b *//*----------------------------------------------------------------------------*/static int sreestimate_setlambda (local_store_t * r, ghmm_cmodel * smo){# define CUR_PROC "sreestimate_setlambda" int res = -1; int i, j, m, l, j_id, osc, fix_flag; double pi_factor, a_factor_i = 0.0, c_factor_i = 0.0, u_im, mue_im, mue_left, mue_right, A, B, Atil, Btil, fix_w, unfix_w; /* Q; */ int a_num_pos, a_denom_pos, c_denom_pos, c_num_pos; char *str; double p_i=0.0; int g, h; if (r->pi_denom <= DBL_MIN) { GHMM_LOG(LCONVERTED, "pi: denominator == 0.0!\n"); goto STOP; } else pi_factor = 1 / r->pi_denom; for (i = 0; i < smo->N; i++) { /* Pi */ smo->s[i].pi = r->pi_num[i] * pi_factor; /* A */ for (osc = 0; osc < smo->cos; osc++) { /* note: denom. might be 0; never reached state? */ a_denom_pos = 1; if (r->a_denom[i][osc] <= DBL_MIN) { a_denom_pos = 0;#if MCI if (smo->s[i].out_states > 0) { if (smo->s[i].in_states == 0) ighmm_mes (MESCONTR, "state %d: no in_states\n", i); else { /* Test: sum all ingoing == 0 ? */ p_i = smo->s[i].pi; for (g = 0; g < smo->cos; g++) for (h = 0; h < smo->s[i].in_states; h++) p_i += smo->s[i].in_a[g][h]; if (p_i == 0) ighmm_mes (MESCONTR, "state %d: P(in) = 0\n", i); else ighmm_mes (MESCONTR, "state %d can be reached but a-denom. = 0.0\n", i); } }#endif } else a_factor_i = 1 / r->a_denom[i][osc]; a_num_pos = 0; for (j = 0; j < smo->s[i].out_states; j++) { j_id = smo->s[i].out_id[j]; /* TEST: denom. < numerator */ if ((r->a_denom[i][osc] - r->a_num[i][osc][j]) < -GHMM_EPS_PREC) {#if MCI ighmm_mes (MESCONTR, "a[%d][%d][%d]: numerator > denom.!\n", i, osc, j_id);#endif smo->s[i].out_a[osc][j] = 1.0; } else if (a_denom_pos) smo->s[i].out_a[osc][j] = r->a_num[i][osc][j] * a_factor_i; else { /* if(smo->s[i].out_states == 1 && smo->s[i].out_id[0]==i) { printf("%d is an absorbing end state -> don't change transitions !\n",i); } */ #if MCI ighmm_mes (MESCONTR, "state %d has no observed outgoing transitions, parameters will not be reestimated. \n", i ); #endif continue; /* smo->s[i].out_a[osc][j] = 0.0; */ } if (r->a_num[i][osc][j] > 0.0) /* >= EPS_PREC ? */ a_num_pos = 1; /* important: also update in_a */ l = 0; while (l < smo->s[j_id].in_states) if (smo->s[j_id].in_id[l] == i) break; else l++; if (l == smo->s[j_id].in_states) { str = ighmm_mprintf (NULL, 0, "no matching in_a for out_a(=a[%d][%d]) found!\n", i, j_id); GHMM_LOG(LCONVERTED, str); m_free (str); goto STOP; } smo->s[j_id].in_a[osc][l] = smo->s[i].out_a[osc][j]; } /* j-loop */#if MCI if (!a_num_pos && smo->s[i].out_states > 0) ighmm_mes (MESCONTR, "all numerators a[%d][%d][j]==0 (denom. = %.4f, P(in)=%.4f)!\n", i, osc, r->a_denom[i][osc], p_i);#endif } /* osc-loop */ /* if fix, continue to next state */ if (smo->s[i].fix){ continue; } /* C, Mue und U */ c_denom_pos = 1; if (r->c_denom[i] <= DBL_MIN) { /* < EPS_PREC ? */#if MCI ighmm_mes (MESCONTR, "c[%d][m]: denominator == 0.0!\n", i);#endif c_denom_pos = 0; } else c_factor_i = 1 / r->c_denom[i]; c_num_pos = 0; fix_w = 1.0; unfix_w = 0.0; fix_flag = 0; for (m = 0; m < smo->s[i].M; m++) { /* if fixed continue to next component */ if (smo->s[i].mixture_fix[m] == 1) { /*printf("state %d, component %d is fixed !\n",i,m);*/ fix_w = fix_w - smo->s[i].c[m]; fix_flag = 1; /* we have to normalize weights -> fix flag is set to one */ continue; } /* TEST: denom. < numerator */ if ((r->c_denom[i] - r->c_num[i][m]) < 0.0) { /* < -EPS_PREC ? */#if MCI ighmm_mes (MESCONTR, "c[%d][%d]: numerator > denominator! (%.4f > %.4f)!\n", i, m, r->c_num[i][m], r->c_denom[i]);#endif smo->s[i].c[m] = 1.0; } else if (c_denom_pos) /* c_denom == 0: no change in c_im (?) */ smo->s[i].c[m] = r->c_num[i][m] * c_factor_i; if (r->c_num[i][m] > 0.0) c_num_pos = 1; unfix_w = unfix_w + smo->s[i].c[m]; if (fabs (r->mue_u_denom[i][m]) <= DBL_MIN) /* < EPS_PREC ? */#if MCI ighmm_mes (MESCONTR, "mue[%d][%d]: denominator == 0.0!\n", i, m);#else ;#endif else { /* set mue_im */ smo->s[i].mue[m] = r->mue_num[i][m] / r->mue_u_denom[i][m]; } /* TEST: u_denom == 0.0 ? */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?