예제 #1
0
void mfl_reroot_subtree(node *n, node *atip, node *subtr, node *base, node *up, 
                        node *dn, tree *swapingon, tree **savedtrees, int ntax, 
                        int nchar, int numnodes, mfl_searchrec *searchrec, 
                        int diff)
{
    /* Traverses the subtree and re-roots it at each branch in preorder and then
     * calls regrafting traversal (same as used in SPR).*/
    
    if (searchrec->success) {
        return;
    }

    mfl_join_nodes(base->next->next, n->edge);
    mfl_join_nodes(base->next, n);
    
    // Reoptimize the subtree base

    mfl_reopt_subtr_root(base, nchar);

    if (!base->next->edge->origbase && !base->next->next->edge->origbase) {
        up->visited = 0;
        dn->visited = 0;
    }
    
    mfl_regrafting_traversal(up, subtr, swapingon, savedtrees, ntax, nchar, 
                             numnodes, searchrec, diff);
    if (searchrec->success) {
        up->visited = 1;
        dn->visited = 1;
        base->skip = true;
        return;
    }
    mfl_regrafting_traversal(dn, subtr, swapingon, savedtrees, ntax, nchar, 
                             numnodes, searchrec, diff);
    
    up->visited = 1;
    dn->visited = 1;
    base->skip = true;
    
    if (searchrec->success) {
        return;
    }
    
    // Remove the base
    mfl_join_nodes(base->next->edge, base->next->next->edge);
    
    if (n->tip) {
        return;
    }
    
    mfl_reroot_subtree(n->next->edge, atip, subtr, base, up, dn, swapingon, 
                       savedtrees, ntax, nchar, numnodes, searchrec, diff);
    if (searchrec->success) {
        return;
    }
    mfl_reroot_subtree(n->next->next->edge, atip, subtr, base, up, dn, 
                       swapingon, savedtrees, ntax, nchar, numnodes, searchrec, 
                       diff);
    
}
예제 #2
0
void mfl_insert_branch(node *br, node *target, int ntax)
{
    // Inserts a branch with a ring base into another branch
    
    node *br1, *br2, *tdesc;
    
    tdesc = target->edge;
    
    if (br->tip) {
        br1 = br->edge->next;
        br2 = br1->next;
    }
    else {
        br1 = mfl_seek_ringnode(br, ntax);
        br2 = mfl_seek_ringnode(br1->next, ntax);
    }

    if (br1->edge || br2->edge) {
        dbg_printf("Error in branch insertion\n");
        return;
    }
    
    mfl_join_nodes(br1, target);
    mfl_join_nodes(br2, tdesc);
}
struct node * cpyfromNWK(char *nwktr, int nwklen, int ntax, int numnodes, 
                         int *pos, nodearray nds, bool isRooted)
{
    
    int i, tipnum;
    char tipbuf[10];
    node *n, *nlst, *p;
    
    n = mfl_seek_internal(ntax - 1, numnodes, nds);
    n->initialized = 1;
    nlst = n;
    
    do {
        
        *pos = *pos + 1;
        
        if (nwktr[*pos] == ')')
        {
            nlst->next = n;
            return n;
        }
        
        if (isdigit(nwktr[*pos]))
        {
            for (i = 0; nwktr[*pos] != ',' && nwktr[*pos] != ')'; ++i, ++*pos) 
            {
                tipbuf[i] = nwktr[*pos];
            }
            
            tipbuf[i] = '\0';
        
            tipnum = atoi(tipbuf);
            
            nlst->next = mfl_allocnode();
            nlst = nlst->next;
            
            mfl_join_nodes(nds[tipnum - 1], nlst);
            
            if (nwktr[*pos] == ')')
            {
                nlst->next = n;
                mfl_set_ring_to_n(n);
                return n;
            }
            
        }
        
        if (nwktr[*pos] == '(') 
        {
            nlst->next = mfl_allocnode();
            nlst = nlst->next;
            p = cpyfromNWK(nwktr, nwklen, ntax, numnodes, pos, nds, isRooted);
            mfl_join_nodes(p, nlst);
        }
        
    } while (nwktr[*pos]);
    
    nlst->next = n;
    return n;
}
예제 #4
0
tree *mfl_addseq_randasis(int ntax, int nchar, int numnodes,
                                 charstate *tipdata, bool addRandom,
                                 tree **savedtrees)
{
    int i, nbeslen = 0;
    int *bestlen = &nbeslen;
    int *taxarray;
    node *p, *bestpos;
    
    tree *newtree = mfl_alloc_noring(ntax, numnodes);
    
    taxarray = (int*)malloc(ntax * sizeof(int));
    memset(taxarray, 0, ntax * sizeof(int));  // This is to see if I can fix the problem
    mfl_init_taxarray(taxarray, ntax);
    
    
    if (addRandom) {
        dbg_printf("Joining taxa by random addition sequence\n");
        mfl_shuffle(taxarray, ntax);
    }
    else {
        dbg_printf("Joining taxa according to order in matrix\n");
    }
    
    p = newtree->trnodes[ntax + 1];
    mfl_newring(p, ntax);
    i = 0;
    do {
        mfl_join_nodes(newtree->trnodes[taxarray[i] - 1], p);
        p = p->next;
        ++i;
    } while (p != newtree->trnodes[ntax + 1]);

    mfl_temproot(newtree, taxarray[0] - 1, ntax);
    newtree->length = *bestlen;
    bestpos = newtree->trnodes[taxarray[0] - 1];
    
    for (i = 3; i < ntax; ++i) {
        mfl_newring(newtree->trnodes[ntax + i - 1], ntax);
        mfl_join_nodes(newtree->trnodes[taxarray[i] - 1], newtree->trnodes[ntax + i - 1]->next);
        mfl_insert_branch(newtree->trnodes[taxarray[i] - 1], newtree->trnodes[taxarray[0] - 1], ntax);
        *bestlen = mfl_get_sttreelen(newtree, tipdata, ntax, nchar, bestlen);
        //dbg_printf("Preliminary length: %i\n", *bestlen);
        mfl_remove_branch(newtree->trnodes[taxarray[i] - 1]);
        bestpos = mfl_tryall(newtree->root, newtree->trnodes[taxarray[i] - 1], bestpos, ntax, nchar, 
                   numnodes, bestlen, newtree, savedtrees, tipdata);
        //Join the nodes//
        mfl_insert_branch(newtree->trnodes[taxarray[i] - 1], bestpos, ntax);
        *bestlen = 0;
    }
    mfl_undo_temproot(ntax, newtree);
    //newtree->bipartitions = mfl_tree_biparts(newtree, ntax, numnodes);
    
    free(taxarray);
    return newtree;
}
예제 #5
0
struct tree *randunrooted(int ntax, int numnodes)
{
    /* Returns a random unrooted tree*/
    
