// Helper method for updateM( boolean, Node, Node ) // Calculates M for Node n, given that M for the two children // of n has been calculated. // (Last modified: 10/02/01) private void calculateMforNode(Node n) { if (!n.isExternal()) { boolean was_duplication = n.isDuplication(); Node a = n.getChild1().getLink(), b = n.getChild2().getLink(); while (a != b) { if (a.getID() > b.getID()) { a = a.getParent(); } else { b = b.getParent(); } } n.setLink(a); if (a == n.getChild1().getLink() || a == n.getChild2().getLink()) { n.setDuplication(true); if (!was_duplication) { increaseDuplications(); } } else { n.setDuplication(false); if (was_duplication) { decreaseDuplications(); } } } } // calculateMforNode( Node )
/** * Traverses the subtree of Node g in postorder, calculating the mapping function M, and * determines which nodes represent speciation events and which ones duplication events. * * <p>Preconditions: Mapping M for external nodes must have been calculated and the species tree * must be labelled in preorder. * * <p>(Last modified: 01/11/01) * * @param g starting node of a gene tree - normally the root */ void geneTreePostOrderTraversal(Node g) { Node a, b; if (!g.isExternal()) { geneTreePostOrderTraversal(g.getChild1()); geneTreePostOrderTraversal(g.getChild2()); a = g.getChild1().getLink(); b = g.getChild2().getLink(); while (a != b) { if (a.getID() > b.getID()) { a = a.getParent(); } else { b = b.getParent(); } } g.setLink(a); // Determines whether dup. or spec. g.setDuplicationOrSpecAssigned(true); if (a == g.getChild1().getLink() || a == g.getChild2().getLink()) { g.setDuplication(true); increaseDuplications(); } else { g.setDuplication(false); } } } // geneTreePostOrderTraversal( Node )