[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