int main(void) { char *s1; /* test string */ char *s3; /* test string */ long i; /* loop counter */ long j; /* loop counter */ lvb_initialize(); for (i = 0; i < 50000; i++) /* repeat to check heap seems OK */ { s1 = alloc(S1_LENGTH + 1, "test string s1"); for (j = 0; j < S1_LENGTH; j++) s1[j] = '@'; s1[S1_LENGTH] = 0; lvb_assert(strcmp(s1, s2) == 0); s3 = alloc(strlen(s1)+1, "test string s3"); strcpy(s3, s1); free(s1); lvb_assert(strcmp(s3, s2) == 0); free(s3); } printf("test passed\n"); return 0; }
int main(void) { const char *p1 = ""; const char *p2 = "\b\a!\"$%^&*()_+NO_SPACE+IN$HERE!@#~'"; const char *p3 = "\v\t\r\n \f\aHello Goodbye \n"; lvb_initialize(); lvb_assert(nextnonwspc(p1) == NULL); lvb_assert(nextnonwspc(p2) == p2); lvb_assert(nextnonwspc(p3) == p3 + 6); printf("test passed\n"); return 0; }
static void upsize(Dataptr matrix, Treestack *sp) /* increase allocation for tree stack *sp */ { long i; /* loop counter */ sp->size++; /* allocate for stack itself */ if (sp->stack == NULL) /* 1st call, stack does not exist */ { sp->stack = alloc(sp->size * sizeof(Treestack_element), "initial best tree stack"); sp->next = 0; lvb_assert(sp->size == 1); /* was incremented above */ } else { sp->stack = realloc(sp->stack, sp->size * sizeof(Treestack_element)); if (sp->stack == NULL) crash("out of memory: cannot increase allocation for\n" "best tree stack to %ld elements", sp->size); } /* MIGUEL */ /* allocate space within stack */ for (i = sp->next; i < sp->size; i++){ /* sp->stack[i].tree = treealloc(matrix->n); */ sp->stack[i].tree = treealloc(matrix); sp->stack[i].root = -1; } } /* end upsize() */
static int get_default_seed(void) /* return a default integer in the interval [0..MAX_SEED], obtained from the * system clock, or exit with an error message if the system time is * unavailable */ { time_t tim; /* system time */ unsigned long ul_seed; /* seed value obtained from system time */ tim = time(NULL); lvb_assert(tim != -1); ul_seed = (unsigned long) tim; ul_seed = ul_seed % (1UL + (unsigned long) MAX_SEED); lvb_assert(ul_seed <= MAX_SEED); return (int) ul_seed; } /* end get_default_seed() */
static void dopush(Dataptr matrix, Treestack *sp, const Branch *const barray, const long root) /* push tree in barray (of root root) on to stack *sp */ { lvb_assert(sp->next <= sp->size); if (sp->next == sp->size) upsize(matrix, sp); treecopy(matrix, sp->stack[sp->next].tree, barray); sp->stack[sp->next].root = root; sp->next++; } /* end dopush() */
int main(void) { long i; /* loop counter */ long rand_val; /* random number */ long first_rand_val; /* first random number */ time_t tim; /* system time */ unsigned long ul_seed; /* seed, from system time */ Lvb_bool all_same = LVB_TRUE; /* all 'random' values same */ lvb_initialize(); /* seed random number generator from system clock */ tim = time(NULL); lvb_assert(tim != -1); ul_seed = (unsigned long) tim; ul_seed = ul_seed % (1UL + (unsigned long) MAX_SEED); lvb_assert(ul_seed <= MAX_SEED); rinit((int) ul_seed); first_rand_val = randpint(UPPER_LIM); for (i = 0; i < LOOP_CNT; i++) { rand_val = randpint(UPPER_LIM); lvb_assert(rand_val <= UPPER_LIM); lvb_assert(rand_val >= 0); if (rand_val != first_rand_val) all_same = LVB_FALSE; } if (all_same == LVB_FALSE) { printf("test passed\n"); return EXIT_SUCCESS; } else { printf("test failed\n"); return EXIT_FAILURE; } }
int main(void) { /* strings that are the same, considered case-insensitively */ static char s1[] = "`1234567890-=!\"$%^&*(" ")_+qwertyuiopasdfghjklzxcvbnm[]{};'#:@~,./<>? \t\n\r"; static char s2[] = "`1234567890-=!\"$%^&*(" ")_+QWERTYUIOPASDFGHJKLZXCVBNM[]{};'#:@~,./<>? \t\n\r"; /* string that is almost the same but actually different */ static char s3[] = "`1234567890-=!\"$%^&*(" ")_+QWERTYUIOPASDFGHJKLZXCVBNN[]{};'#:@~,./<>? \t\n\r"; lvb_initialize(); lvb_assert(cistrcmp(s1, s1) == 0); lvb_assert(cistrcmp(s3 + 5, s3) != 0); lvb_assert(cistrcmp(s1, s2) == 0); lvb_assert(cistrcmp(s2, s3) != 0); printf("test passed\n"); return 0; }
long getplen(Branch *barray, const long root, const long m, const long n, const long *weights) { const long branch_cnt = brcnt(n); /* branch count */ long changes = 0; /* tree length (number of changes) */ unsigned current_ss; /* current state set */ long i; /* loop counter */ long k; /* current character number */ long left; /* current left child number */ unsigned left_ss; /* left state set */ long right; /* current right child number */ unsigned right_ss; /* right state set */ long todo_cnt = 0; /* count of branches "to do" */ long internal_cnt = 0; /* non-leaf non-root branches */ long done = 0; /* count of branches "done" */ long branch; /* current branch number */ static long todo_arr[MAX_BRANCHES + 1]; /* list of "dirty" branch nos */ static long internal_arr[MAX_BRANCHES + 1]; /* list of internal br. nos */ lvb_assert((n >= MIN_N) && (n <= MAX_N)); lvb_assert((m >= MIN_M) && (m <= MAX_M)); lvb_assert((root >= 0) && (root < branch_cnt)); for (i = 0; i < branch_cnt; i++) { if (barray[i].sset[0] == 0U) { todo_arr[todo_cnt] = i; todo_cnt++; } if (barray[i].object == UNSET) { internal_arr[internal_cnt] = i; internal_cnt++; } } lvb_assert(internal_cnt == (branch_cnt - n)); lvb_assert(todo_cnt <= (n - 3)); /* max: internal branches */ /* calculate state sets and changes where not already known */ while (done < todo_cnt) { for (i = 0; i < todo_cnt; i++) { branch = todo_arr[i]; if (barray[branch].sset[0] == 0U) /* "dirty" */ { left = barray[branch].left; right = barray[branch].right; lvb_assert((left >= 0) && (left < branch_cnt)); lvb_assert((right >= 0) && (right < branch_cnt)); if ((barray[left].sset[0] != 0U) && (barray[right].sset[0] != 0U)) { barray[branch].changes = 0; for (k = 0; k < m; k++) { left_ss = barray[left].sset[k]; right_ss = barray[right].sset[k]; current_ss = left_ss & right_ss; if (current_ss == 0U) { current_ss = left_ss | right_ss; barray[branch].changes += weights[k]; } barray[branch].sset[k] = current_ss; } done++; } } } } /* count changes across tree */ for (i = 0; i < internal_cnt; i++) { branch = internal_arr[i]; changes += barray[branch].changes; } /* root: add length for root branch structure, and also for true root which * lies outside the LVB tree data structure; all without altering the * "root" struct statesets (since these represent actual data for the * leaf) */ left = barray[root].left; right = barray[root].right; for (k = 0; k < m; k++) { left_ss = barray[left].sset[k]; right_ss = barray[right].sset[k]; current_ss = left_ss & right_ss; if (current_ss == 0U) { current_ss = left_ss | right_ss; changes += weights[k]; } if ((current_ss & barray[root].sset[k]) == 0U) changes += weights[k]; } return changes; } /* end getplen() */
long anneal(Treestack *bstackp, const Branch *const inittree, long root, const double t0, const double t1, const long maxaccept, const long maxpropose, const long maxfail, FILE *const lenfp, unsigned char **bmat, long m, long n, const long *weights, long *current_iter, Lvb_bool log_progress) /* seek parsimonious tree from initial tree in inittree (of root root) * with initial temperature t0, and subsequent temperatures obtained by * multiplying the current temperature by (t1 / t0) ** n * t0 where n is * the ordinal number of this temperature, after at least maxaccept changes * have been accepted or maxpropose changes have been proposed, whichever is * sooner; * return the length of the best tree(s) found after maxfail consecutive * temperatures have led to no new accepted solution; * lenfp is for output of current tree length and associated details; * *current_iter should give the iteration number at the start of this call and * will be used in any statistics sent to lenfp, and will be updated on * return */ { long accepted = 0; /* changes accespted */ Lvb_bool dect; /* should decrease temperature */ double deltah; /* change in energy (1 - C.I.) */ long deltalen; /* change in length with new tree */ long failedcnt = 0; /* "failed count" for temperatures */ long iter = 0; /* iteration of mutate/evaluate loop */ long len; /* length of current tree */ long prev_len = UNSET; /* length of previous tree */ long lenbest; /* bet length found so far */ long lendash; /* length of proposed new tree */ long lenmin; /* minimum length for any tree */ double ln_t; /* ln(current temperature) */ long t_n = 0; /* ordinal number of current temperature */ Lvb_bool newtree; /* accepted a new configuration */ double pacc; /* prob. of accepting new config. */ Lvb_bool probaccd; /* have accepted based on Pacc */ long proposed = 0; /* trees proposed */ double r_lenmin; /* minimum length for any tree */ long rootdash; /* root of new configuration */ double t = t0; /* current temperature */ double t1_to_t0; /* T1:T0 ratio */ Branch *x; /* current configuration */ Branch *xdash; /* proposed new configuration */ extern Dataptr matrix; /* data matrix */ /* "local" dynamic heap memory */ x = treealloc(brcnt(matrix->n), matrix->m); xdash = treealloc(brcnt(matrix->n), matrix->m); treecopy(x, inittree); /* current configuration */ len = getplen(x, root, m, n, weights); dect = LVB_FALSE; /* made LVB_TRUE as necessary at end of loop */ /* if t1_to_t0 is going to be very small, set it to zero without * calculating it, to avoid underflow. Use this relation: * if T1 / T0 < eps, * ln (T1/T0) < ln eps * i.e., * ln T1 - ln T0 < ln eps */ lvb_assert ((t0 >= LVB_EPS) && (t1 >= LVB_EPS) && (t1 <= t0) && (t0 <= 1.0)); if (log_wrapper(t1) - log_wrapper(t0) < log_wrapper(LVB_EPS)) t1_to_t0 = 0.0; else t1_to_t0 = t1 / t0; lenbest = len; treestack_push(bstackp, inittree, root); /* init. tree initially best */ if ((log_progress == LVB_TRUE) && (*current_iter == 0)) { fprintf(lenfp, "\nRearrangement: Length:\n"); } lenmin = getminlen(matrix); r_lenmin = (double) lenmin; while (1) { if ((log_progress == LVB_TRUE) && ((len != prev_len) || ((*current_iter % STAT_LOG_INTERVAL) == 0))) { lenlog(lenfp, *current_iter, len); } prev_len = len; *current_iter += 1; /* occasionally re-root, to prevent influence from root position */ if ((*current_iter % REROOT_INTERVAL) == 0) root = arbreroot(x, root); lvb_assert(t > DBL_EPSILON); newtree = LVB_FALSE; probaccd = LVB_FALSE; /* mutation: alternate between the two mutation functions */ if (iter % 2) { rootdash = root; mutate_spr(xdash, x, root); /* global change */ } else { rootdash = root; mutate_nni(xdash, x, root); /* local change */ } lendash = getplen(xdash, rootdash, m, n, weights); lvb_assert (lendash >= 1L); deltalen = lendash - len; deltah = (r_lenmin / (double) len) - (r_lenmin / (double) lendash); if (deltah > 1.0) /* getminlen() problem with ambiguous sites */ deltah = 1.0; if (deltalen <= 0) /* accept the change */ { if (lendash <= lenbest) /* store tree if new */ { if (lendash < lenbest) /* very best so far */ treestack_clear(bstackp); /* discard old bests */ if (treestack_push(bstackp, xdash, rootdash) == 1) newtree = LVB_TRUE; /* new */ } /* update current tree and its stats */ prev_len = len; len = lendash; treeswap(&x, &root, &xdash, &rootdash); if (lendash < lenbest) /* very best so far */ lenbest = lendash; } else /* poss. accept change for the worse */ { /* Mathematically, * Pacc = e ** (-1/T * deltaH) * therefore ln Pacc = -1/T * deltaH * * Computationally, if Pacc is going to be small, we * can assume Pacc is 0 without actually working it * out. * i.e., * if ln Pacc < ln eps, let Pacc = 0 * substituting, * if -deltaH / T < ln eps, let Pacc = 0 * rearranging, * if -deltaH < T * ln eps, let Pacc = 0 * This lets us work out whether Pacc will be very * close to zero without dividing anything by T. This * should prevent overflow. Since T is no less * than eps and ln eps is going to have greater * magnitude than eps, underflow when calculating * T * ln eps is not possible. */ if (-deltah < t * log_wrapper(LVB_EPS)) { pacc = 0.0; /* Call uni() even though its not required. It * would have been called in LVB 1.0A, so this * helps make results identical to results with * that version. */ (void) uni(); } else /* possibly accept the change */ { pacc = exp_wrapper(-deltah/t); if (uni() < pacc) /* do accept the change */ { probaccd = LVB_TRUE; treeswap(&x, &root, &xdash, &rootdash); } } if (probaccd == LVB_TRUE) { prev_len = len; len = lendash; } } proposed++; if (newtree == LVB_TRUE) accepted++; /* decide whether to reduce temperature */ if (accepted >= maxaccept) /* enough new trees */ { failedcnt = 0; /* this temperature a 'success' */ dect = LVB_TRUE; } else if (proposed >= maxpropose) /* enough proposals */ { failedcnt++; if (failedcnt >= maxfail) /* system frozen */ break; /* end of cooling */ else /* decrease temp. */ dect = LVB_TRUE; } if (dect == LVB_TRUE) { t_n++; /* originally n is 0 */ /* near the start of the function we ensure t1_to_t0 is * either zero or no less than LVB_EPS */ if (t1_to_t0 < LVB_EPS) t = LVB_EPS; else { ln_t = ((double) t_n) * log_wrapper(t1_to_t0) + log_wrapper(t0); if (ln_t < log_wrapper(LVB_EPS)) t = LVB_EPS; else t = pow_wrapper(t1_to_t0, (double) t_n) * t0; } proposed = 0; accepted = 0; dect = LVB_FALSE; } iter++; } /* free "local" dynamic heap memory */ free(x); free(xdash); return lenbest; } /* end anneal() */