[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