[mlpack-svn] r13533 - mlpack/trunk/src/mlpack/tests

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Tue Sep 11 16:30:08 EDT 2012


Author: rcurtin
Date: 2012-09-11 16:30:08 -0400 (Tue, 11 Sep 2012)
New Revision: 13533

Modified:
   mlpack/trunk/src/mlpack/tests/tree_test.cpp
Log:
Test new HRectBound<n, true> functionality.


Modified: mlpack/trunk/src/mlpack/tests/tree_test.cpp
===================================================================
--- mlpack/trunk/src/mlpack/tests/tree_test.cpp	2012-09-11 20:29:58 UTC (rev 13532)
+++ mlpack/trunk/src/mlpack/tests/tree_test.cpp	2012-09-11 20:30:08 UTC (rev 13533)
@@ -632,6 +632,313 @@
 }
 
 /**
+ * Ensure that we calculate the correct minimum distance between a point and a
+ * bound.
+ */
+BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistancePoint)
+{
+  // We'll do the calculation in five dimensions, and we'll use three cases for
+  // the point: point is outside the bound; point is on the edge of the bound;
+  // point is inside the bound.  In the latter two cases, the distance should be
+  // zero.
+  HRectBound<2, true> b(5);
+
+  b[0] = Range(0.0, 2.0);
+  b[1] = Range(1.0, 5.0);
+  b[2] = Range(-2.0, 2.0);
+  b[3] = Range(-5.0, -2.0);
+  b[4] = Range(1.0, 2.0);
+
+  arma::vec point = "-2.0 0.0 10.0 3.0 3.0";
+
+  // This will be the Euclidean distance.
+  BOOST_REQUIRE_CLOSE(b.MinDistance(point), sqrt(95.0), 1e-5);
+
+  point = "2.0 5.0 2.0 -5.0 1.0";
+
+  BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+
+  point = "1.0 2.0 0.0 -2.0 1.5";
+
+  BOOST_REQUIRE_SMALL(b.MinDistance(point), 1e-5);
+}
+
+/**
+ * Ensure that we calculate the correct minimum distance between a bound and
+ * another bound.
+ */
+BOOST_AUTO_TEST_CASE(HRectBoundRootMinDistanceBound)
+{
+  // We'll do the calculation in five dimensions, and we can use six cases.
+  // The other bound is completely outside the bound; the other bound is on the
+  // edge of the bound; the other bound partially overlaps the bound; the other
+  // bound fully overlaps the bound; the other bound is entirely inside the
+  // bound; the other bound entirely envelops the bound.
+  HRectBound<2, true> b(5);
+
+  b[0] = Range(0.0, 2.0);
+  b[1] = Range(1.0, 5.0);
+  b[2] = Range(-2.0, 2.0);
+  b[3] = Range(-5.0, -2.0);
+  b[4] = Range(1.0, 2.0);
+
+  HRectBound<2, true> c(5);
+
+  // The other bound is completely outside the bound.
+  c[0] = Range(-5.0, -2.0);
+  c[1] = Range(6.0, 7.0);
+  c[2] = Range(-2.0, 2.0);
+  c[3] = Range(2.0, 5.0);
+  c[4] = Range(3.0, 4.0);
+
+  BOOST_REQUIRE_CLOSE(b.MinDistance(c), sqrt(22.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MinDistance(b), sqrt(22.0), 1e-5);
+
+  // The other bound is on the edge of the bound.
+  c[0] = Range(-2.0, 0.0);
+  c[1] = Range(0.0, 1.0);
+  c[2] = Range(-3.0, -2.0);
+  c[3] = Range(-10.0, -5.0);
+  c[4] = Range(2.0, 3.0);
+
+  BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5);
+  BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5);
+
+  // The other bound partially overlaps the bound.
+  c[0] = Range(-2.0, 1.0);
+  c[1] = Range(0.0, 2.0);
+  c[2] = Range(-2.0, 2.0);
+  c[3] = Range(-8.0, -4.0);
+  c[4] = Range(0.0, 4.0);
+
+  BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5);
+  BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5);
+
+  // The other bound fully overlaps the bound.
+  BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5);
+  BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5);
+
+  // The other bound is entirely inside the bound / the other bound entirely
+  // envelops the bound.
+  c[0] = Range(-1.0, 3.0);
+  c[1] = Range(0.0, 6.0);
+  c[2] = Range(-3.0, 3.0);
+  c[3] = Range(-7.0, 0.0);
+  c[4] = Range(0.0, 5.0);
+
+  BOOST_REQUIRE_SMALL(b.MinDistance(c), 1e-5);
+  BOOST_REQUIRE_SMALL(c.MinDistance(b), 1e-5);
+
+  // Now we must be sure that the minimum distance to itself is 0.
+  BOOST_REQUIRE_SMALL(b.MinDistance(b), 1e-5);
+  BOOST_REQUIRE_SMALL(c.MinDistance(c), 1e-5);
+}
+
+/**
+ * Ensure that we calculate the correct maximum distance between a bound and a
+ * point.  This uses the same test cases as the MinDistance test.
+ */
+BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistancePoint)
+{
+  // We'll do the calculation in five dimensions, and we'll use three cases for
+  // the point: point is outside the bound; point is on the edge of the bound;
+  // point is inside the bound.  In the latter two cases, the distance should be
+  // zero.
+  HRectBound<2, true> b(5);
+
+  b[0] = Range(0.0, 2.0);
+  b[1] = Range(1.0, 5.0);
+  b[2] = Range(-2.0, 2.0);
+  b[3] = Range(-5.0, -2.0);
+  b[4] = Range(1.0, 2.0);
+
+  arma::vec point = "-2.0 0.0 10.0 3.0 3.0";
+
+  // This will be the Euclidean distance.
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(253.0), 1e-5);
+
+  point = "2.0 5.0 2.0 -5.0 1.0";
+
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(46.0), 1e-5);
+
+  point = "1.0 2.0 0.0 -2.0 1.5";
+
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(point), sqrt(23.25), 1e-5);
+}
+
+/**
+ * Ensure that we calculate the correct maximum distance between a bound and
+ * another bound.  This uses the same test cases as the MinDistance test.
+ */
+BOOST_AUTO_TEST_CASE(HRectBoundRootMaxDistanceBound)
+{
+  // We'll do the calculation in five dimensions, and we can use six cases.
+  // The other bound is completely outside the bound; the other bound is on the
+  // edge of the bound; the other bound partially overlaps the bound; the other
+  // bound fully overlaps the bound; the other bound is entirely inside the
+  // bound; the other bound entirely envelops the bound.
+  HRectBound<2, true> b(5);
+
+  b[0] = Range(0.0, 2.0);
+  b[1] = Range(1.0, 5.0);
+  b[2] = Range(-2.0, 2.0);
+  b[3] = Range(-5.0, -2.0);
+  b[4] = Range(1.0, 2.0);
+
+  HRectBound<2, true> c(5);
+
+  // The other bound is completely outside the bound.
+  c[0] = Range(-5.0, -2.0);
+  c[1] = Range(6.0, 7.0);
+  c[2] = Range(-2.0, 2.0);
+  c[3] = Range(2.0, 5.0);
+  c[4] = Range(3.0, 4.0);
+
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(210.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(210.0), 1e-5);
+
+  // The other bound is on the edge of the bound.
+  c[0] = Range(-2.0, 0.0);
+  c[1] = Range(0.0, 1.0);
+  c[2] = Range(-3.0, -2.0);
+  c[3] = Range(-10.0, -5.0);
+  c[4] = Range(2.0, 3.0);
+
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(134.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(134.0), 1e-5);
+
+  // The other bound partially overlaps the bound.
+  c[0] = Range(-2.0, 1.0);
+  c[1] = Range(0.0, 2.0);
+  c[2] = Range(-2.0, 2.0);
+  c[3] = Range(-8.0, -4.0);
+  c[4] = Range(0.0, 4.0);
+
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(102.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(102.0), 1e-5);
+
+  // The other bound fully overlaps the bound.
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(b), sqrt(46.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MaxDistance(c), sqrt(61.0), 1e-5);
+
+  // The other bound is entirely inside the bound / the other bound entirely
+  // envelops the bound.
+  c[0] = Range(-1.0, 3.0);
+  c[1] = Range(0.0, 6.0);
+  c[2] = Range(-3.0, 3.0);
+  c[3] = Range(-7.0, 0.0);
+  c[4] = Range(0.0, 5.0);
+
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(c), sqrt(100.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MaxDistance(b), sqrt(100.0), 1e-5);
+
+  // Identical bounds.  This will be the sum of the squared widths in each
+  // dimension.
+  BOOST_REQUIRE_CLOSE(b.MaxDistance(b), sqrt(46.0), 1e-5);
+  BOOST_REQUIRE_CLOSE(c.MaxDistance(c), sqrt(162.0), 1e-5);
+
+  // One last additional case.  If the bound encloses only one point, the
+  // maximum distance between it and itself is 0.
+  HRectBound<2, true> d(2);
+
+  d[0] = Range(2.0, 2.0);
+  d[1] = Range(3.0, 3.0);
+
+  BOOST_REQUIRE_SMALL(d.MaxDistance(d), 1e-5);
+}
+
+/**
+ * Ensure that the ranges returned by RangeDistance() are equal to the minimum
+ * and maximum distance.  We will perform this test by creating random bounds
+ * and comparing the behavior to MinDistance() and MaxDistance() -- so this test
+ * is assuming that those passed and operate correctly.
+ */
+BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistanceBound)
+{
+  for (int i = 0; i < 50; i++)
+  {
+    size_t dim = math::RandInt(20);
+
+    HRectBound<2, true> a(dim);
+    HRectBound<2, true> b(dim);
+
+    // We will set the low randomly and the width randomly for each dimension of
+    // each bound.
+    arma::vec loA(dim);
+    arma::vec widthA(dim);
+
+    loA.randu();
+    widthA.randu();
+
+    arma::vec lo_b(dim);
+    arma::vec width_b(dim);
+
+    lo_b.randu();
+    width_b.randu();
+
+    for (size_t j = 0; j < dim; j++)
+    {
+      a[j] = Range(loA[j], loA[j] + widthA[j]);
+      b[j] = Range(lo_b[j], lo_b[j] + width_b[j]);
+    }
+
+    // Now ensure that MinDistance and MaxDistance report the same.
+    Range r = a.RangeDistance(b);
+    Range s = b.RangeDistance(a);
+
+    BOOST_REQUIRE_CLOSE(r.Lo(), s.Lo(), 1e-5);
+    BOOST_REQUIRE_CLOSE(r.Hi(), s.Hi(), 1e-5);
+
+    BOOST_REQUIRE_CLOSE(r.Lo(), a.MinDistance(b), 1e-5);
+    BOOST_REQUIRE_CLOSE(r.Hi(), a.MaxDistance(b), 1e-5);
+
+    BOOST_REQUIRE_CLOSE(s.Lo(), b.MinDistance(a), 1e-5);
+    BOOST_REQUIRE_CLOSE(s.Hi(), b.MaxDistance(a), 1e-5);
+  }
+}
+
+/**
+ * Ensure that the ranges returned by RangeDistance() are equal to the minimum
+ * and maximum distance.  We will perform this test by creating random bounds
+ * and comparing the bheavior to MinDistance() and MaxDistance() -- so this test
+ * is assuming that those passed and operate correctly.  This is for the
+ * bound-to-point case.
+ */
+BOOST_AUTO_TEST_CASE(HRectBoundRootRangeDistancePoint)
+{
+  for (int i = 0; i < 20; i++)
+  {
+    size_t dim = math::RandInt(20);
+
+    HRectBound<2, true> a(dim);
+
+    // We will set the low randomly and the width randomly for each dimension of
+    // each bound.
+    arma::vec loA(dim);
+    arma::vec widthA(dim);
+
+    loA.randu();
+    widthA.randu();
+
+    for (size_t j = 0; j < dim; j++)
+      a[j] = Range(loA[j], loA[j] + widthA[j]);
+
+    // Now run the test on a few points.
+    for (int j = 0; j < 10; j++)
+    {
+      arma::vec point(dim);
+
+      point.randu();
+
+      Range r = a.RangeDistance(point);
+
+      BOOST_REQUIRE_CLOSE(r.Lo(), a.MinDistance(point), 1e-5);
+      BOOST_REQUIRE_CLOSE(r.Hi(), a.MaxDistance(point), 1e-5);
+    }
+  }
+}
+
+/**
  * Ensure that a bound, by default, is empty and has no dimensionality, and the
  * box size vector is empty.
  */




More information about the mlpack-svn mailing list