static double expShulen(double T, /* absolute error */
                 double M, /* min logarithm */
                 double d,
                 double p,
                 GtUword subjectLength,
                 double *ln_n_fac,
                 double *s1,
                 GtUword n_s)
{
  GtUword i;
  int thresholdReached = 0;

  double prob_i, probOld, delta, factor;

  double e = 0.0;    /* expectation */
  double t = 1.0 - d;
  double p_t = t;

  probOld  = 0.0;

  /*since for i = 0, the whole expression is 0*/
  for (i = 1LU; i < subjectLength; i++) {
    factor = 1.0 - p_t;
    if (!thresholdReached) {
      prob_i = factor * pmax(M, i, p,
                             subjectLength,
                             &thresholdReached,
                             ln_n_fac,
                             s1,
                             n_s);
    }
    else
      prob_i = factor;  /* prob_i = factor * s, where s = 1 */
    delta = (prob_i - probOld) * i;  /* delta should always be positive */
    gt_assert(gt_double_equals_double(delta, 0.0) ||
              gt_double_larger_double(delta, 0.0));
    e += delta;    /* expectation of avg shulen length(Q, S) */
    /* check error */
    if (1.0 <= e && delta / e <= T)
      break;
    p_t *= t;
    probOld = prob_i;
  }
  return e;
}
Example #2
0
void gt_firstcodes_spacelog_add(GtFirstcodesspacelog *fcsl,
                                int line,
                                const char *filename,
                                bool add,
                                const char *title,
                                bool work,
                                size_t size)
{
  GtFirstcodespacelogentry *entry;
  size_t logspace;

  if (add)
  {
    entry = gt_spacelog_find(fcsl,title);
    if (entry != NULL)
    {
      if (entry->size != 0)
      {
        fprintf(stderr,"existing entry for title \"%s\""
                       "(from file %s, line %d) "
                       "in spacelog entries must have size 0\n",
                       title,filename,line);
        exit(GT_EXIT_PROGRAMMING_ERROR);
      }
      gt_spacelog_updateaddentry(entry,filename,line,title,size,work);
    } else
    {
      gt_spacelog_addentry(fcsl,filename,line,title,size,work);
    }
    if (work)
    {
      fcsl->workspace += size;
    } else
    {
      fcsl->splitspace += size;
    }
    gt_firstcodes_updatemax(fcsl);
  } else
  {
    entry = gt_spacelog_find(fcsl,title);
    if (entry == NULL)
    {
      fprintf(stderr,"cannot find title \"%s\" (from file %s, line %d) "
                     "in spacelog entries\n",title,filename,line);
      (void) gt_firstcodes_spacelog_showentries(stderr,fcsl);
      exit(GT_EXIT_PROGRAMMING_ERROR);
    }
    if ((entry->work && !work) || (!entry->work && work))
    {
      fprintf(stderr,"for title \"%s\" (from file %s, line %d) "
                     "in spacelog entries: inconsistent work/splitassignment\n",
               title,filename,line);
      exit(GT_EXIT_PROGRAMMING_ERROR);
    }
    if (work)
    {
      if (entry->size > fcsl->workspace)
      {
        gt_firstcodes_subtract_error(title, filename, line, entry->size, true,
                                     fcsl->workspace);
        (void) gt_firstcodes_spacelog_showentries(stderr,fcsl);
        exit(GT_EXIT_PROGRAMMING_ERROR);
      }
      fcsl->workspace -= entry->size;
    } else
    {
      if (entry->size > fcsl->splitspace)
      {
        gt_firstcodes_subtract_error(title, filename, line, entry->size, false,
                                     fcsl->splitspace);
        (void) gt_firstcodes_spacelog_showentries(stderr,fcsl);
        exit(GT_EXIT_PROGRAMMING_ERROR);
      }
      fcsl->splitspace -= entry->size;
    }
    if (size > 0)
    {
      gt_spacelog_updateaddentry(entry,filename,line,title,size,work);
      if (work)
      {
        fcsl->workspace += size;
      } else
      {
        fcsl->splitspace += size;
      }
      gt_firstcodes_updatemax(fcsl);
      if (size > entry->size)
      {
        add = true;
        size -= entry->size;
      } else
      {
        size = entry->size - size;
      }
    } else
    {
      size = entry->size;
      entry->size = 0;
    }
  }
  logspace = fcsl->workspace+fcsl->splitspace;
  gt_log_log(
#ifdef SKDEBUG
             "file %s, line %d: "
#endif
             "%s %s= %.2f, %s, w=%.2f, s=%.2f, sum=%.2f MB",
#ifdef SKDEBUG
             filename,
             line,
#endif
             work ? "w" : "s",
             add ? "+" : "-",
             GT_MEGABYTES(size),
             title,
             GT_MEGABYTES(fcsl->workspace),
             GT_MEGABYTES(fcsl->splitspace),
             GT_MEGABYTES(logspace));
#ifdef SKDEBUG
  if (gt_ma_bookkeeping_enabled())
  {
    unsigned long realspace = gt_ma_get_space_current() +
                              gt_fa_get_space_current();
    gt_log_log("current space usage %.2f MB (%.2f+%.2f)",
                                GT_MEGABYTES(realspace),
                                GT_MEGABYTES(gt_ma_get_space_current()),
                                GT_MEGABYTES(gt_fa_get_space_current()));
    if (fcsl->calc_difference)
    {
      double percent_difference;

      if ((unsigned long) logspace > realspace)
      {
        fprintf(stderr,"overestimating logspace\n");
        exit(GT_EXIT_PROGRAMMING_ERROR);
      }
      if (realspace >= 1000000UL)
      {
        /*
        printf("realspace=%lu,logspace=%lu\n",realspace,
                                              (unsigned long) logspace);
        */
        percent_difference = 100.0 * (double) (realspace - logspace)/realspace;
        if (gt_double_larger_double(percent_difference,3.0))
        {
          fprintf(stderr,"space difference of %.2f%% is too large\n",
                       percent_difference);
          exit(GT_EXIT_PROGRAMMING_ERROR);
        }
        if (gt_double_smaller_double(fcsl->max_percent_difference,
                                     percent_difference))
        {
          fcsl->max_percent_difference = percent_difference;
        }
      }
    }
  }
#endif
}