1 //
2 //  phylonodemixlen.h
3 //  iqtree
4 //
5 //  Created by Minh Bui on 24/08/15.
6 //
7 //
8 
9 #ifndef __iqtree__phylonodemixlen__
10 #define __iqtree__phylonodemixlen__
11 
12 #include <stdio.h>
13 #include "phylonode.h"
14 
15 /**
16 A neighbor in a phylogenetic tree with mixture branch lengths
17 
18     @author BUI Quang Minh, Steffen Klaere, Arndt von Haeseler <minh.bui@univie.ac.at>
19  */
20 class PhyloNeighborMixlen : public PhyloNeighbor {
21 public:
22 
23     /**
24         construct class with a node and length
25         @param anode the other end of the branch
26         @param alength length of branch
27         @param aid branch ID
28      */
PhyloNeighbor(anode,alength,aid)29     PhyloNeighborMixlen(Node *anode, double alength, int aid = -1) : PhyloNeighbor(anode, alength, aid) {
30         lengths.clear();
31     }
32 
33     PhyloNeighborMixlen(Node *anode, DoubleVector &alength, int aid = -1) : PhyloNeighbor(anode, -1.0, aid) {
34         lengths = alength;
35         if (!lengths.empty()) {
36             length = 0.0;
37             for (int i = 0; i < lengths.size(); i++)
38                 length += lengths[i];
39             length /= lengths.size();
40         }
41     }
42 
PhyloNeighborMixlen(PhyloNeighborMixlen * nei)43     PhyloNeighborMixlen(PhyloNeighborMixlen *nei) : PhyloNeighbor(nei) {
44         lengths = nei->lengths;
45     }
46 
47     /**
48      allocate a new Neighbor by just copying from this one
49      @return pointer to newly created Neighbor
50      */
newNeighbor()51     virtual Neighbor* newNeighbor() {
52         return (new PhyloNeighborMixlen(this));
53     }
54 
55     /** branch lengths for mixture */
56     DoubleVector lengths;
57 
58     /**
59         get branch length for a mixture class c, used by heterotachy model (PhyloNeighborMixlen)
60         the default is just to return a single branch length
61         @param c class index
62         @return branch length for class c
63     */
getLength(int c)64     virtual double getLength(int c) {
65         if (lengths.empty())
66             return length;
67         ASSERT(c < lengths.size());
68         return lengths[c];
69     }
70 
71     /**
72         get branch lengths, used by heterotachy model (PhyloNeighborMixlen)
73         the default is just to return a single branch length
74         @return branch length for class c
75     */
getLength(DoubleVector & vec)76     virtual void getLength(DoubleVector &vec) {
77         vec = lengths;
78     }
79 
80     /**
81         get branch lengths, used by heterotachy model (PhyloNeighborMixlen)
82         the default is just to return a single branch length
83         @param vec (OUT) destination branch length vector
84         @param start_pos starting position in vec to copy to
85     */
getLength(DoubleVector & vec,int start_pos)86     virtual void getLength(DoubleVector &vec, int start_pos) {
87         ASSERT(start_pos+lengths.size() <= vec.size());
88         for (int i = 0; i < lengths.size(); i++)
89             vec[start_pos+i] = lengths[i];
90     }
91 
92 
93     /**
94         set branch length for a mixture class c, used by heterotachy model (PhyloNeighborMixlen)
95         the default is just to return a single branch length
96         @param c class index
97         @return branch length for class c
98     */
setLength(int c,double len)99     virtual void setLength(int c, double len) {
100         if (lengths.empty()) {
101             length = len;
102             return;
103         }
104         ASSERT(c < lengths.size());
105         lengths[c] = len;
106     }
107 
108     /**
109         get branch lengths, used by heterotachy model (PhyloNeighborMixlen)
110         the default is just to return a single branch length
111         @return branch length for class c
112     */
setLength(DoubleVector & vec)113     virtual void setLength(DoubleVector &vec) {
114         lengths = vec;
115     }
116 
117     /**
118         set branch length by length of a Neighbor, used by heterotachy model (PhyloNeighborMixlen)
119         the default is just to return a single branch length
120         @param nei source neigbor to copy branch lengths
121         @return branch length for class c
122     */
setLength(Neighbor * nei)123     virtual void setLength(Neighbor *nei) {
124         length = nei->length;
125         lengths = ((PhyloNeighborMixlen*)nei)->lengths;
126     }
127 
128     /**
129         set branch lengths, used by heterotachy model (PhyloNeighborMixlen)
130         the default is just to return a single branch length
131         @param vec source branch length vector
132         @param start_pos starting position in vec to copy from
133     */
setLength(DoubleVector & vec,int start_pos,int num_elem)134     virtual void setLength(DoubleVector &vec, int start_pos, int num_elem) {
135         ASSERT(start_pos+num_elem <= vec.size());
136         lengths.clear();
137         lengths.insert(lengths.begin(), vec.begin()+start_pos, vec.begin()+start_pos+num_elem);
138     }
139 
140 
141 protected:
142 
143 };
144 
145 class PhyloNodeMixlen : public PhyloNode {
146 public:
147     /**
148         constructor
149      */
PhyloNodeMixlen()150     PhyloNodeMixlen() : PhyloNode() {}
151 
152     /**
153         constructor
154         @param aid id of this node
155      */
PhyloNodeMixlen(int aid)156     PhyloNodeMixlen(int aid) : PhyloNode(aid) {}
157 
158     /**
159         constructor
160         @param aid id of this node
161         @param aname name of this node
162      */
PhyloNodeMixlen(int aid,int aname)163     PhyloNodeMixlen(int aid, int aname) : PhyloNode(aid, aname) {}
164 
165     /**
166         constructor
167         @param aid id of this node
168         @param aname name of this node
169      */
PhyloNodeMixlen(int aid,const char * aname)170     PhyloNodeMixlen(int aid, const char *aname) : PhyloNode(aid, aname) {}
171 
172     /**
173         add a neighbor
174         @param node the neighbor node
175         @param length branch length
176         @param id branch ID
177      */
178     virtual void addNeighbor(Node *node, double length, int id = -1);
179 
180     /**
181         add a neighbor for heterotachy model
182         @param node the neighbor node
183         @param length branch length
184         @param id branch ID
185      */
186     virtual void addNeighbor(Node *node, DoubleVector &length, int id = -1);
187 
188 protected:
189 };
190 
191 #endif /* defined(__iqtree__phylonodemixlen__) */
192