    int i;
    int *taxarray;
    node *p, *q;
    tree *randtree;

    taxarray =(int*) malloc(ntax * sizeof(int));
    mfl_init_taxarray(taxarray, ntax);
    
    mfl_shuffle(taxarray, ntax);
    
    randtree = mfl_alloctree(ntax, numnodes);
    
    randtree->trnodes[0]->start = true;
    randtree->trnodes[0]->edge = randtree->trnodes[taxarray[0]];
    
    // Join all the internal nodes (except the root) together
    for (i = 1; i <= (ntax - 3); ++i) {
        p = randtree->trnodes[ntax + i]->next->next;
        q = randtree->trnodes[ntax + i + 1];
        mfl_join_nodes(p, q);
    }
    
    // Add all the tips to the appropriate internal nodes
    
    mfl_join_nodes(randtree->trnodes[ntax + 1], randtree->trnodes[taxarray[0] - 1]);
    
    for (i = 1; i < ntax - 1; ++i) {
        randtree->trnodes[taxarray[i] - 1]->edge = randtree->trnodes[ntax + i]->next;
        randtree->trnodes[ntax + i]->next->edge = randtree->trnodes[taxarray[i] - 1];
    } 
    
    randtree->trnodes[2 * ntax - 2]->next->next->edge = randtree->trnodes[taxarray[i] - 1];
    randtree->trnodes[taxarray[i] - 1]->edge = randtree->trnodes[2 * ntax - 2]->next->next;
    
