-
Notifications
You must be signed in to change notification settings - Fork 0
/
UPGMATree.php
55 lines (51 loc) · 1.87 KB
/
UPGMATree.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
/**
* Created by PhpStorm.
* User: muntashir
* Date: 9/28/17
* Time: 10:36 PM
*/
namespace PHPPhylogeneticTrees;
/**
* Class UPGMATree
*
* The UPGMA algorithm
*
* @package PHPPhylogeneticTrees
*/
class UPGMATree extends Tree{
public function __construct($ds) {
$N = count($ds);
for ($i = 0; $i < $N; ++$i)
$this->cluster[$i] = new UPGMACluster($i + 1, $ds[$i]);
$this->cluster_count = $N;
while ($this->cluster_count < 2 * $N - 1)
$this->findAndJoin();
}
protected function findAndJoin() { // Find closest two live clusters and join them
$x = -1; $y = -1;
$min_value = INF;
for ($i = 0; $i < $this->cluster_count; ++$i)
if ($this->cluster[$i]->alive())
for ($j = 0; $j < $i; ++$j)
if ($this->cluster[$j]->alive()) {
$cell_value = $this->value($i, $j);
if ($cell_value < $min_value) {
$min_value = $cell_value;
$x = $i;
$y = $j;
}
}
$this->join($x, $y);
}
protected function join($x, $y) { // Join i and j to form node K
$dmat = []; // K
for ($m = 0; $m < $this->cluster_count; ++$m)
if ($this->cluster[$m]->alive() && $m != $x && $m != $y)
$dmat[$m] = ($this->value($x, $m) * $this->cluster[$x]->getCard() + $this->value($y, $m) * $this->cluster[$y]->getCard()) / ($this->cluster[$x]->getCard() + $this->cluster[$y]->getCard());
$this->cluster[$this->cluster_count] = new UPGMACluster([$this->cluster[$x]->getLabel(), $this->cluster[$y]->getLabel()], $dmat, $this->cluster[$x], $this->cluster[$y]);
$this->cluster[$x]->kill();
$this->cluster[$y]->kill();
++$this->cluster_count;
}
}