[mlpack-git] master: R tree clean up. Change Child() to match BSP tree. Copy constructor takes a second argument to specify whether it is a deep copy. (d740ec5)

gitdub at big.cc.gt.atl.ga.us gitdub at big.cc.gt.atl.ga.us
Thu Mar 5 21:55:12 EST 2015


Repository : https://github.com/mlpack/mlpack

On branch  : master
Link       : https://github.com/mlpack/mlpack/compare/904762495c039e345beba14c1142fd719b3bd50e...f94823c800ad6f7266995c700b1b630d5ffdcf40

>---------------------------------------------------------------

commit d740ec5c3b96a0b4f67cf9db059a962d0fa595b3
Author: andrewmw94 <andrewmw94 at gmail.com>
Date:   Mon Jul 28 21:05:47 2014 +0000

    R tree clean up.  Change Child() to match BSP tree.  Copy constructor takes a second argument to specify whether it is a deep copy.


>---------------------------------------------------------------

d740ec5c3b96a0b4f67cf9db059a962d0fa595b3
 .../r_star_tree_descent_heuristic_impl.hpp         |  24 ++--
 .../tree/rectangle_tree/r_star_tree_split_impl.hpp | 110 ++++++++---------
 .../r_tree_descent_heuristic_impl.hpp              |  16 +--
 .../core/tree/rectangle_tree/r_tree_split_impl.hpp |  72 ++++++------
 .../core/tree/rectangle_tree/rectangle_tree.hpp    |  33 ++++--
 .../tree/rectangle_tree/rectangle_tree_impl.hpp    |  42 ++++++-
 src/mlpack/tests/rectangle_tree_test.cpp           | 130 +++++++++++----------
 7 files changed, 241 insertions(+), 186 deletions(-)

