source: branches/port5/PARSIMONY/AP_tree_nlen.cxx

Last change on this file was 6143, checked in by westram, 16 years ago
  • backport [6141] (parts changing code, but only strings and comments)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 39.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3// #include <malloc.h>
4#include <string.h>
5#include <iostream>
6#include <math.h>
7#include <arbdb.h>
8#include <arbdbt.h>
9//
10#include <awt_tree.hxx>
11#include <awt_seq_dna.hxx>
12#include "AP_buffer.hxx"
13#include "parsimony.hxx"
14#include "pars_debug.hxx"
15#include "ap_tree_nlen.hxx"
16// #include <aw_root.hxx>
17
18using namespace std;
19
20#define ap_assert(x) arb_assert(x)
21
22// ---------------------------------
23//      Section base operations:
24// ---------------------------------
25
26//  constructor/destructor
27//  dup
28//  check_update
29//  copy
30//  ostream&<<
31
32AP_tree_nlen::AP_tree_nlen(AP_tree_root *Tree_root)
33    : AP_tree(Tree_root)
34{
35    //    this->init();
36    kernighan = AP_NONE;
37    sequence  = NULL;
38
39    edge[0]  = edge[1] = edge[2] = NULL;
40    index[0] = index[1] = index[2] = 0;
41    distance = INT_MAX;
42
43    //    cout << "AP_tree_nlen-constructor\n";
44}
45
46AP_tree *AP_tree_nlen::dup(void)
47{
48    return (AP_tree *) new AP_tree_nlen(this->tree_root);
49}
50
51AP_UPDATE_FLAGS AP_tree_nlen::check_update(void)
52{
53    AP_UPDATE_FLAGS res = this->AP_tree::check_update();
54
55    if (res == AP_UPDATE_RELOADED) {
56        return AP_UPDATE_OK;
57    }
58
59    return res;
60}
61
62void AP_tree_nlen::copy(AP_tree_nlen *tree)
63{
64    // like = operator
65    // but copies sequence if is leaf
66
67    this->is_leaf = tree->is_leaf;
68    this->leftlen = tree->leftlen;
69    this->rightlen = tree->rightlen;
70    this->gb_node = tree->gb_node;
71
72    if(tree->name != NULL) {
73        this->name = strdup(tree->name);
74    }
75    else {
76        this->name = NULL;
77    }
78
79    if (is_leaf == GB_TRUE) {
80        if (tree->sequence) {
81            this->sequence = tree->sequence;
82        }
83        else {
84            cout << "empty sequence at leaf";
85            this->sequence = 0;
86        }
87    }
88}
89
90ostream& operator<<(ostream& out, const AP_tree_nlen& node)
91{
92    static int notTooDeep;
93
94    out << ' ';
95
96    if (&node==NULL) {
97        out << "NULL";
98    }
99    if (node.is_leaf) {
100        out << ((void *)&node) << '(' << node.name << ')';
101    }
102    else {
103        if (notTooDeep) {
104            out << ((void *)&node);
105            if (!node.father) out << " (ROOT)";
106        }
107        else {
108            notTooDeep = 1;
109
110            out << "NODE(" << ((void *)&node);
111
112            if (!node.father) {
113                out << " (ROOT)";
114            }
115            else {
116                out << ", father=" << node.father;
117            }
118
119            out << ", leftson=" << node.leftson
120                << ", rightson=" << node.rightson
121                << ", edge[0]=" << *(node.edge[0])
122                << ", edge[1]=" << *(node.edge[1])
123                << ", edge[2]=" << *(node.edge[2])
124                << ")";
125
126            notTooDeep = 0;
127        }
128    }
129
130    return out << ' ';
131}
132
133/********************************************
134
135Section Edge operations:
136
137    unusedEdge
138    edgeTo
139    nextEdge
140    unlinkAllEdges
141    destroyAllEdges
142
143********************************************/
144
145int AP_tree_nlen::unusedEdge() const
146{
147    int e;
148
149    for (e=0; e<3; e++) if (edge[e]==NULL) return e;
150
151    cout << "No unused edge found at" << *this << '\n';
152    return -1;
153}
154
155AP_tree_edge* AP_tree_nlen::edgeTo(const AP_tree_nlen *neighbour) const
156{
157    int e;
158
159    for (e=0; e<3; e++) {
160        if (edge[e]!=NULL && edge[e]->node[1-index[e]]==neighbour) {
161            return edge[e];
162        }
163    }
164    cout << "AP_tree_nlen::edgeTo: " << *this << "\nhas no edge to " << *neighbour << '\n';
165    ap_assert(0);
166    return NULL;
167}
168
169AP_tree_edge* AP_tree_nlen::nextEdge(const AP_tree_edge *thisEdge) const
170    // returns the next edge adjacent to the actual node
171    //
172    // if thisEdge == NULL then we return the "first" edge (edge[0])
173    // otherwise we return the next edge following 'thisEdge' in the array edge[]
174{
175    return edge[ thisEdge ? ((indexOf(thisEdge)+1) % 3) : 0 ];
176}
177
178void AP_tree_nlen::unlinkAllEdges(AP_tree_edge **edgePtr1, AP_tree_edge **edgePtr2, AP_tree_edge **edgePtr3)
179{
180    ap_assert(edge[0]!=NULL);
181    ap_assert(edge[1]!=NULL);
182    ap_assert(edge[2]!=NULL);
183
184    *edgePtr1 = edge[0]->unlink();
185    *edgePtr2 = edge[1]->unlink();
186    *edgePtr3 = edge[2]->unlink();
187}
188
189void AP_tree_nlen::linkAllEdges(AP_tree_edge *edge1, AP_tree_edge *edge2, AP_tree_edge *edge3)
190{
191    ap_assert(edge[0]==NULL);
192    ap_assert(edge[1]==NULL);
193    ap_assert(edge[2]==NULL);
194
195    edge1->relink(this,Father()->Father() ? Father() : Brother());
196    edge2->relink(this,Leftson());
197    edge3->relink(this,Rightson());
198}
199
200/********************************************
201
202Section Tree operations:
203
204    insert
205    remove
206    swap
207    set_root
208    move
209    costs
210
211********************************************/
212
213void AP_tree_nlen::insert(AP_tree *new_brother) {
214    //  inserts a node at the father-edge of new_brother
215
216    AP_tree      *pntr;
217    AP_tree_nlen *newBrother = dynamic_cast<AP_tree_nlen*>(new_brother);
218    ap_assert(new_brother);
219
220    AP_tree_edge *oldEdge;
221
222    ap_main->push_node(new_brother, STRUCTURE);
223
224    if (new_brother->father) {
225        ap_main->push_node(new_brother->father, BOTH);
226        for (pntr = new_brother->father->father; pntr; pntr = pntr->father) {
227            ap_main->push_node(pntr, SEQUENCE);
228        }
229
230        if (new_brother->father->father) {
231            oldEdge = newBrother->edgeTo(newBrother->Father())->unlink();
232            AP_tree::insert(new_brother);
233            oldEdge->relink(Father(),Father()->Father());
234        }
235        else { // insert to son of root
236            oldEdge = newBrother->edgeTo(newBrother->Brother())->unlink();
237            AP_tree::insert(new_brother);
238            oldEdge->relink(Father(),Father()->Brother());
239        }
240
241        new AP_tree_edge(this,Father());
242        new AP_tree_edge(Father(),newBrother);
243    }
244    else { // insert at root
245        AP_tree_nlen *lson = newBrother->Leftson();
246        AP_tree_nlen *rson = newBrother->Rightson();
247
248        ap_main->push_node(lson, STRUCTURE);
249        ap_main->push_node(rson, STRUCTURE);
250
251        oldEdge = lson->edgeTo(rson)->unlink();
252#if defined(DEBUG)
253        cout << "old Edge = " << oldEdge << '\n';
254#endif // DEBUG
255
256        AP_tree::insert(new_brother);
257
258        oldEdge->relink(this,newBrother);
259        new AP_tree_edge(newBrother,rson);
260        new AP_tree_edge(newBrother,lson);
261    }
262}
263
264void AP_tree_nlen::remove(void) {
265    // Removes the node and its father from the tree:
266    //
267    //       grandpa                grandpa
268    //           /                    /
269    //          /                    /
270    //    father        =>        brother
271    //       /     \                                            .
272    //      /       \                                           .
273    //   this       brother
274    //
275    // One of the edges is relinked between brother and grandpa.
276    // The other two edges are lost. This is not very relevant in respect to
277    // memory usage because very few remove()s are really performed - the majority
278    // is undone by a pop().
279    // In the last case the two unlinked edges will be re-used, cause their
280    // memory location was stored in the tree-stack.
281
282    AP_tree      *pntr;
283    AP_tree_edge *oldEdge;
284    AP_tree_nlen *oldBrother = Brother();
285
286    ap_assert(father);
287
288    ap_main->push_node(this, STRUCTURE);
289    ap_main->push_node(brother(), STRUCTURE);
290
291    for (pntr = father->father; pntr; pntr = pntr->father) {
292        ap_main->push_node(pntr, SEQUENCE);
293    }
294
295    if (father->father) {
296        AP_tree_nlen *grandPa = Father()->Father();
297
298        ap_main->push_node(father, BOTH);
299        ap_main->push_node(grandPa, STRUCTURE);
300
301        edgeTo(Father())->unlink();
302        Father()->edgeTo(oldBrother)->unlink();
303
304        if (grandPa->father) {
305            oldEdge = Father()->edgeTo(grandPa)->unlink();
306            AP_tree::remove();
307            oldEdge->relink(oldBrother,grandPa);
308        }
309        else { // remove grandson of root
310            AP_tree_nlen *uncle = Father()->Brother();
311            ap_main->push_node(uncle,STRUCTURE);
312
313            oldEdge = Father()->edgeTo(uncle)->unlink();
314            AP_tree::remove();
315            oldEdge->relink(oldBrother,uncle);
316        }
317    }
318    else { // remove son of root
319        AP_tree_nlen *lson = Brother()->Leftson();
320        AP_tree_nlen *rson = Brother()->Rightson();
321
322        ap_assert(lson && rson);
323       
324        ap_main->push_node(lson,STRUCTURE);
325        ap_main->push_node(rson,STRUCTURE);
326        ap_main->push_node(father, ROOT);
327
328        ap_main->set_tree_root(oldBrother);
329
330        //  delete edgeTo(oldBrother);
331        oldBrother->edgeTo(lson)->unlink();
332        //  delete oldBrother->edgeTo(lson);
333        oldEdge = oldBrother->edgeTo(rson)->unlink();
334        AP_tree::remove();
335        oldEdge->relink(lson,rson);
336    }
337}
338
339void AP_tree_nlen::swap_assymetric(AP_TREE_SIDE mode) {
340    // mode AP_LEFT exchanges leftson with brother
341    // mode AP_RIGHT exchanges rightson with brother
342
343    ap_assert(!is_leaf);                            // cannot swap leafs
344    ap_assert(father);                              // cannot swap root (has no brother)
345    ap_assert(mode == AP_LEFT || mode == AP_RIGHT); // illegal mode
346
347    AP_tree_nlen *oldBrother = Brother();
348    AP_tree_nlen *movedSon   = mode == AP_LEFT ? Leftson() : Rightson();
349
350    if (!father->father) {
351        //son of root case
352        //take leftson of brother to exchange with
353
354        if (!oldBrother->is_leaf) { // swap needed ?
355            AP_tree_nlen *nephew = oldBrother->Leftson();
356
357            ap_main->push_node(this, BOTH);
358            ap_main->push_node(movedSon,STRUCTURE);
359            ap_main->push_node(father, SEQUENCE);
360            ap_main->push_node(nephew, STRUCTURE);
361            ap_main->push_node(oldBrother, BOTH);
362
363            AP_tree_edge *edge1 = edgeTo(movedSon)->unlink();
364            AP_tree_edge *edge2 = oldBrother->edgeTo(nephew)->unlink();
365
366            AP_tree::swap_assymetric(mode);
367
368            edge1->relink(this,nephew);
369            edge2->relink(oldBrother,movedSon);
370        }
371    }
372    else {
373        ap_main->push_node(this, BOTH);
374        ap_main->push_node(father, BOTH);
375        ap_main->push_node(oldBrother, STRUCTURE);
376        ap_main->push_node(movedSon,STRUCTURE);
377
378        // from father to root buffer all sequences
379
380        for (AP_tree *pntr = father->father; pntr ; pntr = pntr->father) {
381            ap_main->push_node(pntr, SEQUENCE);
382        }
383
384        AP_tree_edge *edge1 = edgeTo(movedSon)->unlink();
385        AP_tree_edge *edge2 = Father()->edgeTo(oldBrother)->unlink();
386
387        AP_tree::swap_assymetric(mode);
388
389        edge1->relink(this,oldBrother);
390        edge2->relink(Father(),movedSon);
391    }
392}
393
394
395/*-----------------------
396  set_root
397  -----------------------*/
398void AP_tree_nlen::set_root() {
399    if (!father || !father->father) return; // already root
400
401    // from this to root buffer the nodes
402    ap_main->push_node(this , STRUCTURE);
403   
404    AP_tree *old_brother = 0;
405    AP_tree *old_root;
406    {
407        AP_tree *pntr;
408        for (pntr = father; pntr->father; pntr = pntr->father) {
409            ap_main->push_node(pntr, BOTH);
410            old_brother = pntr;
411        }
412        old_root = pntr;
413    }
414
415    if (old_brother) {
416        old_brother = old_brother->brother();
417        ap_main->push_node(old_brother , STRUCTURE);
418    }
419
420    ap_main->push_node(old_root, ROOT);
421    AP_tree::set_root();
422}
423
424/*-----------------------
425  move
426  -----------------------*/
427GB_INLINE void sort(AP_tree_edge **e1, AP_tree_edge **e2) {
428    if ((*e1)->Age() > (*e2)->Age()) {
429        AP_tree_edge *tmp = *e1;
430        *e1 = *e2;
431        *e2 = tmp;
432    }
433}
434
435GB_INLINE void sort(AP_tree_edge **e1, AP_tree_edge **e2, AP_tree_edge **e3) {
436    sort(e1,e2);
437    sort(e2,e3);
438    sort(e1,e2);
439}
440
441void AP_tree_nlen::moveTo(AP_tree *new_brother,AP_FLOAT rel_pos) {
442    ap_assert(father);
443    ap_assert(new_brother->father);
444
445    AP_tree *pntr;
446
447    ap_main->push_node(this , STRUCTURE);
448    ap_main->push_node(brother(), STRUCTURE);
449
450    if (father->father) {
451        AP_tree *grandpa = father->father;
452
453        ap_main->push_node(father , BOTH);
454
455        if (grandpa->father) {
456            ap_main->push_node(grandpa, BOTH);
457            for  (pntr = grandpa->father; pntr; pntr = pntr->father) {
458                ap_main->push_node( pntr, SEQUENCE);
459            }
460        }
461        else { // grandson of root
462            ap_main->push_node(grandpa, ROOT);
463            ap_main->push_node(father->brother(), STRUCTURE);
464        }
465    }
466    else { // son of root
467        ap_main->push_node(father , ROOT);
468
469        if (!brother()->is_leaf) {
470            ap_main->push_node(brother()->leftson, STRUCTURE);
471            ap_main->push_node(brother()->rightson, STRUCTURE);
472        }
473    }
474
475    ap_main->push_node(new_brother , STRUCTURE);
476    if (new_brother->father) {
477        if (new_brother->father->father) {
478            ap_main->push_node(new_brother->father , BOTH);
479        }
480        else { // move to son of root
481            ap_main->push_node(new_brother->father , BOTH);
482            ap_main->push_node(new_brother->brother(), STRUCTURE);
483        }
484
485        for  (pntr = new_brother->father->father; pntr; pntr = pntr->father) {
486            ap_main->push_node( pntr, SEQUENCE);
487        }
488    }
489
490    AP_tree_nlen *thisFather        = Father();
491    AP_tree_nlen *newBrother        = (AP_tree_nlen*)new_brother;
492    AP_tree_nlen *grandFather       = thisFather->Father();
493    AP_tree_nlen *oldBrother        = Brother();
494    AP_tree_nlen *newBrothersFather = newBrother->Father();
495    int           edgesChange       = ! (father==new_brother || new_brother->father==this->father);
496    AP_tree_edge *e1,*e2,*e3,*e4;
497
498    if (edgesChange) {
499        if (thisFather==newBrothersFather->Father()) { // son -> son of brother
500            if (grandFather) {
501                if(grandFather->Father()) {
502                    //          cout << "son -> son of brother\n";
503
504                    thisFather->unlinkAllEdges(&e1,&e2,&e3);
505                    e4 = newBrother->edgeTo(oldBrother)->unlink();
506
507                    AP_tree::moveTo(new_brother,rel_pos);
508
509                    sort(&e1,&e2,&e3);              // sort by age (e1==oldest edge)
510                    e1->relink(oldBrother,grandFather);     // use oldest edge at remove position
511                    thisFather->linkAllEdges(e2,e3,e4);
512                }
513                else { // grandson of root -> son of brother
514                    AP_tree_nlen *uncle = thisFather->Brother();
515
516                    thisFather->unlinkAllEdges(&e1,&e2,&e3);
517                    e4 = newBrother->edgeTo(oldBrother)->unlink();
518
519                    AP_tree::moveTo(new_brother,rel_pos);
520
521                    sort(&e1,&e2,&e3);  // sort by age (e1==oldest edge)
522                    e1->relink(oldBrother,uncle);
523                    thisFather->linkAllEdges(e2,e3,e4);
524                }
525            }
526            else { // son of root -> grandson of root
527                oldBrother->unlinkAllEdges(&e1,&e2,&e3);
528                AP_tree::moveTo(new_brother,rel_pos);
529                thisFather->linkAllEdges(e1,e2,e3);
530            }
531        }
532        else if (grandFather==newBrothersFather) { // son -> brother of father
533            if (grandFather->father) {
534                thisFather->unlinkAllEdges(&e1,&e2,&e3);
535                e4 = grandFather->edgeTo(newBrother)->unlink();
536
537                AP_tree::moveTo(new_brother,rel_pos);
538
539                sort(&e1,&e2,&e3);
540                e1->relink(oldBrother,grandFather);
541                thisFather->linkAllEdges(e2,e3,e4);
542            }
543            else { // no edges change if we move grandson of root -> son of root
544                AP_tree::moveTo(new_brother,rel_pos);
545            }
546        }
547        else {
548            //  now we are sure, the minimal distance
549            //  between 'this' and 'newBrother' is 4 edges
550            //  or if the root-edge is between them, the
551            //  minimal distance is 3 edges
552
553            if (!grandFather) { // son of root
554                oldBrother->unlinkAllEdges(&e1,&e2,&e3);
555                e4 = newBrother->edgeTo(newBrothersFather)->unlink();
556
557                AP_tree::moveTo(new_brother,rel_pos);
558
559                sort(&e1,&e2,&e3);
560                e1->relink(oldBrother->Leftson(),oldBrother->Rightson()); // new root-edge
561                thisFather->linkAllEdges(e2,e3,e4);     // old root
562            }
563            else if (!grandFather->Father()) { // grandson of root
564                if (newBrothersFather->Father()->Father()==NULL) { // grandson of root -> grandson of root
565                    thisFather->unlinkAllEdges(&e1,&e2,&e3);
566                    e4 = newBrother->edgeTo(newBrothersFather)->unlink();
567
568                    AP_tree::moveTo(new_brother,rel_pos);
569
570                    sort(&e1,&e2,&e3);
571                    e1->relink(oldBrother,newBrothersFather);   // new root-edge
572                    thisFather->linkAllEdges(e2,e3,e4);
573                }
574                else {
575                    AP_tree_nlen *uncle = thisFather->Brother();
576
577                    thisFather->unlinkAllEdges(&e1,&e2,&e3);
578                    e4 = newBrother->edgeTo(newBrothersFather)->unlink();
579
580                    AP_tree::moveTo(new_brother,rel_pos);
581
582                    sort(&e1,&e2,&e3);
583                    e1->relink(oldBrother,uncle);
584                    thisFather->linkAllEdges(e2,e3,e4);
585                }
586            }
587            else {
588                if (newBrothersFather->Father()==NULL) { // move to son of root
589                    AP_tree_nlen *newBrothersBrother = newBrother->Brother();
590
591                    thisFather->unlinkAllEdges(&e1,&e2,&e3);
592                    e4 = newBrother->edgeTo(newBrothersBrother)->unlink();
593
594                    AP_tree::moveTo(new_brother,rel_pos);
595
596                    sort(&e1,&e2,&e3);
597                    e1->relink(oldBrother,grandFather);
598                    thisFather->linkAllEdges(e2,e3,e4);
599                }
600                else { // simple independent move
601                    thisFather->unlinkAllEdges(&e1,&e2,&e3);
602                    e4 = newBrother->edgeTo(newBrothersFather)->unlink();
603
604                    AP_tree::moveTo(new_brother,rel_pos);
605
606                    sort(&e1,&e2,&e3);
607                    e1->relink(oldBrother,grandFather);
608                    thisFather->linkAllEdges(e2,e3,e4);
609                }
610            }
611        }
612    }
613    else { // edgesChange==0
614        AP_tree::moveTo(new_brother,rel_pos);
615    }
616}
617
618/*-----------------------
619  costs
620  -----------------------*/
621
622AP_FLOAT AP_tree_nlen::costs(void) { /* cost of a tree (number of changes ..) */
623    if (! this->tree_root->sequence_template) return 0.0;
624    this->parsimony_rek();
625    return (AP_FLOAT)this->mutation_rate;
626}
627
628/*******************************************
629
630Section Buffer Operations:
631
632    unhash_sequence()   // only deletes an existing parsimony sequence
633    push()
634    pop()
635    clear()
636
637********************************************/
638
639void AP_tree_nlen::unhash_sequence() {
640    //removes the current sequence
641    //(not leaf)
642
643    if (sequence != 0) {
644        if (!is_leaf) {
645            sequence->is_set_flag = AP_FALSE;
646        }
647    }
648
649    return;
650}
651
652AP_BOOL AP_tree_nlen::clear(unsigned long datum, unsigned long user_buffer_count) {
653    // returns AP_TRUE if the first element is removed
654    // AP_FALSE if it is copied into the previous level
655    // according if user_buffer is greater than datum
656
657    //    cout << "clear\n";
658
659    AP_tree_buffer * buff;
660    AP_BOOL         result;
661
662    if (!this->stack_level == datum)
663    {
664        AW_ERROR("AP_tree_nlen::clear: internal control number check failed");
665        return AP_FALSE;
666    }
667
668    buff = stack.pop();
669
670    if (buff->controll == datum - 1 || user_buffer_count >= datum) {
671        //previous node is buffered
672
673        if (buff->mode & SEQUENCE) delete buff->sequence;
674
675        stack_level = buff->controll;
676        delete  buff;
677        result      = AP_TRUE;
678    }
679    else {
680        stack_level = datum - 1;
681        stack.push(buff);
682        result      = AP_FALSE;
683    }
684
685    return result;
686}
687
688
689AP_BOOL AP_tree_nlen::push(AP_STACK_MODE mode, unsigned long datum) {
690    // according to mode
691    // tree_structure / sequence is buffered in the node
692
693    AP_tree_buffer *new_buff;
694    AP_BOOL ret;
695
696    if (is_leaf && !(STRUCTURE & mode)) return AP_FALSE;    // tips push only structure
697
698    if (this->stack_level == datum) {
699        AP_tree_buffer *last_buffer = stack.get_first();
700        if (sequence &&(mode & SEQUENCE)) sequence->is_set_flag = AP_FALSE;
701        if (0 == (mode & ~last_buffer->mode)) { // already buffered
702            return AP_FALSE;
703        }
704        new_buff = last_buffer;
705        ret = AP_FALSE;
706    }
707    else {
708        new_buff           = new AP_tree_buffer;
709        new_buff->count    = 1;
710        new_buff->controll = stack_level;
711        new_buff->mode     = NOTHING;
712
713        stack.push(new_buff);
714        this->stack_level = datum;
715        ret = AP_TRUE;
716    }
717
718    if ( (mode & STRUCTURE) && !(new_buff->mode & STRUCTURE) ) {
719        //  cout << "push structure " << *this << '\n';
720        new_buff->father   = father;
721        new_buff->leftson  = leftson;
722        new_buff->rightson = rightson;
723        new_buff->leftlen  = leftlen;
724        new_buff->rightlen = rightlen;
725        new_buff->gb_node  = gb_node;
726        new_buff->distance = distance;
727
728        for (int e=0; e<3; e++) {
729            new_buff->edge[e]      = edge[e];
730            new_buff->edgeIndex[e] = index[e];
731            if (edge[e]) {
732                new_buff->edgeData[e]  = edge[e]->data;
733            }
734        }
735    }
736
737    if ( (mode & SEQUENCE) && !(new_buff->mode & SEQUENCE) ) {
738        if (sequence) {
739            new_buff->sequence      = sequence;
740            new_buff->mutation_rate = mutation_rate;
741            mutation_rate           = 0.0;
742            sequence                = 0;
743        }
744        else {
745            new_buff->sequence = 0;
746            AW_ERROR("Sequence not found %s",this->name);
747        }
748    }
749
750    new_buff->mode = (AP_STACK_MODE)(new_buff->mode|mode);
751
752    return ret;
753}
754
755void AP_tree_nlen::pop(unsigned long datum) { /* pop old tree costs */
756    AP_tree_buffer *buff;
757
758    if (stack_level != datum) {
759        AW_ERROR("AP_tree_nlen::pop(): Error in Node Stack");
760    }
761
762    buff = stack.pop();
763
764    AP_STACK_MODE   mode = buff->mode;
765
766    if (mode&STRUCTURE) {
767        //  cout << "pop structure " << this << '\n';
768
769        father   = buff->father;
770        leftson  = buff->leftson;
771        rightson = buff->rightson;
772        leftlen  = buff->leftlen;
773        rightlen = buff->rightlen;
774        gb_node  = buff->gb_node;
775        distance = buff->distance;
776
777        for (int e=0; e<3; e++) {
778            edge[e] = buff->edge[e];
779
780            if (edge[e]) {
781                index[e] = buff->edgeIndex[e];
782
783                edge[e]->index[index[e]] = e;
784                edge[e]->node[index[e]]  = this;
785                edge[e]->data            = buff->edgeData[e];
786            }
787        }
788    }
789
790    if (mode&SEQUENCE) {
791        if (sequence) delete sequence;
792
793        sequence      = buff->sequence;
794        mutation_rate = buff->mutation_rate;
795    }
796
797    if (ROOT==mode) {
798        //  cout << "root popped:" << this << "\n";
799        ap_main->set_tree_root(this);
800    }
801
802    stack_level = buff->controll;
803    delete buff;
804}
805
806/********************************************************
807Section Parsimony:
808********************************************************/
809
810void AP_tree_nlen::parsimony_rek(void)
811{
812    if (sequence && sequence->is_set_flag) return;
813
814    if (is_leaf) {
815        sequence->is_set_flag = AP_TRUE;
816        return;
817    }
818
819    if (!Leftson()->sequence || !Leftson()->sequence->is_set_flag  ) Leftson()->parsimony_rek();
820    if (!Rightson()->sequence|| !Rightson()->sequence->is_set_flag ) Rightson()->parsimony_rek();
821
822    if (!Leftson()->sequence->is_set_flag || !Rightson()->sequence->is_set_flag) {
823        AW_ERROR("AP_tree_nlen::parsimony_rek:  Cannot set sequence");
824        return;
825    }
826
827    if (sequence == 0) sequence = tree_root->sequence_template->dup();
828
829    AP_FLOAT mutations_for_combine = sequence->combine(Leftson()->sequence, Rightson()->sequence);
830    mutation_rate                  = Leftson()->mutation_rate + Rightson()->mutation_rate + mutations_for_combine;
831
832#if defined(DEBUG) && 0
833    printf("mutation-rates: left=%f right=%f combine=%f overall=%f %s\n",
834           Leftson()->mutation_rate, rightson->mutation_rate, mutations_for_combine, mutation_rate,
835           fullname());
836#endif // DEBUG
837
838    sequence->is_set_flag = AP_TRUE;
839}
840
841/********************************************************
842Section NNI
843********************************************************/
844
845AP_FLOAT AP_tree_nlen::nn_interchange_rek(AP_BOOL openclosestatus, int &Abort,int deep, AP_BL_MODE mode, GB_BOOL skip_hidden)
846{
847    if (!father)
848    {
849        return rootEdge()->nni_rek(openclosestatus,Abort,deep,skip_hidden,mode);
850    }
851
852    if (!father->father)
853    {
854        AP_tree_edge *e = rootEdge();
855
856        return e->nni_rek(openclosestatus,Abort,deep,skip_hidden,mode,e->otherNode(this));
857    }
858
859    return edgeTo(Father())->nni_rek(openclosestatus,Abort,deep,skip_hidden,mode,Father());
860}
861
862
863
864/********************************************************
865Section Kernighan-Lin
866********************************************************/
867
868void            AP_tree_nlen::
869kernighan_rek(int rek_deep, int *rek_2_width, int rek_2_width_max, const int rek_deep_max,
870              double(*funktion) (double, double *, int), double *param_liste, int param_anz,
871              AP_FLOAT pars_best, AP_FLOAT pars_start, AP_FLOAT pars_prev,
872              AP_KL_FLAG rek_width_type, AP_BOOL *abort_flag)
873{
874    //
875    // rek_deep Rekursionstiefe
876    // rek_2_width Verzweigungsgrad
877    // neg_counter zaehler fuer die Aeste in denen Kerninghan Lin schon angewendet wurde
878    // funktino Funktion fuer den dynamischen Schwellwert
879    // pars_ Verschiedene Parsimonywerte
880
881    AP_FLOAT help, pars[8];
882    //acht parsimony werte
883    AP_tree_nlen * pars_refpntr[8];
884    //zeiger auf die naechsten Aeste
885    int             help_ref, pars_ref[8];
886    //referenzen auf die vertauschten parsimonies
887    static AP_TREE_SIDE pars_side_ref[8];
888    //linker oder rechter ast
889    int             i, t, bubblesort_change = 0;
890    //
891    int             rek_width, rek_width_static = 0, rek_width_dynamic = 0;
892    AP_FLOAT        schwellwert = funktion(rek_deep, param_liste, param_anz) + pars_start;
893
894    //parameterausgabe
895
896#if 0
897    cout << "DEEP  " << rek_deep << "   ";
898    cout << "  maxdeep " << rek_deep_max << " suche " << rek_width_type << " abbruch " << *abort_flag;
899    cout << "\npbest    " << pars_best << " pstart  " << pars_start << " pprev  " << pars_prev << "\nParam : ";
900    for (i = 0; i < param_anz; i++)
901        cout << i << " : " << param_liste[i] << "    ";
902    cout << "\nSchwellwert  " << schwellwert << "\n";
903    cout.flush();
904#endif
905    if (rek_deep >= rek_deep_max) return;
906    if (is_leaf == GB_TRUE)       return;
907    if (*abort_flag == AP_TRUE)   return;
908
909    //
910    //Referenzzeiger auf die vier Kanten und
911    // zwei swapmoeglichkeiten initialisieren
912    //
913    AP_tree *this_brother = this->brother();
914    if (rek_deep == 0) {
915        for (i = 0; i < 8; i+=2) {
916            pars_side_ref[i] = AP_LEFT;
917            pars_side_ref[i+1] = AP_RIGHT;
918        }
919        pars_refpntr[0] = pars_refpntr[1] = static_cast<AP_tree_nlen *>(this);
920        pars_refpntr[2] = pars_refpntr[3] = 0;
921        pars_refpntr[4] = pars_refpntr[5] = 0;
922        pars_refpntr[6] = pars_refpntr[7] = 0;
923        //      cout << "NEW REKURSION\n\n";
924    }else{
925        pars_refpntr[0] = pars_refpntr[1] = static_cast<AP_tree_nlen *>(this->leftson);
926        pars_refpntr[2] = pars_refpntr[3] = static_cast<AP_tree_nlen *>(this->rightson);
927        if (father->father != 0) {
928            //Referenzzeiger falls nicht an der Wurzel
929            pars_refpntr[4] = pars_refpntr[5] = static_cast<AP_tree_nlen *>(this->father);
930            pars_refpntr[6] = pars_refpntr[7] = static_cast<AP_tree_nlen *>(this_brother);
931        } else {
932            //an der Wurzel nehme linken und rechten Sohns des Bruders
933            if (this->brother()->is_leaf == GB_FALSE) {
934                pars_refpntr[4] = pars_refpntr[5] = static_cast<AP_tree_nlen *>(this_brother->leftson);
935                pars_refpntr[6] = pars_refpntr[7] = static_cast<AP_tree_nlen *>(this_brother->rightson);
936            } else {
937                pars_refpntr[4] = pars_refpntr[5] = 0;
938                pars_refpntr[6] = pars_refpntr[7] = 0;
939            }
940        }
941    }
942
943
944    if (!father) return;        // no kl at root
945
946    //
947    //parsimony werte bestimmen
948    //
949
950    // Wurzel setzen
951
952    ap_main->push();
953    this->set_root();
954    (*ap_main->tree_root)->costs();
955
956    int             visited_subtrees = 0;
957    int     better_subtrees = 0;
958    for (i = 0; i < 8; i++) {
959        pars_ref[i] = i;
960        pars[i] = -1;
961
962        if (!pars_refpntr[i])   continue;
963        if (pars_refpntr[i]->is_leaf) continue;
964        if (!pars_refpntr[i]->kernighan == AP_NONE) continue;
965        if (pars_refpntr[i]->gr.hidden) continue;
966        if (pars_refpntr[i]->father->gr.hidden) continue;
967
968        //nur wenn kein Blatt ist
969        ap_main->push();
970        pars_refpntr[i]->swap_assymetric(pars_side_ref[i]);
971        pars[i] = (*ap_main->tree_root)->costs();
972        if (pars[i] < pars_best) {
973            better_subtrees++;
974            pars_best      = pars[i];
975            rek_width_type = AP_BETTER;
976        }
977        if (pars[i] < schwellwert) {
978            rek_width_dynamic++;
979        }
980        ap_main->pop();
981        visited_subtrees ++;
982
983    }
984    //Bubblesort, in pars[0] steht kleinstes element
985    //
986    //!!CAUTION ! !The original parsimonies will be exchanged
987
988
989    for (i=7,t=0;t<i;t++) {
990        if (pars[t] <0) {
991            pars[t]     = pars[i];
992            pars_ref[t] = i;
993            t--;
994            i--;
995        }
996    }
997
998    bubblesort_change = 0;
999    for (t = visited_subtrees - 1; t > 0; t--) {
1000        for (i = 0; i < t; i++) {
1001            if (pars[i] > pars[i+1] ) {
1002                bubblesort_change = 1;
1003                help_ref          = pars_ref[i];
1004                pars_ref[i]       = pars_ref[i + 1];
1005                pars_ref[i + 1]   = help_ref;
1006                help              = pars[i];
1007                pars[i]           = pars[i + 1];
1008                pars[i + 1]       = help;
1009            }
1010        }
1011        if (bubblesort_change == 0)
1012            break;
1013    }
1014
1015    display_out(pars, visited_subtrees, pars_prev, pars_start, rek_deep);
1016    //Darstellen
1017
1018
1019    //  for (i=0;i<visited_subtrees;i++)  cout << "  " << pars[i];
1020
1021
1022    if (rek_deep < rek_2_width_max) rek_width_static = rek_2_width[rek_deep];
1023    else rek_width_static                            = 1;
1024
1025    rek_width = visited_subtrees;
1026    if (rek_width_type == AP_BETTER) {
1027        rek_width =  better_subtrees;
1028    }
1029    else {
1030        if (rek_width_type & AP_STATIC) {
1031            if (rek_width> rek_width_static) rek_width = rek_width_static;
1032        }
1033        if (rek_width_type & AP_DYNAMIK) {
1034            if (rek_width> rek_width_dynamic) rek_width = rek_width_dynamic;
1035        }else   if (!(rek_width_type & AP_STATIC)) {
1036            if (rek_width> 1) rek_width = 1;
1037        }
1038
1039    }
1040
1041    if (rek_width > visited_subtrees)   rek_width = visited_subtrees;
1042
1043    //  cout << "   rek_width:  " << rek_width << "\n";
1044    //  cout.flush();
1045
1046    for (i=0;i < rek_width; i++) {
1047        ap_main->push();
1048        pars_refpntr[pars_ref[i]]->kernighan = pars_side_ref[pars_ref[i]];
1049        //Markieren
1050        pars_refpntr[pars_ref[i]]->swap_assymetric(pars_side_ref[pars_ref[i]]);
1051        //vertausche seite
1052        (*ap_main->tree_root)->parsimony_rek();
1053        switch (rek_width_type) {
1054            case AP_BETTER:{
1055                //starte kerninghan_rek mit rekursionstiefe 3, statisch
1056                AP_BOOL flag = AP_FALSE;
1057                cout << "found better !\n";
1058                pars_refpntr[pars_ref[i]]->kernighan_rek(rek_deep + 1, rek_2_width,
1059                                                         rek_2_width_max, rek_deep_max + 4,
1060                                                         funktion, param_liste, param_anz,
1061                                                         pars_best, pars_start, pars[i],
1062                                                         AP_STATIC, &flag);
1063                *abort_flag = AP_TRUE;
1064                break;
1065            }
1066            default:
1067                pars_refpntr[pars_ref[i]]->kernighan_rek(rek_deep + 1, rek_2_width,
1068                                                         rek_2_width_max, rek_deep_max,
1069                                                         funktion, param_liste, param_anz,
1070                                                         pars_best, pars_start, pars[i],
1071                                                         rek_width_type, abort_flag);
1072                break;
1073        }
1074        pars_refpntr[pars_ref[i]]->kernighan = AP_NONE;
1075        //Demarkieren
1076        if (*abort_flag == AP_TRUE) {
1077            cout << "   parsimony:  " << pars_best << "took: " << i <<"\n";
1078            for (i=0;i<visited_subtrees;i++)  cout << "  " << pars[i];
1079            cout << "\n";
1080            if (!rek_deep){
1081                cout << "NEW RECURSION\n\n";
1082            }
1083            cout.flush();
1084
1085            ap_main->clear();
1086            break;
1087        } else {
1088            ap_main->pop();
1089        }
1090    }
1091    if (*abort_flag == AP_TRUE) {       // pop/clear wegen set_root
1092        ap_main->clear();
1093    } else {
1094        ap_main->pop();
1095    }
1096    return;
1097}
1098
1099/*************************************************************************
1100Section Crossover List (Funktionen die die crossover liste aufbauen):
1101
1102    createListRekUp
1103    createListRekSide
1104    createList
1105
1106**************************************************************************/
1107
1108#if 0
1109
1110void addToList(AP_CO_LIST *list,int *number,AP_tree_nlen *pntr,CO_LISTEL& wert0,CO_LISTEL& wert1) {
1111    if (wert0.isLeaf == AP_TRUE) {
1112        list[*number].leaf0 = wert0.refLeaf;
1113        list[*number].node0 = -10;
1114    } else {
1115        list[*number].leaf0 = 0;
1116        list[*number].node0 = wert0.refNode;
1117    }
1118    if (wert1.isLeaf == AP_TRUE) {
1119        list[*number].leaf1 = wert1.refLeaf;
1120        list[*number].node1 = -1;
1121    } else {
1122        list[*number].leaf1 = 0;
1123        list[*number].node1 = wert1.refNode;
1124    }
1125    list[*number].pntr = pntr;
1126    return;
1127}
1128
1129void AP_tree_nlen::createListRekUp(AP_CO_LIST *list,int *cn) {
1130    if (this->is_leaf == AP_TRUE) {
1131        refUp.init    = AP_TRUE;
1132        refUp.isLeaf  = AP_TRUE;
1133        refUp.refLeaf = gb_node;
1134        return;
1135    }
1136    if (refUp.init == AP_FALSE) {
1137        if (leftson->refUp.init == AP_FALSE) leftson->createListRekUp(list,cn);
1138        if (rightson->refUp.init == AP_FALSE) rightson->createListRekUp(list,cn);
1139
1140        refUp.init    = AP_TRUE;
1141        refUp.isLeaf  = AP_FALSE;
1142        refUp.refNode = *cn;
1143        (*cn)++;
1144
1145
1146        addToList(list,cn,this,leftson->refUp,rightson->refUp);
1147        if (father == 0) { // at root
1148            refRight.init = rightson->refUp.init;
1149            if ((refRight.isLeaf = rightson->refUp.isLeaf) == AP_TRUE) {
1150                refRight.refLeaf = rightson->refUp.refLeaf;
1151            }
1152            else {
1153                refRight.refNode = rightson->refUp.refNode;
1154            }
1155
1156            refLeft.init = leftson->refUp.init;
1157            if ((refLeft.isLeaf = leftson->refUp.isLeaf) == AP_TRUE) {
1158                refLeft.refLeaf = leftson->refUp.refLeaf;
1159            }
1160            else {
1161                refLeft.refNode = leftson->refUp.refNode;
1162            }
1163        }
1164    }
1165    return;
1166}
1167
1168void AP_tree_nlen::createListRekSide(AP_CO_LIST *list,int *cn) {
1169    //
1170    // has to be called after createListRekUp !!
1171    if (refRight.init == AP_FALSE) {
1172        refRight.init    = AP_TRUE;
1173        refRight.isLeaf  = AP_FALSE;
1174        refRight.refNode = *cn;
1175        (*cn)++;
1176
1177        if (father->leftson == this) {
1178            if (father->refLeft.init == AP_FALSE) father->createListRekSide(list,cn);
1179            addToList(list,cn,this,leftson->refUp,father->refLeft);
1180        } else {
1181            if (father->refRight.init ==  AP_FALSE) father->createListRekSide(list,cn);
1182            addToList(list,cn,this,leftson->refUp,father->refRight);
1183        }
1184    }
1185    if (refLeft.init == AP_FALSE) {
1186        refLeft.init    = AP_TRUE;
1187        refLeft.isLeaf  = AP_FALSE;
1188        refLeft.refNode = *cn;
1189        (*cn)++;
1190        if (father->leftson == this) {
1191            if (father->refLeft.init == AP_FALSE) father->createListRekSide(list,cn);
1192            addToList(list,cn,this,rightson->refUp,father->refLeft);
1193        } else {
1194            if (father->refRight.init == AP_FALSE) father->createListRekSide(list,cn);
1195            addToList(list,cn,this,rightson->refUp,father->refRight);
1196        }
1197    }
1198    return;
1199}
1200
1201
1202AP_CO_LIST * AP_tree_nlen::createList(int *size)
1203{
1204    // returns an list with all
1205    // tree combinations
1206    AP_CO_LIST *list;
1207    int number = 0;
1208    if (father !=0) {
1209        AW_ERROR("AP_tree_nlen::createList may be called with damaged tree");
1210        return 0;
1211    }
1212    this->test_tree_rek();
1213    // 3*knotenvisited_subtrees +1 platz reservieren
1214    list = (AP_CO_LIST *) calloc((gr.node_sum-gr.leaf_sum)*3+1,sizeof(AP_CO_LIST));
1215    createListRekUp(list,&number);
1216    createListRekSide(list,&number);
1217    *size = number;
1218    return list;
1219}
1220
1221#endif
1222
1223/*************************************************************************
1224Section Misc stuff:
1225
1226    sortByName
1227    test
1228    fullname
1229
1230**************************************************************************/
1231
1232const char* AP_tree_nlen::sortByName()
1233{
1234    if (name) return name;  // leaves
1235
1236    const char *n1 = Leftson()->sortByName();
1237    const char *n2 = Rightson()->sortByName();
1238
1239    if (strcmp(n1,n2)<0) return n1;
1240
1241    AP_tree::swap_sons();
1242
1243    return n2;
1244}
1245
1246int AP_tree_nlen::test(void) const
1247{
1248    int edges = 0;
1249
1250    for (int e=0; e<3; e++) if (edge[e]!=NULL) edges++;
1251
1252    if (!sequence) cout << "Node" << *this << "has no sequence\n";
1253
1254    if (father) {
1255        if (father->father == (AP_tree *)this) {
1256            cout << "Ooops! I am my own grandfather! How is this possible?\n" <<
1257                *this << '\n' <<
1258                *Father() << '\n';
1259        }
1260
1261        if (is_leaf) {
1262            if (edges!=1) cout << "Leaf-Node" << *this << "has" << edges << " edges\n";
1263        }
1264        else {
1265            if (edges!=3) cout << "Inner-Node" << *this << "has" << edges << " edges\n";
1266        }
1267
1268        int e;
1269
1270        for (e=0; e<3; e++) {
1271            if (edge[e]) {
1272                if (edge[e]->isConnectedTo(this)) {
1273                    AP_tree_nlen *neighbour = edge[e]->otherNode(this);
1274
1275                    if ( ! (neighbour==father || neighbour==leftson || neighbour==rightson)) {
1276                        if (father->father==NULL) {
1277                            if (!(father->leftson==neighbour || father->rightson==neighbour)) {
1278                                cout << "Neighbour is not brother (at root)\n";
1279                            }
1280                        }
1281                        else {
1282                            cout << "Edge " << edge[e] << " connects the nodes"
1283                                 << *this << "and" << *(edge[e]->otherNode(this))
1284                                 << "(they are not neighbours)\n";
1285                        }
1286                    }
1287                }
1288                else {
1289                    cout << "Node" << *this
1290                         << "is connected to wrong edge"
1291                         << edge[e] << '\n';
1292                }
1293            }
1294        }
1295    }
1296    else {
1297        if (edges) {
1298            cout << "Root" << *this << "has edges!\n";
1299        }
1300    }
1301
1302    test_tree();    // AP_tree::
1303
1304    return 0;
1305}
1306
1307const char *AP_tree_nlen::fullname() const
1308{
1309    if (!name) {
1310        static char *buffer;
1311        char        *lName = strdup(Leftson()->fullname());
1312        char        *rName = strdup(Rightson()->fullname());
1313        int          len   = strlen(lName)+strlen(rName)+4;
1314
1315        if (buffer) free(buffer);
1316
1317        buffer = (char*)malloc(len);
1318
1319        strcpy(buffer,"[");
1320        strcat(buffer,lName);
1321        strcat(buffer,",");
1322        strcat(buffer,rName);
1323        strcat(buffer,"]");
1324
1325        free(lName);
1326        free(rName);
1327
1328        return buffer;
1329    }
1330
1331    return name;
1332}
1333
1334
1335char* AP_tree_nlen::getSequence()
1336{
1337    char *s;
1338
1339    costs();
1340    AP_sequence_parsimony *pseq = (AP_sequence_parsimony*)sequence;
1341    ap_assert(pseq->is_set_flag);
1342    s = new char[pseq->sequence_len];
1343    memcpy(s,pseq->sequence,(unsigned int)pseq->sequence_len);
1344
1345    return s;
1346}
1347
Note: See TracBrowser for help on using the repository browser.