bpp-phyl3  3.0.0
AbstractAgglomerativeDistanceMethod.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 
7 #include "../Tree/Node.h"
9 
10 using namespace bpp;
11 
12 // From the STL:
13 #include <iostream>
14 
15 using namespace std;
16 
18 {
19  if (matrix.size() <= 3)
20  throw Exception("AbstractAgglomerativeDistanceMethod::setDistanceMatrix(): matrix must be at least of dimension 3.");
21  matrix_ = matrix;
22  currentNodes_.clear();
23  tree_.reset(nullptr);
24 }
25 
27 {
28  // Initialization:
29  for (size_t i = 0; i < matrix_.size(); ++i)
30  {
31  currentNodes_[i] = getLeafNode(static_cast<int>(i), matrix_.getName(i));
32  }
33  int idNextNode = static_cast<int>(matrix_.size());
34  vector<double> newDist(matrix_.size());
35 
36  // Build tree:
37  while (currentNodes_.size() > (rootTree_ ? 2 : 3))
38  {
39  if (verbose_)
40  ApplicationTools::displayGauge(matrix_.size() - currentNodes_.size(), matrix_.size() - (rootTree_ ? 2 : 3) - 1);
41  vector<size_t> bestPair = getBestPair();
42  vector<double> distances = computeBranchLengthsForPair(bestPair);
43  Node* best1 = currentNodes_[bestPair[0]];
44  Node* best2 = currentNodes_[bestPair[1]];
45  // Distances may be used by getParentNodes (PGMA for instance).
46  best1->setDistanceToFather(distances[0]);
47  best2->setDistanceToFather(distances[1]);
48  Node* parent = getParentNode(idNextNode, best1, best2);
49  idNextNode++;
50  for (map<size_t, Node*>::iterator i = currentNodes_.begin(); i != currentNodes_.end(); i++)
51  {
52  size_t id = i->first;
53  if (id != bestPair[0] && id != bestPair[1])
54  {
55  assert (id < newDist.size()); // DEBUG
56  newDist[id] = computeDistancesFromPair(bestPair, distances, id);
57  }
58  else
59  {
60  newDist[id] = 0;
61  }
62  }
63  // Actualize currentNodes_:
64  currentNodes_[bestPair[0]] = parent;
65  currentNodes_.erase(bestPair[1]);
66  for (map<size_t, Node*>::iterator i = currentNodes_.begin(); i != currentNodes_.end(); i++)
67  {
68  size_t id = i->first;
69  matrix_(bestPair[0], id) = matrix_(id, bestPair[0]) = newDist[id];
70  }
71  }
72  finalStep(idNextNode);
73 }
74 
75 Node* AbstractAgglomerativeDistanceMethod::getLeafNode(int id, const std::string& name)
76 {
77  return new Node(id, name);
78 }
79 
81 {
82  Node* parent = new Node(id);
83  parent->addSon(son1);
84  parent->addSon(son2);
85  return parent;
86 }
virtual Node * getLeafNode(int id, const std::string &name)
Get a leaf node.
virtual void setDistanceMatrix(const DistanceMatrix &matrix) override
Set the distance matrix to use.
virtual Node * getParentNode(int id, Node *son1, Node *son2)
Get an inner node.
void computeTree() override
Compute the tree corresponding to the distance matrix.
static void displayGauge(size_t iter, size_t total, char symbol='>', const std::string &mes="")
std::size_t size() const
The phylogenetic node class.
Definition: Node.h:59
virtual void setDistanceToFather(double distance)
Set or update the distance toward the father node.
Definition: Node.h:266
virtual void addSon(size_t pos, Node *node)
Definition: Node.h:374
Defines the basic types of data flow nodes.