/* ========================================================================= */ static int writeAlphabet(xmlTextWriterPtr writer, ghmm_alphabet * alfa, int type) { #define CUR_PROC "writeAlphabet" int i; if (0 > xmlTextWriterStartElement(writer, BAD_CAST (type == kAlphabet ? "alphabet" : "classAlphabet"))) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement"); goto STOP;; } if (type == kAlphabet) if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "id", "%d", alfa->id)) GHMM_LOG_PRINTF(LERROR, LOC, "failed to write id-attribute for alphabet" "with id %d", alfa->id); for (i=0; i<alfa->size; i++) { if (0 > xmlTextWriterStartElement(writer, BAD_CAST "symbol")) { GHMM_LOG_PRINTF(LERROR, LOC, "failed to start symbol-tag no %d", i); goto STOP; } if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "code", "%d", i)) { GHMM_LOG_PRINTF(LERROR, LOC, "failed to write code-attribute for symbol %s" "with code %d", alfa->symbols[i], i); goto STOP; } if (0 > xmlTextWriterWriteRaw(writer, BAD_CAST replaceXMLEntity(alfa->symbols[i]))) { GHMM_LOG_PRINTF(LERROR, LOC, "failed to write symbol %s with code %d", alfa->symbols[i], i); goto STOP; } if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG_PRINTF(LERROR, LOC, "failed to end symbol-tag no %d", i); goto STOP; } } if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG(LERROR, "Error at ending alphabet"); goto STOP; } return 0; STOP: return -1; #undef CUR_PROC }
/* ========================================================================= */ static int writeBackground(xmlTextWriterPtr writer, ghmm_dbackground* bg) { #define CUR_PROC "writeBackground" int i; char * tmp=NULL; for (i=0; i<bg->n; i++) { if (0 > xmlTextWriterStartElement(writer, BAD_CAST "background")) { GHMM_LOG_PRINTF(LERROR, LOC, "Error at starting backgroung %d", i); return -1; } if (!(bg->name)) { if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "key", "bg_%d", i)) GHMM_LOG(LERROR, "Error at writing background key"); } else { if (0 > xmlTextWriterWriteAttribute(writer, BAD_CAST "key", BAD_CAST (bg->name[i]))) GHMM_LOG(LERROR, "Error at writing background key"); } if (0 < bg->order[i]) if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "order", "%d", bg->order[i])) GHMM_LOG(LERROR, "can't write background order attribute"); tmp = doubleArrayToCSV(bg->b[i], pow(bg->m, bg->order[i]+1)); if (tmp) { if (0 > xmlTextWriterWriteRaw(writer, BAD_CAST tmp)) { GHMM_LOG(LERROR, "Error at xmlTextWriterWriteRaw while writing" "background distribution CSV"); m_free(tmp); return -1; } m_free(tmp); } else { GHMM_LOG(LERROR, "converting array to CSV failed for background distribution"); return -1; } if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG(LERROR, "Error at xmlTextWriterEndElement while ending" "background distribution"); return -1; } } return 0; #undef CUR_PROC }
/*============================================================================*/ int ghmm_cmodel_logp_joint(ghmm_cmodel *mo, const double *O, int len, const int *S, int slen, double *log_p) { # define CUR_PROC "ghmm_cmodel_logp_joint" int prevstate, state, state_pos=0, pos=0, j, osc=0; int dim = mo->dim; prevstate = state = S[0]; *log_p = log(mo->s[state].pi); if (!(mo->model_type & GHMM_kSilentStates) || 1 /* XXX !mo->silent[state] */ ) { *log_p += log(ghmm_cmodel_calc_b(mo->s+state, O+pos)); pos+=dim; } for (state_pos=1; state_pos < slen || pos+dim <= len; state_pos++) { state = S[state_pos]; for (j=0; j < mo->s[state].in_states; ++j) { if (prevstate == mo->s[state].in_id[j]) break; } if (mo->cos > 1) { if (!mo->class_change->get_class) { GHMM_LOG(LERROR, "get_class not initialized"); goto STOP; } osc = mo->class_change->get_class(mo, O, mo->class_change->k, pos); if (osc >= mo->cos) { GHMM_LOG_PRINTF(LERROR, LOC, "get_class returned index %d " "but model has only %d classes!", osc, mo->cos); goto STOP; } } if (j == mo->s[state].in_states || fabs(mo->s[state].in_a[osc][j]) < GHMM_EPS_PREC) { GHMM_LOG_PRINTF(LERROR, LOC, "Sequence can't be built. There is no " "transition from state %d to %d.", prevstate, state); goto STOP; } *log_p += log(mo->s[state].in_a[osc][j]); if (!(mo->model_type & GHMM_kSilentStates) || 1 /* XXX !mo->silent[state] */) { *log_p += log(ghmm_cmodel_calc_b(mo->s+state, O+pos)); pos+=dim; } prevstate = state; } if (pos < len) GHMM_LOG_PRINTF(LINFO, LOC, "state sequence too short! processed only %d symbols", pos/dim); if (state_pos < slen) GHMM_LOG_PRINTF(LINFO, LOC, "sequence too short! visited only %d states", state_pos); return 0; STOP: return -1; # undef CUR_PROC }
/* ========================================================================= */ static int writeHMM(xmlTextWriterPtr writer, ghmm_xmlfile* f, int number) { #define CUR_PROC "writeHMM" int rc=0, i, N; int w_cos; double w_prior; char *w_name; char * w_type; /* start HMM */ if (0 > xmlTextWriterStartElement(writer, BAD_CAST "HMM")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (HMM)"); goto STOP;; } /* write HMM attributes applicable */ switch (f->modelType & PTR_TYPE_MASK) { case GHMM_kDiscreteHMM: w_name = f->model.d[number]->name; w_type = strModeltype(f->model.d[number]->model_type); w_prior = f->model.d[number]->prior; N = f->model.d[number]->N; w_cos = 1; break; case (GHMM_kDiscreteHMM+GHMM_kTransitionClasses): w_name = f->model.ds[number]->name; w_type = strModeltype(f->model.ds[number]->model_type); w_prior = f->model.ds[number]->prior; N = f->model.ds[number]->N; w_cos = 0; break; case (GHMM_kDiscreteHMM+GHMM_kPairHMM): case (GHMM_kDiscreteHMM+GHMM_kPairHMM+GHMM_kTransitionClasses): /* w_name = f->model.dp[number]->name; w_type = strModeltype(f->model.dp[number]->model_type); w_prior = f->model.dp[number]->prior; N = f->model.dp[number]->N; w_cos = 0; */ break; case GHMM_kContinuousHMM: case (GHMM_kContinuousHMM+GHMM_kMultivariate): case (GHMM_kContinuousHMM+GHMM_kTransitionClasses): case (GHMM_kContinuousHMM+GHMM_kMultivariate+GHMM_kTransitionClasses): w_name = f->model.c[number]->name; if (f->model.c[number]->model_type) w_type = strModeltype(f->model.c[number]->model_type); else w_type = strModeltype(f->modelType); w_prior = f->model.c[number]->prior; N = f->model.c[number]->N; w_cos = f->model.c[number]->cos; break; default: GHMM_LOG(LERROR, "invalid modelType"); goto STOP;} if (w_name) { if (xmlTextWriterWriteAttribute(writer, BAD_CAST "name", w_name)) GHMM_LOG(LERROR, "writing HMM name failed"); } if (xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST w_type)) GHMM_LOG(LERROR, "writing HMM type failed"); if (w_prior >= 0.0) { WRITE_DOUBLE_ATTRIBUTE(writer, "prior", w_prior); } if (w_cos > 1) if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "transitionClasses", "%d", w_cos)) GHMM_LOG(LERROR, "failed to write no of transitionClasses"); /* write alphabet if applicable */ switch (f->modelType & (GHMM_kDiscreteHMM + GHMM_kTransitionClasses + GHMM_kPairHMM)) { case GHMM_kDiscreteHMM: rc = writeAlphabet(writer, f->model.d[number]->alphabet, kAlphabet); break; case (GHMM_kDiscreteHMM+GHMM_kTransitionClasses): /*rc = writeAlphabet(writer, f->model.ds[number]->alphabet, kAlphabet);*/ break; case (GHMM_kDiscreteHMM+GHMM_kPairHMM): case (GHMM_kDiscreteHMM+GHMM_kPairHMM+GHMM_kTransitionClasses): /*rc = writeAlphabet(writer, f->model.dp[number]->alphabets[0], kAlphabet); if (rc) { GHMM_LOG(LERROR, "writing first alphabet of discrete pair HMM failed"); goto STOP; } rc = writeAlphabet(writer, f->model.dp[number]->alphabets[1], kAlphabet);*/ break; } if (rc) { GHMM_LOG_PRINTF(LERROR, LOC, "writing alphabet for HMM %d (type %s) failed", number, strModeltype(f->modelType)); goto STOP; } /* write label alphabet if applicable */ if ((f->modelType & PTR_TYPE_MASK) == GHMM_kDiscreteHMM && f->modelType & GHMM_kLabeledStates) { if (writeAlphabet(writer, f->model.d[number]->label_alphabet, kLabelAlphabet)) GHMM_LOG(LERROR, "writing of label alphabet failed"); } /* write background distributions if applicable */ if ((f->modelType & PTR_TYPE_MASK) == GHMM_kDiscreteHMM && f->modelType & GHMM_kBackgroundDistributions) { if (writeBackground(writer, f->model.d[number]->bp)) GHMM_LOG(LERROR, "writing of background distributions failed"); } /* write all states */ for (i=0; i<N; i++) if (writeState(writer, f, number, i)) { GHMM_LOG_PRINTF(LERROR, LOC, "writing of state %d in HMM %d failed", i, number); goto STOP; } /* write all outgoing transitions */ for (i=0; i<N; i++) if (writeTransition(writer, f, number, i)) { GHMM_LOG_PRINTF(LERROR, LOC, "writing transitions of state %d in HMM %d failed", i, number); goto STOP; } /*end HMM*/ if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG(LERROR, "Error at xmlTextWriterEndElement (HMM)"); goto STOP; } return 0; STOP: return -1; #undef CUR_PROC }
/* ========================================================================= */ static int writeState(xmlTextWriterPtr writer, ghmm_xmlfile* f, int moNo, int sNo) { #define CUR_PROC "writeState" int rc; double w_pi; char *w_desc=NULL; /* start state */ if (0 > xmlTextWriterStartElement(writer, BAD_CAST "state")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (state)"); goto STOP; } /* write id attribute */ if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "id", "%d", sNo)) GHMM_LOG(LERROR, "failed to write statte id attribute"); /* read state attribute from different model types */ switch (f->modelType & PTR_TYPE_MASK) { case GHMM_kDiscreteHMM: w_pi = f->model.d[moNo]->s[sNo].pi; w_desc = f->model.d[moNo]->s[sNo].desc; break; case (GHMM_kDiscreteHMM+GHMM_kTransitionClasses): w_pi = f->model.ds[moNo]->s[sNo].pi; w_desc = f->model.ds[moNo]->s[sNo].desc; break; case (GHMM_kDiscreteHMM+GHMM_kPairHMM): case (GHMM_kDiscreteHMM+GHMM_kPairHMM+GHMM_kTransitionClasses): /* w_pi = f->model.d[moNo]->s[sNo].pi; w_desc = f->model.d[moNo]->s[sNo]; */ break; case GHMM_kContinuousHMM: case (GHMM_kContinuousHMM+GHMM_kTransitionClasses): case (GHMM_kContinuousHMM+GHMM_kMultivariate): case (GHMM_kContinuousHMM+GHMM_kMultivariate+GHMM_kTransitionClasses): w_pi = f->model.c[moNo]->s[sNo].pi; w_desc = f->model.c[moNo]->s[sNo].desc; break; default: GHMM_LOG(LCRITIC, "invalid modelType");} /* write initial probability as attribute */ WRITE_DOUBLE_ATTRIBUTE(writer, "initial", w_pi); /* write state description */ if (w_desc) { if (xmlTextWriterWriteAttribute(writer, BAD_CAST "desc", BAD_CAST replaceXMLEntity(w_desc))) GHMM_LOG(LERROR, "writing state description failed"); } /* write state contents for different model types */ switch (f->modelType & PTR_TYPE_MASK) { case GHMM_kDiscreteHMM: rc = writeDiscreteStateContents(writer, f, moNo, sNo); break; case (GHMM_kDiscreteHMM+GHMM_kTransitionClasses): rc = writeDiscreteSwitchingStateContents(writer, f, moNo, sNo); break; case (GHMM_kDiscreteHMM+GHMM_kPairHMM): case (GHMM_kDiscreteHMM+GHMM_kPairHMM+GHMM_kTransitionClasses): /* rc = writeDiscretePairStateContents(writer, f, moNo, sNo); */ break; case GHMM_kContinuousHMM: case (GHMM_kContinuousHMM+GHMM_kTransitionClasses): case (GHMM_kContinuousHMM+GHMM_kMultivariate): case (GHMM_kContinuousHMM+GHMM_kMultivariate+GHMM_kTransitionClasses): rc = writeContinuousStateContents(writer, f, moNo, sNo); break; default: GHMM_LOG(LCRITIC, "invalid modelType"); goto STOP; } if (rc) { GHMM_LOG_PRINTF(LERROR, LOC, "writing state contents failed. model_type = %s", strModeltype(f->modelType & PTR_TYPE_MASK)); goto STOP; } /* end state*/ if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG(LERROR, "Error at xmlTextWriterEndElement (state)"); goto STOP; } return 0; STOP: return -1; #undef CUR_PROC }
/* ========================================================================= */ static int writeContinuousStateContents(xmlTextWriterPtr writer, ghmm_xmlfile* f, int moNo, int sNo) { #define CUR_PROC "writeContinuousStateContents" int i; ghmm_cstate *state = f->model.c[moNo]->s + sNo; int allFixed = state->fix; ghmm_c_emission *emission; /* writing continuous distribution */ if (0 > xmlTextWriterStartElement(writer, BAD_CAST "mixture")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (mixture)"); goto STOP; } if (f->model.c[moNo]->s[sNo].fix) allFixed = 1; for(i=0; i < f->model.c[moNo]->s[sNo].M; i++){ emission = f->model.c[moNo]->s[sNo].e+i; switch (emission->type) { case normal: if (0 > xmlTextWriterStartElement(writer, BAD_CAST "normal")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (normal)"); goto STOP; } WRITE_DOUBLE_ATTRIBUTE(writer, "mean", emission->mean.val); WRITE_DOUBLE_ATTRIBUTE(writer, "variance", emission->variance.val); break; case multinormal: if (0 > xmlTextWriterStartElement(writer, BAD_CAST "multinormal")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (multinormal)"); goto STOP; } if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "dimension", "%d", emission->dimension)) { GHMM_LOG(LERROR, "failed to write dimension attribute"); goto STOP; } break; case normal_left: if (0 > xmlTextWriterStartElement(writer, BAD_CAST "normalLeftTail")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (normalLeftTail)"); goto STOP; } WRITE_DOUBLE_ATTRIBUTE(writer, "mean", emission->mean.val); WRITE_DOUBLE_ATTRIBUTE(writer, "variance", emission->variance.val); WRITE_DOUBLE_ATTRIBUTE(writer, "max", emission->min); break; case normal_right: if (0 > xmlTextWriterStartElement(writer, BAD_CAST "normalRightTail")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (normalRightTail)"); goto STOP; } WRITE_DOUBLE_ATTRIBUTE(writer, "mean", emission->mean.val); WRITE_DOUBLE_ATTRIBUTE(writer, "variance", emission->variance.val); WRITE_DOUBLE_ATTRIBUTE(writer, "min", emission->max); break; case uniform: if (0 > xmlTextWriterStartElement(writer, BAD_CAST "uniform")) { GHMM_LOG(LERROR, "Error at xmlTextWriterStartElement (uniform)"); goto STOP; } WRITE_DOUBLE_ATTRIBUTE(writer, "min", emission->min); WRITE_DOUBLE_ATTRIBUTE(writer, "max", emission->max); break; default: GHMM_LOG_PRINTF(LERROR, LOC, "invalid density %d at position %d", emission->type, i); goto STOP; } /*optional values */ if (allFixed || emission->fixed) { if (0 > xmlTextWriterWriteAttribute(writer, BAD_CAST "fixed", BAD_CAST "1")) { GHMM_LOG(LERROR, "failed to set fixed attribute"); goto STOP; } } if (state->M > 1) { WRITE_DOUBLE_ATTRIBUTE(writer, "prior", state->c[i]); } /* write mean vector and covariance matrix as childs for multinormal */ if (emission->type == multinormal) { if (0 > writeMultiNormal(writer, emission)) { GHMM_LOG(LERROR, "failed to write mean and covariance childs"); goto STOP; } } if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG(LERROR, "Error at xmlTextWriterEndElement (all densities)"); goto STOP; } } /* end mixture tag */ if (0 > xmlTextWriterEndElement(writer)) { GHMM_LOG(LERROR, "Error at xmlTextWriterEndElement (mixture)"); goto STOP; } /* writing positions */ if ((state->xPosition > 0) && (state->yPosition > 0)) { if (xmlTextWriterStartElement(writer, BAD_CAST "position") < 0) { GHMM_LOG(LERROR, "failed to start position element (position)"); goto STOP; } if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "x", "%d", state->xPosition)) { GHMM_LOG(LERROR, "failed to write x position"); goto STOP; } if (0 > xmlTextWriterWriteFormatAttribute(writer, BAD_CAST "y", "%d", state->yPosition)) { GHMM_LOG(LERROR, "failed to write y position"); goto STOP; } if (xmlTextWriterEndElement(writer) < 0) { GHMM_LOG(LERROR, "Error at xmlTextWriterEndElement (position)"); goto STOP; } } return 0; STOP: return -1; #undef CUR_PROC }