void BinarySpaceTree<BoundType, StatisticType, MatType>:: SingleTreeTraverser<RuleType>::Traverse( const size_t queryIndex, BinarySpaceTree<BoundType, StatisticType, MatType>& referenceNode) { // If we are a leaf, run the base case as necessary. if (referenceNode.IsLeaf()) { for (size_t i = referenceNode.Begin(); i < referenceNode.End(); ++i) rule.BaseCase(queryIndex, i); } else { // If either score is DBL_MAX, we do not recurse into that node. double leftScore = rule.Score(queryIndex, *referenceNode.Left()); double rightScore = rule.Score(queryIndex, *referenceNode.Right()); if (leftScore < rightScore) { // Recurse to the left. Traverse(queryIndex, *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(queryIndex, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(queryIndex, *referenceNode.Right()); // Recurse to the right. else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(queryIndex, *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(queryIndex, *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) Traverse(queryIndex, *referenceNode.Left()); // Recurse to the left. else ++numPrunes; } else // leftScore is equal to rightScore. { if (leftScore == DBL_MAX) { numPrunes += 2; // Pruned both left and right. } else { // Choose the left first. Traverse(queryIndex, *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(queryIndex, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(queryIndex, *referenceNode.Right()); else ++numPrunes; } } } }
void BinarySpaceTree<BoundType, StatisticType, MatType>:: DualTreeTraverser<RuleType>::Traverse( BinarySpaceTree<BoundType, StatisticType, MatType>& queryNode, BinarySpaceTree<BoundType, StatisticType, MatType>& referenceNode) { // If both are leaves, we must evaluate the base case. if (queryNode.IsLeaf() && referenceNode.IsLeaf()) { // Loop through each of the points in each node. for (size_t query = queryNode.Begin(); query < queryNode.End(); ++query) { // See if we need to investigate this point (this function should be // implemented for the single-tree recursion too). const double score = rule.Score(query, referenceNode); if (score == DBL_MAX) continue; // We can't improve this particular point. for (size_t ref = referenceNode.Begin(); ref < referenceNode.End(); ++ref) rule.BaseCase(query, ref); } } else if ((!queryNode.IsLeaf()) && referenceNode.IsLeaf()) { // We have to recurse down the query node. In this case the recursion order // does not matter. double leftScore = rule.Score(*queryNode.Left(), referenceNode); if (leftScore != DBL_MAX) Traverse(*queryNode.Left(), referenceNode); else ++numPrunes; double rightScore = rule.Score(*queryNode.Right(), referenceNode); if (rightScore != DBL_MAX) Traverse(*queryNode.Right(), referenceNode); else ++numPrunes; } else if (queryNode.IsLeaf() && (!referenceNode.IsLeaf())) { // We have to recurse down the reference node. In this case the recursion // order does matter. double leftScore = rule.Score(queryNode, *referenceNode.Left()); double rightScore = rule.Score(queryNode, *referenceNode.Right()); if (leftScore < rightScore) { // Recurse to the left. Traverse(queryNode, *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(queryNode, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(queryNode, *referenceNode.Right()); else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(queryNode, *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(queryNode, *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) Traverse(queryNode, *referenceNode.Left()); else ++numPrunes; } else // leftScore is equal to rightScore. { if (leftScore == DBL_MAX) { numPrunes += 2; } else { // Choose the left first. Traverse(queryNode, *referenceNode.Left()); rightScore = rule.Rescore(queryNode, *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(queryNode, *referenceNode.Right()); else ++numPrunes; } } } else { // We have to recurse down both query and reference nodes. Because the // query descent order does not matter, we will go to the left query child // first. double leftScore = rule.Score(*queryNode.Left(), *referenceNode.Left()); double rightScore = rule.Score(*queryNode.Left(), *referenceNode.Right()); if (leftScore < rightScore) { // Recurse to the left. Traverse(*queryNode.Left(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Left(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(*queryNode.Left(), *referenceNode.Right()); else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(*queryNode.Left(), *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(*queryNode.Left(), *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) Traverse(*queryNode.Left(), *referenceNode.Left()); else ++numPrunes; } else { if (leftScore == DBL_MAX) { numPrunes += 2; } else { // Choose the left first. Traverse(*queryNode.Left(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Left(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(*queryNode.Left(), *referenceNode.Right()); else ++numPrunes; } } // Now recurse down the right query node. leftScore = rule.Score(*queryNode.Right(), *referenceNode.Left()); rightScore = rule.Score(*queryNode.Right(), *referenceNode.Right()); if (leftScore < rightScore) { // Recurse to the left. Traverse(*queryNode.Right(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Right(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(*queryNode.Right(), *referenceNode.Right()); else ++numPrunes; } else if (rightScore < leftScore) { // Recurse to the right. Traverse(*queryNode.Right(), *referenceNode.Right()); // Is it still valid to recurse to the left? leftScore = rule.Rescore(*queryNode.Right(), *referenceNode.Left(), leftScore); if (leftScore != DBL_MAX) Traverse(*queryNode.Right(), *referenceNode.Left()); else ++numPrunes; } else { if (leftScore == DBL_MAX) { numPrunes += 2; } else { // Choose the left first. Traverse(*queryNode.Right(), *referenceNode.Left()); // Is it still valid to recurse to the right? rightScore = rule.Rescore(*queryNode.Right(), *referenceNode.Right(), rightScore); if (rightScore != DBL_MAX) Traverse(*queryNode.Right(), *referenceNode.Right()); else ++numPrunes; } } } // Now update any necessary information after recursion. rule.UpdateAfterRecursion(queryNode, referenceNode); }