diff --git a/src/mlpack/core/tree/rectangle_tree/r_star_tree_descent_heuristic_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_star_tree_descent_heuristic_impl.hpp
index da6d425..15e5bc5 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_star_tree_descent_heuristic_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_star_tree_descent_heuristic_impl.hpp
@@ -20,7 +20,7 @@ inline size_t RStarTreeDescentHeuristic::ChooseDescentNode(const TreeType* node,
   std::vector<double> originalScores(node->NumChildren());
   double origMinScore = DBL_MAX;
 
-  if (node->Child(0)->IsLeaf()) { // If its children are leaf nodes, use minimum overlap to choose.
+  if (node->Children()[0]->IsLeaf()) { // If its children are leaf nodes, use minimum overlap to choose.
     double bestIndex = 0;
 
     for (size_t i = 0; i < node->NumChildren(); i++) {
@@ -30,10 +30,10 @@ inline size_t RStarTreeDescentHeuristic::ChooseDescentNode(const TreeType* node,
           double overlap = 1.0;
           double newOverlap = 1.0;
           for (size_t k = 0; k < node->Bound().Dim(); k++) {
-            double newHigh = std::max(point[k], node->Child(i)->Bound()[k].Hi());
-            double newLow = std::min(point[k], node->Child(i)->Bound()[k].Lo());
-            overlap *= node->Child(i)->Bound()[k].Hi() < node->Child(j)->Bound()[k].Lo() || node->Child(i)->Bound()[k].Lo() > node->Child(j)->Bound()[k].Hi() ? 0 : std::min(node->Child(i)->Bound()[k].Hi(), node->Child(j)->Bound()[k].Hi()) - std::max(node->Child(i)->Bound()[k].Lo(), node->Child(j)->Bound()[k].Lo());
-            newOverlap *= newHigh < node->Child(j)->Bound()[k].Lo() || newLow > node->Child(j)->Bound()[k].Hi() ? 0 : std::min(newHigh, node->Child(j)->Bound()[k].Hi()) - std::max(newLow, node->Child(j)->Bound()[k].Lo());
+            double newHigh = std::max(point[k], node->Children()[i]->Bound()[k].Hi());
+            double newLow = std::min(point[k], node->Children()[i]->Bound()[k].Lo());
+            overlap *= node->Children()[i]->Bound()[k].Hi() < node->Children()[j]->Bound()[k].Lo() || node->Children()[i]->Bound()[k].Lo() > node->Children()[j]->Bound()[k].Hi() ? 0 : std::min(node->Children()[i]->Bound()[k].Hi(), node->Children()[j]->Bound()[k].Hi()) - std::max(node->Children()[i]->Bound()[k].Lo(), node->Children()[j]->Bound()[k].Lo());
+            newOverlap *= newHigh < node->Children()[j]->Bound()[k].Lo() || newLow > node->Children()[j]->Bound()[k].Hi() ? 0 : std::min(newHigh, node->Children()[j]->Bound()[k].Hi()) - std::max(newLow, node->Children()[j]->Bound()[k].Lo());
           }
           sc += newOverlap - overlap;
         }
@@ -66,9 +66,9 @@ inline size_t RStarTreeDescentHeuristic::ChooseDescentNode(const TreeType* node,
       double v1 = 1.0;
       double v2 = 1.0;
       for (size_t j = 0; j < node->Bound().Dim(); j++) {
-        v1 *= node->Child(i)->Bound()[j].Width();
-        v2 *= node->Child(i)->Bound()[j].Contains(point[j]) ? node->Child(i)->Bound()[j].Width() : (node->Child(i)->Bound()[j].Hi() < point[j] ? (point[j] - node->Child(i)->Bound()[j].Lo()) :
-                (node->Child(i)->Bound()[j].Hi() - point[j]));
+        v1 *= node->Children()[i]->Bound()[j].Width();
+        v2 *= node->Children()[i]->Bound()[j].Contains(point[j]) ? node->Children()[i]->Bound()[j].Width() : (node->Children()[i]->Bound()[j].Hi() < point[j] ? (point[j] - node->Children()[i]->Bound()[j].Lo()) :
+                (node->Children()[i]->Bound()[j].Hi() - point[j]));
       }
       assert(v2 - v1 >= 0);
       vols[i] = v1;
@@ -113,10 +113,10 @@ inline size_t RStarTreeDescentHeuristic::ChooseDescentNode(const TreeType* node,
   for (size_t i = 0; i < node->NumChildren(); i++) {
     double v1 = 1.0;
     double v2 = 1.0;
-    for (size_t j = 0; j < node->Child(i)->Bound().Dim(); j++) {
-      v1 *= node->Child(i)->Bound()[j].Width();
-      v2 *= node->Child(i)->Bound()[j].Contains(insertedNode->Bound()[j]) ? node->Child(i)->Bound()[j].Width() :
-              (insertedNode->Bound()[j].Contains(node->Child(i)->Bound()[j]) ? insertedNode->Bound()[j].Width() : (insertedNode->Bound()[j].Lo() < node->Child(i)->Bound()[j].Lo() ? (node->Child(i)->Bound()[j].Hi() - insertedNode->Bound()[j].Lo()) : (insertedNode->Bound()[j].Hi() - node->Child(i)->Bound()[j].Lo())));
+    for (size_t j = 0; j < node->Children()[i]->Bound().Dim(); j++) {
+      v1 *= node->Children()[i]->Bound()[j].Width();
+      v2 *= node->Children()[i]->Bound()[j].Contains(insertedNode->Bound()[j]) ? node->Children()[i]->Bound()[j].Width() :
+              (insertedNode->Bound()[j].Contains(node->Children()[i]->Bound()[j]) ? insertedNode->Bound()[j].Width() : (insertedNode->Bound()[j].Lo() < node->Children()[i]->Bound()[j].Lo() ? (node->Children()[i]->Bound()[j].Hi() - insertedNode->Bound()[j].Lo()) : (insertedNode->Bound()[j].Hi() - node->Children()[i]->Bound()[j].Lo())));
     }
     assert(v2 - v1 >= 0);
     vols[i] = v1;
diff --git a/src/mlpack/core/tree/rectangle_tree/r_star_tree_split_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_star_tree_split_impl.hpp
index b59dfb9..26d6e1d 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_star_tree_split_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_star_tree_split_impl.hpp
@@ -31,26 +31,17 @@ void RStarTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
   // and other methods don't confuse the end user by giving an address of another node.
   if (tree->Parent() == NULL) {
     RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* copy = 
-            new RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree); // We actually want to copy this way.  Pointers and everything.
+        new RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree, false); // We actually want to copy this way.  Pointers and everything.
+
     copy->Parent() = tree;
     tree->Count() = 0;
     tree->NullifyData();
-    tree->Child((tree->NumChildren())++) = copy; // Because this was a leaf node, numChildren must be 0.
+    tree->Children()[(tree->NumChildren())++] = copy; // Because this was a leaf node, numChildren must be 0.
     assert(tree->NumChildren() == 1);
     RStarTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(copy, relevels);
     return;
   }
    
-  bool foundTreeChildParent = false;
-  for(int nou=0; nou < tree->Parent()->NumChildren(); nou++) {
-    if(tree->Parent()->Child(nou) == tree) {
-      foundTreeChildParent = true;
-    break;
-  }
-  }
-  assert(foundTreeChildParent == true);
-  
-   
  // If we haven't yet reinserted on this level, we try doing so now.
  if(relevels[tree->TreeDepth()]) {
    relevels[tree->TreeDepth()] = false;
@@ -216,14 +207,14 @@ void RStarTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
   RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* par = tree->Parent();
   int index = -1;
   for (int i = 0; i < par->NumChildren(); i++) {
-    if (par->Child(i) == tree) {
+    if (par->Children()[i] == tree) {
       index = i;
       break;
     }
   }
   assert(index != -1);
-  par->Child(index) = treeOne;
-  par->Child(par->NumChildren()++) = treeTwo;
+  par->Children()[index] = treeOne;
+  par->Children()[par->NumChildren()++] = treeTwo;
 
   // we only add one at a time, so we should only need to test for equality
   // just in case, we use an assert.
@@ -260,11 +251,12 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   // and other methods don't confuse the end user by giving an address of another node.
   if (tree->Parent() == NULL) {
     RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* copy = 
-            new RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree); // We actually want to copy this way.  Pointers and everything.
+        new RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree, false); // We actually want to copy this way.  Pointers and everything.
+
     copy->Parent() = tree;
     tree->NumChildren() = 0;
     tree->NullifyData();
-    tree->Child((tree->NumChildren())++) = copy;
+    tree->Children()[(tree->NumChildren())++] = copy;
     RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(copy, relevels);
     return true;
   }
@@ -288,7 +280,7 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
     tree->Bound().Centroid(c1); // Modifies c1.
     for(size_t i = 0; i < sorted.size(); i++) {
       arma::vec c2;
-      tree->Child(i)->Bound().Centroid(c2); // Modifies c2.
+      tree->Children()[i]->Bound().Centroid(c2); // Modifies c2.
       sorted[i].d = tree->Bound().Metric().Evaluate(c1,c2);
       sorted[i].n = i;
     }
@@ -298,8 +290,8 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
  
     std::vector<RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>*> removedNodes(p);
     for(size_t i =0; i < p; i++) {
-      removedNodes[i] = tree->Child(sorted[sorted.size()-1-i].n); // We start from the end of sorted.
-      root->RemoveNode(tree->Child(sorted[sorted.size()-1-i].n), relevels);
+      removedNodes[i] = tree->Children()[sorted[sorted.size()-1-i].n]; // We start from the end of sorted.
+      root->RemoveNode(tree->Children()[sorted[sorted.size()-1-i].n], relevels);
     }
     
     for(size_t i = 0; i < p; i++) {
@@ -314,7 +306,7 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
 //    if(tree->NumChildren() < tree->MinNumChildren()) {
 //      std::vector<RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>*> rmNodes(tree->NumChildren());
 //      for(size_t i = 0; i < rmNodes.size(); i++) {
-//        rmNodes[i] = tree->Child(i);
+//        rmNodes[i] = tree->Children()[i];
 //      }
 //      root->RemoveNode(tree, relevels);
 //      for(size_t i = 0; i < rmNodes.size(); i++) {
@@ -340,7 +332,7 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
     // We'll do Bound().Lo() now and use Bound().Hi() later.
     std::vector<sortStruct> sorted(tree->NumChildren());
     for (int i = 0; i < sorted.size(); i++) {
-      sorted[i].d = tree->Child(i)->Bound()[j].Lo();
+      sorted[i].d = tree->Children()[i]->Bound()[j].Lo();
       sorted[i].n = i;
     }
 
@@ -368,21 +360,21 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
       std::vector<double> maxG2(maxG1.size());
       std::vector<double> minG2(maxG1.size());
       for (int k = 0; k < tree->Bound().Dim(); k++) {
-        minG1[k] = tree->Child(sorted[0].n)->Bound()[k].Lo();
-        maxG1[k] = tree->Child(sorted[0].n)->Bound()[k].Hi();
-        minG2[k] = tree->Child(sorted[sorted.size() - 1].n)->Bound()[k].Lo();
-        maxG2[k] = tree->Child(sorted[sorted.size() - 1].n)->Bound()[k].Hi();
+        minG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Lo();
+        maxG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Hi();
+        minG2[k] = tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Lo();
+        maxG2[k] = tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Hi();
         for (int l = 1; l < tree->NumChildren() - 1; l++) {
           if (l < cutOff) {
-            if (tree->Child(sorted[l].n)->Bound()[k].Lo() < minG1[k])
-              minG1[k] = tree->Child(sorted[l].n)->Bound()[k].Lo();
-            else if (tree->Child(sorted[l].n)->Bound()[k].Hi() > maxG1[k])
-              maxG1[k] = tree->Child(sorted[l].n)->Bound()[k].Hi();
+            if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG1[k])
+              minG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
+            else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG1[k])
+              maxG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
           } else {
-            if (tree->Child(sorted[l].n)->Bound()[k].Lo() < minG2[k])
-              minG2[k] = tree->Child(sorted[l].n)->Bound()[k].Lo();
-            else if (tree->Child(sorted[l].n)->Bound()[k].Hi() > maxG2[k])
-              maxG2[k] = tree->Child(sorted[l].n)->Bound()[k].Hi();
+            if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG2[k])
+              minG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
+            else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG2[k])
+              maxG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
           }
         }
       }
@@ -424,7 +416,7 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
     // We'll do Bound().Lo() now and use Bound().Hi() later.
     std::vector<sortStruct> sorted(tree->NumChildren());
     for (int i = 0; i < sorted.size(); i++) {
-      sorted[i].d = tree->Child(i)->Bound()[j].Hi();
+      sorted[i].d = tree->Children()[i]->Bound()[j].Hi();
       sorted[i].n = i;
     }
 
@@ -452,21 +444,21 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
       std::vector<double> maxG2(maxG1.size());
       std::vector<double> minG2(maxG1.size());
       for (int k = 0; k < tree->Bound().Dim(); k++) {
-        minG1[k] = tree->Child(sorted[0].n)->Bound()[k].Lo();
-        maxG1[k] = tree->Child(sorted[0].n)->Bound()[k].Hi();
-        minG2[k] = tree->Child(sorted[sorted.size() - 1].n)->Bound()[k].Lo();
-        maxG2[k] = tree->Child(sorted[sorted.size() - 1].n)->Bound()[k].Hi();
+        minG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Lo();
+        maxG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Hi();
+        minG2[k] = tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Lo();
+        maxG2[k] = tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Hi();
         for (int l = 1; l < tree->NumChildren() - 1; l++) {
           if (l < cutOff) {
-            if (tree->Child(sorted[l].n)->Bound()[k].Lo() < minG1[k])
-              minG1[k] = tree->Child(sorted[l].n)->Bound()[k].Lo();
-            else if (tree->Child(sorted[l].n)->Bound()[k].Hi() > maxG1[k])
-              maxG1[k] = tree->Child(sorted[l].n)->Bound()[k].Hi();
+            if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG1[k])
+              minG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
+            else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG1[k])
+              maxG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
           } else {
-            if (tree->Child(sorted[l].n)->Bound()[k].Lo() < minG2[k])
-              minG2[k] = tree->Child(sorted[l].n)->Bound()[k].Lo();
-            else if (tree->Child(sorted[l].n)->Bound()[k].Hi() > maxG2[k])
-              maxG2[k] = tree->Child(sorted[l].n)->Bound()[k].Hi();
+            if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG2[k])
+              minG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
+            else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG2[k])
+              maxG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
           }
         }
       }
