<commit_before>#!/usr/bin/env php
<?php
include("GroupingImage.php");
include("BinaryTree.php");
include("Tree.php");

list($species_names, $distances) = read_matrix($argv[1]);
$size = count($distances);

print("Original distance matrix:\n");
print_matrix($distances);

$groupings = array();
foreach ($species_names as $name)
	$groupings[] = new LeafNode($name);

do {
print "-------------------\n";
	$Q = calculate_Q($distances, $size);
	if ($size != count($Q)) exit;
	print("Q matrix\n");
	print_matrix($Q);

	choose_smallest_Q($Q, $size, $minI, $minJ);
	print("Smallest Q at ($minI, $minJ)\n");
	if ($minI == $minJ) exit;

	$colsumI = 0;
	$colsumJ = 0;
	for ($k = 0; $k < $size; ++$k) {
		$colsumI += ($minI < $k)? $distances[$minI][$k]: $distances[$k][$minI];
		$colsumJ += ($minJ < $k)? $distances[$minJ][$k]: $distances[$k][$minJ];
	}

	$d1 = $distances[$minI][$minJ]/2.0 + ($colsumI - $colsumJ)/(2*$size - 4);
	$d2 = $distances[$minI][$minJ] - $d1;

	print("new grouping from $minI:$d1, $minJ:$d2\n");
	$newgroup = new InteriorNode();
	$newgroup->add_neighbor($groupings[$minI], $d1);
	$newgroup->add_neighbor($groupings[$minJ], $d2);

	// $newgroup placed at $new_idx. $other_idx eliminated.
	$new_idx = ($minI < $minJ)? $minI: $minJ;
	$other_idx = ($new_idx == $minI)? $minJ: $minI;
print("Put new grouping at $new_idx, eliminate $other_idx\n");

	$newgroupings = array();
	foreach ($groupings as $idx => $grouping) {
		if ($idx == $other_idx)
			continue;
		else if ($idx == $new_idx)
			$newgroupings[] = $newgroup;
		else
			$newgroupings[] = $grouping;
	}
	$groupings = $newgroupings;
print("Now have ". count($groupings) . " groupings\n");
print("\$size == $size\n");

	$distances = recalculate_distances($distances, $size, $minI, $minJ);
print("\$distances now sized ".count($distances)."\n");

	print("\nNew distance matrix:\n");
	print_matrix($distances);

	$size = count($distances);
	if ($size != count($groupings)) exit;

} while ($size > 3);

// $size == 3 at this point.
$b = ($distances[1][2] + $distances[0][1] - $distances[0][2])/2.0;
$a = $distances[0][1] - $b;
$c = $distances[1][2] - $b;

print("Distance to new node: $a\n");
print("Distance from node1 to new node: $b\n");
print("Distance from node2 to new node: $c\n");

$g = new InteriorNode();
$g->add_neighbor($groupings[0], $a);
$g->add_neighbor($groupings[1], $b);
$g->add_neighbor($groupings[2], $c);

function findoutgroup($node) {
	global $outgroup_name;
	global $outgroup_node;
	$cn = get_class($node);
	if ($cn == 'LeafNode') {
		if ($node->label == $outgroup_name) {
			$outgroup_node = $node;
			return;
		}
	}
}

function printnode($node) {
	$cn = get_class($node);
	if ($cn == 'InteriorNode') {
		if (!$node->n1->visited)
			print($node->get_label().' - '.$node->n1->get_label().": {$node->dist1}\n");
		if (!$node->n2->visited)
			print($node->get_label().' - '.$node->n2->get_label().": {$node->dist2}\n");
		if (!$node->n3->visited)
			print($node->get_label().' - '.$node->n3->get_label().": {$node->dist3}\n");
	} else if ($cn = 'LeafNode') {
		print("Leaf node \"{$node->label}\"\n");
	}
}

function genericnode($node) {
	$cn = get_class($node);
	if ($cn == 'InteriorNode') {
		if (!$node->n1->visited) {
		}
		if (!$node->n2->visited) {
		}
		if (!$node->n3->visited) {
		}
	} else if ($cn = 'LeafNode') {
	}
}

$outgroup_name = '2.0';
$outgroup_node = null;<commit_msg>Make outgroup settable from command line<commit_after>#!/usr/bin/env php
<?php
include("GroupingImage.php");
include("BinaryTree.php");
include("Tree.php");

