本文整理汇总了C++中TreeType::Point方法的典型用法代码示例。如果您正苦于以下问题:C++ TreeType::Point方法的具体用法?C++ TreeType::Point怎么用?C++ TreeType::Point使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TreeType
的用法示例。
在下文中一共展示了TreeType::Point方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: distances
void NeighborSearchRules<
SortPolicy,
MetricType,
TreeType>::
UpdateAfterRecursion(TreeType& queryNode, TreeType& /* referenceNode */)
{
// Find the worst distance that the children found (including any points), and
// update the bound accordingly.
double worstDistance = SortPolicy::BestDistance();
// First look through children nodes.
for (size_t i = 0; i < queryNode.NumChildren(); ++i)
{
if (SortPolicy::IsBetter(worstDistance, queryNode.Child(i).Stat().Bound()))
worstDistance = queryNode.Child(i).Stat().Bound();
}
// Now look through children points.
for (size_t i = 0; i < queryNode.NumPoints(); ++i)
{
if (SortPolicy::IsBetter(worstDistance,
distances(distances.n_rows - 1, queryNode.Point(i))))
worstDistance = distances(distances.n_rows - 1, queryNode.Point(i));
}
// Take the worst distance from all of these, and update our bound to reflect
// that.
queryNode.Stat().Bound() = worstDistance;
}
示例2: FastMKSStat
FastMKSStat(const TreeType& node) :
bound(-DBL_MAX),
lastKernel(0.0),
lastKernelNode(NULL)
{
// Do we have to calculate the centroid?
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
{
// If this type of tree has self-children, then maybe the evaluation is
// already done. These statistics are built bottom-up, so the child stat
// should already be done.
if ((tree::TreeTraits<TreeType>::HasSelfChildren) &&
(node.NumChildren() > 0) &&
(node.Point(0) == node.Child(0).Point(0)))
{
selfKernel = node.Child(0).Stat().SelfKernel();
}
else
{
selfKernel = sqrt(node.Metric().Kernel().Evaluate(
node.Dataset().col(node.Point(0)),
node.Dataset().col(node.Point(0))));
}
}
else
{
// Calculate the centroid.
arma::vec center;
node.Center(center);
selfKernel = sqrt(node.Metric().Kernel().Evaluate(center, center));
}
}
示例3: EvaluateKernel
inline double KDERules<MetricType, KernelType, TreeType>::
Score(const size_t queryIndex, TreeType& referenceNode)
{
double score, maxKernel, minKernel, bound;
const arma::vec& queryPoint = querySet.unsafe_col(queryIndex);
const double minDistance = referenceNode.MinDistance(queryPoint);
bool newCalculations = true;
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid &&
lastQueryIndex == queryIndex &&
traversalInfo.LastReferenceNode() != NULL &&
traversalInfo.LastReferenceNode()->Point(0) == referenceNode.Point(0))
{
// Don't duplicate calculations.
newCalculations = false;
lastQueryIndex = queryIndex;
lastReferenceIndex = referenceNode.Point(0);
}
else
{
// Calculations are new.
maxKernel = kernel.Evaluate(minDistance);
minKernel = kernel.Evaluate(referenceNode.MaxDistance(queryPoint));
bound = maxKernel - minKernel;
}
if (newCalculations &&
bound <= (absError + relError * minKernel) / referenceSet.n_cols)
{
// Estimate values.
double kernelValue;
// Calculate kernel value based on reference node centroid.
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
{
kernelValue = EvaluateKernel(queryIndex, referenceNode.Point(0));
}
else
{
kde::KDEStat& referenceStat = referenceNode.Stat();
kernelValue = EvaluateKernel(queryPoint, referenceStat.Centroid());
}
densities(queryIndex) += referenceNode.NumDescendants() * kernelValue;
// Don't explore this tree branch.
score = DBL_MAX;
}
else
{
score = minDistance;
}
++scores;
traversalInfo.LastReferenceNode() = &referenceNode;
traversalInfo.LastScore() = score;
return score;
}
示例4: BaseCase
double RangeSearchRules<MetricType, TreeType>::Score(const size_t queryIndex,
TreeType& referenceNode)
{
// We must get the minimum and maximum distances and store them in this
// object.
math::Range distances;
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
{
// In this situation, we calculate the base case. So we should check to be
// sure we haven't already done that.
double baseCase;
if (tree::TreeTraits<TreeType>::HasSelfChildren &&
(referenceNode.Parent() != NULL) &&
(referenceNode.Point(0) == referenceNode.Parent()->Point(0)))
{
// If the tree has self-children and this is a self-child, the base case
// was already calculated.
baseCase = referenceNode.Parent()->Stat().LastDistance();
lastQueryIndex = queryIndex;
lastReferenceIndex = referenceNode.Point(0);
}
else
{
// We must calculate the base case by hand.
baseCase = BaseCase(queryIndex, referenceNode.Point(0));
}
// This may be possibly loose for non-ball bound trees.
distances.Lo() = baseCase - referenceNode.FurthestDescendantDistance();
distances.Hi() = baseCase + referenceNode.FurthestDescendantDistance();
// Update last distance calculation.
referenceNode.Stat().LastDistance() = baseCase;
}
else
{
distances = referenceNode.RangeDistance(querySet.unsafe_col(queryIndex));
}
// If the ranges do not overlap, prune this node.
if (!distances.Contains(range))
return DBL_MAX;
// In this case, all of the points in the reference node will be part of the
// results.
if ((distances.Lo() >= range.Lo()) && (distances.Hi() <= range.Hi()))
{
AddResult(queryIndex, referenceNode);
return DBL_MAX; // We don't need to go any deeper.
}
// Otherwise the score doesn't matter. Recursion order is irrelevant in
// range search.
return 0.0;
}
示例5: DTBStat
DTBStat(const TreeType& node) :
maxNeighborDistance(DBL_MAX),
minNeighborDistance(DBL_MAX),
bound(DBL_MAX),
componentMembership(
((node.NumPoints() == 1) && (node.NumChildren() == 0)) ?
node.Point(0) : -1) { }
示例6: DualTreeKMeansStatistic
DualTreeKMeansStatistic(TreeType& node) :
neighbor::NeighborSearchStat<neighbor::NearestNeighborSort>(),
upperBound(DBL_MAX),
lowerBound(DBL_MAX),
owner(size_t(-1)),
pruned(size_t(-1)),
staticPruned(false),
staticUpperBoundMovement(0.0),
staticLowerBoundMovement(0.0),
trueParent(node.Parent())
{
// Empirically calculate the centroid.
centroid.zeros(node.Dataset().n_rows);
for (size_t i = 0; i < node.NumPoints(); ++i)
{
// Correct handling of cover tree: don't double-count the point which
// appears in the children.
if (tree::TreeTraits<TreeType>::HasSelfChildren && i == 0 &&
node.NumChildren() > 0)
continue;
centroid += node.Dataset().col(node.Point(i));
}
for (size_t i = 0; i < node.NumChildren(); ++i)
centroid += node.Child(i).NumDescendants() *
node.Child(i).Stat().Centroid();
centroid /= node.NumDescendants();
// Set the true children correctly.
trueChildren.resize(node.NumChildren());
for (size_t i = 0; i < node.NumChildren(); ++i)
trueChildren[i] = &node.Child(i);
}
示例7: Score
inline double NeighborSearchRules<SortPolicy, MetricType, TreeType>::Score(
const size_t queryIndex,
TreeType& referenceNode)
{
++scores; // Count number of Score() calls.
double distance;
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
{
// The first point in the tree is the centroid. So we can then calculate
// the base case between that and the query point.
double baseCase = -1.0;
if (tree::TreeTraits<TreeType>::HasSelfChildren)
{
// If the parent node is the same, then we have already calculated the
// base case.
if ((referenceNode.Parent() != NULL) &&
(referenceNode.Point(0) == referenceNode.Parent()->Point(0)))
baseCase = referenceNode.Parent()->Stat().LastDistance();
else
baseCase = BaseCase(queryIndex, referenceNode.Point(0));
// Save this evaluation.
referenceNode.Stat().LastDistance() = baseCase;
}
distance = SortPolicy::CombineBest(baseCase,
referenceNode.FurthestDescendantDistance());
}
else
{
distance = SortPolicy::BestPointToNodeDistance(querySet.col(queryIndex),
&referenceNode);
}
// Compare against the best k'th distance for this query point so far.
const double bestDistance = distances(distances.n_rows - 1, queryIndex);
return (SortPolicy::IsBetter(distance, bestDistance)) ? distance : DBL_MAX;
}
示例8:
inline double DTBRules<MetricType, TreeType>::CalculateBound(
TreeType& queryNode) const
{
double worstPointBound = -DBL_MAX;
double bestPointBound = DBL_MAX;
double worstChildBound = -DBL_MAX;
double bestChildBound = DBL_MAX;
// Now, find the best and worst point bounds.
for (size_t i = 0; i < queryNode.NumPoints(); ++i)
{
const size_t pointComponent = connections.Find(queryNode.Point(i));
const double bound = neighborsDistances[pointComponent];
if (bound > worstPointBound)
worstPointBound = bound;
if (bound < bestPointBound)
bestPointBound = bound;
}
// Find the best and worst child bounds.
for (size_t i = 0; i < queryNode.NumChildren(); ++i)
{
const double maxBound = queryNode.Child(i).Stat().MaxNeighborDistance();
if (maxBound > worstChildBound)
worstChildBound = maxBound;
const double minBound = queryNode.Child(i).Stat().MinNeighborDistance();
if (minBound < bestChildBound)
bestChildBound = minBound;
}
// Now calculate the actual bounds.
const double worstBound = std::max(worstPointBound, worstChildBound);
const double bestBound = std::min(bestPointBound, bestChildBound);
// We must check that bestBound != DBL_MAX; otherwise, we risk overflow.
const double bestAdjustedBound = (bestBound == DBL_MAX) ? DBL_MAX :
bestBound + 2 * queryNode.FurthestDescendantDistance();
// Update the relevant quantities in the node.
queryNode.Stat().MaxNeighborDistance() = worstBound;
queryNode.Stat().MinNeighborDistance() = bestBound;
queryNode.Stat().Bound() = std::min(worstBound, bestAdjustedBound);
return queryNode.Stat().Bound();
}
示例9: DualTreeKMeansStatistic
DualTreeKMeansStatistic(TreeType& node) :
closestQueryNode(NULL),
minQueryNodeDistance(DBL_MAX),
maxQueryNodeDistance(DBL_MAX),
clustersPruned(0),
iteration(size_t() - 1)
{
// Empirically calculate the centroid.
centroid.zeros(node.Dataset().n_rows);
for (size_t i = 0; i < node.NumPoints(); ++i)
centroid += node.Dataset().col(node.Point(i));
for (size_t i = 0; i < node.NumChildren(); ++i)
centroid += node.Child(i).NumDescendants() *
node.Child(i).Stat().Centroid();
centroid /= node.NumDescendants();
}
示例10: PellegMooreKMeansStatistic
PellegMooreKMeansStatistic(TreeType& node)
{
centroid.zeros(node.Dataset().n_rows);
// Hope it's a depth-first build procedure. Also, this won't work right for
// trees that have self-children or stuff like that.
for (size_t i = 0; i < node.NumChildren(); ++i)
{
centroid += node.Child(i).NumDescendants() *
node.Child(i).Stat().Centroid();
}
for (size_t i = 0; i < node.NumPoints(); ++i)
{
centroid += node.Dataset().col(node.Point(i));
}
if (node.NumDescendants() > 0)
centroid /= node.NumDescendants();
else
centroid.fill(DBL_MAX); // Invalid centroid. What else can we do?
}
示例11: Traverse
void GreedySingleTreeTraverser<TreeType, RuleType>::Traverse(
const size_t queryIndex,
TreeType& referenceNode)
{
// Run the base case as necessary for all the points in the reference node.
for (size_t i = 0; i < referenceNode.NumPoints(); ++i)
rule.BaseCase(queryIndex, referenceNode.Point(i));
size_t bestChild = rule.GetBestChild(queryIndex, referenceNode);
size_t numDescendants;
// Check that referencenode is not a leaf node while calculating number of
// descendants of it's best child.
if (!referenceNode.IsLeaf())
numDescendants = referenceNode.Child(bestChild).NumDescendants();
else
numDescendants = referenceNode.NumPoints();
// If number of descendants are more than minBaseCases than we can go along
// with best child otherwise we need to traverse for each descendant to
// ensure that we calculate at least minBaseCases number of base cases.
if (!referenceNode.IsLeaf())
{
if (numDescendants > minBaseCases)
{
// We are prunning all but one child.
numPrunes += referenceNode.NumChildren() - 1;
// Recurse the best child.
Traverse(queryIndex, referenceNode.Child(bestChild));
}
else
{
// Run the base case over first minBaseCases number of descendants.
for (size_t i = 0; i <= minBaseCases; ++i)
rule.BaseCase(queryIndex, referenceNode.Descendant(i));
}
}
}
示例12:
void RangeSearchRules<MetricType, TreeType>::AddResult(const size_t queryIndex,
TreeType& referenceNode)
{
// Some types of trees calculate the base case evaluation before Score() is
// called, so if the base case has already been calculated, then we must avoid
// adding that point to the results again.
size_t baseCaseMod = 0;
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid &&
(queryIndex == lastQueryIndex) &&
(referenceNode.Point(0) == lastReferenceIndex))
{
baseCaseMod = 1;
}
// Resize distances and neighbors vectors appropriately. We have to use
// reserve() and not resize(), because we don't know if we will encounter the
// case where the datasets and points are the same (and we skip in that case).
const size_t oldSize = neighbors[queryIndex].size();
neighbors[queryIndex].reserve(oldSize + referenceNode.NumDescendants() -
baseCaseMod);
distances[queryIndex].reserve(oldSize + referenceNode.NumDescendants() -
baseCaseMod);
for (size_t i = baseCaseMod; i < referenceNode.NumDescendants(); ++i)
{
if ((&referenceSet == &querySet) &&
(queryIndex == referenceNode.Descendant(i)))
continue;
const double distance = metric.Evaluate(querySet.unsafe_col(queryIndex),
referenceNode.Dataset().unsafe_col(referenceNode.Descendant(i)));
neighbors[queryIndex].push_back(referenceNode.Descendant(i));
distances[queryIndex].push_back(distance);
}
}
示例13: CheckTrees
void CheckTrees(TreeType& tree,
TreeType& xmlTree,
TreeType& textTree,
TreeType& binaryTree)
{
const typename TreeType::Mat* dataset = &tree.Dataset();
// Make sure that the data matrices are the same.
if (tree.Parent() == NULL)
{
CheckMatrices(*dataset,
xmlTree.Dataset(),
textTree.Dataset(),
binaryTree.Dataset());
// Also ensure that the other parents are null too.
BOOST_REQUIRE_EQUAL(xmlTree.Parent(), (TreeType*) NULL);
BOOST_REQUIRE_EQUAL(textTree.Parent(), (TreeType*) NULL);
BOOST_REQUIRE_EQUAL(binaryTree.Parent(), (TreeType*) NULL);
}
// Make sure the number of children is the same.
BOOST_REQUIRE_EQUAL(tree.NumChildren(), xmlTree.NumChildren());
BOOST_REQUIRE_EQUAL(tree.NumChildren(), textTree.NumChildren());
BOOST_REQUIRE_EQUAL(tree.NumChildren(), binaryTree.NumChildren());
// Make sure the number of descendants is the same.
BOOST_REQUIRE_EQUAL(tree.NumDescendants(), xmlTree.NumDescendants());
BOOST_REQUIRE_EQUAL(tree.NumDescendants(), textTree.NumDescendants());
BOOST_REQUIRE_EQUAL(tree.NumDescendants(), binaryTree.NumDescendants());
// Make sure the number of points is the same.
BOOST_REQUIRE_EQUAL(tree.NumPoints(), xmlTree.NumPoints());
BOOST_REQUIRE_EQUAL(tree.NumPoints(), textTree.NumPoints());
BOOST_REQUIRE_EQUAL(tree.NumPoints(), binaryTree.NumPoints());
// Check that each point is the same.
for (size_t i = 0; i < tree.NumPoints(); ++i)
{
BOOST_REQUIRE_EQUAL(tree.Point(i), xmlTree.Point(i));
BOOST_REQUIRE_EQUAL(tree.Point(i), textTree.Point(i));
BOOST_REQUIRE_EQUAL(tree.Point(i), binaryTree.Point(i));
}
// Check that the parent distance is the same.
BOOST_REQUIRE_CLOSE(tree.ParentDistance(), xmlTree.ParentDistance(), 1e-8);
BOOST_REQUIRE_CLOSE(tree.ParentDistance(), textTree.ParentDistance(), 1e-8);
BOOST_REQUIRE_CLOSE(tree.ParentDistance(), binaryTree.ParentDistance(), 1e-8);
// Check that the furthest descendant distance is the same.
BOOST_REQUIRE_CLOSE(tree.FurthestDescendantDistance(),
xmlTree.FurthestDescendantDistance(), 1e-8);
BOOST_REQUIRE_CLOSE(tree.FurthestDescendantDistance(),
textTree.FurthestDescendantDistance(), 1e-8);
BOOST_REQUIRE_CLOSE(tree.FurthestDescendantDistance(),
binaryTree.FurthestDescendantDistance(), 1e-8);
// Check that the minimum bound distance is the same.
BOOST_REQUIRE_CLOSE(tree.MinimumBoundDistance(),
xmlTree.MinimumBoundDistance(), 1e-8);
BOOST_REQUIRE_CLOSE(tree.MinimumBoundDistance(),
textTree.MinimumBoundDistance(), 1e-8);
BOOST_REQUIRE_CLOSE(tree.MinimumBoundDistance(),
binaryTree.MinimumBoundDistance(), 1e-8);
// Recurse into the children.
for (size_t i = 0; i < tree.NumChildren(); ++i)
{
// Check that the child dataset is the same.
BOOST_REQUIRE_EQUAL(&xmlTree.Dataset(), &xmlTree.Child(i).Dataset());
BOOST_REQUIRE_EQUAL(&textTree.Dataset(), &textTree.Child(i).Dataset());
BOOST_REQUIRE_EQUAL(&binaryTree.Dataset(), &binaryTree.Child(i).Dataset());
// Make sure the parent link is right.
BOOST_REQUIRE_EQUAL(xmlTree.Child(i).Parent(), &xmlTree);
BOOST_REQUIRE_EQUAL(textTree.Child(i).Parent(), &textTree);
BOOST_REQUIRE_EQUAL(binaryTree.Child(i).Parent(), &binaryTree);
CheckTrees(tree.Child(i), xmlTree.Child(i), textTree.Child(i),
binaryTree.Child(i));
}
}
示例14: CalculateBound
//.........这里部分代码省略.........
else
{
// The reference parent could be NULL, which does weird things and we have
// to consider.
if (traversalInfo.LastQueryNode() != NULL)
{
adjustedScore += refDescDist *
traversalInfo.LastQueryNode()->Stat().SelfKernel();
dualRefTerm = refDescDist;
}
else
{
// This makes it so a child-parent (or parent-parent) prune is not
// possible.
dualRefTerm = 0.0;
adjustedScore = bestKernel;
}
}
// Now add the dual term.
adjustedScore += (dualQueryTerm * dualRefTerm);
if (adjustedScore < bestKernel)
{
// It is not possible that this node combination can contain a point
// combination with kernel value better than the minimum kernel value to
// improve any of the results, so we can prune it.
return DBL_MAX;
}
// We were unable to perform a parent-child or parent-parent prune, so now we
// must calculate kernel evaluation, if necessary.
double kernelEval = 0.0;
if (tree::TreeTraits<TreeType>::FirstPointIsCentroid)
{
// For this type of tree, we may have already calculated the base case in
// the parents.
if ((traversalInfo.LastQueryNode() != NULL) &&
(traversalInfo.LastReferenceNode() != NULL) &&
(traversalInfo.LastQueryNode()->Point(0) == queryNode.Point(0)) &&
(traversalInfo.LastReferenceNode()->Point(0) == referenceNode.Point(0)))
{
// Base case already done.
kernelEval = traversalInfo.LastBaseCase();
// When BaseCase() is called after Score(), these must be correct so that
// another kernel evaluation is not performed.
lastQueryIndex = queryNode.Point(0);
lastReferenceIndex = referenceNode.Point(0);
}
else
{
// The kernel must be evaluated, but it is between points in the dataset,
// so we can call BaseCase(). BaseCase() will set lastQueryIndex and
// lastReferenceIndex correctly.
kernelEval = BaseCase(queryNode.Point(0), referenceNode.Point(0));
}
traversalInfo.LastBaseCase() = kernelEval;
}
else
{
// Calculate the maximum possible kernel value.
arma::vec queryCentroid;
arma::vec refCentroid;
queryNode.Centroid(queryCentroid);
示例15: CalculateBound
inline double NeighborSearchRules<SortPolicy, MetricType, TreeType>::
CalculateBound(TreeType& queryNode) const
{
// We have five possible bounds, and we must take the best of them all. We
// don't use min/max here, but instead "best/worst", because this is general
// to the nearest-neighbors/furthest-neighbors cases. For nearest neighbors,
// min = best, max = worst.
//
// (1) worst ( worst_{all points p in queryNode} D_p[k],
// worst_{all children c in queryNode} B(c) );
// (2) best_{all points p in queryNode} D_p[k] + worst child distance +
// worst descendant distance;
// (3) best_{all children c in queryNode} B(c) +
// 2 ( worst descendant distance of queryNode -
// worst descendant distance of c );
// (4) B_1(parent of queryNode)
// (5) B_2(parent of queryNode);
//
// D_p[k] is the current k'th candidate distance for point p.
// So we will loop over the points in queryNode and the children in queryNode
// to calculate all five of these quantities.
// Hm, can we populate our distances vector with estimates from the parent?
// This is written specifically for the cover tree and assumes only one point
// in a node.
// if (queryNode.Parent() != NULL && queryNode.NumPoints() > 0)
// {
// size_t parentIndexStart = 0;
// for (size_t i = 0; i < neighbors.n_rows; ++i)
// {
// const double pointDistance = distances(i, queryNode.Point(0));
// if (pointDistance == DBL_MAX)
// {
// // Cool, can we take an estimate from the parent?
// const double parentWorstBound = distances(distances.n_rows - 1,
// queryNode.Parent()->Point(0));
// if (parentWorstBound != DBL_MAX)
// {
// const double parentAdjustedDistance = parentWorstBound +
// queryNode.ParentDistance();
// distances(i, queryNode.Point(0)) = parentAdjustedDistance;
// }
// }
// }
// }
double worstPointDistance = SortPolicy::BestDistance();
double bestPointDistance = SortPolicy::WorstDistance();
// Loop over all points in this node to find the best and worst distance
// candidates (for (1) and (2)).
for (size_t i = 0; i < queryNode.NumPoints(); ++i)
{
const double distance = distances(distances.n_rows - 1,
queryNode.Point(i));
if (SortPolicy::IsBetter(distance, bestPointDistance))
bestPointDistance = distance;
if (SortPolicy::IsBetter(worstPointDistance, distance))
worstPointDistance = distance;
}
// Loop over all the children in this node to find the worst bound (for (1))
// and the best bound with the correcting factor for descendant distances (for
// (3)).
double worstChildBound = SortPolicy::BestDistance();
double bestAdjustedChildBound = SortPolicy::WorstDistance();
const double queryMaxDescendantDistance =
queryNode.FurthestDescendantDistance();
for (size_t i = 0; i < queryNode.NumChildren(); ++i)
{
const double firstBound = queryNode.Child(i).Stat().FirstBound();
const double secondBound = queryNode.Child(i).Stat().SecondBound();
const double childMaxDescendantDistance =
queryNode.Child(i).FurthestDescendantDistance();
if (SortPolicy::IsBetter(worstChildBound, firstBound))
worstChildBound = firstBound;
// Now calculate adjustment for maximum descendant distances.
const double adjustedBound = SortPolicy::CombineWorst(secondBound,
2 * (queryMaxDescendantDistance - childMaxDescendantDistance));
if (SortPolicy::IsBetter(adjustedBound, bestAdjustedChildBound))
bestAdjustedChildBound = adjustedBound;
}
// This is bound (1).
const double firstBound =
(SortPolicy::IsBetter(worstPointDistance, worstChildBound)) ?
worstChildBound : worstPointDistance;
// This is bound (2).
const double secondBound = SortPolicy::CombineWorst(
SortPolicy::CombineWorst(bestPointDistance, queryMaxDescendantDistance),
queryNode.FurthestPointDistance());
// Bound (3) is bestAdjustedChildBound.
// Bounds (4) and (5) are the parent bounds.
const double fourthBound = (queryNode.Parent() != NULL) ?
//.........这里部分代码省略.........