@@ -505,12 +497,12 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   std::vector<sortStruct> sorted(tree->NumChildren());
   if (lowIsBest) {
     for (int i = 0; i < sorted.size(); i++) {
-      sorted[i].d = tree->Child(i)->Bound()[bestAxis].Lo();
+      sorted[i].d = tree->Children()[i]->Bound()[bestAxis].Lo();
       sorted[i].n = i;
     }
   } else {
     for (int i = 0; i < sorted.size(); i++) {
-      sorted[i].d = tree->Child(i)->Bound()[bestAxis].Hi();
+      sorted[i].d = tree->Children()[i]->Bound()[bestAxis].Hi();
       sorted[i].n = i;
     }
   }
@@ -525,16 +517,16 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   if (tiedOnOverlap) {
     for (int i = 0; i < tree->NumChildren(); i++) {
       if (i < bestAreaIndexOnBestAxis + tree->MinNumChildren())
-        InsertNodeIntoTree(treeOne, tree->Child(sorted[i].n));
+        InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
       else
-        InsertNodeIntoTree(treeTwo, tree->Child(sorted[i].n));
+        InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
     }
   } else {
     for (int i = 0; i < tree->NumChildren(); i++) {
       if (i < bestOverlapIndexOnBestAxis + tree->MinNumChildren())
-        InsertNodeIntoTree(treeOne, tree->Child(sorted[i].n));
+        InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
       else
-        InsertNodeIntoTree(treeTwo, tree->Child(sorted[i].n));
+        InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
     }
   }
 
