/* This file converts a set of bipartitions into a tree. Copyright (C) 2004 The University of Texas at Austin Based upon Daniel Huson's implementation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Email: usman@cs.njit.edu Mail: Usman Roshan, Department of Computer Sciences, NJIT-CCS, Computer Science Department, GITC 4400, University Heights, Newark, NJ 07102 */ #include #include #include #include #include #include #include /* #include */ static void splits2tree_rec(const node v, const edge e, const list_node ln, const list listsplits, const int_set taxa, hashtable2 edge2split, phylogenetic_tree T); /* extern int diff_time; */ void splits2tree(const list listsplits, const int_set taxa, phylogenetic_tree T) { hashtable2 edge2split; node v; node_aux_vars node_vars; list_node it; int i; /* diff_time = 0; */ assert(T->G->n_nodes == 0 && T->G->n_edges == 0); assert(taxa && size_int_set(taxa)); edge2split = new_hashtable2(size_list(listsplits)); node_vars = new_node_aux_vars(); assign_int_set(node_vars->taxaset, taxa); v = new_node(T->G, node_vars); for (it = listsplits->head; it; it = it->next) splits2tree_rec(v, (edge) 0, it, listsplits, taxa, edge2split, T); /* free up the hashtable2 structure */ for (i = 0; i < edge2split->size_; i++) if (edge2split->table_[i] && edge2split->table_[i]->value) edge2split->table_[i]->value = NULL; del_hashtable2(edge2split); edge2split = NULL; /* set taxon_ids correctly */ for (v = T->G->first_node; v; v = v->next) if (v->degree == 1) { T->num_leaves++; ((node_aux_vars) v->aux_vars)->taxon_id = choose_int_set(((node_aux_vars) v->aux_vars)->taxaset); assert(((node_aux_vars) v->aux_vars)->taxon_id != -1); } else ((node_aux_vars) v->aux_vars)->taxon_id = -1; /* printf("diff time=%d\n", diff_time); */ } static void splits2tree_rec(const node v, const edge e, const list_node it, const list listsplits, const int_set taxa, hashtable2 edge2split, phylogenetic_tree T) { list tomove; list_node ln; edge f, g; node w, n; int_set A, B, diff; node_aux_vars node_vars; edge_aux_vars edge_vars; void *vp; /* time_t begin, end; */ tomove = new_list(); for (f = v->first_edge; f;) { if (f != e) { A = get_A_split((split) (it->data)); B = get_A_split((split) lookup_hashtable2(edge2split, (PTR_TYPE) f)); if (subseteq_int_set(B, A)) { splits2tree_rec(opposite(v, f), f, it, listsplits, taxa, edge2split, T); for (ln = tomove->head; ln; ln = ln->next) ln->data = NULL; del_list(tomove); tomove = NULL; return; } else if (subseteq_int_set(A, B)) { append_list(tomove, (void *) f); } } if (f->u == v) f = f->u_next; else if (f->v == v) f = f->v_next; else assert(0); } /* begin=time(NULL); */ diff = diff_int_set(((node_aux_vars) (v->aux_vars))->taxaset, get_A_split((split) (it->data))); /* end=time(NULL); diff_time+=difftime(end,begin); */ node_vars = new_node_aux_vars(); assign_int_set(node_vars->taxaset, diff); del_int_set(diff); diff = NULL; n = new_node(T->G, node_vars); /* begin=time(NULL); */ diff = diff_int_set(((node_aux_vars) (v->aux_vars))->taxaset, ((node_aux_vars) (n->aux_vars))->taxaset); /* end=time(NULL); diff_time+=difftime(end,begin); */ assign_int_set(((node_aux_vars) (v->aux_vars))->taxaset, diff); del_int_set(diff); diff = NULL; edge_vars = new_edge_aux_vars(); edge_vars->wgt = ((split) (it->data))->wgt; f = new_edge(T->G, v, n, edge_vars); insert_hashtable2(edge2split, (PTR_TYPE) f, it->data); for (ln = tomove->head; ln; ln = ln->next) { f = (edge) ln->data; w = opposite(v, f); edge_vars = new_edge_aux_vars(); edge_vars->wgt = ((edge_aux_vars) (f->aux_vars))->wgt; g = new_edge(T->G, w, n, edge_vars); vp = lookup_hashtable2(edge2split, (PTR_TYPE) f); insert_hashtable2(edge2split, (PTR_TYPE) g, vp); /* * del_edge_aux_vars((edge_aux_vars)(f->aux_vars)); * f->aux_vars = NULL; */ if (lookup_hashtable2(edge2split, (PTR_TYPE) f)) set_value_null_hashtable2(edge2split, (PTR_TYPE) f); del_edge(T->G, f); f = NULL; } /* free up tomove list */ for (ln = tomove->head; ln; ln = ln->next) ln->data = NULL; del_list(tomove); tomove = NULL; }