list($species_names, $distances) = read_matrix($argv[1]);
$size = count($distances);

print("Original distance matrix:\n");
print_matrix($distances);

$groupings = array();
foreach ($species_names as $name)
	$groupings[] = new LeafNode($name);

do {
print "-------------------\n";
	$Q = calculate_Q($distances, $size);
	if ($size != count($Q)) exit;
	print("Q matrix\n");
	print_matrix($Q);

	choose_smallest_Q($Q, $size, $minI, $minJ);
	print("Smallest Q at ($minI, $minJ)\n");
	if ($minI == $minJ) exit;

	$colsumI = 0;
	$colsumJ = 0;
	for ($k = 0; $k < $size; ++$k) {
		$colsumI += ($minI < $k)? $distances[$minI][$k]: $distances[$k][$minI];
		$colsumJ += ($minJ < $k)? $distances[$minJ][$k]: $distances[$k][$minJ];
	}

	$d1 = $distances[$minI][$minJ]/2.0 + ($colsumI - $colsumJ)/(2*$size - 4);
	$d2 = $distances[$minI][$minJ] - $d1;

	print("new grouping from $minI:$d1, $minJ:$d2\n");
	$newgroup = new InteriorNode();
	$newgroup->add_neighbor($groupings[$minI], $d1);
	$newgroup->add_neighbor($groupings[$minJ], $d2);

	// $newgroup placed at $new_idx. $other_idx eliminated.
	$new_idx = ($minI < $minJ)? $minI: $minJ;
	$other_idx = ($new_idx == $minI)? $minJ: $minI;
print("Put new grouping at $new_idx, eliminate $other_idx\n");

	$newgroupings = array();
	foreach ($groupings as $idx => $grouping) {
		if ($idx == $other_idx)
			continue;
		else if ($idx == $new_idx)
			$newgroupings[] = $newgroup;
		else
			$newgroupings[] = $grouping;
	}
	$groupings = $newgroupings;
print("Now have ". count($groupings) . " groupings\n");
print("\$size == $size\n");

	$distances = recalculate_distances($distances, $size, $minI, $minJ);
print("\$distances now sized ".count($distances)."\n");

	print("\nNew distance matrix:\n");
	print_matrix($distances);

	$size = count($distances);
	if ($size != count($groupings)) exit;

} while ($size > 3);

// $size == 3 at this point.
$b = ($distances[1][2] + $distances[0][1] - $distances[0][2])/2.0;
$a = $distances[0][1] - $b;
$c = $distances[1][2] - $b;

print("Distance to new node: $a\n");
print("Distance from node1 to new node: $b\n");
print("Distance from node2 to new node: $c\n");

$g = new InteriorNode();
$g->add_neighbor($groupings[0], $a);
$g->add_neighbor($groupings[1], $b);
$g->add_neighbor($groupings[2], $c);

function findoutgroup($node) {
	global $outgroup_name;
	global $outgroup_node;
	$cn = get_class($node);
	if ($cn == 'LeafNode') {
		if ($node->label == $outgroup_name) {
			$outgroup_node = $node;
			return;
		}
	}
}

function printnode($node) {
	$cn = get_class($node);
	if ($cn == 'InteriorNode') {
		if (!$node->n1->visited)
			print($node->get_label().' - '.$node->n1->get_label().": {$node->dist1}\n");
		if (!$node->n2->visited)
			print($node->get_label().' - '.$node->n2->get_label().": {$node->dist2}\n");
		if (!$node->n3->visited)
			print($node->get_label().' - '.$node->n3->get_label().": {$node->dist3}\n");
	} else if ($cn = 'LeafNode') {
		print("Leaf node \"{$node->label}\"\n");
	}
}

function genericnode($node) {
	$cn = get_class($node);
	if ($cn == 'InteriorNode') {
		if (!$node->n1->visited) {
		}
		if (!$node->n2->visited) {
		}
		if (!$node->n3->visited) {
		}
	} else if ($cn = 'LeafNode') {
	}
}

$outgroup_name = $argv[3];
$outgroup_node = null;
{'fraction_non_alphanumeric': 0.2492616656822209, 'fraction_numerical': 0.014028352037802717, 'mean_word_length': 4.583676834295136, 'pattern_counts': {'":': 6, '<': 13, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '320549', 'n_tokens_mistral': 2870, 'n_tokens_neox': 2758, 'n_words': 550}