📄 seq.c
字号:
done = (p == NULL); if (!done) done = (place[p->index - 1] != j); if (done) { nextnode++; } } } } } if (flipback) flipnodes(outgrnode, flipback->back); else { if (root2) { reroot3(outgrnode, root, root2, lastdesc, grbg); root = root2; } } if (binroot) backtobinary(&root, binroot, grbg);} /* savetree */ void addnsave(node *p, node *item, node *nufork, node **root, node **grbg, boolean multf, pointarray treenode, long *place, long *zeros){ /* adds item to tree and save it. Then removes item. */ node *dummy; if (!multf) add(p, item, nufork, root, false, treenode, grbg, zeros); else add(p, item, NULL, root, false, treenode, grbg, zeros); savetree(*root, place, treenode, grbg, zeros); if (!multf) re_move(item, &nufork, root, false, treenode, grbg, zeros); else re_move(item, &dummy, root, false, treenode, grbg, zeros);} /* addnsave */void addbestever(long *pos, long *nextree, long maxtrees, boolean collapse, long *place, bestelm *bestrees){ /* adds first best tree */ *pos = 1; *nextree = 1; initbestrees(bestrees, maxtrees, true); initbestrees(bestrees, maxtrees, false); addtree(*pos, nextree, collapse, place, bestrees);} /* addbestever */void addtiedtree(long pos, long *nextree, long maxtrees, boolean collapse, long *place, bestelm *bestrees){ /* add tied tree */ if (*nextree <= maxtrees) addtree(pos, nextree, collapse, place, bestrees);} /* addtiedtree */void clearcollapse(pointarray treenode){ /* clears collapse status at a node */ long i; node *p; for (i = 0; i < nonodes; i++) { treenode[i]->collapse = undefined; if (!treenode[i]->tip) { p = treenode[i]->next; while (p != treenode[i]) { p->collapse = undefined; p = p->next; } } }} /* clearcollapse */void clearbottom(pointarray treenode){ /* clears boolean bottom at a node */ long i; node *p; for (i = 0; i < nonodes; i++) { treenode[i]->bottom = false; if (!treenode[i]->tip) { p = treenode[i]->next; while (p != treenode[i]) { p->bottom = false; p = p->next; } } }} /* clearbottom */void collabranch(node *collapfrom, node *tempfrom, node *tempto){ /* collapse branch from collapfrom */ long i, j, b, largest, descsteps; boolean done; for (i = 0; i < endsite; i++) { descsteps = 0; for (j = (long)A; j <= (long)O; j++) { b = 1 << j; if ((descsteps == 0) && (collapfrom->base[i] & b)) descsteps = tempfrom->oldnumsteps[i] - (collapfrom->numdesc - collapfrom->numnuc[i][j]) * weight[i]; } done = false; for (j = (long)A; j <= (long)O; j++) { b = 1 << j; if (!done && (tempto->base[i] & b)) { descsteps += (tempto->numsteps[i] - (tempto->numdesc - collapfrom->numdesc - tempto->numnuc[i][j]) * weight[i]); done = true; } } for (j = (long)A; j <= (long)O; j++) tempto->numnuc[i][j] += collapfrom->numnuc[i][j]; largest = getlargest(tempto->numnuc[i]); tempto->base[i] = 0; for (j = (long)A; j <= (long)O; j++) { if (tempto->numnuc[i][j] == largest) tempto->base[i] |= (1 << j); } tempto->numsteps[i] = (tempto->numdesc - largest) * weight[i] + descsteps; }} /* collabranch */boolean allcommonbases(node *a, node *b, boolean *allsame){ /* see if bases are common at all sites for nodes a and b */ long i; boolean allcommon; allcommon = true; *allsame = true; for (i = 0; i < endsite; i++) { if ((a->base[i] & b->base[i]) == 0) allcommon = false; else if (a->base[i] != b->base[i]) *allsame = false; } return allcommon;} /* allcommonbases */void findbottom(node *p, node **bottom){ /* find a node with field bottom set at node p */ node *q; if (p->bottom) *bottom = p; else { q = p->next; while(!q->bottom && q != p) q = q->next; *bottom = q; }} /* findbottom */boolean moresteps(node *a, node *b){ /* see if numsteps of node a exceeds those of node b */ long i; for (i = 0; i < endsite; i++) if (a->numsteps[i] > b->numsteps[i]) return true; return false;} /* moresteps */boolean passdown(node *desc, node *parent, node *start, node *below, node *item, node *added, node *total, node *tempdsc, node *tempprt, boolean multf){ /* track down to node start to see if an ancestor branch can be collapsed */ node *temp; boolean done, allsame; done = (parent == start); while (!done) { desc = parent; findbottom(parent->back, &parent); if (multf && start == below && parent == below) parent = added; memcpy(tempdsc->base, tempprt->base, endsite*sizeof(long)); memcpy(tempdsc->numsteps, tempprt->numsteps, endsite*sizeof(long)); memcpy(tempdsc->oldbase, desc->base, endsite*sizeof(long)); memcpy(tempdsc->oldnumsteps, desc->numsteps, endsite*sizeof(long)); memcpy(tempprt->base, parent->base, endsite*sizeof(long)); memcpy(tempprt->numsteps, parent->numsteps, endsite*sizeof(long)); memcpy(tempprt->numnuc, parent->numnuc, endsite*sizeof(nucarray)); tempprt->numdesc = parent->numdesc; multifillin(tempprt, tempdsc, 0); if (!allcommonbases(tempprt, parent, &allsame)) return false; else if (moresteps(tempprt, parent)) return false; else if (allsame) return true; if (parent == added) parent = below; done = (parent == start); if (done && ((start == item) || (!multf && start == below))) { memcpy(tempdsc->base, tempprt->base, endsite*sizeof(long)); memcpy(tempdsc->numsteps, tempprt->numsteps, endsite*sizeof(long)); memcpy(tempdsc->oldbase, start->base, endsite*sizeof(long)); memcpy(tempdsc->oldnumsteps, start->numsteps, endsite*sizeof(long)); multifillin(added, tempdsc, 0); tempprt = added; } } temp = tempdsc; if (start == below || start == item) fillin(temp, tempprt, below->back); else fillin(temp, tempprt, added); return !moresteps(temp, total);} /* passdown */boolean trycollapdesc(node *desc, node *parent, node *start, node *below, node *item, node *added, node *total, node *tempdsc, node *tempprt, boolean multf, long *zeros) { /* see if branch between nodes desc and parent can be collapsed */ boolean allsame; if (desc->numdesc == 1) return true; if (multf && start == below && parent == below) parent = added; memcpy(tempdsc->base, zeros, endsite*sizeof(long)); memcpy(tempdsc->numsteps, zeros, endsite*sizeof(long)); memcpy(tempdsc->oldbase, desc->base, endsite*sizeof(long)); memcpy(tempdsc->oldnumsteps, desc->numsteps, endsite*sizeof(long)); memcpy(tempprt->base, parent->base, endsite*sizeof(long)); memcpy(tempprt->numsteps, parent->numsteps, endsite*sizeof(long)); memcpy(tempprt->numnuc, parent->numnuc, endsite*sizeof(nucarray)); tempprt->numdesc = parent->numdesc - 1; multifillin(tempprt, tempdsc, -1); tempprt->numdesc += desc->numdesc; collabranch(desc, tempdsc, tempprt); if (!allcommonbases(tempprt, parent, &allsame) || moresteps(tempprt, parent)) { if (parent != added) { desc->collapse = nocollap; parent->collapse = nocollap; } return false; } else if (allsame) { if (parent != added) { desc->collapse = tocollap; parent->collapse = tocollap; } return true; } if (parent == added) parent = below; if ((start == item && parent == item) || (!multf && start == below && parent == below)) { memcpy(tempdsc->base, tempprt->base, endsite*sizeof(long)); memcpy(tempdsc->numsteps, tempprt->numsteps, endsite*sizeof(long)); memcpy(tempdsc->oldbase, start->base, endsite*sizeof(long)); memcpy(tempdsc->oldnumsteps, start->numsteps, endsite*sizeof(long)); memcpy(tempprt->base, added->base, endsite*sizeof(long)); memcpy(tempprt->numsteps, added->numsteps, endsite*sizeof(long)); memcpy(tempprt->numnuc, added->numnuc, endsite*sizeof(nucarray)); tempprt->numdesc = added->numdesc; multifillin(tempprt, tempdsc, 0); if (!allcommonbases(tempprt, added, &allsame)) return false; else if (moresteps(tempprt, added)) return false; else if (allsame) return true; } return passdown(desc, parent, start, below, item, added, total, tempdsc, tempprt, multf);} /* trycollapdesc */void setbottom(node *p){ /* set field bottom at node p */ node *q; p->bottom = true; q = p->next; do { q->bottom = false; q = q->next; } while (q != p);} /* setbottom */boolean zeroinsubtree(node *subtree, node *start, node *below, node *item, node *added, node *total, node *tempdsc, node *tempprt, boolean multf, node* root, long *zeros){ /* sees if subtree contains a zero length branch */ node *p; if (!subtree->tip) { setbottom(subtree); p = subtree->next; do { if (p->back && !p->back->tip && !((p->back->collapse == nocollap) && (subtree->collapse == nocollap)) && (subtree->numdesc != 1)) { if ((p->back->collapse == tocollap) && (subtree->collapse == tocollap) && multf && (subtree != below)) return true; /* when root->numdesc == 2 * there is no mandatory step at the root, * instead of checking at the root we check around it * we only need to check p because the first if * statement already gets rid of it for the subtree */ else if ((p->back->index != root->index || root->numdesc > 2) && trycollapdesc(p->back, subtree, start, below, item, added, total, tempdsc, tempprt, multf, zeros)) return true; else if ((p->back->index == root->index && root->numdesc == 2) && !(root->next->back->tip) && !(root->next->next->back->tip) && trycollapdesc(root->next->back, root->next->next->back, start, below, item,added, total, tempdsc, tempprt, multf, zeros)) return true; } p = p->next; } while (p != subtree); p = subtree->next; do { if (p->back && !p->back->tip) { if (zeroinsubtree(p->back, start, below, item, added, total, tempdsc, tempprt, multf, root, zeros)) return true; } p = p->next; } while (p != subtree); } return false;} /* zeroinsubtree */boolean collapsible(node *item, node *below, node *temp, node *temp1, node *tempdsc, node *tempprt, node *added, node *total, boolean multf, node *root, long *zeros, pointarray treenode){ /* sees if any branch can be collapsed */ node *belowbk; boolean allsame; if (multf) { memcpy(tempdsc->base, item->base, endsite*sizeof(long)); memcpy(tempdsc->numsteps, item->numsteps, endsite*sizeof(long)); memcpy(tempdsc->oldbase, zeros, endsite*sizeof(long)); memcpy(tempdsc->oldnumsteps, zeros, endsite*sizeof(long)); memcpy(added->base, below->base, endsite*sizeof(long)); memcpy(added->numsteps, below->numsteps, endsite*sizeof(long)); memcpy(added->numnuc, below->numnuc, endsite*sizeof(nucarray)); added->numdesc = below->numdesc + 1; multifillin(added, tempdsc, 1); } else { fillin(added, item, below); added->numdesc = 2; } fillin(total, added, below->back); clearbottom(treenode); if (below->back) { if (zeroinsubtree(below->back, below->back, below, item, added, total, tempdsc, tempprt, multf, root, zeros)) return true; } if (multf) { if (zeroinsubtree(below, below, below, item, added, total, tempdsc, tempprt, multf, root, zeros)) return true; } else if (!below->tip) { if (zeroinsubtree(below, below, below, item, added, total, tempdsc, tempprt, multf, root, zeros)) return true; } if (!item->tip) { if (zeroinsubtree(item, item, below, item, added, total, tempdsc, tempprt, multf, root, zeros)) return true; } if (multf && below->back && !below->back->tip) { memcpy(tempdsc->base, zeros, endsite*sizeof(long)); memcpy(tempdsc->numsteps, zeros, endsite*sizeof(long)); memcpy(tempdsc->oldbase, added->base, endsite*sizeof(long)); memcpy(tempdsc->oldnumsteps, added->numsteps, endsite*sizeof(long)); if (below->back == treenode[below->back->index - 1]) belowbk = below->back->next; else belowbk = treenode[below->back->index - 1]; memcpy(tempprt->base, belowbk->base, endsite*sizeof(long)); memcpy(tempprt->numsteps, belowbk->numsteps, endsite*sizeof(long)); memcpy(tempprt->numnuc, belowbk->numnuc, endsite*sizeof(nucarray)); tempprt->numdesc = belowbk->numdesc - 1; multifillin(tempprt, tempdsc, -1); tempprt->numdesc += added->numdesc; collabranch(added, tempdsc, tempprt); if (!allcommonbases(tempprt, belowbk, &allsame)) return false; else if (allsame && !moresteps(tempprt, belowbk)) return true; else if (belowbk->back) { fillin(temp, tempprt, belowbk->back); fillin(temp1, belowbk, belowbk->back); return !moresteps(temp, temp1); } } return false;} /* collapsible */void replaceback(node **oldback, node *item, node *forknode, node **grbg, long *zeros){ /* replaces back node of item with another */ node *p; p = forknode; while (p->next->back != item) p = p->next; *oldback = p->next; gnutreenode(grbg, &p->next, forknode->index, endsite, zeros); p->next->next = (*oldback)->next; p->next->back = (*oldback)->back; p->next->back->back = p->next; (*oldback)->next = (*oldback)->back = NULL;} /* replaceback */void putback(node *oldback, node *item, node *forknode, node **grbg){ /* restores node to back of item */ node *p, *q; p = forknode; while (p->next != item->back) p = p->next; q = p->next; oldback->next = p->next->next; p->next = oldback; oldback->back = item; item->back = oldback; oldback->index = forknode->index; chucktreenode(grbg, q);} /* putback */void savelocrearr(node *item, node *forknode, node *below, node *tmp, node *tmp1, node *tmp2, node *tmp3, node *tmprm, node *tmpadd, node **root, long maxtrees, long *nextree, boolean multf, boolean bestever, boolean *saved, long *place, bestelm *bestrees, pointarray treenode, node **grbg, long *zeros){ /* saves tied or better trees during local rearrangements by removing item from forknode and adding to below */ node *other, *otherback = NULL, *oldfork, *nufork, *oldback; long pos; boolean found, collapse; if (fork
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -