[mlpack] 76/207: Add copy and move constructors.

Barak A. Pearlmutter barak+git at pearlmutter.net
Thu Mar 23 17:53:42 UTC 2017


This is an automated email from the git hooks/post-receive script.

bap pushed a commit to branch master
in repository mlpack.

commit 2f74df3af07ce67e8e031090c3d17a898c9913d5
Author: Ryan Curtin <ryan at ratml.org>
Date:   Wed Aug 10 16:08:04 2016 -0400

    Add copy and move constructors.
---
 src/mlpack/methods/range_search/range_search.hpp   | 11 ++++
 .../methods/range_search/range_search_impl.hpp     | 61 +++++++++++++++++++
 src/mlpack/tests/range_search_test.cpp             | 71 +++++++++++++++++++++-
 3 files changed, 141 insertions(+), 2 deletions(-)

diff --git a/src/mlpack/methods/range_search/range_search.hpp b/src/mlpack/methods/range_search/range_search.hpp
index 9d4c3e1..b0c16d7 100644
--- a/src/mlpack/methods/range_search/range_search.hpp
+++ b/src/mlpack/methods/range_search/range_search.hpp
@@ -133,6 +133,17 @@ class RangeSearch
               const MetricType metric = MetricType());
 
   /**
+   * Copy constructor: this will copy any trees, so it may not be a great idea
+   * to call this!
+   */
+  RangeSearch(const RangeSearch& other);
+
+  /**
+   * Move constructor: take possession of all the members of the other model.
+   */
+  RangeSearch(RangeSearch&& other);
+
+  /**
    * Destroy the RangeSearch object.  If trees were created, they will be
    * deleted.
    */
diff --git a/src/mlpack/methods/range_search/range_search_impl.hpp b/src/mlpack/methods/range_search/range_search_impl.hpp
index e669597..adccb9a 100644
--- a/src/mlpack/methods/range_search/range_search_impl.hpp
+++ b/src/mlpack/methods/range_search/range_search_impl.hpp
@@ -171,6 +171,55 @@ template<typename MetricType,
          template<typename TreeMetricType,
                   typename TreeStatType,
                   typename TreeMatType> class TreeType>
