[mlpack-git] master: Fixed copy constructor of RectangleTree and added move constructor. (be94cfe)
gitdub at mlpack.org
gitdub at mlpack.org
Fri Aug 19 15:23:22 EDT 2016
Repository : https://github.com/mlpack/mlpack
On branch : master
Link : https://github.com/mlpack/mlpack/compare/20f4eacd1b082d04d9aab1fc2f61ef3edaac3f33...5429a59ec38c2b8ebaf27257c74b5e45594976e1
>---------------------------------------------------------------
commit be94cfe400d330f1961540a7773997bc6e4800d7
Author: Mikhail Lozhnikov <lozhnikovma at gmail.com>
Date: Fri Aug 19 22:22:12 2016 +0300
Fixed copy constructor of RectangleTree and added move constructor.
>---------------------------------------------------------------
be94cfe400d330f1961540a7773997bc6e4800d7
.../tree/rectangle_tree/discrete_hilbert_value.hpp | 25 ++++++-
.../rectangle_tree/discrete_hilbert_value_impl.hpp | 84 ++++++++++++++++++++--
.../hilbert_r_tree_auxiliary_information.hpp | 29 +++++++-
.../hilbert_r_tree_auxiliary_information_impl.hpp | 23 +++++-
.../rectangle_tree/hilbert_r_tree_split_impl.hpp | 7 +-
.../rectangle_tree/no_auxiliary_information.hpp | 12 +++-
.../r_plus_plus_tree_auxiliary_information.hpp | 21 ++++--
...r_plus_plus_tree_auxiliary_information_impl.hpp | 12 +++-
.../core/tree/rectangle_tree/rectangle_tree.hpp | 11 ++-
.../tree/rectangle_tree/rectangle_tree_impl.hpp | 70 ++++++++++++++++--
.../x_tree_auxiliary_information.hpp | 61 ++++++++++++++--
src/mlpack/tests/rectangle_tree_test.cpp | 78 ++++++++++++++++++++
12 files changed, 399 insertions(+), 34 deletions(-)
diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp
index 3ce0788..a2a12b0 100644
--- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value.hpp
@@ -45,9 +45,21 @@ class DiscreteHilbertValue
/**
* Create a Hilbert value object by copying from another one.
*
- * @param other The Hilbert value object from which the value will be copied.
+ * @param other The object from which the value will be copied.
+ * @param tree The node that holds the Hilbert value.
+ * @param deepCopy If false, the dataset will not be copied.
*/
- DiscreteHilbertValue(const DiscreteHilbertValue& other);
+ template<typename TreeType>
+ DiscreteHilbertValue(const DiscreteHilbertValue& other,
+ TreeType* tree,
+ bool deepCopy);
+
+ /**
+ * Create a Hilbert value object by moving another one.
+ *
+ * @param other The Hilbert value object from which the value will be moved.
+ */
+ DiscreteHilbertValue(DiscreteHilbertValue&& other);
//! Free memory
~DiscreteHilbertValue();
@@ -224,12 +236,21 @@ class DiscreteHilbertValue
arma::Mat<HilbertElemType>*& LocalHilbertValues()
{ return localHilbertValues; }
+ //! Return the ownsLocalHilbertValues variable.
+ bool OwnsLocalHilbertValues() const { return ownsLocalHilbertValues; }
+ //! Modify the ownsLocalHilbertValues variable.
+ bool& OwnsLocalHilbertValues() { return ownsLocalHilbertValues; }
+
//! Return the cached point (valueToInsert).
const arma::Col<HilbertElemType>* ValueToInsert() const
{ return valueToInsert; }
//! Modify the cached point (valueToInsert).
arma::Col<HilbertElemType>* ValueToInsert() { return valueToInsert; }
+ //! Return the ownsValueToInsert variable.
+ bool OwnsValueToInsert() const { return ownsValueToInsert; }
+ //! Modify the ownsValueToInsert variable.
+ bool& OwnsValueToInsert() { return ownsValueToInsert; }
private:
//! The number of bits that we can store.
static constexpr size_t order = sizeof(HilbertElemType) * CHAR_BIT;
diff --git a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp
index 6495927..5c549f8 100644
--- a/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/discrete_hilbert_value_impl.hpp
@@ -60,16 +60,86 @@ DiscreteHilbertValue<TreeElemType>::DiscreteHilbertValue(const TreeType* tree) :
}
template<typename TreeElemType>
+template<typename TreeType>
DiscreteHilbertValue<TreeElemType>::
-DiscreteHilbertValue(const DiscreteHilbertValue& other) :
- localHilbertValues(
- const_cast<arma::Mat<HilbertElemType>*>(other.LocalHilbertValues())),
+DiscreteHilbertValue(const DiscreteHilbertValue& other,
+ TreeType* tree,
+ bool deepCopy) :
+ localHilbertValues(NULL),
ownsLocalHilbertValues(other.ownsLocalHilbertValues),
numValues(other.NumValues()),
- valueToInsert(
- const_cast<arma::Col<HilbertElemType>*>(other.ValueToInsert())),
- ownsValueToInsert(false)
-{ }
+ valueToInsert(NULL),
+ ownsValueToInsert(other.ownsValueToInsert)
+{
+ if (deepCopy)
+ {
+ // Only leaf nodes own the localHilbertValues dataset.
+ // Intarmediate nodes store the pointer to the corresponding dataset.
+ if (ownsLocalHilbertValues)
+ localHilbertValues = new arma::Mat<HilbertElemType>(
+ *other.LocalHilbertValues());
+ else
+ localHilbertValues = NULL;
+
+ // Only the root owns ownsValueToInsert. Other nodes the pointer.
+ if (ownsValueToInsert)
+ valueToInsert = new arma::Col<HilbertElemType>(
+ *other.ValueToInsert());
+ else
+ {
+ assert(tree->Parent() != NULL);
+ // Copy the pointer from the parent node.
+ valueToInsert = const_cast<arma::Col<HilbertElemType>*>
+ (tree->Parent()->AuxiliaryInfo().HilbertValue().ValueToInsert());
+ }
+
+ if (tree->NumChildren() == 0)
+ {
+ // We have to update pointers to the localHilbertValues dataset in
+ // intermediate nodes.
+ TreeType* node = tree;
+
+ while (node->Parent() != NULL)
+ {
+ if (node->Parent()->NumChildren() > 1)
+ {
+ const std::vector<TreeType*> parentChildren =
+ node->AuxiliaryInfo().Children(node->Parent());
+ // If node is not the last child of its parent, we shouldn't copy
+ // the localHilbertValues pointer.
+ if (parentChildren[node->Parent()->NumChildren() - 2] == NULL)
+ break;
+ }
+ node->Parent()->AuxiliaryInfo().HilbertValue().LocalHilbertValues() =
+ localHilbertValues;
+ node = node->Parent();
+ }
+ }
+ }
+ else
+ {
+ localHilbertValues = const_cast<arma::Mat<HilbertElemType>*>
+ (other.LocalHilbertValues());
+ valueToInsert = const_cast<arma::Col<HilbertElemType>*>
+ (other.ValueToInsert());
+ }
+}
+
+template<typename TreeElemType>
+DiscreteHilbertValue<TreeElemType>::
+DiscreteHilbertValue(DiscreteHilbertValue&& other) :
+ localHilbertValues(other.localHilbertValues),
+ ownsLocalHilbertValues(other.ownsLocalHilbertValues),
+ numValues(other.numValues),
+ valueToInsert(other.valueToInsert),
+ ownsValueToInsert(other.ownsValueToInsert)
+{
+ other.localHilbertValues = NULL;
+ other.ownsLocalHilbertValues = false;
+ other.numValues = 0;
+ other.valueToInsert = NULL;
+ other.ownsValueToInsert = false;
+}
template<typename TreeElemType>
template<typename VecType>
diff --git a/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information.hpp b/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information.hpp
index 8c0b4ae..4db0fa6 100644
--- a/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information.hpp
@@ -30,11 +30,32 @@ class HilbertRTreeAuxiliaryInformation
HilbertRTreeAuxiliaryInformation(const TreeType* node);
/**
- * Create an auxiliary information object by copying from the other node.
+ * Create an auxiliary information object by copying from another object.
*
- * @param other The node from which the information will be copied.
+ * @param other Another auxiliary information object from which the
+ * information will be copied.
+ * @param tree The node that holds the auxiliary information.
+ * @param deepCopy If false, the new object uses the same memory
+ * (not used here).
*/
HilbertRTreeAuxiliaryInformation(
+ const HilbertRTreeAuxiliaryInformation& other,
+ TreeType* tree = NULL,
+ bool deepCopy = true);
+
+ /**
+ * Create an auxiliary information object by moving from the other node.
+ *
+ * @param other The object from which the information will be moved.
+ */
+ HilbertRTreeAuxiliaryInformation(HilbertRTreeAuxiliaryInformation&& other);
+
+ /**
+ * Copy the auxiliary information.
+ *
+ * @param other The object from which the information will be moved.
+ */
+ HilbertRTreeAuxiliaryInformation& operator=(
const HilbertRTreeAuxiliaryInformation& other);
/**
@@ -94,6 +115,10 @@ class HilbertRTreeAuxiliaryInformation
//! Clear memory.
void NullifyData();
+ //! Return the children vector of the tree.
+ static const std::vector<TreeType*> Children(const TreeType* tree)
+ { return tree->children; }
+
private:
//! The largest Hilbert value of a point enclosed by the node.
HilbertValueType<ElemType> hilbertValue;
diff --git a/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information_impl.hpp b/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information_impl.hpp
index b27507f..73689bf 100644
--- a/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_auxiliary_information_impl.hpp
@@ -30,12 +30,31 @@ template<typename TreeType,
template<typename> class HilbertValueType>
HilbertRTreeAuxiliaryInformation<TreeType, HilbertValueType>::
HilbertRTreeAuxiliaryInformation(
- const HilbertRTreeAuxiliaryInformation& other) :
- hilbertValue(other.HilbertValue())
+ const HilbertRTreeAuxiliaryInformation& other,
+ TreeType* tree,
+ bool deepCopy) :
+ hilbertValue(other.HilbertValue(), tree, deepCopy)
{ }
template<typename TreeType,
template<typename> class HilbertValueType>
+HilbertRTreeAuxiliaryInformation<TreeType, HilbertValueType>::
+HilbertRTreeAuxiliaryInformation(HilbertRTreeAuxiliaryInformation&& other) :
+ hilbertValue(std::move(other.hilbertValue))
+{ }
+
+template<typename TreeType,
+ template<typename> class HilbertValueType>
+HilbertRTreeAuxiliaryInformation<TreeType, HilbertValueType>&
+HilbertRTreeAuxiliaryInformation<TreeType, HilbertValueType>::operator=(
+ const HilbertRTreeAuxiliaryInformation& other)
+{
+ hilbertValue = other.hilbertValue;
+ return *this;
+}
+
+template<typename TreeType,
+ template<typename> class HilbertValueType>
bool HilbertRTreeAuxiliaryInformation<TreeType, HilbertValueType>::
HandlePointInsertion(TreeType* node, const size_t point)
{
diff --git a/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_split_impl.hpp b/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_split_impl.hpp
index 5fa7911..12ba1ae 100644
--- a/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_split_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/hilbert_r_tree_split_impl.hpp
@@ -28,6 +28,10 @@ void HilbertRTreeSplit<splitOrder>::SplitLeafNode(TreeType* tree,
{
// We actually want to copy this way. Pointers and everything.
TreeType* copy = new TreeType(*tree, false);
+ // Only the root node owns this variable.
+ copy->AuxiliaryInfo().HilbertValue().OwnsValueToInsert() = false;
+ // Only leaf nodes own this variable.
+ tree->AuxiliaryInfo().HilbertValue().OwnsLocalHilbertValues() = false;
copy->Parent() = tree;
tree->Count() = 0;
tree->NullifyData();
@@ -89,7 +93,8 @@ SplitNonLeafNode(TreeType* tree, std::vector<bool>& relevels)
{
// We actually want to copy this way. Pointers and everything.
TreeType* copy = new TreeType(*tree, false);
-
+ // Only the root node owns this variable.
+ copy->AuxiliaryInfo().HilbertValue().OwnsValueToInsert() = false;
copy->Parent() = tree;
tree->NumChildren() = 0;
tree->NullifyData();
diff --git a/src/mlpack/core/tree/rectangle_tree/no_auxiliary_information.hpp b/src/mlpack/core/tree/rectangle_tree/no_auxiliary_information.hpp
index e282a4c..c0772f8 100644
--- a/src/mlpack/core/tree/rectangle_tree/no_auxiliary_information.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/no_auxiliary_information.hpp
@@ -20,7 +20,17 @@ class NoAuxiliaryInformation
//! Construct the auxiliary information object.
NoAuxiliaryInformation(const TreeType* /* node */) { };
//! Construct the auxiliary information object.
- NoAuxiliaryInformation(const TreeType& /* node */) { };
+ NoAuxiliaryInformation(const NoAuxiliaryInformation& /* other */,
+ TreeType* /* tree */,
+ bool /* deepCopy */ = true) { };
+ //! Construct the auxiliary information object.
+ NoAuxiliaryInformation(NoAuxiliaryInformation&& /* other */) { };
+
+ //! Copy the auxiliary information object.
+ NoAuxiliaryInformation& operator=(const NoAuxiliaryInformation& /* other */)
+ {
+ return *this;
+ }
/**
* Some tree types require to save some properties at the insertion process.
diff --git a/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information.hpp b/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information.hpp
index aebd98f..768c870 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information.hpp
@@ -35,13 +35,26 @@ class RPlusPlusTreeAuxiliaryInformation
RPlusPlusTreeAuxiliaryInformation(const TreeType* /* node */);
/**
- * Create an auxiliary information object by copying from another node.
+ * Create an auxiliary information object by copying from another object.
*
- * @param other The auxiliary information object from which the information
- * will be copied.
+ * @param other Another auxiliary information object from which the
+ * information will be copied.
+ * @param tree The node that holds the auxiliary information.
+ * @param deepCopy If false, the new object uses the same memory
+ * (not used here).
*/
RPlusPlusTreeAuxiliaryInformation(
- const RPlusPlusTreeAuxiliaryInformation& other);
+ const RPlusPlusTreeAuxiliaryInformation& other,
+ TreeType* tree,
+ bool /* deepCopy */ = true);
+
+ /**
+ * Create an auxiliary information object by moving from another node.
+ *
+ * @param other The auxiliary information object from which the information
+ * will be moved.
+ */
+ RPlusPlusTreeAuxiliaryInformation(RPlusPlusTreeAuxiliaryInformation&& other);
/**
* Some tree types require to save some properties at the insertion process.
diff --git a/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information_impl.hpp
index 534ad9a..3494494 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_plus_plus_tree_auxiliary_information_impl.hpp
@@ -41,13 +41,23 @@ RPlusPlusTreeAuxiliaryInformation(const TreeType* tree) :
template<typename TreeType>
RPlusPlusTreeAuxiliaryInformation<TreeType>::
RPlusPlusTreeAuxiliaryInformation(
- const RPlusPlusTreeAuxiliaryInformation& other) :
+ const RPlusPlusTreeAuxiliaryInformation& other,
+ TreeType* /* tree */,
+ bool /* deepCopy */) :
outerBound(other.OuterBound())
{
}
template<typename TreeType>
+RPlusPlusTreeAuxiliaryInformation<TreeType>::
+RPlusPlusTreeAuxiliaryInformation(RPlusPlusTreeAuxiliaryInformation&& other) :
+ outerBound(std::move(other.outerBound))
+{
+
+}
+
+template<typename TreeType>
bool RPlusPlusTreeAuxiliaryInformation<TreeType>::HandlePointInsertion(
TreeType* /* node */, const size_t /* point */)
{
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
index c694337..57e80f2 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
@@ -168,7 +168,16 @@ class RectangleTree
* @param other The tree to be copied.
* @param deepCopy If false, the children are not recursively copied.
*/
- RectangleTree(const RectangleTree& other, const bool deepCopy = true);
+ RectangleTree(const RectangleTree& other,
+ const bool deepCopy = true,
+ RectangleTree* newParent = NULL);
+
+ /**
+ * Create a rectangle tree by moving the other tree.
+ *
+ * @param other The tree to be copied.
+ */
+ RectangleTree(RectangleTree&& other);
/**
* Construct the tree from a boost::serialization archive.
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
index 81842ac..6c553ec 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
@@ -143,12 +143,13 @@ RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
AuxiliaryInformationType>::
RectangleTree(
const RectangleTree& other,
- const bool deepCopy) :
+ const bool deepCopy,
+ RectangleTree* newParent) :
maxNumChildren(other.MaxNumChildren()),
minNumChildren(other.MinNumChildren()),
numChildren(other.NumChildren()),
- children(maxNumChildren + 1),
- parent(other.Parent()),
+ children(maxNumChildren + 1, NULL),
+ parent(deepCopy ? newParent : other.Parent()),
begin(other.Begin()),
count(other.Count()),
numDescendants(other.numDescendants),
@@ -156,23 +157,78 @@ RectangleTree(
minLeafSize(other.MinLeafSize()),
bound(other.bound),
parentDistance(other.ParentDistance()),
- dataset(deepCopy ? new MatType(*other.dataset) : &other.Dataset()),
- ownsDataset(deepCopy),
+ dataset(deepCopy ?
+ (parent ? parent->dataset : new MatType(*other.dataset)) :
+ &other.Dataset()),
+ ownsDataset(deepCopy && (!parent)),
points(other.points),
- auxiliaryInfo(other.auxiliaryInfo)
+ auxiliaryInfo(other.auxiliaryInfo, this, deepCopy)
{
if (deepCopy)
{
if (numChildren > 0)
{
for (size_t i = 0; i < numChildren; i++)
- children[i] = new RectangleTree(other.Child(i));
+ children[i] = new RectangleTree(other.Child(i), true, this);
}
}
else
children = other.children;
}
+template<typename MetricType,
+ typename StatisticType,
+ typename MatType,
+ typename SplitType,
+ typename DescentType,
+ template<typename> class AuxiliaryInformationType>
+RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
+ AuxiliaryInformationType>::
+RectangleTree(RectangleTree&& other) :
+ maxNumChildren(other.MaxNumChildren()),
+ minNumChildren(other.MinNumChildren()),
+ numChildren(other.NumChildren()),
+ children(std::move(other.children)),
+ parent(other.Parent()),
+ begin(other.Begin()),
+ count(other.Count()),
+ numDescendants(other.numDescendants),
+ maxLeafSize(other.MaxLeafSize()),
+ minLeafSize(other.MinLeafSize()),
+ bound(std::move(other.bound)),
+ parentDistance(other.ParentDistance()),
+ dataset(other.dataset),
+ ownsDataset(other.ownsDataset),
+ points(std::move(other.points)),
+ auxiliaryInfo(std::move(other.auxiliaryInfo))
+{
+ if (parent)
+ {
+ size_t iChild = 0;
+ while (parent->children[iChild] != (&other))
+ iChild++;
+ assert(iChild < numChildren);
+ parent->children[iChild] = this;
+ }
+ if (!IsLeaf())
+ {
+ for (size_t i = 0; i < numChildren; i++)
+ children[i]->parent = this;
+ }
+ other.maxNumChildren = 0;
+ other.minNumChildren = 0;
+ other.numChildren = 0;
+ other.parent = NULL;
+ other.begin = 0;
+ other.count = 0;
+ other.numDescendants = 0;
+ other.maxLeafSize = 0;
+ other.minLeafSize = 0;
+ other.parentDistance = 0;
+ other.dataset = NULL;
+ other.ownsDataset = false;
+}
+
/**
* Construct the tree from a boost::serialization archive.
*/
diff --git a/src/mlpack/core/tree/rectangle_tree/x_tree_auxiliary_information.hpp b/src/mlpack/core/tree/rectangle_tree/x_tree_auxiliary_information.hpp
index f8a553f..ed4a317 100644
--- a/src/mlpack/core/tree/rectangle_tree/x_tree_auxiliary_information.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/x_tree_auxiliary_information.hpp
@@ -38,17 +38,47 @@ class XTreeAuxiliaryInformation
{ };
/**
- * Create an auxiliary information object by copying from the other node.
+ * Create an auxiliary information object by copying from another object.
*
- * @param other The node from which the information will be copied.
+ * @param other Another auxiliary information object from which the
+ * information will be copied.
+ * @param tree The node that holds the auxiliary information.
+ * @param deepCopy If false, the new object uses the same memory
+ * (not used here).
*/
- XTreeAuxiliaryInformation(const TreeType& other) :
- normalNodeMaxNumChildren(
- other.AuxiliaryInfo().NormalNodeMaxNumChildren()),
- splitHistory(other.AuxiliaryInfo().SplitHistory())
+ XTreeAuxiliaryInformation(const XTreeAuxiliaryInformation& other,
+ TreeType* /* tree */ = NULL,
+ bool /* deepCopy */ = true) :
+ normalNodeMaxNumChildren(other.NormalNodeMaxNumChildren()),
+ splitHistory(other.SplitHistory())
{ };
/**
+ * Copy the auxiliary information object.
+ *
+ * @param other The node from which the information will be copied.
+ */
+ XTreeAuxiliaryInformation& operator=(const XTreeAuxiliaryInformation& other)
+ {
+ normalNodeMaxNumChildren = other.NormalNodeMaxNumChildren();
+ splitHistory = other.SplitHistory();
+
+ return *this;
+ }
+
+ /**
+ * Create an auxiliary information object by moving from the other node.
+ *
+ * @param other The object from which the information will be moved.
+ */
+ XTreeAuxiliaryInformation(XTreeAuxiliaryInformation&& other) :
+ normalNodeMaxNumChildren(other.NormalNodeMaxNumChildren()),
+ splitHistory(std::move(other.splitHistory))
+ {
+ other.normalNodeMaxNumChildren = 0;
+ };
+
+ /**
* Some tree types require to save some properties at the insertion process.
* This method allows the auxiliary information the option of manipulating the
* tree in order to perform the insertion process. If the auxiliary
@@ -142,6 +172,25 @@ class XTreeAuxiliaryInformation
history[i] = false;
}
+ SplitHistoryStruct(const SplitHistoryStruct& other) :
+ lastDimension(other.lastDimension),
+ history(other.history)
+ { }
+
+ SplitHistoryStruct& operator=(const SplitHistoryStruct& other)
+ {
+ lastDimension = other.lastDimension;
+ history = other.history;
+ return *this;
+ }
+
+ SplitHistoryStruct(SplitHistoryStruct&& other) :
+ lastDimension(other.lastDimension),
+ history(std::move(other.history))
+ {
+ other.lastDimension = 0;
+ }
+
template<typename Archive>
void Serialize(Archive& ar, const unsigned int /* version */)
{
diff --git a/src/mlpack/tests/rectangle_tree_test.cpp b/src/mlpack/tests/rectangle_tree_test.cpp
index 80e6fc7..c8b99a2 100644
--- a/src/mlpack/tests/rectangle_tree_test.cpp
+++ b/src/mlpack/tests/rectangle_tree_test.cpp
@@ -865,6 +865,83 @@ BOOST_AUTO_TEST_CASE(DiscreteHilbertValueTest)
}
template<typename TreeType>
+void CheckHilbertValue(const TreeType& tree)
+{
+ typedef DiscreteHilbertValue<typename TreeType::ElemType>
+ HilbertValue;
+
+ const HilbertValue& value = tree.AuxiliaryInfo().HilbertValue();
+
+ if (tree.IsLeaf())
+ {
+ BOOST_REQUIRE_EQUAL(value.OwnsLocalHilbertValues(), true);
+ return;
+ }
+
+ for (size_t i = 0; i < tree.NumChildren(); i++)
+ {
+ const HilbertValue& childValue =
+ tree.Child(i).AuxiliaryInfo().HilbertValue();
+ BOOST_REQUIRE_EQUAL(value.ValueToInsert(), childValue.ValueToInsert());
+ }
+
+ const HilbertValue& childValue =
+ tree.Child(tree.NumChildren() - 1).AuxiliaryInfo().HilbertValue();
+ BOOST_REQUIRE_EQUAL(value.LocalHilbertValues(),
+ childValue.LocalHilbertValues());
+
+ if (!tree.Parent())
+ BOOST_REQUIRE_EQUAL(value.OwnsValueToInsert(), true);
+ else
+ BOOST_REQUIRE_EQUAL(value.OwnsValueToInsert(), false);
+
+ BOOST_REQUIRE_EQUAL(value.OwnsLocalHilbertValues(), false);
+
+ for (size_t i = 0; i < tree.NumChildren(); i++)
+ CheckHilbertValue(tree.Child(i));
+}
+
+BOOST_AUTO_TEST_CASE(HilbertRTeeCopyConstructorTest)
+{
+ typedef HilbertRTree<EuclideanDistance,
+ NeighborSearchStat<NearestNeighborSort>, arma::mat> TreeType;
+
+ arma::mat dataset;
+ dataset.randu(8, 1000); // 1000 points in 8 dimensions.
+
+ TreeType tree(dataset, 20, 6, 5, 2, 0);
+ TreeType copy(tree);
+
+ CheckHilbertValue(copy);
+ CheckDiscreteHilbertValueSync(copy);
+ CheckHilbertOrdering(copy);
+ CheckContainment(copy);
+ CheckExactContainment(copy);
+ CheckHierarchy(copy);
+ CheckNumDescendants(copy);
+}
+
+BOOST_AUTO_TEST_CASE(HilbertRTeeMoveConstructorTest)
+{
+ typedef HilbertRTree<EuclideanDistance,
+ NeighborSearchStat<NearestNeighborSort>, arma::mat> TreeType;
+
+ arma::mat dataset;
+ dataset.randu(8, 1000); // 1000 points in 8 dimensions.
+
+ TreeType tree(dataset, 20, 6, 5, 2, 0);
+ TreeType copy(std::move(tree));
+
+ CheckHilbertValue(copy);
+ CheckDiscreteHilbertValueSync(copy);
+ CheckHilbertOrdering(copy);
+ CheckContainment(copy);
+ CheckExactContainment(copy);
+ CheckHierarchy(copy);
+ CheckNumDescendants(copy);
+}
+
+template<typename TreeType>
void CheckOverlap(const TreeType& tree)
{
bool success = true;
@@ -893,6 +970,7 @@ void CheckOverlap(const TreeType& tree)
CheckOverlap(tree.Child(i));
}
+
BOOST_AUTO_TEST_CASE(RPlusTreeOverlapTest)
{
arma::mat dataset;
More information about the mlpack-git
mailing list