    free(taxarray);
    
    /*printNewick(randtree->trnodes[0]);*/
    dbg_printf(";\n");
    
    return (randtree);
}
예제 #6
0
void mfl_remove_branch(node *n)
{
    node *p, *q, *nb;
    
    nb = n->edge;
    p = nb->next->edge;
    q = nb->next->next->edge;
    nb->next->edge = NULL;
    nb->next->next->edge = NULL;
    mfl_join_nodes(p, q);
}
예제 #7
0
void mfl_bisection_traversal(node *n, tree *swapingon, tree **savedtrees, 
                             int ntax, int nchar, int numnodes, 
                             mfl_searchrec *searchrec)
{
    /* Traverses a binary tree clipping out a subtree in postorder and passing 
     * a pointer to the subtree to mfl_reroot_subtree. */
    
    int i, diff, *srcchanging, *tgtchanging;
    node *p, *q, *src, *tgt, *s_dn, *s_up, *t_dn, *t_up, *t_dn_N, *t_up_N;
    node *s_dn_N, *s_up_N, *atip;
    nodearray nds = swapingon->trnodes;
    
    mfl_undone_tree(swapingon->trnodes, numnodes);
    
    for (i = ntax + 1; i < numnodes; ++i) {
        
        p = nds[i];
        q = nds[i];
        
        do {
                
            src = p->edge;
            tgt = p;
            src->done = true;
            
            if (!tgt->done) {
                if (!src->skip) {
                    src->skip = true;
                    
                    if (src->tip) {
                        memcpy(src->apomorphies, src->tempapos, 
                               nchar * sizeof(charstate));
                    }
                    else {
                        mfl_set_updown(src, &s_up, &s_dn);
                        s_up_N = s_up->edge;
                        s_dn_N = s_dn->edge;
                        
                        if (src->tocalcroot) {
                            
                            srcchanging = mfl_get_subtr_changing(src, NULL, NULL, 
                                                                 nchar);
                            mfl_reopt_subtr(src, swapingon, nchar, numnodes, 
                                            srcchanging);
                            free(srcchanging);
                        }
                        else {
                            if (src->next->edge->tip && src->next->next->edge->tip) {
                                mfl_set_rootstates(src, nchar, NULL);
                            }
                            else {
                                srcchanging = mfl_get_tgt_changing(s_dn->edge, s_up, 
                                                                   s_dn, nchar);
                                mfl_join_nodes(s_dn, s_up);
                                mfl_partial_downpass(s_dn, swapingon, numnodes, ntax, 
                                                     nchar, srcchanging);
                                mfl_join_nodes(s_up_N, s_up);
                                mfl_join_nodes(s_dn_N, s_dn);
                                mfl_reopt_subtr_root(src, nchar);
                                free(srcchanging);
                            }
                        }
                    }
                    
                    mfl_set_updown(tgt, &t_up, &t_dn);
                    t_up_N = t_up->edge;
                    t_dn_N = t_dn->edge;
                    
                    if (!tgt->tocalcroot) {
                        tgtchanging = mfl_get_tgt_changing(t_dn->edge, t_up, t_dn, 
                                                           nchar);
                        // Pop out redundant node:
                        mfl_join_nodes(t_up, t_dn);
                        mfl_partial_downpass(t_dn, swapingon, numnodes, ntax, nchar, 
                                             tgtchanging);
                        free(tgtchanging);
                    }
                    else {
                        tgtchanging = mfl_get_subtr_changing(tgt, NULL, NULL, 
                                                             nchar);
                        tgt->isroot = true;
                        mfl_reopt_subtr(tgt, swapingon, nchar, numnodes, 
                                        tgtchanging);
                        tgt->isroot = false;
                        free(tgtchanging);
                        // Pop out the redundant node:
                        mfl_join_nodes(t_up, t_dn);
                    }
                    
                    diff = mfl_subtr_reinsertion(src, t_up, t_dn, nchar);
                    
                    t_up->visited = true;
                    t_dn->visited = true;
                    
                    if (mfl_subtr_isrerootable(src)) {
                        
                        atip = mfl_find_atip(src);
                        
                        mfl_join_nodes(s_up, s_dn);
                        s_up->origbase = true;
                        s_dn->origbase = true;
                        
                        mfl_reroot_subtree(atip->edge, atip, src->edge->next->next, 
                                           src, t_up, t_dn, swapingon, savedtrees, 
                                           ntax, nchar, numnodes, searchrec, diff);
                        
                        s_up->origbase = false;
                        s_dn->origbase = false;
                        
                        if (searchrec->success) {
                            t_up->visited = false;
                            t_dn->visited = false;
                            src->skip = false;
                            return;
                        }
                        
                        mfl_join_nodes(s_up_N, s_up);
                        mfl_join_nodes(s_dn_N, s_dn);
                        
                    }
                    else {
                        mfl_regrafting_traversal(t_up, src->edge->next->next, 
                                                 swapingon, savedtrees, ntax, nchar, 
                                                 numnodes, searchrec, diff);
                        
                        mfl_regrafting_traversal(t_dn, src->edge->next->next, 
                                                 swapingon, savedtrees, ntax, nchar, 
                                                 numnodes, searchrec, diff);
                    }
                    
                    t_up->visited = false;
                    t_dn->visited = false;
                    src->skip = false;
                    
                    if (searchrec->success) {
                        return;
                    }
                    
                    mfl_join_nodes(t_up, t_up_N);
                    mfl_join_nodes(t_dn, t_dn_N);
                    
                    mfl_restore_origstates(swapingon, ntax, numnodes, nchar);
                    src->skip = false;
                }
                else {
                    src->skip = false;
                }
            }
            
            assert(q == nds[i]);
            
            p = p->next;
            
        } while (p != nds[i]);
    }
}
예제 #8
0
void mfl_subtree_pruning(node *n, tree *swapingon, tree **savedtrees, int ntax, 
                         int nchar, int numnodes, mfl_searchrec *searchrec)
{
    
    /* Indexes over the node array of a tree, pruning subtrees and calling
     * the regrafting function */
    
    int i, diff = 0, *srcchanging, *tgtchanging;
    node *p, *q, *src, *tgt, *s_dn, *s_up, *t_dn, *t_up, *t_dn_N, *t_up_N;
    node *s_dn_N, *s_up_N;
    nodearray nds = swapingon->trnodes;
    
    mfl_undone_tree(swapingon->trnodes, numnodes);
    
    for (i = ntax + 1; i < numnodes; ++i) {
        
        p = nds[i];
        q = nds[i];
        
        do {
            
            if (!p->edge->skip) {
                p->edge->skip = true;
                src = p->edge;
                tgt = p;
                
                if (!tgt->tocalcroot) {
                    
                    mfl_set_updown(tgt, &t_up, &t_dn);
                    
                    tgtchanging = mfl_get_tgt_changing(t_dn->edge, t_up, t_dn, 
                                                       nchar);
                    // Pop out redundant node:
                    t_up_N = t_up->edge;
                    t_dn_N = t_dn->edge;
                    mfl_join_nodes(t_up, t_dn);
                    mfl_partial_downpass(t_dn, swapingon, numnodes, ntax, nchar, 
                                         tgtchanging);
                    free(tgtchanging);
                }
                else {
                    mfl_set_updown(tgt, &t_up, &t_dn);
                    
                    if (t_up->tip && t_dn->tip) {
                        p = p->next;
                        continue;
                    }
                    else {
                        //mfl_set_updown(tgt, &t_up, &t_dn);
                        tgtchanging = mfl_get_subtr_changing(tgt, NULL, NULL, 
                                                             nchar);
                        tgt->isroot = true;
                        mfl_reopt_subtr(tgt, swapingon, nchar, numnodes, 
                                        tgtchanging);
                        tgt->isroot = false;
                        free(tgtchanging);
                    }
                    // Pop out the redundant node:
                    t_up_N = t_up->edge;
                    t_dn_N = t_dn->edge;
                    mfl_join_nodes(t_up, t_dn);
                    
                }
                
                if (src->tip) {
                    memcpy(src->apomorphies, src->tempapos, 
                           nchar * sizeof(charstate));
                }
                else if (src->tocalcroot) {
                    mfl_set_rootstates(src, nchar, NULL);
                    /*if (src->next->edge->tip && src->next->next->edge->tip) {
                        printNewick(src);
                        dbg_printf("\n");
                    }*/

                }
                else {
                    
                    if (src->next->edge->tip && src->next->next->edge->tip) {
                        mfl_set_rootstates(src, nchar, NULL);
                    }
                    else {
                        mfl_set_updown(src, &s_up, &s_dn);
                        srcchanging = mfl_get_tgt_changing(s_dn->edge, s_up, 
                                                           s_dn, nchar);
                        s_up_N = s_up->edge;
                        s_dn_N = s_dn->edge;
                        mfl_join_nodes(s_dn, s_up);
                        mfl_partial_downpass(s_dn, swapingon, numnodes, ntax, 
                                             nchar, srcchanging);
                        mfl_join_nodes(s_up_N, s_up);
                        mfl_join_nodes(s_dn_N, s_dn);
                        mfl_reopt_subtr_root(src, nchar);
                        free(srcchanging);
                    }
                }
                
                diff = mfl_subtr_reinsertion(src, t_up, t_dn, nchar);
                // Perform all reinsertions of SRC on TGT
                /* OPTIMIZATION: This program can be greatly speeded up by 
                 * taking advantage of the fact that the two subtrees are 
                 * already reoptimized at this stage. Once one set of 
                 * reinsertions has been completed and did not result in a
                 * better tree, this function can reverse the order and begin
                 * reinserting the old target tree on the source tree. In this 
                 * diff may need to be recalculated. */
                
                t_up->visited = true;
                t_dn->visited = true;
                mfl_regrafting_traversal(t_up, src->edge->next->next, swapingon, 
                                         savedtrees, ntax, nchar, numnodes, 
                                         searchrec, diff);
                
                mfl_regrafting_traversal(t_dn, src->edge->next->next, swapingon, 
                                         savedtrees, ntax, nchar, numnodes, 
                                         searchrec, diff);
                
                t_up->visited = false;
                t_dn->visited = false;
                p->edge->skip = false;
                if (searchrec->success) {
                    return;
                }
                
                mfl_join_nodes(t_up, t_up_N);
                mfl_join_nodes(t_dn, t_dn_N);
                
                mfl_restore_origstates(swapingon, ntax, numnodes, nchar);
            }
            assert(q == nds[i]);
            p->edge->skip = false;
            p = p->next;
            
        } while (p != nds[i]);
        
    }
}
예제 #9
0
void mfl_regrafting_traversal(node *n, node *subtr, tree *swapingon, 
                              tree **savedtrees, int ntax, int nchar, int numnodes, mfl_searchrec *searchrec, int diff)
{
    /* Called from within any subtree pruning algorithm used in either SPR or
     * TBR branch swapping. Traverses a binary tree in preorder, inserting the 
     * subtree at each node and (hopefully) skipping a reinsertion at the original
     * site of pruning (flagged by the "visited" boolean values in those nodes) */
    
    if (searchrec->success) {
        return;
    }
    
    int trlength = 0;
    int al = 0;
    node *up;
    node *down, *top;
    
    if (!(n->visited) && !(n->edge->visited)) {
        up = n->edge;
        
        al = mfl_locreopt_cost(subtr->next->edge, n, up, nchar, diff);
        trlength = searchrec->bestinrep - diff + al;
        assert(trlength >= 0);

        searchrec->niter_total = searchrec->niter_total + 1;
        
#ifdef MFY_DEBUG
        /*** BEGIN COMMENT OUT BEFORE COMMIT ***
        int trulen = 0;
        if (subtr->tocalcroot) {
            down = subtr;
            top = subtr->next->next;
        }
        else {
            down = subtr->next->next;
            top = subtr;
        }
        
        mfl_join_nodes(top, up);
        mfl_join_nodes(down, n);
        
        mfl_temproot(swapingon, 0, ntax);
        mfl_count_postorder(swapingon->root, &trulen, nchar, NULL);
        trulen = 0;
        mfl_fitch_preorder(swapingon->root, nchar, &trulen);
        mfl_undo_temproot(ntax, swapingon);
        
        if (trulen != trlength) {
            if (subtr->next->edge->tocalcroot) {
                printNewick(subtr->next->edge);
                dbg_printf("\n");
                printNewick(swapingon->trnodes[0]);
                dbg_printf("\n");
            }
            dbg_printf("estimated: %i\n", trlength);
            dbg_printf("true:      %i\n", trulen);
            dbg_printf("diff:      %i\n", diff);
            dbg_printf("al:        %i\n\n", al);
            //trlength = trulen;
            //dbg_printf("report mismatch\n");
        }
        else {
            dbg_printf("MATCH:\n");
            dbg_printf("estimated: %i\n", trlength);
            dbg_printf("true:      %i\n", trulen);
            dbg_printf("diff:      %i\n", diff);
            dbg_printf("al:        %i\n\n", al);
        }
        
        trlength = trulen;
        mfl_join_nodes(n, up);
        *** END COMMENT OUT BEFORE COMMIT ***/
#endif
        
        if (trlength < searchrec->bestinrep) {
        
            
            dbg_printf("length: %i\n", trlength);

            mfl_join_nodes(subtr->next->next, up);
            mfl_join_nodes(subtr, n);
            
            searchrec->foundbettertr = true;
            searchrec->success = true;
            swapingon->length = trlength;
            searchrec->bestinrep = trlength;
            
            if (searchrec->bestinrep < searchrec->bestlength) {
                searchrec->bestlength = searchrec->bestinrep;
                mfl_reinit_treebuffer(savedtrees, swapingon, &searchrec->nextinbuffer, numnodes);
            }
            else {
                mfl_reinit_tbinrange(savedtrees, swapingon, searchrec->trbufstart, &searchrec->nextinbuffer, numnodes);
            }
            free(swapingon->compressedtr);
            swapingon->compressedtr = mfl_compress_tree(swapingon, ntax, numnodes);
            searchrec->nextinbuffer = searchrec->nextinbuffer + 1;
            
            return;
        }
        
        searchrec->foundbettertr = false;
        searchrec->success = false;
        
        if (trlength == searchrec->bestinrep) 
        {
            
            if (subtr->tocalcroot) {
                down = subtr;
                top = subtr->next->next;
            }
            else {
                down = subtr->next->next;
                top = subtr;
            }
            
            mfl_join_nodes(top, up);
            mfl_join_nodes(down, n);

            
            if (!mfl_compare_alltrees(swapingon, savedtrees, ntax, numnodes, &searchrec->trbufstart, searchrec->nextinbuffer)) 
            {
                if (searchrec->currentreplicate > 0) {
                    if (trlength == searchrec->bestlength) {
                        
                        long int bstart = 0;
                        
                        if (mfl_compare_alltrees(swapingon, savedtrees, ntax, numnodes, &bstart, searchrec->trbufstart)) {
                            mfl_reinit_tbinrange(savedtrees, swapingon, searchrec->trbufstart, &searchrec->nextinbuffer, numnodes);
                            searchrec->success = true;
                            return;
                        }

                    }
                }
                
                savedtrees[searchrec->nextinbuffer] = mfl_copytree(swapingon, ntax, numnodes);
                savedtrees[searchrec->nextinbuffer]->index = searchrec->nextinbuffer;
                savedtrees[searchrec->nextinbuffer]->length = trlength;
                savedtrees[searchrec->nextinbuffer]->swapped = false;
                searchrec->nextinbuffer = searchrec->nextinbuffer + 1;
                
            }
            trlength = 0;
        }
        
        mfl_join_nodes(n, up);
    }
    
    if (n->tip) {
        return;
    }

    mfl_regrafting_traversal(n->next->edge, subtr, swapingon, savedtrees, ntax,
                                 nchar, numnodes, searchrec, diff);
    if (searchrec->success) {
        return;
    }
    mfl_regrafting_traversal(n->next->next->edge, subtr, swapingon, savedtrees, ntax,
                             nchar, numnodes, searchrec, diff);

}