[mlpack-svn] r15828 - mlpack/trunk/src/mlpack/methods/fastmks

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Mon Sep 23 12:52:30 EDT 2013


Author: rcurtin
Date: Mon Sep 23 12:52:30 2013
New Revision: 15828

Log:
The parent-child pruning bounds were too tight.  They did not consider one of
the bound terms and the cross-term, and thus failed, especially when considering
a leaf node where the furthest descendant distance was 0.  Also update
documentation a bit so that big chunk of code makes a bit more sense.


Modified:
   mlpack/trunk/src/mlpack/methods/fastmks/fastmks_rules_impl.hpp

Modified: mlpack/trunk/src/mlpack/methods/fastmks/fastmks_rules_impl.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/fastmks/fastmks_rules_impl.hpp	(original)
+++ mlpack/trunk/src/mlpack/methods/fastmks/fastmks_rules_impl.hpp	Mon Sep 23 12:52:30 2013
@@ -208,13 +208,26 @@
 
   const double queryDistBound = (queryParentDist + queryDescDist);
   const double refDistBound = (refParentDist + refDescDist);
+  const double dualTerm = queryDistBound * refDistBound;
 
+  // The parent-child and parent-parent prunes work by applying the same pruning
+  // condition, except they are tighter because
+  //    queryDistBound < queryNode.Parent()->FurthestDescendantDistance()
+  // and
+  //    refDistBound < referenceNode.Parent()->FurthestDescendantDistance()
+  // so we construct the same bounds that were used when Score() was called with
+  // the parents, except with the tighter distance bounds.  Sometimes this
+  // allows us to prune nodes without evaluating the base cases between them.
   if ((queryParent != NULL) &&
       (queryParent->Stat().LastKernelNode() == (void*) &referenceNode))
   {
     // Query parent was last evaluated with reference node.
-    const double maxKernelBound = queryParent->Stat().LastKernel() +
+    const double queryKernelTerm =
+        refDistBound * queryParent->Stat().SelfKernel();
+    const double refKernelTerm =
         queryDistBound * referenceNode.Stat().SelfKernel();
+    const double maxKernelBound = queryParent->Stat().LastKernel() +
+        queryKernelTerm + refKernelTerm + dualTerm;
 
     if (maxKernelBound < bestKernel)
       return DBL_MAX;
@@ -223,8 +236,11 @@
       (refParent->Stat().LastKernelNode() == (void*) &queryNode))
   {
     // Reference parent was last evaluated with query node.
+    const double queryKernelTerm = refDistBound * queryNode.Stat().SelfKernel();
+    const double refKernelTerm =
+        queryDistBound * refParent->Stat().SelfKernel();
     const double maxKernelBound = refParent->Stat().LastKernel() +
-        (refParentDist + refDescDist) * queryNode.Stat().SelfKernel();
+        queryKernelTerm + refKernelTerm + dualTerm;
 
     if (maxKernelBound < bestKernel)
       return DBL_MAX;
@@ -250,12 +266,10 @@
       (refParent->Stat().LastKernelNode() == (void*) queryParent))
   {
     // Reference parent was last calculated with query parent.
-    const double queryKernelTerm = (refParentDist + refDescDist) *
+    const double queryKernelTerm = refDistBound *
         queryParent->Stat().SelfKernel();
-    const double refKernelTerm = (queryParentDist + queryDescDist) *
+    const double refKernelTerm = queryDistBound *
         refParent->Stat().SelfKernel();
-    const double dualTerm = (queryParentDist + queryDescDist) *
-        (refParentDist + refDescDist);
 
     const double maxKernelBound = refParent->Stat().LastKernel() +
         queryKernelTerm + refKernelTerm + dualTerm;
@@ -264,10 +278,13 @@
       return DBL_MAX;
   }
 
-  // Calculate kernel evaluation, if necessary.
+  // 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.  So see if it is already cached there.
     bool alreadyDone = false;
     if ((queryNode.Parent() != NULL) &&
         (queryNode.Parent()->Point(0) == queryNode.Point(0)))



More information about the mlpack-svn mailing list