@@ -542,13 +534,13 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* par = tree->Parent();
   int index = 0;
   for (int i = 0; i < par->NumChildren(); i++) {
-    if (par->Child(i) == tree) {
+    if (par->Children()[i] == tree) {
       index = i;
       break;
     }
   }
-  par->Child(index) = treeOne;
-  par->Child(par->NumChildren()++) = treeTwo;
+  par->Children()[index] = treeOne;
+  par->Children()[par->NumChildren()++] = treeTwo;
 
   // we only add one at a time, so we should only need to test for equality
   // just in case, we use an assert.
@@ -560,10 +552,10 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   // We have to update the children of each of these new nodes so that they record the 
   // correct parent.
   for (int i = 0; i < treeOne->NumChildren(); i++) {
-    treeOne->Child(i)->Parent() = treeOne;
+    treeOne->Children()[i]->Parent() = treeOne;
   }
   for (int i = 0; i < treeTwo->NumChildren(); i++) {
-    treeTwo->Child(i)->Parent() = treeTwo;
+    treeTwo->Children()[i]->Parent() = treeTwo;
   }
 
   assert(treeOne->Parent()->NumChildren() <= treeOne->MaxNumChildren());
@@ -590,7 +582,7 @@ void RStarTreeSplit<DescentType, StatisticType, MatType>::InsertNodeIntoTree(
         RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* srcNode)
 {
   destTree->Bound() |= srcNode->Bound();
-  destTree->Child(destTree->NumChildren()++) = srcNode;
+  destTree->Children()[destTree->NumChildren()++] = srcNode;
 }
 
 }; // namespace tree
