Um, I made it faster. We're well into the land of confusion. Confusion will reign until eventual refactoring. Hamerly prunes still don't appear to be working properly after a couple iterations.
This commit is contained in:
@@ -66,7 +66,8 @@ class DualTreeKMeans
|
||||
const arma::vec& clusterDistances,
|
||||
const arma::Col<size_t>& assignments,
|
||||
const arma::mat& oldCentroids,
|
||||
const arma::mat& dataset);
|
||||
const arma::mat& dataset,
|
||||
const std::vector<size_t>& oldFromNew);
|
||||
};
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
|
||||
@@ -127,7 +127,7 @@ double DualTreeKMeans<MetricType, MatType, TreeType>::Iterate(
|
||||
|
||||
// Update the tree with the centroid movement information.
|
||||
TreeUpdate(tree, centroids.n_cols, clusterDistances, assignments,
|
||||
oldCentroids, dataset);
|
||||
oldCentroids, dataset, oldFromNewCentroids);
|
||||
|
||||
delete centroidTree;
|
||||
|
||||
@@ -177,7 +177,8 @@ void DualTreeKMeans<MetricType, MatType, TreeType>::TreeUpdate(
|
||||
const arma::vec& clusterDistances,
|
||||
const arma::Col<size_t>& assignments,
|
||||
const arma::mat& centroids,
|
||||
const arma::mat& dataset)
|
||||
const arma::mat& dataset,
|
||||
const std::vector<size_t>& oldFromNew)
|
||||
{
|
||||
// This is basically IterationUpdate(), but pulled out to be separate from the
|
||||
// actual dual-tree algorithm.
|
||||
@@ -186,9 +187,15 @@ void DualTreeKMeans<MetricType, MatType, TreeType>::TreeUpdate(
|
||||
node->Stat().Owner() = node->Parent()->Stat().Owner();
|
||||
|
||||
const size_t cluster = assignments[node->Descendant(0)];
|
||||
if (node->Begin() == 16954)
|
||||
Log::Info << "r16954c" << node->Count() << ", descendant 0 has cluster "
|
||||
<< cluster << ".\n";
|
||||
bool allSame = true;
|
||||
for (size_t i = 1; i < node->NumDescendants(); ++i)
|
||||
{
|
||||
if (node->Begin() == 16954)
|
||||
Log::Info << "Descendant " << i << " has cluster " <<
|
||||
assignments[node->Descendant(i)] << ".\n";
|
||||
if (assignments[node->Descendant(i)] != cluster)
|
||||
{
|
||||
allSame = false;
|
||||
@@ -198,7 +205,10 @@ void DualTreeKMeans<MetricType, MatType, TreeType>::TreeUpdate(
|
||||
|
||||
if (allSame)
|
||||
node->Stat().Owner() = cluster;
|
||||
else
|
||||
node->Stat().Owner() = clusters; // No owner.
|
||||
|
||||
const bool prunedLastIteration = node->Stat().HamerlyPruned();
|
||||
node->Stat().HamerlyPruned() = false;
|
||||
|
||||
// The easy case: this node had an owner.
|
||||
@@ -221,29 +231,159 @@ void DualTreeKMeans<MetricType, MatType, TreeType>::TreeUpdate(
|
||||
if (node->Stat().SecondClosestBound() == DBL_MAX && node->Parent() == NULL)
|
||||
node->Stat().SecondClosestBound() = 0.0; // Don't prune the root.
|
||||
|
||||
if (node->Begin() == 34654)
|
||||
Log::Warn << "r34654c" << node->Count() << " scb " <<
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "r16954c" << node->Count() << " scb " <<
|
||||
node->Stat().SecondClosestBound() << " and lscb " <<
|
||||
node->Stat().LastSecondClosestBound() << ".\n";
|
||||
|
||||
if (node->Parent()->Stat().SecondClosestBound() != DBL_MAX &&
|
||||
node->Stat().LastSecondClosestBound() != DBL_MAX)
|
||||
// If both the second closest bound and last second closest bound are valid,
|
||||
// we have the option of taking the better of the two bounds. But if only
|
||||
// one is valid, take the minimum of the two (which will be the valid one).
|
||||
// If neither is valid, then we end up with a second closest bound of
|
||||
// DBL_MAX.
|
||||
const double scb = node->Stat().SecondClosestBound();
|
||||
const double lscb = node->Stat().LastSecondClosestBound();
|
||||
if (scb != DBL_MAX && lscb != DBL_MAX)
|
||||
node->Stat().SecondClosestBound() = std::max(scb, lscb);
|
||||
else
|
||||
node->Stat().SecondClosestBound() = std::min(scb, lscb);
|
||||
|
||||
// But if we were Hamerly pruned last time, we can't trust the second
|
||||
// closest bound and thus have to take last iteration's.
|
||||
if (prunedLastIteration)
|
||||
node->Stat().SecondClosestBound() = lscb;
|
||||
else
|
||||
{
|
||||
// Now, we must ensure that we don't need to take the parent's second
|
||||
// closest bound. We surely do if the current bound is DBL_MAX. We
|
||||
// already took care of the root node earlier so we don't need to check if
|
||||
// Parent() is NULL.
|
||||
if (node->Stat().SecondClosestBound() == DBL_MAX)
|
||||
node->Stat().SecondClosestBound() =
|
||||
node->Parent()->Stat().SecondClosestBound();
|
||||
|
||||
// There may exist a case where the true second closest query node got
|
||||
// pruned by the parent, and was thus never visited with this node. This
|
||||
// situation occurs if the second closest query node is not a descendant
|
||||
// of the second closest query node of the parent.
|
||||
if (node->Stat().SecondClosestQueryNode() != NULL)
|
||||
{
|
||||
if (node->Begin() == 16954)
|
||||
{
|
||||
Log::Warn << "Second closest query node is q" << ((TreeType*)
|
||||
node->Stat().SecondClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
node->Stat().SecondClosestQueryNode())->Count() << ", with scb " <<
|
||||
node->Stat().SecondClosestBound() << ".\n";
|
||||
Log::Warn << "True SCB to this node should be " <<
|
||||
node->MinDistance((TreeType*) node->Stat().SecondClosestQueryNode()) << ".\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (node->Stat().ClosestQueryNode() != NULL)
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "Closest query node: q" << ((TreeType*)
|
||||
node->Stat().ClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
node->Stat().ClosestQueryNode())->Count() << ", with MQND " <<
|
||||
node->Stat().MaxQueryNodeDistance() << " and mQND " <<
|
||||
node->Stat().MinQueryNodeDistance() << ".\n";
|
||||
|
||||
// If the closest query node contains more than one descendant, we have to
|
||||
// find the closest...
|
||||
TreeType* cqn = (TreeType*) node->Stat().ClosestQueryNode();
|
||||
if (cqn != NULL && cqn->NumDescendants() > 1)
|
||||
{
|
||||
size_t closest = centroids.n_cols;
|
||||
double closestDistance = DBL_MAX;
|
||||
size_t secondClosest = centroids.n_cols;
|
||||
double secondClosestDistance = DBL_MAX;
|
||||
for (size_t i = 0; i < cqn->NumDescendants(); ++i)
|
||||
{
|
||||
const size_t index = cqn->Descendant(i);
|
||||
const double distance =
|
||||
node->MinDistance(centroids.col(oldFromNew[index]));
|
||||
// Log::Info << "Index " << index << ", distance " << distance << " (i "
|
||||
// << i + cqn->Begin() << ").\n";
|
||||
++distanceCalculations;
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
secondClosest = closest;
|
||||
secondClosestDistance = closestDistance;
|
||||
closest = index;
|
||||
closestDistance = distance;
|
||||
}
|
||||
else if (distance < secondClosestDistance)
|
||||
{
|
||||
secondClosest = index;
|
||||
secondClosestDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate maximum distance.
|
||||
const double maxDistance = node->MaxDistance(centroids.col(closest));
|
||||
++distanceCalculations;
|
||||
|
||||
node->Stat().MinQueryNodeDistance() = closestDistance;
|
||||
node->Stat().MaxQueryNodeDistance() = maxDistance;
|
||||
if (secondClosestDistance < node->Stat().SecondClosestBound())
|
||||
node->Stat().SecondClosestBound() = secondClosestDistance;
|
||||
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "After recalculation, closest for r" << node->Begin() << "c" << node->Count()
|
||||
<< " is " << closest << ", with mQND " << node->Stat().MinQueryNodeDistance() <<
|
||||
", MQND" << node->Stat().MaxQueryNodeDistance() << ", and scb " <<
|
||||
node->Stat().SecondClosestBound() << ", " << secondClosest << ".\n";
|
||||
}
|
||||
|
||||
if (node->Parent() != NULL &&
|
||||
node->Parent()->Stat().SecondClosestQueryNode() != NULL)
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "Parent's (r" << node->Parent()->Begin() << "c"
|
||||
<< node->Parent()->Count() << ") second closest query node is q" << ((TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode())->Count() << ", with scb " <<
|
||||
node->Parent()->Stat().SecondClosestBound() << ".\n";
|
||||
|
||||
if (node->Parent() != NULL &&
|
||||
node->Stat().SecondClosestQueryNode() != NULL &&
|
||||
node->Parent()->Stat().SecondClosestQueryNode() != NULL && !IsDescendantOf((*(TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode()), (*(TreeType*)
|
||||
node->Stat().SecondClosestQueryNode())))
|
||||
{
|
||||
// Does this even work?
|
||||
const double minDistance = node->MinDistance((TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode());
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "r16954c" << node->Count() << " has min distance " <<
|
||||
minDistance << " to SCQN of parent (q" << ((TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode())->Count() << ")\n";
|
||||
|
||||
if (minDistance < node->Stat().SecondClosestBound())
|
||||
{
|
||||
node->Stat().SecondClosestBound() =
|
||||
std::max(node->Parent()->Stat().SecondClosestBound(),
|
||||
node->Stat().LastSecondClosestBound());
|
||||
else
|
||||
node->Stat().SecondClosestBound() =
|
||||
std::min(node->Parent()->Stat().SecondClosestBound(),
|
||||
node->Stat().LastSecondClosestBound());
|
||||
// if (node->Begin() == 35871)
|
||||
// Log::Warn << "Update second closest bound for r35871c" <<
|
||||
node->Parent()->Stat().SecondClosestBound();
|
||||
node->Stat().SecondClosestQueryNode() =
|
||||
node->Parent()->Stat().SecondClosestQueryNode();
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "r16954c" << node->Count() << " has recalculated scb "
|
||||
<< node->Stat().SecondClosestBound() << ".\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "r16954c" << node->Count() << " now scb " <<
|
||||
node->Stat().SecondClosestBound() << " and lscb " <<
|
||||
node->Stat().LastSecondClosestBound() << ".\n";
|
||||
// if (node->Begin() == 16954)
|
||||
// Log::Warn << "Update second closest bound for r16954c" <<
|
||||
//node->Count() << " to " << node->Stat().SecondClosestBound() << ", which could "
|
||||
// << "have been parent's (" << node->Parent()->Stat().SecondClosestBound()
|
||||
//<< ") or adjusted last iteration's (" << node->Stat().LastSecondClosestBound()
|
||||
//<< ").\n";
|
||||
|
||||
// if (node->Begin() == 35871)
|
||||
// Log::Warn << "r35871c" << node->Count() << " has second bound " <<
|
||||
// if (node->Begin() == 16954)
|
||||
// Log::Warn << "r16954c" << node->Count() << " has second bound " <<
|
||||
//node->Stat().SecondClosestBound() << " (q" << ((TreeType*)
|
||||
//node->Stat().SecondClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
//node->Stat().SecondClosestQueryNode())->Count() << ") and parent has second "
|
||||
@@ -259,61 +399,61 @@ node->Stat().SecondClosestQueryNode()), *((TreeType*)
|
||||
node->Parent()->Stat().SecondClosestQueryNode())) &&
|
||||
node->Parent()->Stat().SecondClosestBound() < node->Stat().SecondClosestBound())
|
||||
{
|
||||
// if (node->Begin() == 35871)
|
||||
// Log::Warn << "Take second closest bound for r35871c" <<
|
||||
// if (node->Begin() == 16954)
|
||||
// Log::Warn << "Take second closest bound for r16954c" <<
|
||||
//node->Count() << " from parent: " << node->Parent()->Stat().SecondClosestBound()
|
||||
//<< " (was " << node->Stat().SecondClosestBound() << ").\n";
|
||||
node->Stat().SecondClosestBound() =
|
||||
node->Parent()->Stat().SecondClosestBound();
|
||||
}*/
|
||||
|
||||
if (node->Begin() == 34654)
|
||||
if (node->Begin() == 16954)
|
||||
{
|
||||
Log::Warn << "Attempt Hamerly prune on r34654c" << node->Count() <<
|
||||
Log::Warn << "Attempt Hamerly prune on r16954c" << node->Count() <<
|
||||
" with MQND " << node->Stat().MaxQueryNodeDistance() << ", scb "
|
||||
<< node->Stat().SecondClosestBound() << ", owner " <<
|
||||
node->Stat().Owner() << ", and clusterDistances " << clusterDistances[clusters]
|
||||
<< ".\n";
|
||||
}
|
||||
|
||||
// Check the second bound. (This is time-consuming...)
|
||||
for (size_t j = 0; j < node->NumDescendants(); ++j)
|
||||
{
|
||||
arma::vec distances(centroids.n_cols);
|
||||
double secondClosestDist = DBL_MAX;
|
||||
for (size_t i = 0; i < centroids.n_cols; ++i)
|
||||
{
|
||||
const double distance = MetricType::Evaluate(centroids.col(i),
|
||||
dataset.col(node->Descendant(j)));
|
||||
if (distance < secondClosestDist && i != node->Stat().Owner())
|
||||
secondClosestDist = distance;
|
||||
|
||||
distances(i) = distance;
|
||||
}
|
||||
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "r16954c" << node->Count() << ": " << distances.t();
|
||||
if (secondClosestDist < node->Stat().SecondClosestBound() - 1e-15)
|
||||
{
|
||||
Log::Warn << "r" << node->Begin() << "c" << node->Count() << ":\n";
|
||||
Log::Warn << "Owner " << node->Stat().Owner() << ", mqnd " <<
|
||||
node->Stat().MaxQueryNodeDistance() << ", mnqnd " <<
|
||||
node->Stat().MinQueryNodeDistance() << ".\n";
|
||||
Log::Warn << distances.t();
|
||||
Log::Fatal << "Second closest bound " <<
|
||||
node->Stat().SecondClosestBound() << " is too loose! -- " << secondClosestDist
|
||||
<< "! (" << node->Stat().SecondClosestBound() - secondClosestDist
|
||||
<< ")\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (node->Stat().MaxQueryNodeDistance() < node->Stat().SecondClosestBound()
|
||||
- clusterDistances[clusters])
|
||||
{
|
||||
node->Stat().HamerlyPruned() = true;
|
||||
// if (node->Begin() == 35871)
|
||||
if (node->Begin() == 16954)
|
||||
Log::Warn << "Mark r" << node->Begin() << "c" << node->Count() << " as "
|
||||
<< "Hamerly pruned.\n";
|
||||
|
||||
// Check the second bound. (This is time-consuming...)
|
||||
for (size_t j = 0; j < node->NumDescendants(); ++j)
|
||||
{
|
||||
arma::vec distances(centroids.n_cols);
|
||||
double secondClosestDist = DBL_MAX;
|
||||
for (size_t i = 0; i < centroids.n_cols; ++i)
|
||||
{
|
||||
const double distance = MetricType::Evaluate(centroids.col(i),
|
||||
dataset.col(node->Descendant(j)));
|
||||
if (distance < secondClosestDist && i != node->Stat().Owner())
|
||||
secondClosestDist = distance;
|
||||
|
||||
distances(i) = distance;
|
||||
}
|
||||
|
||||
if (secondClosestDist < node->Stat().SecondClosestBound() - 1e-15)
|
||||
{
|
||||
Log::Warn << "Owner " << node->Stat().Owner() << ", mqnd " <<
|
||||
node->Stat().MaxQueryNodeDistance() << ", mnqnd " <<
|
||||
node->Stat().MinQueryNodeDistance() << ".\n";
|
||||
Log::Warn << distances.t();
|
||||
Log::Fatal << "Second closest bound " <<
|
||||
node->Stat().SecondClosestBound() << " is too loose! -- " << secondClosestDist
|
||||
<< "! (" << node->Stat().SecondClosestBound() - secondClosestDist
|
||||
<< ")\n";
|
||||
|
||||
}
|
||||
// if (node->Begin() == 35871)
|
||||
// Log::Warn << "r35871c" << node->Count() << ": " << distances.t();
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
@@ -342,6 +482,7 @@ node->Stat().SecondClosestBound() << " is too loose! -- " << secondClosestDist
|
||||
|
||||
// Since the node didn't have an owner, it can't be Hamerly pruned.
|
||||
node->Stat().HamerlyPruned() = false;
|
||||
node->Stat().Owner() = centroids.n_cols;
|
||||
}
|
||||
|
||||
node->Stat().Iteration() = iteration;
|
||||
@@ -350,14 +491,14 @@ node->Stat().SecondClosestBound() << " is too loose! -- " << secondClosestDist
|
||||
// be rebuilt.
|
||||
node->Stat().ClosestQueryNode() = NULL;
|
||||
|
||||
// if (node->Begin() == 35871)
|
||||
// Log::Warn << "scb for r35871c" << node->Count() << " updated to " <<
|
||||
// if (node->Begin() == 16954)
|
||||
// Log::Warn << "scb for r16954c" << node->Count() << " updated to " <<
|
||||
//node->Stat().SecondClosestBound() << ".\n";
|
||||
|
||||
if (!node->Stat().HamerlyPruned())
|
||||
// if (!node->Stat().HamerlyPruned())
|
||||
for (size_t i = 0; i < node->NumChildren(); ++i)
|
||||
TreeUpdate(&node->Child(i), clusters, clusterDistances, assignments,
|
||||
centroids, dataset);
|
||||
centroids, dataset, oldFromNew);
|
||||
|
||||
node->Stat().LastSecondClosestBound() = node->Stat().SecondClosestBound() -
|
||||
clusterDistances[clusters];
|
||||
|
||||
@@ -113,9 +113,9 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
|
||||
traversalInfo.LastReferenceNode() = &referenceNode;
|
||||
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Visit r37591c" << referenceNode.Count() << ", q" <<
|
||||
//queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "Visit r16954c" << referenceNode.Count() << ", q" <<
|
||||
queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
|
||||
// If there's no closest query node assigned, but the parent has one, take
|
||||
// that one.
|
||||
@@ -123,13 +123,13 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
referenceNode.Parent() != NULL &&
|
||||
referenceNode.Parent()->Stat().ClosestQueryNode() != NULL)
|
||||
{
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Update closest query node for r37591c" <<
|
||||
//referenceNode.Count() << " to parent's, which is "
|
||||
// << ((TreeType*)
|
||||
//referenceNode.Parent()->Stat().ClosestQueryNode())->Begin() << "c" <<
|
||||
//((TreeType*) referenceNode.Parent()->Stat().ClosestQueryNode())->Count() <<
|
||||
//".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "Update closest query node for r16954c" <<
|
||||
referenceNode.Count() << " to parent's, which is "
|
||||
<< ((TreeType*)
|
||||
referenceNode.Parent()->Stat().ClosestQueryNode())->Begin() << "c" <<
|
||||
((TreeType*) referenceNode.Parent()->Stat().ClosestQueryNode())->Count() <<
|
||||
".\n";
|
||||
|
||||
referenceNode.Stat().ClosestQueryNode() =
|
||||
referenceNode.Parent()->Stat().ClosestQueryNode();
|
||||
@@ -139,8 +139,8 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
// referenceNode.Stat().SecondClosestBound() = std::min(
|
||||
// referenceNode.Parent()->Stat().SecondClosestBound(),
|
||||
// referenceNode.Stat().SecondClosestBound());
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Update second closest bound for r37591c" <<
|
||||
// if (referenceNode.Begin() == 16954)
|
||||
// Log::Warn << "Update second closest bound for r16954c" <<
|
||||
//referenceNode.Count() << " to parent's, which "
|
||||
// << "is " << referenceNode.Stat().SecondClosestBound() << ".\n";
|
||||
}
|
||||
@@ -148,9 +148,9 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
double score = HamerlyTypeScore(referenceNode);
|
||||
if (score == DBL_MAX)
|
||||
{
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Hamerly prune for r37591c" << referenceNode.Count() << ", q" << queryNode.Begin() << "c" <<
|
||||
//queryNode.Count() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "Hamerly prune for r16954c" << referenceNode.Count() << ", q" << queryNode.Begin() << "c" <<
|
||||
queryNode.Count() << ".\n";
|
||||
if (origPruned == size_t(-1))
|
||||
{
|
||||
const size_t cluster = referenceNode.Stat().Owner();
|
||||
@@ -175,9 +175,11 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
const double minDistance = referenceNode.MinDistance(&queryNode);
|
||||
++distanceCalculations;
|
||||
score = PellegMooreScore(queryNode, referenceNode, minDistance);
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "mQND for r37591c" << referenceNode.Count() << " is "
|
||||
// << referenceNode.Stat().MinQueryNodeDistance() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "mQND for r16954c" << referenceNode.Count() << " is "
|
||||
<< referenceNode.Stat().MinQueryNodeDistance() << "; minDistance "
|
||||
<< minDistance << ", scb " <<
|
||||
referenceNode.Stat().SecondClosestBound() << ".\n";
|
||||
|
||||
if (minDistance < referenceNode.Stat().MinQueryNodeDistance())
|
||||
{
|
||||
@@ -192,10 +194,10 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
referenceNode.Stat().MinQueryNodeDistance();
|
||||
referenceNode.Stat().SecondClosestQueryNode() =
|
||||
referenceNode.Stat().ClosestQueryNode();
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "scb for r37591c" << referenceNode.Count() << " taken "
|
||||
// << "from minDistance, which is " <<
|
||||
//referenceNode.Stat().MinQueryNodeDistance() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "scb for r16954c" << referenceNode.Count() << " taken "
|
||||
<< "from minDistance, which is " <<
|
||||
referenceNode.Stat().MinQueryNodeDistance() << ".\n";
|
||||
}
|
||||
|
||||
if (referenceNode.Stat().MinQueryNodeDistance() == DBL_MAX &&
|
||||
@@ -204,10 +206,10 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
{
|
||||
referenceNode.Stat().SecondClosestBound() = minDistance;
|
||||
referenceNode.Stat().SecondClosestQueryNode() = &queryNode;
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "scb for r37591c" << referenceNode.Count() << " taken "
|
||||
// << "from minDistance for pruned query node, which is " <<
|
||||
//minDistance << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "scb for r16954c" << referenceNode.Count() << " taken "
|
||||
<< "from minDistance for pruned query node, which is " <<
|
||||
minDistance << ".\n";
|
||||
}
|
||||
|
||||
if (score != DBL_MAX)
|
||||
@@ -217,60 +219,60 @@ double DualTreeKMeansRules<MetricType, TreeType>::Score(
|
||||
referenceNode.Stat().MinQueryNodeDistance() = minDistance;
|
||||
referenceNode.Stat().MaxQueryNodeDistance() = maxDistance;
|
||||
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "mQND for r37591c" << referenceNode.Count() << " updated to " << minDistance << " and "
|
||||
// << "MQND to " << maxDistance << " with furthest query node " <<
|
||||
// queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "mQND for r16954c" << referenceNode.Count() << " updated to " << minDistance << " and "
|
||||
<< "MQND to " << maxDistance << " with furthest query node " <<
|
||||
queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
}
|
||||
}
|
||||
else if (IsDescendantOf(*((TreeType*)
|
||||
referenceNode.Stat().ClosestQueryNode()), queryNode))
|
||||
{
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Old closest for r37591c" << referenceNode.Count() <<
|
||||
// " is q" << ((TreeType*)
|
||||
//referenceNode.Stat().ClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
//referenceNode.Stat().ClosestQueryNode())->Count() << " with mQND " <<
|
||||
//referenceNode.Stat().MinQueryNodeDistance() << " and MQND " <<
|
||||
//referenceNode.Stat().MaxQueryNodeDistance() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "Old closest for r16954c" << referenceNode.Count() <<
|
||||
" is q" << ((TreeType*)
|
||||
referenceNode.Stat().ClosestQueryNode())->Begin() << "c" << ((TreeType*)
|
||||
referenceNode.Stat().ClosestQueryNode())->Count() << " with mQND " <<
|
||||
referenceNode.Stat().MinQueryNodeDistance() << " and MQND " <<
|
||||
referenceNode.Stat().MaxQueryNodeDistance() << ".\n";
|
||||
const double maxDistance = referenceNode.MaxDistance(&queryNode);
|
||||
++distanceCalculations;
|
||||
referenceNode.Stat().ClosestQueryNode() = (void*) &queryNode;
|
||||
referenceNode.Stat().MinQueryNodeDistance() = minDistance;
|
||||
referenceNode.Stat().MaxQueryNodeDistance() = maxDistance;
|
||||
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "mQND for r37591c" << referenceNode.Count() << " updated to " << minDistance << " and "
|
||||
// << "MQND to " << maxDistance << " via descendant with fqn " <<
|
||||
// queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "mQND for r16954c" << referenceNode.Count() << " updated to " << minDistance << " and "
|
||||
<< "MQND to " << maxDistance << " via descendant with fqn " <<
|
||||
queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
}
|
||||
else if (minDistance < referenceNode.Stat().SecondClosestBound())
|
||||
{
|
||||
referenceNode.Stat().SecondClosestBound() = minDistance;
|
||||
referenceNode.Stat().SecondClosestQueryNode() = &queryNode;
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "scb for r37591c" << referenceNode.Count() << " updated to " << minDistance << " via "
|
||||
// << queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "scb for r16954c" << referenceNode.Count() << " updated to " << minDistance << " via "
|
||||
<< queryNode.Begin() << "c" << queryNode.Count() << ".\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((TreeType*) referenceNode.Stat().ClosestQueryNode())->NumDescendants() > 1)
|
||||
{
|
||||
referenceNode.Stat().SecondClosestBound() =
|
||||
referenceNode.Stat().MinQueryNodeDistance();
|
||||
referenceNode.Stat().SecondClosestQueryNode() =
|
||||
referenceNode.Stat().ClosestQueryNode();
|
||||
}
|
||||
// if (((TreeType*) referenceNode.Stat().ClosestQueryNode())->NumDescendants() > 1)
|
||||
// {
|
||||
// referenceNode.Stat().SecondClosestBound() =
|
||||
// referenceNode.Stat().MinQueryNodeDistance();
|
||||
// referenceNode.Stat().SecondClosestQueryNode() =
|
||||
// referenceNode.Stat().ClosestQueryNode();
|
||||
// }
|
||||
|
||||
if (score == DBL_MAX)
|
||||
{
|
||||
referenceNode.Stat().ClustersPruned() += queryNode.NumDescendants();
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "For r37591c" << referenceNode.Count() << ", q" <<
|
||||
//queryNode.Begin() << "c" << queryNode.Count() << " is pruned. Min distance is"
|
||||
// << " " << queryNode.MinDistance(&referenceNode) << " and scb is " <<
|
||||
//referenceNode.Stat().SecondClosestBound() << ".\n";
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Warn << "For r16954c" << referenceNode.Count() << ", q" <<
|
||||
queryNode.Begin() << "c" << queryNode.Count() << " is pruned. Min distance is"
|
||||
<< " " << queryNode.MinDistance(&referenceNode) << " and scb is " <<
|
||||
referenceNode.Stat().SecondClosestBound() << ".\n";
|
||||
|
||||
// Have we pruned everything?
|
||||
if (referenceNode.Stat().ClustersPruned() +
|
||||
@@ -325,7 +327,8 @@ double DualTreeKMeansRules<MetricType, TreeType>::HamerlyTypeScore(
|
||||
{
|
||||
if (referenceNode.Stat().HamerlyPruned())
|
||||
{
|
||||
Log::Warn << "Hamerly prune! r" << referenceNode.Begin() << "c" <<
|
||||
if (referenceNode.Begin() == 16954)
|
||||
Log::Info << "Hamerly prune! r" << referenceNode.Begin() << "c" <<
|
||||
referenceNode.Count() << ".\n";
|
||||
return DBL_MAX;
|
||||
}
|
||||
@@ -372,8 +375,8 @@ double DualTreeKMeansRules<MetricType, TreeType>::ElkanTypeScore(
|
||||
queryNode)) &&
|
||||
(&queryNode != (TreeType*) referenceNode.Stat().ClosestQueryNode()))
|
||||
{
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Elkan prune r37591c" << referenceNode.Count() << ", q" <<
|
||||
// if (referenceNode.Begin() == 16954)
|
||||
// Log::Warn << "Elkan prune r16954c" << referenceNode.Count() << ", q" <<
|
||||
//queryNode.Begin() << "c" << queryNode.Count() << "!\n";
|
||||
// Then we can conclude d_max(best(N_r), N_r) <= d_min(N_q, N_r) which
|
||||
// means that N_q cannot possibly hold any clusters that own any points in
|
||||
@@ -393,14 +396,14 @@ double DualTreeKMeansRules<MetricType, TreeType>::PellegMooreScore(
|
||||
// If the minimum distance to the node is greater than the bound, then every
|
||||
// cluster in the query node cannot possibly be the nearest neighbor of any of
|
||||
// the points in the reference node.
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// Log::Warn << "Pelleg-Moore prune attempt r37591c" << referenceNode.Count() << ", "
|
||||
// if (referenceNode.Begin() == 16954)
|
||||
// Log::Warn << "Pelleg-Moore prune attempt r16954c" << referenceNode.Count() << ", "
|
||||
// << "q" << queryNode.Begin() << "c" << queryNode.Count() << "; "
|
||||
// << "minDistance " << minDistance << ", MQND " <<
|
||||
//referenceNode.Stat().MaxQueryNodeDistance() << ".\n";
|
||||
if (minDistance > referenceNode.Stat().MaxQueryNodeDistance())
|
||||
{
|
||||
// if (referenceNode.Begin() == 37591)
|
||||
// if (referenceNode.Begin() == 16954)
|
||||
// Log::Warn << "Attempt successful!\n";
|
||||
return DBL_MAX;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user