+RangeSearch<MetricType, MatType, TreeType>::RangeSearch(
+    const RangeSearch& other) :
+    oldFromNewReferences(other.oldFromNewReferences),
+    referenceTree(other.naive ? NULL : new Tree(*other.referenceTree)),
+    referenceSet(other.naive ? new MatType(*other.referenceSet) :
+        &referenceTree->Dataset()),
+    treeOwner(!other.naive),
+    setOwner(other.naive),
+    naive(other.naive),
+    singleMode(other.singleMode),
+    metric(other.metric),
+    baseCases(other.baseCases),
+    scores(other.scores)
+{
+  // Nothing to do.
+}
+
+template<typename MetricType,
+         typename MatType,
+         template<typename TreeMetricType,
+                  typename TreeStatType,
+                  typename TreeMatType> class TreeType>
+RangeSearch<MetricType, MatType, TreeType>::RangeSearch(
+    RangeSearch&& other) :
+    oldFromNewReferences(std::move(other.oldFromNewReferences)),
+    referenceTree(other.naive ? NULL : std::move(other.referenceTree)),
+    referenceSet(other.naive ? std::move(other.referenceSet) :
+        &referenceTree->Dataset()),
+    treeOwner(other.treeOwner),
+    setOwner(other.setOwner),
+    naive(other.naive),
+    singleMode(other.singleMode),
+    metric(std::move(other.metric)),
+    baseCases(other.baseCases),
+    scores(other.scores)
+{
+  other.referenceTree = NULL;
+  other.referenceSet = new arma::mat(); // Empty dataset.
+  other.treeOwner = false;
+  other.setOwner = true;
+  other.baseCases = 0;
+  other.scores = 0;
+}
+
+template<typename MetricType,
+         typename MatType,
+         template<typename TreeMetricType,
+                  typename TreeStatType,
+                  typename TreeMatType> class TreeType>
 RangeSearch<MetricType, MatType, TreeType>::~RangeSearch()
 {
   if (treeOwner && referenceTree)
@@ -297,6 +346,10 @@ void RangeSearch<MetricType, MatType, TreeType>::Search(
     throw std::invalid_argument(oss.str());
   }
 
+  // If there are no points, there is no search to be done.
+  if (referenceSet->n_cols == 0)
+    return;
+
   Timer::Start("range_search/computing_neighbors");
 
   // This will hold mappings for query points, if necessary.
@@ -469,6 +522,10 @@ void RangeSearch<MetricType, MatType, TreeType>::Search(
     std::vector<std::vector<size_t>>& neighbors,
     std::vector<std::vector<double>>& distances)
 {
+  // If there are no points, there is no search to be done.
+  if (referenceSet->n_cols == 0)
+    return;
+
   Timer::Start("range_search/computing_neighbors");
 
   // Get a reference to the query set.
@@ -535,6 +592,10 @@ void RangeSearch<MetricType, MatType, TreeType>::Search(
     std::vector<std::vector<size_t>>& neighbors,
     std::vector<std::vector<double>>& distances)
 {
+  // If there are no points, there is no search to be done.
+  if (referenceSet->n_cols == 0)
+    return;
+
   Timer::Start("range_search/computing_neighbors");
 
   // Here, we will use the query set as the reference set.
diff --git a/src/mlpack/tests/range_search_test.cpp b/src/mlpack/tests/range_search_test.cpp
index 749426e..ecc1e67 100644
--- a/src/mlpack/tests/range_search_test.cpp
+++ b/src/mlpack/tests/range_search_test.cpp
@@ -1167,7 +1167,7 @@ BOOST_AUTO_TEST_CASE(NaiveTrainTreeTest)
 /**
  * Test that the move constructor works.
  */
-BOOST_AUTO_TEST_CASE(MoveConstructorTest)
+BOOST_AUTO_TEST_CASE(TreeMoveConstructorTest)
 {
   arma::mat dataset = arma::randu<arma::mat>(3, 100);
   arma::mat copy(dataset);
@@ -1426,7 +1426,7 @@ BOOST_AUTO_TEST_CASE(NeighborPtrDeleteTest)
   arma::mat dataset = arma::randu<arma::mat>(5, 100);
 
   // Build the tree ourselves.
-  std::vector<size_t> oldFromNewReferences;
+  vector<size_t> oldFromNewReferences;
   RangeSearch<>::Tree tree(dataset);
   RangeSearch<> ra(&tree);
 
@@ -1442,5 +1442,72 @@ BOOST_AUTO_TEST_CASE(NeighborPtrDeleteTest)
   BOOST_REQUIRE_EQUAL(distances.size(), 50);
 }
 
+/**
+ * Make sure the copy constructor works.
+ */
+BOOST_AUTO_TEST_CASE(CopyConstructorTest)
+{
+  arma::mat dataset(5, 100, arma::fill::randu);
+
+  RangeSearch<> r(dataset);
+  RangeSearch<> r2(r);
+
+  vector<vector<double>> distances, distances2;
+  vector<vector<size_t>> neighbors, neighbors2;
+
+  r.Search(math::Range(0.2, 0.5), neighbors, distances);
+  r2.Search(math::Range(0.2, 0.5), neighbors2, distances2);
+
+  BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size());
+  BOOST_REQUIRE_EQUAL(distances.size(), distances2.size());
+  for (size_t i = 0; i < neighbors.size(); ++i)
+  {
+    BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size());
+    BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size());
+
+    for (size_t j = 0; j < neighbors[i].size(); ++j)
+    {
+      BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]);
+      BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5);
+    }
+  }
+}
+
+/**
+ * Make sure the move constructor works.
+ */
+BOOST_AUTO_TEST_CASE(MoveConstructorTest)
+{
+  arma::mat dataset(5, 100, arma::fill::randu);
+
+  RangeSearch<> r(dataset);
+  RangeSearch<> rCopy(r);
+  RangeSearch<> r2(std::move(rCopy));
+
+  vector<vector<double>> distances, distancesCopy, distances2;
+  vector<vector<size_t>> neighbors, neighborsCopy, neighbors2;
+
+  // Search with all three objects.  The second should give no results.
+  r.Search(math::Range(0.2, 0.5), neighbors, distances);
+  rCopy.Search(math::Range(0.2, 0.5), neighborsCopy, distancesCopy);
+  r2.Search(math::Range(0.2, 0.5), neighbors2, distances2);
+
+  BOOST_REQUIRE_EQUAL(distancesCopy.size(), 0);
+  BOOST_REQUIRE_EQUAL(neighborsCopy.size(), 0);
+
+  BOOST_REQUIRE_EQUAL(distances.size(), distances2.size());
+  BOOST_REQUIRE_EQUAL(neighbors.size(), neighbors2.size());
+  for (size_t i = 0; i < neighbors.size(); ++i)
+  {
+    BOOST_REQUIRE_EQUAL(neighbors[i].size(), neighbors2[i].size());
+    BOOST_REQUIRE_EQUAL(distances[i].size(), distances2[i].size());
+
+    for (size_t j = 0; j < neighbors[i].size(); ++j)
+    {
+      BOOST_REQUIRE_EQUAL(neighbors[i][j], neighbors2[i][j]);
+      BOOST_REQUIRE_CLOSE(distances[i][j], distances2[i][j], 1e-5);
+    }
+  }
+}
 
 BOOST_AUTO_TEST_SUITE_END();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mlpack.git



More information about the debian-science-commits mailing list