git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@1592 331e1502-861f-0410-8da2-ba01fb791d7f
119 lines
No EOL
2.9 KiB
C++
119 lines
No EOL
2.9 KiB
C++
#ifndef _SPLITCALCULATOR_H_
|
|
#define _SPLITCALCULATOR_H_
|
|
|
|
#include <phylotreeIND.h>
|
|
|
|
struct split_table
|
|
{
|
|
phylotreeIND &tree;
|
|
vector<struct split_info> splitstable;
|
|
node_map<struct split_info*> interior_node;
|
|
edge_map<struct split_info*> interior_edge;
|
|
|
|
split_table( phylotreeIND &t ) : tree(t) {};
|
|
|
|
};
|
|
|
|
|
|
class SplitCalculator : public TreeCalculator <split_info>
|
|
{
|
|
|
|
private :
|
|
|
|
struct split_info temp;
|
|
|
|
public :
|
|
|
|
/// virtual dtor here so there is no need to define it in derived classes
|
|
virtual ~SplitCalculator() {}
|
|
|
|
/// The pure virtual function that needs to be implemented by the subclass
|
|
|
|
struct split_info operator()(phylotreeIND &tree)
|
|
{
|
|
// hash table
|
|
int n = tree.number_of_taxons();
|
|
struct split_info **hash_table; // hash that points struct info
|
|
struct split_info *interior_node_info = new struct split_info[n-1];
|
|
vector<struct split_info> splitstable;
|
|
splitstable.resize(n);
|
|
|
|
int idx_interior = 0;
|
|
node_map<struct split_info*> interior_node(tree.TREE, NULL);
|
|
edge_map<struct split_info*> interior_edge(tree.TREE, NULL);
|
|
// node mapes
|
|
int *map_nodes;
|
|
int node_count = 0;
|
|
|
|
int temp2 = 2;
|
|
|
|
|
|
// allocate memory
|
|
hash_table = new struct split_info*[n];
|
|
for(int i=0; i<n; i++)hash_table[i] = NULL;
|
|
map_nodes = new int[n];
|
|
|
|
// step 1
|
|
// select last taxon as root
|
|
node root1 = tree.taxon_number( n-1);
|
|
|
|
// step 2 and 3
|
|
postorder_Iterator it = tree.postorder_begin( root1);
|
|
|
|
int l, r;
|
|
while( *it != root1 )
|
|
{
|
|
struct split_info *father_info = interior_node [ it.ancestor() ] ;
|
|
struct split_info *current_info = interior_node [ *it ] ;
|
|
|
|
|
|
//cout << " node " << *it << " ancestral" << it.ancestor() << endl;
|
|
if( tree.istaxon(*it) )
|
|
{
|
|
// update the map
|
|
map_nodes[ tree.taxon_id( *it) ] = r = node_count;
|
|
splitstable[ tree.taxon_id( *it) ].map_to_node = node_count;
|
|
splitstable[ node_count ] = tree.taxon_id( *it);
|
|
// check if is the leftmost
|
|
if( father_info == NULL )
|
|
{
|
|
interior_node [ it.ancestor() ] = father_info = &interior_node_info[idx_interior];
|
|
interior_node [ it.ancestor() ] = father_info = &(splitstable[idx_interior]);
|
|
idx_interior++;
|
|
//father_info.left_most = *it;
|
|
father_info->left = node_count;
|
|
}
|
|
//else father_info.right = node_count;
|
|
node_count++;
|
|
++it;
|
|
}
|
|
else
|
|
{
|
|
int idx;
|
|
l = current_info->left;
|
|
interior_edge[ it.branch() ] = current_info;
|
|
|
|
if( father_info == NULL )
|
|
{
|
|
interior_node [ it.ancestor() ] = father_info = &interior_node_info[idx_interior];
|
|
interior_node [ it.ancestor() ] = father_info = &(splitstable[idx_interior]);
|
|
idx_interior++;
|
|
father_info->left = current_info->left;
|
|
}
|
|
|
|
++it;
|
|
if (tree.istaxon(*it) || *it==root1) idx = r;
|
|
else idx = l;
|
|
|
|
current_info->right = r;
|
|
// fill hash table
|
|
hash_table[ idx ] = current_info;
|
|
splitstable[ idx ].hash = current_info;
|
|
}
|
|
}
|
|
delete [] interior_node_info;
|
|
delete [] map_nodes;
|
|
delete [] hash_table;
|
|
}
|
|
};
|
|
#endif |