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
10using namespace bpp;
11
12// From the STL:
13#include <iostream>
14
15using namespace std;
16
17void AbstractAgglomerativeDistanceMethod::setDistanceMatrix(const DistanceMatrix& matrix)
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_)
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
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 double computeDistancesFromPair(const std::vector< size_t > &pair, const std::vector< double > &branchLengths, size_t pos)=0
Actualizes the distance matrix according to a given pair and the corresponding branch lengths.
virtual std::vector< size_t > getBestPair()=0
Get the best pair of nodes to agglomerate.
virtual Node * getParentNode(int id, Node *son1, Node *son2)
Get an inner node.
virtual std::vector< double > computeBranchLengthsForPair(const std::vector< size_t > &pair)=0
Compute the branch lengths for two nodes to agglomerate.
virtual void finalStep(int idRoot)=0
Method called when there ar eonly three remaining node to agglomerate, and creates the root node of t...
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="")
const std::string & getName(std::size_t i) const
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:386
Defines the basic types of data flow nodes.