source: tags/arb-6.0.1/PARSIMONY/ap_tree_nlen.hxx

Last change on this file was 12267, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.6 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ap_tree_nlen.hxx                                  //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in Summer 1995    //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#ifndef AP_TREE_NLEN_HXX
13#define AP_TREE_NLEN_HXX
14
15#ifndef _GLIBCXX_IOSTREAM
16#include <iostream>
17#endif
18#ifndef _GLIBCXX_CLIMITS
19#include <climits>
20#endif
21#ifndef AP_MAIN_HXX
22#include <ap_main.hxx>
23#endif
24
25class AP_tree_nlen;
26
27struct AP_CO_LIST {     // liste fuer crossover
28    GBDATA *leaf0;
29    GBDATA *leaf1;
30    int     node0;
31    int     node1;
32
33    class AP_tree_nlen *pntr;
34};
35
36enum AP_KL_FLAG {  // flags fuer die Rekursionsart bei Kernighan Lin
37    AP_DYNAMIK       = 1,
38    AP_STATIC        = 2,
39    AP_BETTER        = 4,
40    // Funktionstyp der Schwellwertfunktion
41    AP_QUADRAT_START = 5,
42    AP_QUADRAT_MAX   = 6
43};
44
45enum AP_BL_MODE {
46    APBL_NONE                = 0,
47    AP_BL_NNI_ONLY           = 1, // try te find a better tree only
48    AP_BL_BL_ONLY            = 2, // try to calculate the branch lengths
49    AP_BL_NNI_BL             = 3, // better tree & branch lengths
50    AP_BL_BOOTSTRAP_LIMIT    = 4, // calculate upper bootstrap limits
51    AP_BL_BOOTSTRAP_ESTIMATE = 12 // calculate estimate of bootstrap (includes AP_BL_BOOTSTRAP_LIMIT)
52};
53
54class AP_tree_edge;
55
56class AP_tree_nlen : public AP_tree { // derived from a Noncopyable
57    // tree that is independent of branch lengths and root
58
59    AP_TREE_SIDE kernighan;     // Flag zum markieren
60    int          distance;      // distance to tree border (0=leaf, INT_MAX=UNKNOWN)
61
62    // definitions for AP_tree_edge:
63
64    AP_tree_edge *edge[3];      // the edges to the father and the sons
65    int           index[3];     // index to node[] in AP_tree_edge
66
67    AP_FLOAT mutation_rate;
68
69
70
71    void createListRekUp(AP_CO_LIST *list, int *cn);
72    void createListRekSide(AP_CO_LIST *list, int *cn);
73
74public:
75    explicit AP_tree_nlen(AP_tree_root *troot)
76        : AP_tree(troot),
77          kernighan(AP_NONE),
78          distance(INT_MAX),
79          mutation_rate(0)
80    {
81        edge[0]  = edge[1]  = edge[2]  = NULL;
82        index[0] = index[1] = index[2] = 0;
83    }
84    ~AP_tree_nlen() OVERRIDE {}
85
86    DEFINE_TREE_ACCESSORS(AP_tree_root, AP_tree_nlen);
87
88    void     unhash_sequence();
89    AP_FLOAT costs(char *mutPerSite = NULL);        // cost of a tree (number of changes ..)
90
91    bool push(AP_STACK_MODE, unsigned long); // push state of costs
92    void pop(unsigned long);    // pop old tree costs
93    bool clear(unsigned long stack_update, unsigned long user_push_counter);
94
95    virtual AP_UPDATE_FLAGS check_update() OVERRIDE; // disable  load !!!!
96
97    void copy(AP_tree_nlen *tree);
98    int  Distance();
99
100    // tree reconstruction methods:
101    void insert(AP_tree_nlen *new_brother);
102    void initial_insert(AP_tree_nlen *new_brother, AP_tree_root *troot);
103
104    void remove() OVERRIDE;
105    void swap_sons() OVERRIDE;
106    void swap_assymetric(AP_TREE_SIDE mode) OVERRIDE;
107    void moveNextTo(AP_tree_nlen *new_brother, AP_FLOAT rel_pos); // if unsure, use cantMoveNextTo to test if possible
108    void set_root() OVERRIDE;
109
110    // overload virtual methods from AP_tree:
111    void insert(AP_tree *new_brother) OVERRIDE { insert(DOWNCAST(AP_tree_nlen*, new_brother)); }
112    void initial_insert(AP_tree *new_brother, AP_tree_root *troot) OVERRIDE { initial_insert(DOWNCAST(AP_tree_nlen*, new_brother), troot); }
113    void moveNextTo(AP_tree *node, AP_FLOAT rel_pos) OVERRIDE { moveNextTo(DOWNCAST(AP_tree_nlen*, node), rel_pos); }
114
115    // tree optimization methods:
116    void parsimony_rek(char *mutPerSite = NULL);
117
118    AP_FLOAT nn_interchange_rek(int         deep,   // -1 means: do whole subtree
119                                AP_BL_MODE  mode,
120                                bool        skip_hidden);
121
122    AP_FLOAT nn_interchange(AP_FLOAT parsimony, AP_BL_MODE mode);
123
124    void kernighan_rek(int         rek_deep,
125                       int        *rek_breite,
126                       int         rek_breite_anz,
127                       const int   rek_deep_max,
128                       double    (*function)(double, double *, int),
129                       double     *param_liste,
130                       int         param_anz,
131                       AP_FLOAT    pars_best,
132                       AP_FLOAT    pars_start,
133                       AP_FLOAT    pars_prev,
134                       AP_KL_FLAG  searchflag,
135                       bool       *abort_flag);
136
137    // for crossover creates a list of 3 times the nodes with all
138    // ancestors in it
139    AP_CO_LIST * createList(int *size);
140
141    class AP_tree_stack stack;  // tree stack
142
143    // misc stuff:
144
145    void setBranchlen(double leftLen, double rightLen) { leftlen = leftLen; rightlen = rightLen; }
146
147    const char* fullname() const;
148    const char* sortByName();
149
150    // AP_tree_edge access functions:
151
152    int indexOf(const AP_tree_edge *e) const { int i; for (i=0; i<3; i++) if (edge[i]==e) return i; return -1; }
153
154    AP_tree_edge* edgeTo(const AP_tree_nlen *brother) const;
155    AP_tree_edge* nextEdge(const AP_tree_edge *afterThatEdge=NULL) const;
156    int unusedEdgeIndex() const; // [0..2], -1 if none
157
158    // more complex edge functions:
159
160    void linkAllEdges(AP_tree_edge *edge1, AP_tree_edge *edge2, AP_tree_edge *edge3);
161    void unlinkAllEdges(AP_tree_edge **edgePtr1, AP_tree_edge **edgePtr2, AP_tree_edge **edgePtr3);
162
163    char *getSequenceCopy();
164
165#if defined(PROVIDE_TREE_STRUCTURE_TESTS)
166    void assert_edges_valid() const;
167    void assert_valid() const;
168#endif // PROVIDE_TREE_STRUCTURE_TESTS
169
170
171    friend      class AP_tree_edge;
172    friend      std::ostream& operator<<(std::ostream&, const AP_tree_nlen&);
173};
174
175struct AP_TreeNlenNodeFactory : public RootedTreeNodeFactory {
176    RootedTree *makeNode(TreeRoot *root) const OVERRIDE {
177        return new AP_tree_nlen(DOWNCAST(AP_tree_root*, root));
178    }
179};
180
181// ---------------------
182//      AP_tree_edge
183
184class MutationsPerSite;
185
186class AP_tree_edge : virtual Noncopyable {
187    // the following members are stored/restored by
188    // AP_tree_nlen::push/pop:
189
190    AP_tree_nlen      *node[2]; // the two nodes of this edge
191    int                index[2]; // index to edge[] in AP_tree_nlen
192    AP_tree_edge_data  data;    // data stored in edge (defined in AP_buffer.hxx)
193
194    // and these arent pushed:
195
196    AP_tree_edge *next;                 // temporary next pointer used by some methods
197    int           used;                 // test-counter
198    long          age;                  // age of the edge
199
200    static long timeStamp;              // static counter for edge-age
201    // recursive methods:
202    //
203    //  deep:   determines how deep we go into the tree
204    //          -1 means we go through the whole tree
205    //           0 means we only act on the actual edge
206
207    AP_tree_edge *buildChain(int                 deep,
208                             bool                skip_hidden = false,
209                             int                 distance    = 0,
210                             const AP_tree_nlen *skip        = NULL,
211                             AP_tree_edge       *comesFrom   = NULL);
212
213    long sizeofChain();
214    void calcDistance();
215    void tailDistance(AP_tree_nlen*);
216
217    int distanceOK() const { int diff = node[0]->distance-node[1]->distance; return diff>=-1 && diff<=1; }
218
219    // my friends:
220
221    friend class AP_tree_nlen;
222    friend std::ostream& operator<<(std::ostream&, const AP_tree_edge&);
223#if defined(UNIT_TESTS) // UT_DIFF
224    friend void TEST_tree_modifications();
225#endif
226
227protected:
228
229    ~AP_tree_edge();
230
231    // relink & unlink (they are also used by constructor & destructor)
232
233    void relink(AP_tree_nlen *node1, AP_tree_nlen *node2);
234    AP_tree_edge *unlink();
235
236public:
237
238    AP_tree_edge(AP_tree_nlen *node1, AP_tree_nlen *node2);
239
240    static void initialize(AP_tree_nlen *root);
241    static void destroy(AP_tree_nlen *root);
242
243    // access methods:
244
245    int isConnectedTo(const AP_tree_nlen *n) const              { return node[0]==n || node[1]==n; }
246    int indexOf(const AP_tree_nlen *n) const                    { ap_assert(isConnectedTo(n)); return node[1] == n; }
247    AP_tree_nlen* otherNode(const AP_tree_nlen *n) const        { return node[1-indexOf(n)]; }
248    AP_tree_nlen* sonNode() const                               { return node[0]->get_father() == node[1] ? node[0] : node[1]; }
249    AP_tree_edge* Next() const                                  { return next; }
250    long Age() const                                            { return age; }
251
252    // encapsulated AP_tree_nlen methods:
253
254    void set_root()                                             { return sonNode()->set_root(); }
255
256    // tree optimization:
257
258    AP_FLOAT nni_rek(int deep, bool skip_hidden, AP_BL_MODE mode, AP_tree_nlen *skipNode);
259
260    AP_FLOAT calc_branchlengths() { return nni_rek(-1, false, AP_BL_BL_ONLY, NULL); }
261
262    AP_FLOAT nni_mutPerSite(AP_FLOAT pars_one, AP_BL_MODE mode, MutationsPerSite *mps);
263    AP_FLOAT nni(AP_FLOAT pars_one, AP_BL_MODE mode) { return nni_mutPerSite(pars_one, mode, NULL); }
264
265    // test methods:
266
267    void mixTree(int cnt);
268    int test() const;
269    int dumpChain() const;
270    void testChain(int deep);
271
272    int Distance() const { ap_assert(distanceOK()); return (node[0]->distance+node[1]->distance) >> 1; }
273    int distanceToBorder(int maxsearch=INT_MAX, AP_tree_nlen *skipNode=NULL) const; // obsolete
274
275    static int dumpNNI;             // should NNI dump its values?
276    static int distInsertBorder; // distance from insert pos to tree border
277    static int basesChanged;    // no of bases which were changed
278    // in fathers sequence because of insertion
279
280    void countSpecies(int deep=-1, const AP_tree_nlen* skip=NULL);
281
282    static int speciesInTree;                       // no of species (leafs) in tree (updated by countSpecies)
283    static int nodesInTree;                         // no of nodes in tree - including leafs, but w/o rootnode (updated by countSpecies)
284
285    static int edgesInTree() { return nodesInTree-1; } // (updated by countSpecies)
286};
287
288std::ostream& operator<<(std::ostream&, const AP_tree_edge&);
289
290
291inline AP_tree_nlen *rootNode() {
292    return ap_main->get_root_node();
293}
294
295inline AP_tree_edge *rootEdge() {
296    return rootNode()->get_leftson()->edgeTo(rootNode()->get_rightson());
297}
298
299#else
300#error ap_tree_nlen.hxx included twice
301#endif // AP_TREE_NLEN_HXX
Note: See TracBrowser for help on using the repository browser.