smodel.c

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

C
1,896
字号
           smo->M, smo->N, (int) smo->s[0].density[0], smo->cos);  fprintf (file, "\tprior = %.3f;\n", smo->prior);  fprintf (file, "\tPi = vector {\n");  ghmm_cmodel_Pi_print (file, smo, "\t", ",", ";");  fprintf (file, "\t};\n");  fprintf (file, "\tfix_state = vector {\n");  ghmm_cmodel_fix_print (file, smo, "\t", ",", ";");  fprintf (file, "\t};\n");  /* Attention: assumption is: A_k are all the same */  fprintf (file, "\tA = matrix {\n");  ghmm_cmodel_Ak_print (file, smo, 0, "\t", ",", ";");  fprintf (file, "\t};\n");  /***/  fprintf (file, "\tC = matrix {\n");  ghmm_cmodel_C_print (file, smo, "\t", ",", ";");  fprintf (file, "\t};\n\tMue = matrix {\n");  ghmm_cmodel_Mue_print (file, smo, "\t", ",", ";");  fprintf (file, "\t};\n\tU = matrix {\n");  ghmm_cmodel_U_print (file, smo, "\t", ",", ";");  fprintf (file, "\t};\n");  fprintf (file, "};\n\n");}                               /* ghmm_cmodel_print *//*============================================================================*/double ghmm_cmodel_calc_cmbm (ghmm_cmodel * smo, int state, int m, double omega){  double bm = 0.0;  switch (smo->s[state].density[m]) {  case normal:    bm = ighmm_rand_normal_density (omega, smo->s[state].mue[m],                                 smo->s[state].u[m]);    break;  case normal_right:    bm = ighmm_rand_normal_density_trunc (omega, smo->s[state].mue[m],                                     smo->s[state].u[m],smo->s[state].a[m]);    break;  case normal_left:    bm = ighmm_rand_normal_density_trunc (-omega, -smo->s[state].mue[m],                                     smo->s[state].u[m],-smo->s[state].a[m]);    break;  case normal_approx:    bm = ighmm_rand_normal_density_approx (omega,                                        smo->s[state].mue[m],                                        smo->s[state].u[m]);    break;  case uniform:    bm = ighmm_rand_uniform_density (omega,                                   smo->s[state].mue[m],                                  smo->s[state].u[m]);    break;  default:    ighmm_mes (MES_WIN, "Warning: density function not specified!\n");  }  if (bm == -1) {    ighmm_mes (MES_WIN, "Warning: density function returns -1!\n");    bm = 0.0;  }  return (smo->s[state].c[m] * bm);}                               /* ghmm_cmodel_calc_cmbm *//*============================================================================*//* PDF(omega) in a given state */double ghmm_cmodel_calc_b (ghmm_cmodel * smo, int state, double omega){  int m;  double b = 0.0;  for (m = 0; m < smo->s[state].M; m++)    b += ghmm_cmodel_calc_cmbm (smo, state, m, omega);  return (b);}                               /* ghmm_cmodel_calc_b *//*============================================================================*/double ghmm_cmodel_prob_distance (ghmm_cmodel * cm0, ghmm_cmodel * cm, int maxT,                             int symmetric, int verbose){#define CUR_PROC "ghmm_cmodel_prob_distance"#define STEPS 100  double p0, p;  double d = 0.0;  double *d1;  ghmm_cseq *seq0 = NULL;  ghmm_cseq *tmp = NULL;  ghmm_cmodel *smo1, *smo2;  int i, t, a, k, n;  int true_len;  int true_number;  int left_to_right = 0;  long total, index;  int step_width = 0;  int steps = 1;  if (verbose) {                /* If we are doing it verbosely we want to have STEPS steps */    step_width = maxT / STEPS;    steps = STEPS;  }  else                          /* else just one */    step_width = maxT;  ARRAY_CALLOC (d1, steps);  smo1 = cm0;  smo2 = cm;  for (k = 0; k < 2; k++) {    seq0 = ghmm_cmodel_generate_sequences (smo1, 0, maxT + 1, 1, 0, maxT + 1);    /*ghmm_cseq_print(stdout,seq0,0);*/    if (seq0->seq_len[0] < maxT) {      /* There is an absorbing state */      /* For now check that Pi puts all weight on state */      /*         t = 0;         for (i = 0; i < smo1->N; i++) {         if (smo1->s[i].pi > 0.001)         t++;         }             if (t > 1) {         GHMM_LOG(LCONVERTED, "No proper left-to-right model. Multiple start states");         goto STOP;         } */      left_to_right = 1;      total = seq0->seq_len[0];      while (total <= maxT) {        /* create a additional sequences at once */        a = (maxT - total) / (total / seq0->seq_number) + 1;        /* printf("total=%d generating %d", total, a); */        tmp = ghmm_cmodel_generate_sequences (smo1, 0, 0, a, 0, maxT + 1);        ghmm_cseq_add (seq0, tmp);        ghmm_cseq_free (&tmp);        total = 0;        for (i = 0; i < seq0->seq_number; i++)          total += seq0->seq_len[i];      }    }    if (left_to_right) {      for (t = step_width, i = 0; t <= maxT; t += step_width, i++) {        index = 0;        total = seq0->seq_len[0];        /* Determine how many sequences we need to get a total of t           and adjust length of last sequence to obtain total of            exactly t */        while (total < t) {          index++;          total += seq0->seq_len[index];        }        true_len = seq0->seq_len[index];        true_number = seq0->seq_number;        if ((total - t) > 0)          seq0->seq_len[index] = total - t;        seq0->seq_number = index + 1;        if (ghmm_cmodel_likelihood (smo1, seq0, &p0) == -1) {          /* error! */          GHMM_LOG(LCONVERTED, "seq0 can't be build from smo1!");          goto STOP;        }        n = ghmm_cmodel_likelihood (smo2, seq0, &p); /* ==-1: KEINE Seq. erzeugbar */        if (n < seq0->seq_number) {          ighmm_mes (MES_WIN,               "problem: some seqences in seq0 can't be build from smo2\n");          /* what shall we do now? */          goto STOP;        }        /*printf("1/%d *(%f - %f)\n",t,p0,p);*/        d = 1.0 / t * (p0 - p);        if (symmetric) {          if (k == 0)            /* save d */            d1[i] = d;          else {            /* calculate d */            d = 0.5 * (d1[i] + d);          }        }        if (verbose && (!symmetric || k == 1))          printf ("%d\t%f\t%f\t%f\n", t, p0, p, d);        seq0->seq_len[index] = true_len;        seq0->seq_number = true_number;      }    }    else {                      /* no left to right model */      true_len = seq0->seq_len[0];      for (t = step_width, i = 0; t <= maxT; t += step_width, i++) {        seq0->seq_len[0] = t;        if (ghmm_cmodel_likelihood (smo1, seq0, &p0) == -1) {          /* error case */          GHMM_LOG(LCONVERTED, "seq0 can't be build from smo1!");          goto STOP;        }        n = ghmm_cmodel_likelihood (smo2, seq0, &p);/*== -1: KEINE Seq. erzeugbar*/        if (n < seq0->seq_number) {          ighmm_mes (MES_WIN,               "problem: some sequences in seq0 can't be build from smo2\n");          /* what shall we do now? */          goto STOP;        }        /*printf("1/%d *(%f - %f)\n",t,p0,p);*/        d = 1.0 / t * (p0 - p);        if (symmetric) {          if (k == 0)            /* save d */            d1[i] = d;          else {            /* calculate d */            d = 0.5 * (d1[i] + d);          }        }        if (verbose && (!symmetric || k == 1))          printf ("%d\t%f\t%f\t%f\n", t, p0, p, d);      }      seq0->seq_len[0] = true_len;    }    if (symmetric) {      ghmm_cseq_free (&seq0);      smo1 = cm;      smo2 = cm0;    }    else      break;  }                             /* k = 1,2 */  ghmm_cseq_free (&seq0);  return d;STOP:     /* Label STOP from ARRAY_[CM]ALLOC */  ghmm_cseq_free (&seq0);  return (-1.0);#undef CUR_PROC}/*============================================================================*/double ghmm_cmodel_calc_cmBm (ghmm_cmodel * smo, int state, int m, double omega){  double Bm = 0.0;  switch (smo->s[state].density[m]) {  case normal_approx:  case normal:    Bm = ighmm_rand_normal_cdf (omega, smo->s[state].mue[m], smo->s[state].u[m]);    break;  case normal_right:    Bm = ighmm_rand_normal_right_cdf (omega, smo->s[state].mue[m],                              smo->s[state].u[m],smo->s[state].a[m]);    break;  case normal_left:    Bm = (ighmm_rand_normal_right_cdf (omega, -smo->s[state].mue[m], smo->s[state].u[m],-smo->s[state].a[m]));    break;  case uniform:    Bm = (ighmm_rand_uniform_cdf (omega, smo->s[state].mue[m], smo->s[state].u[m]));    break;  default:    ighmm_mes (MES_WIN, "Warning: density function not specified!\n");  }  if (Bm == -1) {    ighmm_mes (MES_WIN, "Warning: density function returns -1!\n");    Bm = 0.0;  }  return (smo->s[state].c[m] * Bm);}                               /* smodel_calc_Bm *//*============================================================================*//* CDF(omega) in a given state */double ghmm_cmodel_calc_B (ghmm_cmodel * smo, int state, double omega){  int m;  double B = 0.0;  for (m = 0; m < smo->s[state].M; m++)    B += ghmm_cmodel_calc_cmBm (smo, state, m, omega);  return (B);}                               /* ghmm_cmodel_calc_B *//*============================================================================*//* What is the dimension of the modell ( = dimension of the parameter vektor) ?   count the number of free parameters in a field of models; used for calc. BIC   Only those parameters, that can be changed during  training.   mixture coeff from smix and priors are not counted! */int ghmm_cmodel_count_free_parameter (ghmm_cmodel ** smo, int smo_number){  int i, k;  int pi_counted = 0, cnt = 0;  for (k = 0; k < smo_number; k++) {    pi_counted = 0;    /* for states */    for (i = 0; i < smo[k]->N; i++) {      if (smo[k]->s[i].out_states > 1)        /* multipl. with COS correct ??? */        cnt += smo[k]->cos * (smo[k]->s[i].out_states - 1);      if (smo[k]->s[i].pi != 0 && smo[k]->s[i].pi != 1) {        pi_counted = 1;        cnt++;      }      if (!smo[k]->s[i].fix) {        if (smo[k]->s[i].M == 1)          cnt += 2;             /* mu, sigma */        else          cnt += (3 * smo[k]->s[i].M);       /* c, mu, sigma */      }    }                           /* for (i ..) */    if (pi_counted)      cnt--;                    /* due to condition: sum(pi) = 1 */    if (smo[k]->s[0].M > 1)      cnt--;                    /* due to condition: sum(c) = 1 */  }  return cnt;}/*============================================================================*//* interval (a,b) with ~ B(a) < 0.01, B(b) > 0.99 */void ghmm_cmodel_get_interval_B (ghmm_cmodel * smo, int state, double *a, double *b){  int m;  double mue, delta, max, min;  *a = DBL_MAX;  *b = -DBL_MAX;  for (m = 0; m < smo->s[state].M; m++) {    switch (smo->s[state].density[m]) {    case normal:    case normal_approx:      mue = smo->s[state].mue[m];      delta = 3 * sqrt (smo->s[state].u[m]);      if (*a > mue - delta)        *a = floor (mue - delta);      if (*b < mue + delta)        *b = ceil (mue + delta);    case normal_right:    case normal_left:      if (smo->s[state].density[state] == normal_right && *a < smo->s[state].a[m])        *a = smo->s[state].a[m];      if (smo->s[state].density[state] == normal_left && *b > smo->s[state].a[m])        *b = smo->s[state].a[m] ;    break;    case uniform:      max = smo->s[state].mue[m];      min = smo->s[state].u[m];      *a = floor ((0.01 * (max - min))+min);      *b = ceil ((0.99 * (max - min))+min);    break;          default:      ighmm_mes (MES_WIN, "Warning: density function not specified!\n");    }  }  return;}                               /* ghmm_cmodel_get_interval_B */double ghmm_cmodel_get_transition(ghmm_cmodel* smo, int i, int j, int c){# define CUR_PROC "ghmm_dmodel_get_transition"  int out;  if (smo->s && smo->s[i].out_a && smo->s[j].in_a) {    for (out=0; out < smo->s[i].out_states; out++) {      if (smo->s[i].out_id[out] == j)        return smo->s[i].out_a[c][out];    }  }  return 0.0;# undef CUR_PROC}   /* ghmm_cmodel_get_transition */void ghmm_cmodel_set_transition (ghmm_cmodel* smo, int i, int j, int c, double prob){# define CUR_PROC "ghmm_cmodel_set_transition"  int in, out;  if (smo->s && smo->s[i].out_a && smo->s[j].in_a) {    for (out = 0; out < smo->s[i].out_states; out++) {      if (smo->s[i].out_id[out] == j) {        smo->s[i].out_a[c][out] = prob;        /* fprintf(stderr, CUR_PROC": State %d, %d, = %f\n", i, j,                prob); */        break;      }    }    for (in = 0; in < smo->s[j].in_states; in++) {      if (smo->s[j].in_id[in] == i) {        smo->s[j].in_a[c][in] = prob;        break;      }    }  }# undef CUR_PROC}   /* ghmm_cmodel_set_transition *//*============================================================================*/double ghmm_cmodel_ifunc (ghmm_cmodel * smo, int state, double c, double x){  return (fabs (ghmm_cmodel_calc_B (smo, state, x) - c));}/*============================ TEST =========================================*/#ifdef XXXint smodel_test_callback(int pos){   char* ModuleName = "class_change";   char* FunctionName = "getClass";   int class;   PyObject *pName, *pModule, *pDict, *pFunc, *pArgs, *pValue;       /*Py_Initialize();*/      /* Init Python Interpreter*/      /*PyRun_SimpleString("import sys\n");*/   /*PyRun_SimpleString("sys.stdout.write('Hello from an embedded Python Script\\n')\n"); */      printf("C: Importing Python module ... ");   pName = PyString_FromString(ModuleName);   pModule = PyImport_Import(pName);       /* Import module*/   pDict = PyModule_GetDict(pModule);   printf("done.\n");           printf("C: Calling Python with value %d\n",pos);   pFunc = PyDict_GetItemString(pDict, FunctionName);   pArgs = PyTuple_New(1);   pValue = PyInt_FromLong(pos);   PyTuple_SetItem(pArgs, 0, pValue);    pValue = PyObject_CallObject(pFunc, pArgs); /* Calling Python */   /* parsing the result from Python to C data type   class = PyInt_AsLong(pValue);   printf("C: The returned class is %d\n",class); */        /*Py_Finalize();         */      return class;  }#endif

⌨️ 快捷键说明

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