diff --git a/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp
index f30d676..5767062 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_tree_descent_heuristic_impl.hpp
@@ -25,10 +25,10 @@ inline size_t RTreeDescentHeuristic::ChooseDescentNode(const TreeType* node, con
   for (size_t i = 0; i < node->NumChildren(); i++) {
     double v1 = 1.0;
     double v2 = 1.0;
-    for (size_t j = 0; j < node->Child(i)->Bound().Dim(); j++) {
-      v1 *= node->Child(i)->Bound()[j].Width();
-      v2 *= node->Child(i)->Bound()[j].Contains(point[j]) ? node->Child(i)->Bound()[j].Width() : (node->Child(i)->Bound()[j].Hi() < point[j] ? (point[j] - node->Child(i)->Bound()[j].Lo()) :
-              (node->Child(i)->Bound()[j].Hi() - point[j]));
+    for (size_t j = 0; j < node->Children()[i]->Bound().Dim(); j++) {
+      v1 *= node->Children()[i]->Bound()[j].Width();
+      v2 *= node->Children()[i]->Bound()[j].Contains(point[j]) ? node->Children()[i]->Bound()[j].Width() : (node->Children()[i]->Bound()[j].Hi() < point[j] ? (point[j] - node->Children()[i]->Bound()[j].Lo()) :
+              (node->Children()[i]->Bound()[j].Hi() - point[j]));
     }
     assert(v2 - v1 >= 0);
     vols[i] = v1;
@@ -66,10 +66,10 @@ inline size_t RTreeDescentHeuristic::ChooseDescentNode(const TreeType* node, con
   for (size_t i = 0; i < node->NumChildren(); i++) {
     double v1 = 1.0;
     double v2 = 1.0;
-    for (size_t j = 0; j < node->Child(i)->Bound().Dim(); j++) {
-      v1 *= node->Child(i)->Bound()[j].Width();
-      v2 *= node->Child(i)->Bound()[j].Contains(insertedNode->Bound()[j]) ? node->Child(i)->Bound()[j].Width() :
-              (insertedNode->Bound()[j].Contains(node->Child(i)->Bound()[j]) ? insertedNode->Bound()[j].Width() : (insertedNode->Bound()[j].Lo() < node->Child(i)->Bound()[j].Lo() ? (node->Child(i)->Bound()[j].Hi() - insertedNode->Bound()[j].Lo()) : (insertedNode->Bound()[j].Hi() - node->Child(i)->Bound()[j].Lo())));
+    for (size_t j = 0; j < node->Children()[i]->Bound().Dim(); j++) {
+      v1 *= node->Children()[i]->Bound()[j].Width();
+      v2 *= node->Children()[i]->Bound()[j].Contains(insertedNode->Bound()[j]) ? node->Children()[i]->Bound()[j].Width() :
+              (insertedNode->Bound()[j].Contains(node->Children()[i]->Bound()[j]) ? insertedNode->Bound()[j].Width() : (insertedNode->Bound()[j].Lo() < node->Children()[i]->Bound()[j].Lo() ? (node->Children()[i]->Bound()[j].Hi() - insertedNode->Bound()[j].Lo()) : (insertedNode->Bound()[j].Hi() - node->Children()[i]->Bound()[j].Lo())));
     }
     assert(v2 - v1 >= 0);
     vols[i] = v1;
diff --git a/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp b/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp
index 6dd41eb..18cfcec 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_tree_split_impl.hpp
@@ -30,12 +30,15 @@ void RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
   // If we are splitting the root node, we need will do things differently so that the constructor
   // and other methods don't confuse the end user by giving an address of another node.
   if (tree->Parent() == NULL) {
+    
+//     RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* copy = tree->ExactClone(); // We actually want to copy this way.  Pointers and everything.
     RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* copy = 
-            new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree); // We actually want to copy this way.  Pointers and everything.
+    new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree, false); // We actually want to copy this way.  Pointers and everything.
+
     copy->Parent() = tree;
     tree->Count() = 0;
     tree->NullifyData();
-    tree->Child((tree->NumChildren())++) = copy; // Because this was a leaf node, numChildren must be 0.
+    tree->Children()[(tree->NumChildren())++] = copy; // Because this was a leaf node, numChildren must be 0.
     RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(copy, relevels);
     return;
   }
@@ -60,13 +63,13 @@ void RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
   RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* par = tree->Parent();
   int index = 0;
   for (int i = 0; i < par->NumChildren(); i++) {
-    if (par->Child(i) == tree) {
+    if (par->Children()[i] == tree) {
       index = i;
       break;
     }
   }
-  par->Child(index) = treeOne;
-  par->Child(par->NumChildren()++) = treeTwo;
+  par->Children()[index] = treeOne;
+  par->Children()[par->NumChildren()++] = treeTwo;
 
   // we only add one at a time, so we should only need to test for equality
   // just in case, we use an assert.
@@ -104,11 +107,12 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   // and other methods don't confuse the end user by giving an address of another node.
   if (tree->Parent() == NULL) {
     RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* copy = 
-            new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree); // We actually want to copy this way.  Pointers and everything.
+    new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>(*tree, false); // We actually want to copy this way.  Pointers and everything.
+
     copy->Parent() = tree;
     tree->NumChildren() = 0;
     tree->NullifyData();
-    tree->Child((tree->NumChildren())++) = copy;
+    tree->Children()[(tree->NumChildren())++] = copy;
     RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(copy, relevels);
     return true;
   }
@@ -131,17 +135,17 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* par = tree->Parent();
   int index = -1;
   for (int i = 0; i < par->NumChildren(); i++) {
-    if (par->Child(i) == tree) {
+    if (par->Children()[i] == tree) {
       index = i;
       break;
     }
   }
   assert(index != -1);
-  par->Child(index) = treeOne;
-  par->Child(par->NumChildren()++) = treeTwo;
+  par->Children()[index] = treeOne;
+  par->Children()[par->NumChildren()++] = treeTwo;
 
   for (int i = 0; i < par->NumChildren(); i++) {
-    assert(par->Child(i) != tree);
+    assert(par->Children()[i] != tree);
   }
 
   // we only add one at a time, so should only need to test for equality
@@ -155,10 +159,10 @@ bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   // We have to update the children of each of these new nodes so that they record the 
   // correct parent.
   for (int i = 0; i < treeOne->NumChildren(); i++) {
-    treeOne->Child(i)->Parent() = treeOne;
+    treeOne->Children()[i]->Parent() = treeOne;
   }
   for (int i = 0; i < treeTwo->NumChildren(); i++) {
-    treeTwo->Child(i)->Parent() = treeTwo;
+    treeTwo->Children()[i]->Parent() = treeTwo;
   }
 
   assert(treeOne->NumChildren() <= treeOne->MaxNumChildren());
@@ -228,8 +232,8 @@ void RTreeSplit<DescentType, StatisticType, MatType>::GetBoundSeeds(
     for (int j = i + 1; j < tree.NumChildren(); j++) {
       double score = 1.0;
       for (int k = 0; k < tree.Bound().Dim(); k++) {
-        score *= std::max(tree.Child(i)->Bound()[k].Hi(), tree.Child(j)->Bound()[k].Hi()) -
-                std::min(tree.Child(i)->Bound()[k].Lo(), tree.Child(j)->Bound()[k].Lo());
+        score *= std::max(tree.Children()[i]->Bound()[k].Hi(), tree.Children()[j]->Bound()[k].Hi()) -
+                std::min(tree.Children()[i]->Bound()[k].Lo(), tree.Children()[j]->Bound()[k].Lo());
       }
       if (score > worstPairScore) {
         worstPairScore = score;
@@ -380,20 +384,20 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignNodeDestNode(
 
   for (int i = 0; i < oldTree->NumChildren(); i++) {
     for (int j = i + 1; j < oldTree->NumChildren(); j++) {
-      assert(oldTree->Child(i) != oldTree->Child(j));
+      assert(oldTree->Children()[i] != oldTree->Children()[j]);
     }
   }
 
-  InsertNodeIntoTree(treeOne, oldTree->Child(intI));
-  InsertNodeIntoTree(treeTwo, oldTree->Child(intJ));
+  InsertNodeIntoTree(treeOne, oldTree->Children()[intI]);
+  InsertNodeIntoTree(treeTwo, oldTree->Children()[intJ]);
 
   // If intJ is the last node in the tree, we need to switch the order so that we remove the correct nodes.
   if (intI > intJ) {
-    oldTree->Child(intI) = oldTree->Child(--end); // decrement end
-    oldTree->Child(intJ) = oldTree->Child(--end); // decrement end
+    oldTree->Children()[intI] = oldTree->Children()[--end]; // decrement end
+    oldTree->Children()[intJ] = oldTree->Children()[--end]; // decrement end
   } else {
-    oldTree->Child(intJ) = oldTree->Child(--end); // decrement end
-    oldTree->Child(intI) = oldTree->Child(--end); // decrement end
+    oldTree->Children()[intJ] = oldTree->Children()[--end]; // decrement end
+    oldTree->Children()[intI] = oldTree->Children()[--end]; // decrement end
   }
 
   assert(treeOne->NumChildren() == 1);
@@ -401,16 +405,16 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignNodeDestNode(
 
   for (int i = 0; i < end; i++) {
     for (int j = i + 1; j < end; j++) {
-      assert(oldTree->Child(i) != oldTree->Child(j));
+      assert(oldTree->Children()[i] != oldTree->Children()[j]);
     }
   }
 
   for (int i = 0; i < end; i++) {
-    assert(oldTree->Child(i) != treeOne->Child(0));
+    assert(oldTree->Children()[i] != treeOne->Children()[0]);
   }
 
   for (int i = 0; i < end; i++) {
-    assert(oldTree->Child(i) != treeTwo->Child(0));
+    assert(oldTree->Children()[i] != treeTwo->Children()[0]);
   }
 
 
@@ -439,7 +443,7 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignNodeDestNode(
       for (int i = 0; i < oldTree->Bound().Dim(); i++) {
         // For each of the new rectangles, find the width in this dimension if we add the rectangle at index to
         // the new rectangle.
-        math::Range range = oldTree->Child(index)->Bound()[i];
+        math::Range range = oldTree->Children()[index]->Bound()[i];
         newVolOne *= treeOne->Bound()[i].Contains(range) ? treeOne->Bound()[i].Width() :
                 (range.Contains(treeOne->Bound()[i]) ? range.Width() : (range.Lo() < treeOne->Bound()[i].Lo() ? (treeOne->Bound()[i].Hi() - range.Lo()) :
                 (range.Hi() - treeOne->Bound()[i].Lo())));
@@ -467,25 +471,25 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignNodeDestNode(
     // Assign the rectangle that causes the least increase in volume 
     // to the appropriate rectangle.
     if (bestRect == 1) {
-      InsertNodeIntoTree(treeOne, oldTree->Child(bestIndex));
+      InsertNodeIntoTree(treeOne, oldTree->Children()[bestIndex]);
       numAssignTreeOne++;
     } else {
-      InsertNodeIntoTree(treeTwo, oldTree->Child(bestIndex));
+      InsertNodeIntoTree(treeTwo, oldTree->Children()[bestIndex]);
       numAssignTreeTwo++;
     }
 
-    oldTree->Child(bestIndex) = oldTree->Child(--end); // Decrement end.
+    oldTree->Children()[bestIndex] = oldTree->Children()[--end]; // Decrement end.
   }
   // See if we need to satisfy the minimum fill.
   if (end > 0) {
     if (numAssignTreeOne < numAssignTreeTwo) {
       for (int i = 0; i < end; i++) {
-        InsertNodeIntoTree(treeOne, oldTree->Child(i));
+        InsertNodeIntoTree(treeOne, oldTree->Children()[i]);
         numAssignTreeOne++;
       }
     } else {
       for (int i = 0; i < end; i++) {
-        InsertNodeIntoTree(treeTwo, oldTree->Child(i));
+        InsertNodeIntoTree(treeTwo, oldTree->Children()[i]);
         numAssignTreeTwo++;
       }
     }
@@ -493,12 +497,12 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignNodeDestNode(
 
   for (int i = 0; i < treeOne->NumChildren(); i++) {
     for (int j = i + 1; j < treeOne->NumChildren(); j++) {
-      assert(treeOne->Child(i) != treeOne->Child(j));
+      assert(treeOne->Children()[i] != treeOne->Children()[j]);
     }
   }
   for (int i = 0; i < treeTwo->NumChildren(); i++) {
     for (int j = i + 1; j < treeTwo->NumChildren(); j++) {
-      assert(treeTwo->Child(i) != treeTwo->Child(j));
+      assert(treeTwo->Children()[i] != treeTwo->Children()[j]);
     }
   }
 }
@@ -514,7 +518,7 @@ void RTreeSplit<DescentType, StatisticType, MatType>::InsertNodeIntoTree(
         RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* srcNode)
 {
   destTree->Bound() |= srcNode->Bound();
-  destTree->Child(destTree->NumChildren()++) = srcNode;
+  destTree->Children()[destTree->NumChildren()++] = srcNode;
 }
 
 
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
index 32c888c..cc5d205 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
@@ -102,12 +102,12 @@ class RectangleTree
    * "CENTERAL" DATA MATRIX.
    */
   RectangleTree(MatType& data,
-		const size_t maxLeafSize = 20,
-		const size_t minLeafSize = 8,
-		const size_t maxNumChildren = 5,
-		const size_t minNumChildren = 2,
-		const size_t firstDataIndex = 0
- 	      );
+    const size_t maxLeafSize = 20,
+    const size_t minLeafSize = 8,
+    const size_t maxNumChildren = 5,
+    const size_t minNumChildren = 2,
+    const size_t firstDataIndex = 0
+  );
   
   /**
    * Construct this as an empty node with the specified parent.  Copying the parameters
@@ -118,6 +118,14 @@ class RectangleTree
   explicit RectangleTree(RectangleTree<SplitType, DescentType, StatisticType, MatType>* parentNode);
   
   /**
+   * Create a rectangle tree by copying the other tree.  Be careful!  This can
+   * take a long time and use a lot of memory.
+   * 
+   * @param other The tree to be copied.
+   */
+  RectangleTree(const RectangleTree& other, const bool deepCopy = true);
+
+  /**
    * Deletes this node, deallocating the memory for the children and calling
    * their destructors in turn.  This will invalidate any younters or references
    * to any nodes which are children of this one.
@@ -317,10 +325,10 @@ class RectangleTree
     *
     * @param child Index of child to return.
     */
-  inline RectangleTree<SplitType, DescentType, StatisticType, MatType>*
+  inline RectangleTree<SplitType, DescentType, StatisticType, MatType>&
     Child(const size_t child) const
   {
-    return children[child];
+    return *children[child];
   }
 
   /**
@@ -328,10 +336,10 @@ class RectangleTree
     *
     * @param child Index of child to return.
    */
-  inline RectangleTree<SplitType, DescentType, StatisticType, MatType>*&
+  inline RectangleTree<SplitType, DescentType, StatisticType, MatType>&
     Child(const size_t child)
   {
-    return children[child];
+    return *children[child];
   }
 
   //! Return the number of points in this node (returns 0 if this node is not a leaf).
@@ -494,6 +502,11 @@ class RectangleTree
   bool ShrinkBoundForBound(const HRectBound<>& changedBound);
   
   /**
+   * Make an exact copy of this node, pointers and everything.
+   */
+  RectangleTree* ExactClone();
+  
+  /**
    * Returns a string representation of this object.
    */
   std::string ToString() const;
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 392458b..44d95d8 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
@@ -78,6 +78,46 @@ localDataset(new MatType(static_cast<int> (parentNode->Bound().Dim()), static_ca
 }
 
 /**
+ * Create a rectangle tree by copying the other tree.  Be careful!  This can
+ * take a long time and use a lot of memory.
+ */
+template<typename SplitType,
+typename DescentType,
+typename StatisticType,
+typename MatType>
+RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
+  const RectangleTree& other, const bool deepCopy) :
+  maxNumChildren(other.MaxNumChildren()),
+  minNumChildren(other.MinNumChildren()),
+  numChildren(other.NumChildren()),
+  children(maxNumChildren + 1),
+  parent(other.Parent()),
+  begin(other.Begin()),
+  count(other.Count()),
+  maxLeafSize(other.MaxLeafSize()),
+  minLeafSize(other.MinLeafSize()),
+  bound(other.bound),
+  parentDistance(other.ParentDistance()),
+  dataset(other.dataset),
+  points(other.Points()),
+  localDataset(NULL)
+{
+  if(deepCopy) {
+    if(numChildren > 0) {
+      for(size_t i = 0; i < numChildren; i++) {
+        children[i] = new RectangleTree(*(other.Children()[i]));
+      }
+    } else {
+      localDataset = new MatType(other.LocalDataset());
+    }
+  } else {
+    children = other.Children();
+    arma::mat& otherData = const_cast<arma::mat&> (other.LocalDataset());
+    localDataset = &otherData;
+  }
+}
+
+/**
  * Deletes this node, deallocating the memory for the children and calling
  * their destructors in turn.  This will invalidate any pointers or references
  * to any nodes which are children of this one.
@@ -292,7 +332,7 @@ RemoveNode(const RectangleTree* node, std::vector<bool>& relevels)
     }
     bool contains = true;
     for (size_t j = 0; j < node->Bound().Dim(); j++) {
-      contains &= Child(i)->Bound()[j].Contains(node->Bound()[j]);
+      contains &= Children()[i]->Bound()[j].Contains(node->Bound()[j]);
     }
     if (contains)
       if (children[i]->RemoveNode(node, relevels))
diff --git a/src/mlpack/tests/rectangle_tree_test.cpp b/src/mlpack/tests/rectangle_tree_test.cpp
index eb1738d..1755864 100644
--- a/src/mlpack/tests/rectangle_tree_test.cpp
+++ b/src/mlpack/tests/rectangle_tree_test.cpp
@@ -56,7 +56,13 @@ BOOST_AUTO_TEST_CASE(RectangleTreeConstructionCountTest) {
           tree::RTreeDescentHeuristic,
           NeighborSearchStat<NearestNeighborSort>,
           arma::mat> tree(dataset, 20, 6, 5, 2, 0);
+    RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
+          tree::RTreeDescentHeuristic,
+          NeighborSearchStat<NearestNeighborSort>,
+          arma::mat> tree2 = tree;
+	  
   BOOST_REQUIRE_EQUAL(tree.NumDescendants(), 1000);
+  BOOST_REQUIRE_EQUAL(tree2.NumDescendants(), 1000);
 }
 
 /**
@@ -71,7 +77,7 @@ std::vector<arma::vec*> getAllPointsInTree(const RectangleTree<tree::RTreeSplit<
   std::vector<arma::vec*> vec;
   if (tree.NumChildren() > 0) {
     for (size_t i = 0; i < tree.NumChildren(); i++) {
-      std::vector<arma::vec*> tmp = getAllPointsInTree(*(tree.Child(i)));
+      std::vector<arma::vec*> tmp = getAllPointsInTree(*(tree.Children()[i]));
       vec.insert(vec.begin(), tmp.begin(), tmp.end());
     }
   } else {
@@ -131,7 +137,7 @@ void checkContainment(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeu
       for (size_t j = 0; j < tree.Bound().Dim(); j++) {
         BOOST_REQUIRE_EQUAL(tree.Bound()[j].Contains(tree.Children()[i]->Bound()[j]), true);
       }
-      checkContainment(*(tree.Child(i)));
+      checkContainment(*(tree.Children()[i]));
     }
   }
   return;
@@ -167,7 +173,7 @@ void checkSync(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic,
     }
   } else {
     for (size_t i = 0; i < tree.NumChildren(); i++) {
-      checkSync(*tree.Child(i));
+      checkSync(*tree.Children()[i]);
     }
   }
   return;
@@ -204,7 +210,7 @@ void checkFills(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic
   } else {
     for (size_t i = 0; i < tree.NumChildren(); i++) {
         BOOST_REQUIRE_EQUAL((tree.NumChildren() >= tree.MinNumChildren() || tree.Parent() == NULL) && tree.NumChildren() <= tree.MaxNumChildren(), true);
-      checkFills(*tree.Child(i));
+      checkFills(*tree.Children()[i]);
     }
   }
   return;
@@ -236,7 +242,7 @@ int getMaxLevel(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic
   if (!tree.IsLeaf()) {
     int m = 0;
     for (size_t i = 0; i < tree.NumChildren(); i++) {
-      int n = getMaxLevel(*tree.Child(i));
+      int n = getMaxLevel(*tree.Children()[i]);
       if (n > m)
         m = n;
     }
@@ -259,7 +265,7 @@ int getMinLevel(const RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic
   if (!tree.IsLeaf()) {
     int m = INT_MAX;
     for (size_t i = 0; i < tree.NumChildren(); i++) {
-      int n = getMinLevel(*tree.Child(i));
+      int n = getMinLevel(*tree.Children()[i]);
       if (n < m)
         m = n;
     }
@@ -449,7 +455,7 @@ void checkContainment(const RectangleTree<tree::RStarTreeSplit<tree::RStarTreeDe
       for (size_t j = 0; j < tree.Bound().Dim(); j++) {
         BOOST_REQUIRE_EQUAL(tree.Bound()[j].Contains(tree.Children()[i]->Bound()[j]), true);
       }
-      checkContainment(*(tree.Child(i)));
+      checkContainment(*(tree.Children()[i]));
     }
   }
   return;
@@ -472,7 +478,7 @@ void checkSync(const RectangleTree<tree::RStarTreeSplit<tree::RStarTreeDescentHe
     }
   } else {
     for (size_t i = 0; i < tree.NumChildren(); i++) {
-      checkSync(*tree.Child(i));
+      checkSync(*tree.Children()[i]);
     }
   }
   return;
@@ -547,44 +553,44 @@ BOOST_AUTO_TEST_CASE(RTreeSplitTest) {
     BOOST_REQUIRE_EQUAL(RTree.TreeDepth(), 3);
     
     int firstChild = 0, secondChild = 1;
-    if(RTree.Child(firstChild)->NumChildren() == 2) {
+    if(RTree.Children()[firstChild]->NumChildren() == 2) {
       firstChild = 1;
       secondChild = 0;
     }
     
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[0].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[0].Hi(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[1].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[1].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[0].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[0].Hi(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[1].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[1].Hi(), 1.0);
     
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[0].Lo(), 0.3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[0].Hi(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[1].Lo(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[1].Hi(), 0.9);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[0].Lo(), 0.3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[0].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[1].Lo(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[1].Hi(), 0.9);
     
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->NumChildren(), 1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[0].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[0].Hi(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[1].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[1].Hi(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Count(), 3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->NumChildren(), 1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[0].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[0].Hi(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[1].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[1].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Count(), 3);
     
     int firstPrime = 0, secondPrime = 1;
-    if(RTree.Child(secondChild)->Child(firstPrime)->Count() == 3) {
+    if(RTree.Children()[secondChild]->Children()[firstPrime]->Count() == 3) {
       firstPrime = 1;
       secondPrime = 0;
     }
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->NumChildren(), 2);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Count(), 4);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[0].Lo(), 0.3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[0].Hi(), 0.7);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[1].Lo(), 0.3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[1].Hi(), 0.7);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Count(), 3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[0].Lo(), 0.9);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[0].Hi(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[1].Lo(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[1].Hi(), 0.9);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->NumChildren(), 2);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Count(), 4);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[0].Lo(), 0.3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[0].Hi(), 0.7);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[1].Lo(), 0.3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[1].Hi(), 0.7);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Count(), 3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[0].Lo(), 0.9);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[0].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[1].Lo(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[1].Hi(), 0.9);
   
 }
 
@@ -615,44 +621,44 @@ BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) {
     BOOST_REQUIRE_EQUAL(RTree.TreeDepth(), 3);
     
     int firstChild = 0, secondChild = 1;
-    if(RTree.Child(firstChild)->NumChildren() == 2) {
+    if(RTree.Children()[firstChild]->NumChildren() == 2) {
       firstChild = 1;
       secondChild = 0;
     }
     
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[0].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[0].Hi(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[1].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Bound()[1].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[0].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[0].Hi(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[1].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Bound()[1].Hi(), 1.0);
     
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[0].Lo(), 0.3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[0].Hi(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[1].Lo(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Bound()[1].Hi(), 0.9);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[0].Lo(), 0.3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[0].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[1].Lo(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Bound()[1].Hi(), 0.9);
     
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->NumChildren(), 1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[0].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[0].Hi(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[1].Lo(), 0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Bound()[1].Hi(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(firstChild)->Child(0)->Count(), 3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->NumChildren(), 1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[0].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[0].Hi(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[1].Lo(), 0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Bound()[1].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[firstChild]->Children()[0]->Count(), 3);
     
     int firstPrime = 0, secondPrime = 1;
-    if(RTree.Child(secondChild)->Child(firstPrime)->Count() == 3) {
+    if(RTree.Children()[secondChild]->Children()[firstPrime]->Count() == 3) {
       firstPrime = 1;
       secondPrime = 0;
     }
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->NumChildren(), 2);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Count(), 4);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[0].Lo(), 0.3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[0].Hi(), 0.7);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[1].Lo(), 0.3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[1].Hi(), 0.7);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Count(), 3);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[0].Lo(), 0.9);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[0].Hi(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[1].Lo(), 0.1);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[1].Hi(), 0.9);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->NumChildren(), 2);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Count(), 4);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[0].Lo(), 0.3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[0].Hi(), 0.7);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[1].Lo(), 0.3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[firstPrime]->Bound()[1].Hi(), 0.7);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Count(), 3);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[0].Lo(), 0.9);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[0].Hi(), 1.0);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[1].Lo(), 0.1);
+    BOOST_REQUIRE_EQUAL(RTree.Children()[secondChild]->Children()[secondPrime]->Bound()[1].Hi(), 0.9);
 }
 
 BOOST_AUTO_TEST_SUITE_END();



More information about the mlpack-git mailing list