From 97f9f962d063dad5dc71052c9abd425bda0e62bc Mon Sep 17 00:00:00 2001 From: abhinavrai44 Date: Mon, 19 Dec 2016 23:01:32 +0530 Subject: [PATCH] Add Copy, Move Constructor and Assignment Operator --- src/mlpack/methods/det/dtree.hpp | 22 +++++++- src/mlpack/methods/det/dtree_impl.hpp | 67 +++++++++++++++++++++++ src/mlpack/tests/det_test.cpp | 78 +++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/mlpack/methods/det/dtree.hpp b/src/mlpack/methods/det/dtree.hpp index d910af7167e..46002fe03ad 100644 --- a/src/mlpack/methods/det/dtree.hpp +++ b/src/mlpack/methods/det/dtree.hpp @@ -52,12 +52,32 @@ class DTree typedef typename MatType::elem_type ElemType; typedef typename MatType::vec_type VecType; typedef typename arma::Col StatType; - + + /** + * Swap Function + */ + void swap(DTree& other) + /** * Create an empty density estimation tree. */ DTree(); + /** + * Create a Copy Constructor. + */ + DTree(const DTree& other); + + /** + * Create a Move Constructor. + */ + DTree(DTree&& other); + + /** + * Create a Copy & Move Assignment Operator. + */ + DTree& operator=(DTree other); + /** * Create a density estimation tree with the given bounds and the given number * of total points. Children will not be created. diff --git a/src/mlpack/methods/det/dtree_impl.hpp b/src/mlpack/methods/det/dtree_impl.hpp index 5625006504f..ed4251d0b03 100644 --- a/src/mlpack/methods/det/dtree_impl.hpp +++ b/src/mlpack/methods/det/dtree_impl.hpp @@ -147,6 +147,27 @@ namespace details } }; +template +void DTree::swap(DTree& other) +{ + std::swap(start, other.start); + std::swap(end, other.end); + std::swap(maxVals, other.maxVals); + std::swap(minVals, other.minVals); + std::swap(splitDim, other.splitDim); + std::swap(splitValue, other.splitValue); + std::swap(logNegError, other.logNegError); + std::swap(subtreeLeavesLogNegError, other.subtreeLeavesLogNegError); + std::swap(subtreeLeaves, other.subtreeLeaves); + std::swap(root, other.root); + std::swap(ratio, other.ratio); + std::swap(logVolume, other.logVolume); + std::swap(bucketTag, other.bucketTag); + std::swap(alphaUpper, other.alphaUpper); + std::swap(left, other.left); + std::swap(right, other.right); +} + template DTree::DTree() : start(0), @@ -166,6 +187,52 @@ DTree::DTree() : { /* Nothing to do. */ } +template +DTree::DTree(const DTree& other) : + start(other.start), + end(other.end), + maxVals(other.maxVals), + minVals(other.minVals), + splitDim(other.splitDim), + splitValue(other.splitValue), + logNegError(other.logNegError), + subtreeLeavesLogNegError(other.subtreeLeavesLogNegError), + subtreeLeaves(other.subtreeLeaves), + root(other.root), + ratio(other.ratio), + logVolume(other.logVolume), + bucketTag(other.bucketTag), + alphaUpper(other.alphaUpper), + left(other.left), + right(other.right) +{ /* Nothing to do. */ } + +template +DTree::DTree(DTree&& other) : + start(0), + end(0), + splitDim(size_t(-1)), + splitValue(std::numeric_limits::max()), + logNegError(-DBL_MAX), + subtreeLeavesLogNegError(-DBL_MAX), + subtreeLeaves(0), + root(true), + ratio(1.0), + logVolume(-DBL_MAX), + bucketTag(-1), + alphaUpper(0.0), + left(NULL), + right(NULL) +{ + swap(other); +} + +template +DTree::& DTree::operator=(DTree other) +{ + swap(other); +} + // Root node initializers template diff --git a/src/mlpack/tests/det_test.cpp b/src/mlpack/tests/det_test.cpp index 5bba5aa4751..afe45614c8d 100644 --- a/src/mlpack/tests/det_test.cpp +++ b/src/mlpack/tests/det_test.cpp @@ -447,6 +447,84 @@ BOOST_AUTO_TEST_CASE(TestSparseComputeValue) BOOST_REQUIRE_CLOSE(0.0, testDTree.ComputeValue(q4), 1e-10); } +// Test the copy constructor and the copy operator. +BOOST_AUTO_TEST_CASE(CopyConstructorAndOperatorTest) +{ + arma::mat testData(3, 5); + + testData << 4 << 5 << 7 << 3 << 5 << arma::endr + << 5 << 0 << 1 << 7 << 1 << arma::endr + << 5 << 6 << 7 << 1 << 8 << arma::endr; + + DTree tree(testData); + + // Copy the Tree + DTree tree2(tree); + DTree tree3 = tree; + + delete tree; + + BOOST_REQUIRE_EQUAL(tree2.maxVals[0], 7); + BOOST_REQUIRE_EQUAL(tree2.minVals[0], 3); + BOOST_REQUIRE_EQUAL(tree2.maxVals[1], 7); + BOOST_REQUIRE_EQUAL(tree2.minVals[1], 0); + BOOST_REQUIRE_EQUAL(tree2.maxVals[2], 8); + BOOST_REQUIRE_EQUAL(tree2.minVals[2], 1); + + BOOST_REQUIRE_EQUAL(tree3.maxVals[0], 7); + BOOST_REQUIRE_EQUAL(tree3.minVals[0], 3); + BOOST_REQUIRE_EQUAL(tree3.maxVals[1], 7); + BOOST_REQUIRE_EQUAL(tree3.minVals[1], 0); + BOOST_REQUIRE_EQUAL(tree3.maxVals[2], 8); + BOOST_REQUIRE_EQUAL(tree3.minVals[2], 1); +} + +// Test the move constructor. +BOOST_AUTO_TEST_CASE(MoveConstructorTest) +{ + arma::mat testData(3, 5); + + testData << 4 << 5 << 7 << 3 << 5 << arma::endr + << 5 << 0 << 1 << 7 << 1 << arma::endr + << 5 << 6 << 7 << 1 << 8 << arma::endr; + + DTree* tree = new DTree(testData); + + DTree tree2(std::move(*tree)); + + delete tree; + + BOOST_REQUIRE_EQUAL(tree2.maxVals[0], 7); + BOOST_REQUIRE_EQUAL(tree2.minVals[0], 3); + BOOST_REQUIRE_EQUAL(tree2.maxVals[1], 7); + BOOST_REQUIRE_EQUAL(tree2.minVals[1], 0); + BOOST_REQUIRE_EQUAL(tree2.maxVals[2], 8); + BOOST_REQUIRE_EQUAL(tree2.minVals[2], 1); +} + +// Test the move operator. +BOOST_AUTO_TEST_CASE(MoveOperatorTest) +{ + arma::mat testData(3, 5); + + testData << 4 << 5 << 7 << 3 << 5 << arma::endr + << 5 << 0 << 1 << 7 << 1 << arma::endr + << 5 << 6 << 7 << 1 << 8 << arma::endr; + + DTree* tree = new DTree(testData); + + DTree tree2 = std::move(*tree); + + delete tree; + + BOOST_REQUIRE_EQUAL(tree2.maxVals[0], 7); + BOOST_REQUIRE_EQUAL(tree2.minVals[0], 3); + BOOST_REQUIRE_EQUAL(tree2.maxVals[1], 7); + BOOST_REQUIRE_EQUAL(tree2.minVals[1], 0); + BOOST_REQUIRE_EQUAL(tree2.maxVals[2], 8); + BOOST_REQUIRE_EQUAL(tree2.minVals[2], 1); +} + /** * These are not yet implemented. *