void ClusterByHeight(const Tree &tree, double dMaxHeight, unsigned Subtrees[], unsigned *ptruSubtreeCount) { if (!tree.IsRooted()) Quit("ClusterByHeight: requires rooted tree"); #if TRACE Log("ClusterByHeight, max height=%g\n", dMaxHeight); #endif unsigned uSubtreeCount = 0; const unsigned uNodeCount = tree.GetNodeCount(); for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex) { if (tree.IsRoot(uNodeIndex)) continue; unsigned uParent = tree.GetParent(uNodeIndex); double dHeight = tree.GetNodeHeight(uNodeIndex); double dParentHeight = tree.GetNodeHeight(uParent); #if TRACE Log("Node %3u Height %5.2f ParentHeight %5.2f\n", uNodeIndex, dHeight, dParentHeight); #endif if (dParentHeight > dMaxHeight && dHeight <= dMaxHeight) { Subtrees[uSubtreeCount] = uNodeIndex; #if TRACE Log("Subtree[%u]=%u\n", uSubtreeCount, uNodeIndex); #endif ++uSubtreeCount; } } *ptruSubtreeCount = uSubtreeCount; }
static void ClusterBySubfamCount_Iteration(const Tree &tree, unsigned Subfams[], unsigned uCount) { // Find highest child node of current set of subfamilies. double dHighestHeight = -1e20; int iParentSubscript = -1; for (int n = 0; n < (int) uCount; ++n) { const unsigned uNodeIndex = Subfams[n]; if (tree.IsLeaf(uNodeIndex)) continue; const unsigned uLeft = tree.GetLeft(uNodeIndex); const double dHeightLeft = tree.GetNodeHeight(uLeft); if (dHeightLeft > dHighestHeight) { dHighestHeight = dHeightLeft; iParentSubscript = n; } const unsigned uRight = tree.GetRight(uNodeIndex); const double dHeightRight = tree.GetNodeHeight(uRight); if (dHeightRight > dHighestHeight) { dHighestHeight = dHeightRight; iParentSubscript = n; } } if (-1 == iParentSubscript) Quit("CBSFCIter: failed to find highest child"); const unsigned uNodeIndex = Subfams[iParentSubscript]; const unsigned uLeft = tree.GetLeft(uNodeIndex); const unsigned uRight = tree.GetRight(uNodeIndex); // Delete parent by replacing with left child Subfams[iParentSubscript] = uLeft; // Append right child to list Subfams[uCount] = uRight; #if TRACE { Log("Iter %3u:", uCount); for (unsigned n = 0; n < uCount; ++n) Log(" %u", Subfams[n]); Log("\n"); } #endif }
void GetInternalNodesInHeightOrder(const Tree &tree, unsigned NodeIndexes[]) { const unsigned uNodeCount = tree.GetNodeCount(); if (uNodeCount < 3) Quit("GetInternalNodesInHeightOrder: %u nodes, none are internal", uNodeCount); const unsigned uInternalNodeCount = (uNodeCount - 1)/2; double *Heights = new double[uInternalNodeCount]; unsigned uIndex = 0; for (unsigned uNodeIndex = 0; uNodeIndex < uNodeCount; ++uNodeIndex) { if (tree.IsLeaf(uNodeIndex)) continue; NodeIndexes[uIndex] = uNodeIndex; Heights[uIndex] = tree.GetNodeHeight(uNodeIndex); ++uIndex; } if (uIndex != uInternalNodeCount) Quit("Internal error: GetInternalNodesInHeightOrder"); // Simple but slow bubble sort (probably don't care about speed here) bool bDone = false; while (!bDone) { bDone = true; for (unsigned i = 0; i < uInternalNodeCount - 1; ++i) { if (Heights[i] > Heights[i+1]) { double dTmp = Heights[i]; Heights[i] = Heights[i+1]; Heights[i+1] = dTmp; unsigned uTmp = NodeIndexes[i]; NodeIndexes[i] = NodeIndexes[i+1]; NodeIndexes[i+1] = uTmp; bDone = false; } } } #if TRACE Log("Internal node index Height\n"); Log("------------------- --------\n"); // 1234567890123456789 123456789 for (unsigned n = 0; n < uInternalNodeCount; ++n) Log("%19u %9.3f\n", NodeIndexes[n], Heights[n]); #endif delete[] Heights; }