source: tags/svn.1.5.4/PARSIMONY/ap_tree_nlen.hxx

Last change on this file was 7812, checked in by westram, 13 years ago

merge from dev [7751] [7752]

  • updated many old-style typedefs (typedef struct/enum)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 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    AP_tree_nlen(AP_tree_root *tree_root);
76    virtual ~AP_tree_nlen() {}
77    DEFINE_TREE_ACCESSORS(AP_tree_root, AP_tree_nlen);
78
79    // ARB_tree interface
80    virtual AP_tree_nlen *dup() const;
81    // ARB_tree interface (end)
82
83    void     unhash_sequence();
84    AP_FLOAT costs(char *mutPerSite = NULL);        // cost of a tree (number of changes ..)
85
86    bool push(AP_STACK_MODE, unsigned long); // push state of costs
87    void pop(unsigned long);    // pop old tree costs
88    bool clear(unsigned long stack_update, unsigned long user_push_counter);
89
90    virtual AP_UPDATE_FLAGS check_update(); // disable  load !!!!
91
92    void copy(AP_tree_nlen *tree);
93    int  Distance();
94
95    // tree reconstruction methods:
96    void insert(AP_tree_nlen *new_brother);
97    void remove();
98    void swap_assymetric(AP_TREE_SIDE mode);
99    void moveTo(AP_tree_nlen *new_brother, AP_FLOAT rel_pos); // if unsure, use cantMoveTo to test if possible
100    void set_root();
101
102    // overload virtual methods from AP_tree:
103    void insert(AP_tree *new_brother) { insert(DOWNCAST(AP_tree_nlen*, new_brother)); }
104    void moveTo(AP_tree *node, AP_FLOAT rel_pos) { moveTo(DOWNCAST(AP_tree_nlen*, node), rel_pos); }
105
106    // tree optimization methods:
107    void parsimony_rek(char *mutPerSite = NULL);
108
109    AP_FLOAT nn_interchange_rek(int         deep,   // -1 means: do whole subtree
110                                AP_BL_MODE  mode,
111                                bool        skip_hidden);
112
113    AP_FLOAT nn_interchange(AP_FLOAT parsimony, AP_BL_MODE mode);
114
115    void kernighan_rek(int         rek_deep,
116                       int        *rek_breite,
117                       int         rek_breite_anz,
118                       const int   rek_deep_max,
119                       double    (*function)(double, double *, int),
120                       double     *param_liste,
121                       int         param_anz,
122                       AP_FLOAT    pars_best,
123                       AP_FLOAT    pars_start,
124                       AP_FLOAT    pars_prev,
125                       AP_KL_FLAG  searchflag,
126                       bool       *abort_flag);
127
128    // for crossover creates a list of 3 times the nodes with all
129    // ancestors in it
130    AP_CO_LIST * createList(int *size);
131
132    class AP_tree_stack stack;  // tree stack
133
134    // misc stuff:
135
136    void setBranchlen(double leftLen, double rightLen) { leftlen = leftLen; rightlen = rightLen; }
137
138    const char* fullname() const;
139    const char* sortByName();
140
141    // AP_tree_edge access functions:
142
143    int indexOf(const AP_tree_edge *e) const { int i; for (i=0; i<3; i++) if (edge[i]==e) return i; return -1; }
144
145    AP_tree_edge* edgeTo(const AP_tree_nlen *brother) const;
146    AP_tree_edge* nextEdge(const AP_tree_edge *thisEdge=NULL) const;
147    int unusedEdgeIndex() const; // [0..2], -1 if none
148
149    // more complex edge functions:
150
151    void linkAllEdges(AP_tree_edge *edge1, AP_tree_edge *edge2, AP_tree_edge *edge3);
152    void unlinkAllEdges(AP_tree_edge **edgePtr1, AP_tree_edge **edgePtr2, AP_tree_edge **edgePtr3);
153
154    char *getSequenceCopy();
155
156#if defined(CHECK_TREE_STRUCTURE)
157    void assert_edges_valid() const;
158    void assert_valid() const;
159#endif // CHECK_TREE_STRUCTURE
160
161
162    friend      class AP_tree_edge;
163    friend      std::ostream& operator<<(std::ostream&, const AP_tree_nlen&);
164};
165
166// ---------------------
167//      AP_tree_edge
168
169class MutationsPerSite;
170
171class AP_tree_edge : virtual Noncopyable {
172    // the following members are stored/restored by
173    // AP_tree_nlen::push/pop:
174
175    AP_tree_nlen      *node[2]; // the two nodes of this edge
176    int                index[2]; // index to edge[] in AP_tree_nlen
177    AP_tree_edge_data  data;    // data stored in edge (defined in AP_buffer.hxx)
178
179    // and these arent pushed:
180
181    AP_tree_edge *next;                 // temporary next pointer used by some methods
182    int           used;                 // test-counter
183    long          age;                  // age of the edge
184
185    static long timeStamp;              // static counter for edge-age
186    // recursive methods:
187    //
188    //  deep:   determines how deep we go into the tree
189    //          -1 means we go through the whole tree
190    //           0 means we only act on the actual edge
191
192    AP_tree_edge *buildChain(int                 deep,
193                             bool                skip_hidden = false,
194                             int                 distance    = 0,
195                             const AP_tree_nlen *skip        = NULL,
196                             AP_tree_edge       *comesFrom   = NULL);
197
198    long sizeofChain();
199    void calcDistance();
200    void tailDistance(AP_tree_nlen*);
201
202    int distanceOK() const { int diff = node[0]->distance-node[1]->distance; return diff>=-1 && diff<=1; }
203
204    // my friends:
205
206    friend class AP_tree_nlen;
207    friend std::ostream& operator<<(std::ostream&, const AP_tree_edge&);
208
209protected:
210
211    ~AP_tree_edge();
212
213    // relink & unlink (they are also used by constructor & destructor)
214
215    void relink(AP_tree_nlen *node1, AP_tree_nlen *node2);
216    AP_tree_edge *unlink();
217
218public:
219
220    AP_tree_edge(AP_tree_nlen *node1, AP_tree_nlen *node2);
221
222    static void initialize(AP_tree_nlen *root);
223
224    // access methods:
225
226    int isConnectedTo(const AP_tree_nlen *n) const              { return node[0]==n || node[1]==n; }
227    int indexOf(const AP_tree_nlen *n) const                    { ap_assert(isConnectedTo(n)); return node[1] == n; }
228    AP_tree_nlen* otherNode(const AP_tree_nlen *n) const        { return node[1-indexOf(n)]; }
229    AP_tree_nlen* sonNode() const                               { return node[0]->get_father() == node[1] ? node[0] : node[1]; }
230    AP_tree_edge* Next() const                                  { return next; }
231    long Age() const                                            { return age; }
232
233    // encapsulated AP_tree_nlen methods:
234
235    void set_root()                                             { return sonNode()->set_root(); }
236
237    // tree optimization:
238
239    AP_FLOAT nni_rek(int deep, bool skip_hidden, AP_BL_MODE mode, AP_tree_nlen *skipNode);
240
241    AP_FLOAT calc_branchlengths() { return nni_rek(-1, false, AP_BL_BL_ONLY, NULL); }
242
243    AP_FLOAT nni_mutPerSite(AP_FLOAT pars_one, AP_BL_MODE mode, MutationsPerSite *mps);
244    AP_FLOAT nni(AP_FLOAT pars_one, AP_BL_MODE mode) { return nni_mutPerSite(pars_one, mode, NULL); }
245
246    // test methods:
247
248    void mixTree(int cnt);
249    int test() const;
250    int dumpChain() const;
251    void testChain(int deep);
252
253    int Distance() const { ap_assert(distanceOK()); return (node[0]->distance+node[1]->distance) >> 1; }
254    int distanceToBorder(int maxsearch=INT_MAX, AP_tree_nlen *skip=NULL) const; // obsolete
255
256    static int dumpNNI;             // should NNI dump its values?
257    static int distInsertBorder; // distance from insert pos to tree border
258    static int basesChanged;    // no of bases which were changed
259    // in fathers sequence because of insertion
260
261    void countSpecies(int deep=-1, const AP_tree_nlen* skip=NULL);
262
263    static int speciesInTree;                       // no of species (leafs) in tree (updated by countSpecies)
264    static int nodesInTree;                         // no of nodes in tree - including leafs, but w/o rootnode (updated by countSpecies)
265
266    static int edgesInTree() { return nodesInTree-1; } // (updated by countSpecies)
267};
268
269std::ostream& operator<<(std::ostream&, const AP_tree_edge&);
270
271
272inline AP_tree_nlen *rootNode() {
273    return ap_main->get_root_node();
274}
275
276inline AP_tree_edge *rootEdge() {
277    return rootNode()->get_leftson()->edgeTo(rootNode()->get_rightson());
278}
279
280#else
281#error ap_tree_nlen.hxx included twice
282#endif // AP_TREE_NLEN_HXX
Note: See TracBrowser for help on using the repository browser.