model.c
来自「General Hidden Markov Model Library 一个通用」· C语言 代码 · 共 2,232 行 · 第 1/5 页
C
2,232 行
sq = ghmm_dseq_calloc(seq_number); if (!sq) { GHMM_LOG_QUEUED(LCONVERTED); goto STOP; } /* allocating additional fields for the state sequence in the ghmm_dseq struct */ ARRAY_CALLOC(sq->states, seq_number); ARRAY_CALLOC(sq->states_len, seq_number); /* allocating additional fields for the labels in the ghmm_dseq struct */ ARRAY_CALLOC(sq->state_labels, seq_number); ARRAY_CALLOC(sq->state_labels_len, seq_number); /* A specific length of the sequences isn't given. As a model should have an end state, the konstant MAX_SEQ_LEN is used. */ if (len <= 0) len = (int)GHMM_MAX_SEQ_LEN; if (seed > 0) { GHMM_RNG_SET(RNG, seed); } /* initialize the emission history */ mo->emission_history = 0; while (n < seq_number) { ARRAY_CALLOC(sq->seq[n], len); /* for silent models we have to allocate for the maximal possible number of lables and states */ if (mo->model_type & GHMM_kSilentStates) { ARRAY_CALLOC(sq->states[n], len * mo->N); ARRAY_CALLOC(sq->state_labels[n], len * mo->N); } else { ARRAY_CALLOC(sq->states[n], len); ARRAY_CALLOC(sq->state_labels[n], len); } pos = label_pos = 0; /* Get a random initial state i */ p = GHMM_RNG_UNIFORM(RNG); sum = 0.0; for (state=0; state < mo->N; state++) { sum += mo->s[state].pi; if (sum >= p) break; } while (pos < len) { /* save the state path and label */ sq->states[n][label_pos] = state; sq->state_labels[n][label_pos] = mo->label[state]; label_pos++; /* Get a random output m if the state is not a silent state */ if (!(mo->model_type & GHMM_kSilentStates) || !(mo->silent[state])) { m = get_random_output(mo, state, pos); update_emission_history(mo, m); sq->seq[n][pos] = m; pos++; } /* get next state */ p = GHMM_RNG_UNIFORM(RNG); if (pos < mo->maxorder) { max_sum = 0.0; for (j = 0; j < mo->s[state].out_states; j++) { j_id = mo->s[state].out_id[j]; if (!(mo->model_type & GHMM_kHigherOrderEmissions) || mo->order[j_id] < pos) max_sum += mo->s[state].out_a[j]; } if (j && fabs(max_sum) < GHMM_EPS_PREC) { GHMM_LOG_PRINTF(LERROR, LOC, "No possible transition from state %d " "since all successor states require more history " "than seen up to position: %d.", state, pos); break; } if (j) p *= max_sum; } sum = 0.0; for (j = 0; j < mo->s[state].out_states; j++) { j_id = mo->s[state].out_id[j]; if (!(mo->model_type & GHMM_kHigherOrderEmissions) || mo->order[j_id] < pos) { sum += mo->s[state].out_a[j]; if (sum >= p) break; } } if (sum == 0.0) { GHMM_LOG_PRINTF(LINFO, LOC, "final state (%d) reached at position %d " "of sequence %d", state, pos, n); break; } state = j_id; } /* while (pos < len) */ /* realocate state path and label sequence to actual size */ if (mo->model_type & GHMM_kSilentStates) { ARRAY_REALLOC(sq->states[n], label_pos); ARRAY_REALLOC(sq->state_labels[n], label_pos); } sq->seq_len[n] = pos; sq->states_len[n] = label_pos; sq->state_labels_len[n] = label_pos; n++; } /* while( n < seq_number ) */ return (sq);STOP: /* Label STOP from ARRAY_[CM]ALLOC */ ghmm_dseq_free(&sq); return NULL;#undef CUR_PROC}/*----------------------------------------------------------------------------*//* Scales the output and transitions probs of all states in a given model */int ghmm_dmodel_normalize (ghmm_dmodel * mo){#define CUR_PROC "ghmm_dmodel_normalize" double pi_sum=0.0; int i, j, m, j_id, i_id=0, res=0; int size = 1; char *str; for (i = 0; i < mo->N; i++) { if (mo->s[i].pi >= 0.0) pi_sum += mo->s[i].pi; else mo->s[i].pi = 0.0; /* check model_type before using state order */ if (mo->model_type & GHMM_kHigherOrderEmissions) size = ghmm_ipow (mo, mo->M, mo->order[i]); /* normalize transition probabilities */ if (ighmm_cvector_normalize (mo->s[i].out_a, mo->s[i].out_states) == -1) { res = -1; } /* for every outgoing probability update the corrosponding incoming probability */ for (j = 0; j < mo->s[i].out_states; j++) { j_id = mo->s[i].out_id[j]; for (m = 0; m < mo->s[j_id].in_states; m++) { if (i == mo->s[j_id].in_id[m]) { i_id = m; break; } } if (i_id == mo->s[j_id].in_states) { str = ighmm_mprintf (NULL, 0, "Outgoing transition from state %d to \ state %d has no corresponding incoming transition.\n", i, j_id); GHMM_LOG(LCONVERTED, str); return -1; } mo->s[j_id].in_a[i_id] = mo->s[i].out_a[j]; } /* normalize emission probabilities, but not for silent states */ if (!((mo->model_type & GHMM_kSilentStates) && mo->silent[i])) { for (m = 0; m < size; m++) { if (ighmm_cvector_normalize (&(mo->s[i].b[m * mo->M]), mo->M) == -1) res = -1; } } } for (i = 0; i < mo->N; i++) mo->s[i].pi /= pi_sum; return res;#undef CUR_PROC} /* ghmm_dmodel_normalize *//*----------------------------------------------------------------------------*/int ghmm_dmodel_add_noise (ghmm_dmodel * mo, double level, int seed){#define CUR_PROC "model_add_noise_A" int h, i, j, hist; int size = 1; if (level > 1.0) level = 1.0; for (i = 0; i < mo->N; i++) { for (j = 0; j < mo->s[i].out_states; j++) /* add noise only to out_a, in_a is updated on normalisation */ mo->s[i].out_a[j] *= (1 - level) + (GHMM_RNG_UNIFORM (RNG) * 2 * level); if (mo->model_type & GHMM_kHigherOrderEmissions) size = ghmm_ipow (mo, mo->M, mo->order[i]); for (hist = 0; hist < size; hist++) for (h = hist * mo->M; h < hist * mo->M + mo->M; h++) mo->s[i].b[h] *= (1 - level) + (GHMM_RNG_UNIFORM (RNG) * 2 * level); } return ghmm_dmodel_normalize (mo);#undef CUR_PROC}/*----------------------------------------------------------------------------*/static int ghmm_dstate_transition_add(ghmm_dstate * s, int start, int dest, double prob){#define CUR_PROC "ghmm_dmodel_transition_add" int i; /* resize the arrays */ ARRAY_REALLOC (s[dest].in_id, s[dest].in_states + 1); ARRAY_REALLOC (s[dest].in_a, s[dest].in_states + 1); ARRAY_REALLOC (s[start].out_id, s[start].out_states + 1); ARRAY_REALLOC (s[start].out_a, s[start].out_states + 1); s[dest].in_states += 1; s[start].out_states += 1; /* search the right place to insert while moving greater entrys one field back */ for (i = s[start].out_states - 1; i >= 0; i--) { if (i == 0 || dest > s[start].out_id[i - 1]) { s[start].out_id[i] = dest; s[start].out_a[i] = prob; break; } else { s[start].out_id[i] = s[start].out_id[i - 1]; s[start].out_a[i] = s[start].out_a[i - 1]; } } /* search the right place to insert while moving greater entrys one field back */ for (i = s[dest].in_states - 1; i >= 0; i--) if (i == 0 || start > s[dest].in_id[i - 1]) { s[dest].in_id[i] = start; s[dest].in_a[i] = prob; break; } else { s[dest].in_id[i] = s[dest].in_id[i - 1]; s[dest].in_a[i] = s[dest].in_a[i - 1]; } return 0;STOP: /* Label STOP from ARRAY_[CM]ALLOC */ return -1;#undef CUR_PROC}/*----------------------------------------------------------------------------*/static int ghmm_dstate_transition_del(ghmm_dstate * s, int start, int dest){#define CUR_PROC "ghmm_dmodel_transition_del" int i, j; /* search ... */ for (j = 0; dest != s[start].out_id[j]; j++) if (j == s[start].out_states) { GHMM_LOG(LCONVERTED, "No such transition"); return -1; } /* ... and replace outgoing */ for (i = j + 1; i < s[start].out_states; i++) { s[start].out_id[i - 1] = s[start].out_id[i]; s[start].out_a[i - 1] = s[start].out_a[i]; } /* search ... */ for (j = 0; start != s[dest].in_id[j]; j++) if (j == s[dest].in_states) { GHMM_LOG(LCONVERTED, "No such transition"); return -1; } /* ... and replace incoming */ for (i = j + 1; i < s[dest].in_states; i++) { s[dest].in_id[i - 1] = s[dest].in_id[i]; s[dest].in_a[i - 1] = s[dest].in_a[i]; } /* reset number */ s[dest].in_states -= 1; s[start].out_states -= 1; /* free memory */ ARRAY_REALLOC (s[dest].in_id, s[dest].in_states); ARRAY_REALLOC (s[dest].in_a, s[dest].in_states); ARRAY_REALLOC (s[start].out_id, s[start].out_states); ARRAY_REALLOC (s[start].out_a, s[start].out_states); return 0;STOP: /* Label STOP from ARRAY_[CM]ALLOC */ return -1;#undef CUR_PROC}/*----------------------------------------------------------------------------*//** Allocates a new ghmm_dbackground struct and assigs the arguments to the respective fields. Note: The arguments need allocation outside of this function. @return : 0 on success, -1 on error @param mo : one model @param cur : a id of a state @param times: number of times the state cur is at least evaluated*/int ghmm_dmodel_duration_apply (ghmm_dmodel * mo, int cur, int times){#define CUR_PROC "ghmm_dmodel_duration_apply" int i, j, last, size, failed=0; if (mo->model_type & GHMM_kSilentStates) { GHMM_LOG(LCONVERTED, "Sorry, apply_duration doesn't support silent states yet\n"); return -1; } last = mo->N; mo->N += times - 1; ARRAY_REALLOC (mo->s, mo->N); if (mo->model_type & GHMM_kSilentStates) { ARRAY_REALLOC (mo->silent, mo->N); ARRAY_REALLOC (mo->topo_order, mo->N); } if (mo->model_type & GHMM_kTiedEmissions) ARRAY_REALLOC (mo->tied_to, mo->N); if (mo->model_type & GHMM_kBackgroundDistributions) ARRAY_REALLOC (mo->background_id, mo->N); size = ghmm_ipow (mo, mo->M, mo->order[cur] + 1); for (i = last; i < mo->N; i++) { /* set the new state */ mo->s[i].pi = 0.0; mo->order[i] = mo->order[cur]; mo->s[i].fix = mo->s[cur].fix; mo->label[i] = mo->label[cur]; mo->s[i].in_a = NULL; mo->s[i].in_id = NULL; mo->s[i].in_states = 0; mo->s[i].out_a = NULL; mo->s[i].out_id = NULL; mo->s[i].out_states = 0; ARRAY_MALLOC (mo->s[i].b, size); for (j = 0; j < size; j++) mo->s[i].b[j] = mo->s[cur].b[j]; if (mo->model_type & GHMM_kSilentStates) { mo->silent[i] = mo->silent[cur]; /* XXX what to do with topo_order mo->topo_order[i] = ????????????; */ } if (mo->model_type & GHMM_kTiedEmissions) /* XXX is there a clean solution for tied states? what if the current state is a tie group leader? the last added state should probably become the new tie group leader */ mo->tied_to[i] = GHMM_kUntied; if (mo->model_type & GHMM_kBackgroundDistributions) mo->background_id[i] = mo->background_id[cur]; } /* move the outgoing transitions to the last state */ while (mo->s[cur].out_states > 0) { if (mo->s[cur].out_id[0] == cur) { ghmm_dstate_transition_add (mo->s, mo->N - 1, mo->N - 1, mo->s[cur].out_a[0]); ghmm_dstate_transition_del (mo->s, cur, mo->s[cur].out_id[0]); } else { ghmm_dstate_transition_add (mo->s, mo->N - 1, mo->s[cur].out_id[0], mo->s[cur].out_a[0]); ghmm_dstate_transition_del (mo->s, cur, mo->s[cur].out_id[0]); } } /* set the linear transitions through all added states */ ghmm_dstate_transition_add (mo->s, cur, last, 1.0); for (i = last + 1; i < mo->N; i++) { ghmm_dstate_transition_add (mo->s, i - 1, i, 1.0); } if (ghmm_dmodel_normalize (mo)) goto STOP; return 0;STOP: /* Label STOP from ARRAY_[CM]ALLOC */ /* Fail hard if these realloc fail. They shouldn't because we have the memory and try only to clean up! */ if (failed++) exit (1); ARRAY_REALLOC (mo->s, last); ARRAY_REALLOC (mo->tied_to, last); ARRAY_REALLOC (mo->background_id, last); mo->N = last; return -1;#undef CUR_PROC}/*----------------------------------------------------------------------------*//** Allocates a new ghmm_dbackground struct and assigns the arguments to the respective fields. Note: The arguments need allocation outside of this function. @return: new pointer to a ghmm_dbackground struct or NULL @param n: number of distributions @param order: orders of the distribtions (optional) @param B: matrix of distribution parameters (optional)*/ghmm_dbackground *ghmm_dbackground_alloc (int n, int m, int *orders, double **B){#define CUR_PROC "ghmm_dbackground_alloc" ghmm_dbackground *ptbackground; ARRAY_CALLOC(ptbackground, 1); ptbackground->n = n; ptbackground->m = m; if (orders) ptbackground->order = orders; if (B) ptbackground->b = B; ARRAY_CALLOC(ptbackground->name, n); return ptbackground;STOP: /* Label STOP from ARRAY_[CM]ALLOC */ return NULL;#undef CUR_PROC}/*----------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?