[mlpack-git] master: Explicitly relax the separation invariant (it was already relaxed in the code). (3f5503b)
gitdub at mlpack.org
gitdub at mlpack.org
Thu Sep 15 11:24:48 EDT 2016
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/02e7f5decaee4fba970f3b7a952b8eda1c5b43dc...3f5503bfe71dbbda4b4551c9cdfaba8b819565ad
>---------------------------------------------------------------
commit 3f5503bfe71dbbda4b4551c9cdfaba8b819565ad
Author: Ryan Curtin <ryan at ratml.org>
Date: Thu Sep 15 11:24:23 2016 -0400
Explicitly relax the separation invariant (it was already relaxed in the code).
>---------------------------------------------------------------
3f5503bfe71dbbda4b4551c9cdfaba8b819565ad
src/mlpack/core/tree/cover_tree/cover_tree.hpp | 8 +--
src/mlpack/tests/tree_test.cpp | 72 +++-----------------------
2 files changed, 13 insertions(+), 67 deletions(-)
diff --git a/src/mlpack/core/tree/cover_tree/cover_tree.hpp b/src/mlpack/core/tree/cover_tree/cover_tree.hpp
index 38a9f98..15316bf 100644
--- a/src/mlpack/core/tree/cover_tree/cover_tree.hpp
+++ b/src/mlpack/core/tree/cover_tree/cover_tree.hpp
@@ -23,14 +23,16 @@ namespace tree {
*
* The tree can be thought of as a hierarchy with the root node at the top level
* and the leaf nodes at the bottom level. Each level in the tree has an
- * assigned 'scale' i. The tree follows these three conditions:
+ * assigned 'scale' i. The tree follows these two invariants:
*
* - nesting: the level C_i is a subset of the level C_{i - 1}.
* - covering: all node in level C_{i - 1} have at least one node in the
* level C_i with distance less than or equal to b^i (exactly one of these
* is a parent of the point in level C_{i - 1}.
- * - separation: all nodes in level C_i have distance greater than b^i to all
- * other nodes in level C_i.
+ *
+ * Note that in the cover tree paper, there is a third invariant (the
+ * 'separation invariant'), but that does not apply to our implementation,
+ * because we have relaxed the invariant.
*
* The value 'b' refers to the base, which is a parameter of the tree. These
* three properties make the cover tree very good for fast, high-dimensional
diff --git a/src/mlpack/tests/tree_test.cpp b/src/mlpack/tests/tree_test.cpp
index 507a3e9..d4bbb9e 100644
--- a/src/mlpack/tests/tree_test.cpp
+++ b/src/mlpack/tests/tree_test.cpp
@@ -1833,62 +1833,6 @@ void CheckCovering(const TreeType& node)
}
}
-template<typename TreeType, typename MetricType>
-void CheckIndividualSeparation(const TreeType& constantNode,
- const TreeType& node)
-{
- // Don't check points at a lower scale.
- if (node.Scale() < constantNode.Scale())
- return;
-
- // If at a higher scale, recurse.
- if (node.Scale() > constantNode.Scale())
- {
- for (size_t i = 0; i < node.NumChildren(); ++i)
- {
- // Don't recurse into leaves.
- if (node.Child(i).NumChildren() > 0)
- CheckIndividualSeparation<TreeType, MetricType>(constantNode,
- node.Child(i));
- }
-
- return;
- }
-
- // Don't compare the same point against itself.
- if (node.Point() == constantNode.Point())
- return;
-
- // Now we know we are at the same scale, so make the comparison.
- const typename TreeType::Mat& dataset = constantNode.Dataset();
- const size_t constantPoint = constantNode.Point();
- const size_t nodePoint = node.Point();
-
- // Make sure the distance is at least the following value (in accordance with
- // the separation principle of cover trees).
- double minDistance = pow(constantNode.Base(),
- constantNode.Scale());
-
- double distance = MetricType::Evaluate(dataset.col(constantPoint),
- dataset.col(nodePoint));
-
- BOOST_REQUIRE_GE(distance, minDistance);
-}
-
-template<typename TreeType, typename MetricType>
-void CheckSeparation(const TreeType& node, const TreeType& root)
-{
- // Check the separation between this point and all other points on this scale.
- CheckIndividualSeparation<TreeType, MetricType>(node, root);
-
- // Check the children, but only if they are not leaves. Leaves don't need to
- // be checked.
- for (size_t i = 0; i < node.NumChildren(); ++i)
- if (node.Child(i).NumChildren() > 0)
- CheckSeparation<TreeType, MetricType>(node.Child(i), root);
-}
-
-
/**
* Create a simple cover tree and then make sure it is valid.
*/
@@ -1942,8 +1886,8 @@ BOOST_AUTO_TEST_CASE(SimpleCoverTreeConstructionTest)
// than or equal to a certain distance apart).
CheckCovering<TreeType, LMetric<2, true>>(tree);
- // Each node's children must be separated by at least a certain value.
- CheckSeparation<TreeType, LMetric<2, true>>(tree, tree);
+ // There's no need to check the separation invariant because that is relaxed
+ // in our implementation.
}
/**
@@ -1974,8 +1918,8 @@ BOOST_AUTO_TEST_CASE(CoverTreeConstructionTest)
// than or equal to a certain distance apart).
CheckCovering<TreeType, LMetric<2, true> >(tree);
- // Each node's children must be separated by at least a certain value.
- CheckSeparation<TreeType, LMetric<2, true> >(tree, tree);
+ // There's no need to check the separation because that is relaxed in our
+ // implementation.
}
/**
@@ -2006,8 +1950,8 @@ BOOST_AUTO_TEST_CASE(SparseCoverTreeConstructionTest)
// than or equal to a certain distance apart).
CheckCovering<TreeType, LMetric<2, true> >(tree);
- // Each node's children must be separated by at least a certain value.
- CheckSeparation<TreeType, LMetric<2, true> >(tree, tree);
+ // There's no need to check the separation invariant because that is relaxed
+ // in our implementation.
}
/**
@@ -2059,8 +2003,8 @@ BOOST_AUTO_TEST_CASE(CoverTreeAlternateMetricTest)
// than or equal to a certain distance apart).
CheckCovering<TreeType, ManhattanDistance>(tree);
- // Each node's children must be separated by at least a certain value.
- CheckSeparation<TreeType, ManhattanDistance>(tree, tree);
+ // There's no need to check the separation invariant because that is relaxed
+ // in our implementation.
}
/**
More information about the mlpack-git
mailing list