9 #include "../Likelihood/NNIHomogeneousTreeLikelihood.h"
25 searchableTree_->topologyChangePerformed(event);
26 for (
size_t i = 0; i < topoListeners_.size(); i++)
28 topoListeners_[i]->topologyChangePerformed(event);
34 searchableTree_->topologyChangeTested(event);
35 for (
size_t i = 0; i < topoListeners_.size(); i++)
37 topoListeners_[i]->topologyChangeTested(event);
43 searchableTree_->topologyChangeSuccessful(event);
44 for (
size_t i = 0; i < topoListeners_.size(); i++)
46 topoListeners_[i]->topologyChangeSuccessful(event);
52 if (algorithm_ == FAST)
54 else if (algorithm_ == BETTER)
56 else if (algorithm_ == PHYML)
59 throw Exception(
"Unknown NNI algorithm: " + algorithm_ +
".\n");
68 vector<Node*> nodes = tree.
getNodes();
70 vector<Node*> nodesSub = nodes;
71 for (
size_t i = nodesSub.size(); i > 0; i--)
74 if (!(nodesSub[i - 1]->hasFather()))
75 nodesSub.erase(nodesSub.begin() +
static_cast<ptrdiff_t
>(i - 1));
76 else if (!(nodesSub[i - 1]->getFather()->hasFather()))
77 nodesSub.erase(nodesSub.begin() +
static_cast<ptrdiff_t
>(i - 1));
82 for (
size_t i = 0; !test && i < nodesSub.size(); i++)
84 Node* node = nodesSub[i];
85 double diff = searchableTree_->testNNI(node->
getId());
101 searchableTree_->doNNI(node->
getId());
120 vector<Node*> nodes = tree.
getNodes();
125 vector<Node*> nodesSub = nodes;
126 for (
size_t i = nodesSub.size(); i > 0; i--)
128 if (!(nodesSub[i - 1]->hasFather()))
129 nodesSub.erase(nodesSub.begin() +
static_cast<ptrdiff_t
>(i - 1));
130 else if (!(nodesSub[i - 1]->getFather()->hasFather()))
131 nodesSub.erase(nodesSub.begin() +
static_cast<ptrdiff_t
>(i - 1));
135 vector<Node*> improving;
136 vector<double> improvement;
139 for (
size_t i = 0; i < nodesSub.size(); i++)
141 Node* node = nodesSub[i];
142 double diff = searchableTree_->testNNI(node->
getId());
152 improving.push_back(node);
153 improvement.push_back(diff);
158 test = improving.size() > 0;
162 Node* node = improving[nodeMin];
167 searchableTree_->doNNI(node->
getId());
187 vector<Node*> nodes = tree.
getNodes();
188 vector<Node*> nodesSub = nodes;
189 for (
size_t i = nodesSub.size(); i > 0; i--)
192 if (!(nodesSub[i - 1]->hasFather()))
193 nodesSub.erase(nodesSub.begin() +
static_cast<ptrdiff_t
>(i - 1));
194 else if (!(nodesSub[i - 1]->getFather()->hasFather()))
195 nodesSub.erase(nodesSub.begin() +
static_cast<ptrdiff_t
>(i - 1));
199 vector<int> improving;
200 vector<Node*> improvingNodes;
201 vector<double> improvement;
204 for (
size_t i = 0; i < nodesSub.size(); i++)
206 Node* node = nodesSub[i];
207 double diff = searchableTree_->testNNI(node->
getId());
219 for (
size_t j = improving.size(); j > 0; j--)
221 if (improvingNodes[j - 1]->getFather()->getId() == node->
getFather()->
getId()
223 || improvingNodes[j - 1]->getId() == node->
getFather()->
getId() || improvingNodes[j - 1]->getFather()->getId() == node->
getId()
224 || improvingNodes[j - 1]->getId() == node->
getFather()->
getFather()->
getId() || improvingNodes[j - 1]->getFather()->getFather()->getId() == node->
getId()
228 if (diff < improvement[j - 1])
230 improvingNodes.erase(improvingNodes.begin() +
static_cast<ptrdiff_t
>(j - 1));
231 improving.erase(improving.begin() +
static_cast<ptrdiff_t
>(j - 1));
232 improvement.erase(improvement.begin() +
static_cast<ptrdiff_t
>(j - 1));
243 size_t pos = improvement.size();
244 for (
size_t j = 0; j < improvement.size(); j++)
246 if (diff < improvement[j])
251 if (pos < improvement.size())
253 improvingNodes.insert(improvingNodes.begin() +
static_cast<ptrdiff_t
>(pos), node);
254 improving.insert(improving.begin() +
static_cast<ptrdiff_t
>(pos), node->
getId());
255 improvement.insert(improvement.begin() +
static_cast<ptrdiff_t
>(pos), diff);
259 improvingNodes.insert(improvingNodes.end(), node);
260 improving.insert(improving.end(), node->
getId());
261 improvement.insert(improvement.end(), diff);
269 improvingNodes.clear();
272 test = improving.size() > 0;
275 double currentValue = searchableTree_->getTopologyValue();
283 for (
size_t i = 0; i < improving.size(); i++)
285 int nodeId = improving[i];
292 searchableTree_->doNNI(improving[i]);
299 if (searchableTree_->getTopologyValue() >= currentValue)
303 searchableTree_.reset(backup->
clone());
309 if (improving.size() == 1)
312 throw Exception(
"NNITopologySearch::searchPhyML. Error, no improving NNI!\n This may be due to a change in parameters between testNNI and doNNI. Check your code!");
314 size_t n = (size_t)ceil((
double)improving.size() / 2.);
315 improving.erase(improving.begin() +
static_cast<ptrdiff_t
>(n), improving.end());
316 improvement.erase(improvement.begin() +
static_cast<ptrdiff_t
>(n), improvement.end());
Interface for Nearest Neighbor Interchanges algorithms.
virtual NNISearchable * clone() const =0
static const std::string PHYML
void notifyAllTested(const TopologyChangeEvent &event)
Process a TopologyChangeEvent to all listeners.
void notifyAllPerformed(const TopologyChangeEvent &event)
Process a TopologyChangeEvent to all listeners.
static const std::string FAST
static const std::string BETTER
void search()
Performs the search.
void notifyAllSuccessful(const TopologyChangeEvent &event)
Process a TopologyChangeEvent to all listeners.
The phylogenetic node class.
virtual int getId() const
Get the node's id.
virtual const Node * getFather() const
Get the father of this node is there is one.
Class for notifying new toplogy change events.
The phylogenetic tree class.
virtual std::vector< const N * > getNodes() const
std::string toString(T t)
Defines the basic types of data flow nodes.