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; }
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 }