[mlpack-git] master: R* tree bug fixes. (234378b)

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


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

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

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

commit 234378b2a4ad04f9088d79631394b34948809a17
Author: andrewmw94 <andrewmw94 at gmail.com>
Date:   Sat Jul 26 23:19:04 2014 +0000

    R* tree bug fixes.


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

234378b2a4ad04f9088d79631394b34948809a17
 .../tree/rectangle_tree/r_star_tree_split_impl.hpp | 126 ++++++++++++++++++++-
 .../r_tree_descent_heuristic_impl.hpp              |   1 -
 .../core/tree/rectangle_tree/r_tree_split_impl.hpp |  10 +-
 .../core/tree/rectangle_tree/rectangle_tree.hpp    |  15 +--
 .../tree/rectangle_tree/rectangle_tree_impl.hpp    |  76 +++++++------
 src/mlpack/methods/neighbor_search/allknn_main.cpp |   2 +-
 src/mlpack/tests/rectangle_tree_test.cpp           |  14 ++-
 7 files changed, 187 insertions(+), 57 deletions(-)

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 5e612dc..b59dfb9 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
@@ -41,6 +41,63 @@ void RStarTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
     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;
+   // We sort the points by decreasing distance to the centroid of the bound.
+   // We then remove the first p entries and reinsert them at the root.
+   RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* root = tree;
+   while(root->Parent() != NULL)
+     root = root->Parent();
+   size_t p = tree->MaxLeafSize() * 0.3; // The paper says this works the best.
+   if(p == 0) {
+     SplitLeafNode(tree, relevels);
+     return;
+   }
+   
+   std::vector<sortStruct> sorted(tree->Count());
+   arma::vec centroid;
+   tree->Bound().Centroid(centroid); // Modifies centroid.
+   for(size_t i = 0; i < sorted.size(); i++) {
+     sorted[i].d = tree->Bound().Metric().Evaluate(centroid, tree->LocalDataset().col(i));
+     sorted[i].n = i;
+   }
+   
+   std::sort(sorted.begin(), sorted.end(), structComp);
+   std::vector<int> pointIndices(p);
+   for(size_t i = 0; i < p; i++) {
+     pointIndices[i] = tree->Points()[sorted[sorted.size()-1-i].n]; // We start from the end of sorted.
+     root->DeletePoint(tree->Points()[sorted[sorted.size()-1-i].n], relevels);
+   }
+   for(size_t i = 0; i < p; i++) { // We reverse the order again to reinsert the closest points first.
+     root->InsertPoint(pointIndices[p-1-i], relevels);
+   }
+   
+//    // If we went below min fill, delete this node and reinsert all points.
+//    if(tree->Count() < tree->MinLeafSize()) {
+//      std::vector<int> pointIndices(tree->Count());
+//      for(size_t i = 0; i < tree->Count(); i++) {
+//        pointIndices[i] = tree->Points()[i];
+//      }
+//      root->RemoveNode(tree, relevels);
+//      for(size_t i = 0; i < pointIndices.size(); i++) {
+//        root->InsertPoint(pointIndices[i], relevels);
+//      }
+//      //tree->SoftDelete();      
+//    }
+   return;
+ }
+
   int bestOverlapIndexOnBestAxis = 0;
   int bestAreaIndexOnBestAxis = 0;
   bool tiedOnOverlap = false;
@@ -110,8 +167,8 @@ void RStarTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
     if (axisScore < bestAxisScore) {
       bestAxisScore = axisScore;
       bestAxis = j;
-      double bestOverlapIndexOnBestAxis = 0;
-      double bestAreaIndexOnBestAxis = 0;
+      bestOverlapIndexOnBestAxis = 0;
+      bestAreaIndexOnBestAxis = 0;
       for (int i = 1; i < areas.size(); i++) {
         if (overlapedAreas[i] < overlapedAreas[bestOverlapIndexOnBestAxis]) {
           tiedOnOverlap = false;
@@ -157,13 +214,14 @@ void RStarTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
 
   //Remove this node and insert treeOne and treeTwo
   RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* par = tree->Parent();
-  int index = 0;
+  int index = -1;
   for (int i = 0; i < par->NumChildren(); i++) {
     if (par->Child(i) == tree) {
       index = i;
       break;
     }
   }
+  assert(index != -1);
   par->Child(index) = treeOne;
   par->Child(par->NumChildren()++) = treeTwo;
 
@@ -211,6 +269,65 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
     return true;
   }
 
+  // If we haven't yet reinserted on this level, we try doing so now.
+  if(relevels[tree->TreeDepth()]) {
+    relevels[tree->TreeDepth()] = false;
+    // We sort the points by decreasing centroid to centroid distance.
+    // We then remove the first p entries and reinsert them at the root.
+    RectangleTree<RStarTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* root = tree;
+    while(root->Parent() != NULL)
+      root = root->Parent();
+    size_t p = tree->MaxNumChildren() * 0.3; // The paper says this works the best.
+    if(p == 0) {
+      SplitNonLeafNode(tree, relevels);
+      return false;
+    }
+    
+    std::vector<sortStruct> sorted(tree->NumChildren());
+    arma::vec c1;
+    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.
+      sorted[i].d = tree->Bound().Metric().Evaluate(c1,c2);
+      sorted[i].n = i;
+    }
+    std::sort(sorted.begin(), sorted.end(), structComp);
+    
+    //bool startBelowMinFill = tree->NumChildren() < tree->MinNumChildren();
+ 
+    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);
+    }
+    
+    for(size_t i = 0; i < p; i++) {
+      root->InsertNode(removedNodes[p-1-i], tree->TreeDepth(), relevels); // We reverse the order again to reinsert the closest nodes first.
+    }
+    
+    // If we went below min fill, delete this node and reinsert all children.
+    //SOMETHING IS WRONG.  SHOULD NOT GO BELOW MIN FILL.
+//    if(!startBelowMinFill && tree->NumChildren() < tree->MinNumChildren())
+//    std::cout<<"MINFILLERROR "<< p << ", " << tree->NumChildren() << "; " << tree->MaxNumChildren()<<std::endl;
+    
+//    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);
+//      }
+//      root->RemoveNode(tree, relevels);
+//      for(size_t i = 0; i < rmNodes.size(); i++) {
+//        root->InsertNode(rmNodes[i], tree->TreeDepth(), relevels);
+//      }
+// //      tree->SoftDelete();
+//    }    
+ //    assert(tree->NumChildren() >= tree->MinNumChildren());
+ //    assert(tree->NumChildren() <= tree->MaxNumChildren());
+   
+   return false;
+ }
+
   int bestOverlapIndexOnBestAxis = 0;
   int bestAreaIndexOnBestAxis = 0;
   bool tiedOnOverlap = false;
@@ -454,6 +571,9 @@ bool RStarTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
   assert(treeTwo->Parent()->NumChildren() <= treeTwo->MaxNumChildren());
   assert(treeTwo->Parent()->NumChildren() >= treeTwo->MinNumChildren());
   
+  assert(treeOne->MaxNumChildren() < 7);
+  assert(treeTwo->MaxNumChildren() < 7);
+
   tree->SoftDelete();
   
   return false;
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 337e232..f30d676 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
@@ -51,7 +51,6 @@ inline size_t RTreeDescentHeuristic::ChooseDescentNode(const TreeType* node, con
       }
     }
   }  
-  
   return bestIndex;
 }
 
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 54e4ac9..6dd41eb 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
@@ -270,17 +270,16 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignPointDestNode(
   // If intJ is the last point in the tree, we need to switch the order so that we remove the correct points.
   if (intI > intJ) {
     oldTree->Points()[intI] = oldTree->Points()[--end]; // decrement end
-    oldTree->LocalDataset()[intI] = oldTree->LocalDataset()[end];
+    oldTree->LocalDataset().col(intI) = oldTree->LocalDataset().col(end);
     oldTree->Points()[intJ] = oldTree->Points()[--end]; // decrement end
-    oldTree->LocalDataset()[intJ] = oldTree->LocalDataset()[end];
+    oldTree->LocalDataset().col(intJ) = oldTree->LocalDataset().col(end);
   } else {
     oldTree->Points()[intJ] = oldTree->Points()[--end]; // decrement end
-    oldTree->LocalDataset()[intJ] = oldTree->LocalDataset()[end];
+    oldTree->LocalDataset().col(intJ) = oldTree->LocalDataset().col(end);
     oldTree->Points()[intI] = oldTree->Points()[--end]; // decrement end
-    oldTree->LocalDataset()[intI] = oldTree->LocalDataset()[end];
+    oldTree->LocalDataset().col(intI) = oldTree->LocalDataset().col(end);
   }  
   
-
   int numAssignedOne = 1;
   int numAssignedTwo = 1;
 
@@ -292,7 +291,6 @@ void RTreeSplit<DescentType, StatisticType, MatType>::AssignPointDestNode(
   // The below is safe because if end decreases and the right hand side of the second part of the conjunction changes
   // on the same iteration, we added the point to the node with fewer points anyways.
   while (end > 0 && end > oldTree->MinLeafSize() - std::min(numAssignedOne, numAssignedTwo)) {
-
     int bestIndex = 0;
     double bestScore = DBL_MAX;
     int bestRect = 1;
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
index f8639de..536a199 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
@@ -103,9 +103,9 @@ class RectangleTree
    */
   RectangleTree(MatType& data,
 		const size_t maxLeafSize = 20,
-		const size_t minLeafSize = 6,
-		const size_t maxNumChildren = 4,
-		const size_t minNumChildren = 0,
+		const size_t minLeafSize = 8,
+		const size_t maxNumChildren = 5,
+		const size_t minNumChildren = 2,
 		const size_t firstDataIndex = 0
  	      );
 
@@ -117,9 +117,6 @@ class RectangleTree
    */
   explicit RectangleTree(RectangleTree<SplitType, DescentType, StatisticType, MatType>* parentNode);
 
-
-  //TODO implement the oldFromNew stuff if applicable.
-
   /**
    * Deletes this node, deallocating the memory for the children and calling
    * their destructors in turn.  This will invalidate any younters or references
@@ -166,7 +163,7 @@ class RectangleTree
    * contained "node".
    * @param relevels The levels that have been reinserted to on this top level insertion.
    */
-  void InsertNode(const RectangleTree* node, const size_t level, std::vector<bool>& relevels);
+  void InsertNode(RectangleTree* node, const size_t level, std::vector<bool>& relevels);
 
   /**
    * Deletes a point in the tree.  The point will be removed from the data matrix
@@ -189,9 +186,9 @@ class RectangleTree
   bool DeletePoint(const size_t point, std::vector<bool>& relevels);
   
   /**
-   * Deletes a node from the tree (along with all descendants).
+   * Removes a node from the tree.  You are responsible for deleting it if you wish to do so.
    */
-  bool DeleteNode(const RectangleTree* node, std::vector<bool>& relevels);
+  bool RemoveNode(const RectangleTree* node, std::vector<bool>& relevels);
 
   /**
    * Find a node in this tree by its begin and count (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 b642048..d40d675 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
@@ -145,18 +145,20 @@ InsertPoint(const size_t point)
   // Expand the bound regardless of whether it is a leaf node.
   bound |= dataset.col(point);
 
+  std::vector<bool> lvls(TreeDepth());
+  for (int i = 0; i < lvls.size(); i++)
+    lvls[i] = true;
   // If this is a leaf node, we stop here and add the point.
   if (numChildren == 0) {
     localDataset->col(count) = dataset.col(point);
     points[count++] = point;
-    std::vector<bool> lvls(TreeDepth());
     SplitNode(lvls);
     return;
   }
 
   // If it is not a leaf node, we use the DescentHeuristic to choose a child
   // to which we recurse.
-  children[DescentType::ChooseDescentNode(this, dataset.col(point))]->InsertPoint(point);
+  children[DescentType::ChooseDescentNode(this, dataset.col(point))]->InsertPoint(point, lvls);
 }
 
 /**
@@ -178,14 +180,13 @@ void RectangleTree<SplitType, DescentType, StatisticType, MatType>::InsertPoint(
   if (numChildren == 0) {
     localDataset->col(count) = dataset.col(point);
     points[count++] = point;
-    std::vector<bool> lvls(TreeDepth());
-    SplitNode(lvls);
+    SplitNode(relevels);
     return;
   }
 
   // If it is not a leaf node, we use the DescentHeuristic to choose a child
   // to which we recurse.
-  children[DescentType::ChooseDescentNode(this, dataset.col(point))]->InsertPoint(point);
+  children[DescentType::ChooseDescentNode(this, dataset.col(point))]->InsertPoint(point, relevels);
 }
 
 /**
@@ -198,16 +199,14 @@ template<typename SplitType,
 typename DescentType,
 typename StatisticType,
 typename MatType>
-void RectangleTree<SplitType, DescentType, StatisticType, MatType>::InsertNode(const RectangleTree* node, const size_t level, std::vector<bool>& relevels)
+void RectangleTree<SplitType, DescentType, StatisticType, MatType>::InsertNode(RectangleTree* node, const size_t level, std::vector<bool>& relevels)
 {
   // Expand the bound regardless of the level.
   bound |= node->Bound();
-
   if (level == TreeDepth()) {
-    children[numChildren++] = const_cast<RectangleTree*> (node);
-    assert(numChildren <= maxNumChildren); // We should never have increased without splitting.
-    if (numChildren == maxNumChildren)
-      SplitType::SplitNonLeafNode(this, relevels);
+    children[numChildren++] = node;
+    node->Parent() = this;
+    SplitNode(relevels);
   } else {
     children[DescentType::ChooseDescentNode(this, node)]->InsertNode(node, level, relevels);
   }
@@ -224,16 +223,18 @@ typename MatType>
 bool RectangleTree<SplitType, DescentType, StatisticType, MatType>::
 DeletePoint(const size_t point)
 {
+  //It is possible that this will cause a reinsertion, so we need to handle the lvls properly.
+  RectangleTree* root = this;
+  while (root->Parent() != NULL)
+    root = root->Parent();
+  std::vector<bool> lvls(root->TreeDepth());
+  for (int i = 0; i < lvls.size(); i++)
+    lvls[i] = true;
   if (numChildren == 0) {
     for (size_t i = 0; i < count; i++) {
       if (points[i] == point) {
         localDataset->col(i) = localDataset->col(--count); // decrement count
         points[i] = points[count];
-        //It is possible that this will cause a reinsertion, so we need to handle the lvls properly.
-        RectangleTree* root = this;
-        while(root->Parent() != NULL)
-          root = root->Parent();
-        std::vector<bool> lvls(root->TreeDepth());
         CondenseTree(dataset.col(point), lvls, true); // This function will ensure that minFill is satisfied.
         return true;
       }
@@ -241,7 +242,7 @@ DeletePoint(const size_t point)
   }
   for (size_t i = 0; i < numChildren; i++) {
     if (children[i]->Bound().Contains(dataset.col(point)))
-      if (children[i]->DeletePoint(point))
+      if (children[i]->DeletePoint(point, lvls))
         return true;
   }
   return false;
@@ -270,7 +271,7 @@ DeletePoint(const size_t point, std::vector<bool>& relevels)
   }
   for (size_t i = 0; i < numChildren; i++) {
     if (children[i]->Bound().Contains(dataset.col(point)))
-      if (children[i]->DeletePoint(point))
+      if (children[i]->DeletePoint(point, relevels))
         return true;
   }
   return false;
@@ -285,16 +286,20 @@ typename DescentType,
 typename StatisticType,
 typename MatType>
 bool RectangleTree<SplitType, DescentType, StatisticType, MatType>::
-DeleteNode(const RectangleTree* node, std::vector<bool>& relevels)
+RemoveNode(const RectangleTree* node, std::vector<bool>& relevels)
 {
   for (size_t i = 0; i < numChildren; i++) {
     if (children[i] == node) {
       children[i] = children[--numChildren]; // Decrement numChildren
-      CondenseTree(arma::vec(), false);
+      CondenseTree(arma::vec(), relevels, false);
       return true;
     }
-    if (children[i]->Bound().Contains(node->Bound()))
-      if (children[i]->DeleteNode(node))
+    bool contains = true;
+    for (size_t j = 0; j < node->Bound().Dim(); j++) {
+      contains &= Child(i)->Bound()[j].Contains(node->Bound()[j]);
+    }
+    if (contains)
+      if (children[i]->RemoveNode(node, relevels))
         return true;
   }
   return false;
@@ -469,17 +474,24 @@ typename StatisticType,
 typename MatType>
 void RectangleTree<SplitType, DescentType, StatisticType, MatType>::SplitNode(std::vector<bool>& relevels)
 {
-  // This should always be a leaf node.  When we need to split other nodes,
-  // the split will be called from here but will take place in the SplitType code.
-  assert(numChildren == 0);
+  if (numChildren == 0) {
+
+    // Check to see if we are full.
+    if (count <= maxLeafSize)
+      return; // We don't need to split.
 
-  // Check to see if we are full.
-  if (count < maxLeafSize)
-    return; // We don't need to split.
+    // If we are full, then we need to split (or at least try).  The SplitType takes
+    // care of this and of moving up the tree if necessary.
+    SplitType::SplitLeafNode(this, relevels);
+  } else {
+    // Check to see if we are full.
+    if (numChildren <= maxNumChildren)
+      return; // We don't need to split.
 
-  // If we are full, then we need to split (or at least try).  The SplitType takes
-  // care of this and of moving up the tree if necessary.
-  SplitType::SplitLeafNode(this, relevels);
+    // If we are full, then we need to split (or at least try).  The SplitType takes
+    // care of this and of moving up the tree if necessary.
+    SplitType::SplitNonLeafNode(this, relevels);
+  }
 }
 
 /**
@@ -505,7 +517,7 @@ void RectangleTree<SplitType, DescentType, StatisticType, MatType>::CondenseTree
           root = root->Parent();
 
         for (size_t j = 0; j < count; j++) {
-          root->InsertPoint(points[j]);
+          root->InsertPoint(points[j], relevels);
         }
 
         parent->CondenseTree(point, relevels, usePoint); // This will check the MinFill of the parent.
diff --git a/src/mlpack/methods/neighbor_search/allknn_main.cpp b/src/mlpack/methods/neighbor_search/allknn_main.cpp
index 7510746..9401e9f 100644
--- a/src/mlpack/methods/neighbor_search/allknn_main.cpp
+++ b/src/mlpack/methods/neighbor_search/allknn_main.cpp
@@ -286,7 +286,7 @@ int main(int argc, char *argv[])
 		    tree::RStarTreeDescentHeuristic,
 		    NeighborSearchStat<NearestNeighborSort>,
 		    arma::mat>
-      refTree(referenceData, leafSize, leafSize/3, 5, 2, 0);
+      refTree(referenceData, leafSize, leafSize * 0.4, 5, 2, 0);
 
       RectangleTree<tree::RStarTreeSplit<tree::RStarTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
 		    tree::RStarTreeDescentHeuristic,
diff --git a/src/mlpack/tests/rectangle_tree_test.cpp b/src/mlpack/tests/rectangle_tree_test.cpp
index cc559c9..eb1738d 100644
--- a/src/mlpack/tests/rectangle_tree_test.cpp
+++ b/src/mlpack/tests/rectangle_tree_test.cpp
@@ -21,6 +21,8 @@ using namespace mlpack::metric;
 
 BOOST_AUTO_TEST_SUITE(RectangleTreeTest);
 
+
+
 // Be careful!  When writing new tests, always get the boolean value and store
 // it in a temporary, because the Boost unit test macros do weird things and
 // will cause bizarre problems.
@@ -537,6 +539,7 @@ BOOST_AUTO_TEST_CASE(RTreeSplitTest) {
           NeighborSearchStat<NearestNeighborSort>,
           arma::mat> RTree(data, 5, 2, 2, 1, 0);
     
+  
     //There's technically no reason they have to be in a certain order, so we
     //use firstChild etc. to arbitrarily name them.
     BOOST_REQUIRE_EQUAL(RTree.NumChildren(), 2);
@@ -585,6 +588,7 @@ BOOST_AUTO_TEST_CASE(RTreeSplitTest) {
   
 }
 
+
 // Test the tree splitting.  We set MaxLeafSize and MaxNumChildren rather low
 // to allow us to test by hand without adding hundreds of points.
 BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) {
@@ -641,14 +645,14 @@ BOOST_AUTO_TEST_CASE(RStarTreeSplitTest) {
     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(), 1.0);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[1].Lo(), 0.5);
-    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(firstPrime)->Bound()[1].Hi(), 0.9);
+    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.6);
+    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.3);
+    BOOST_REQUIRE_EQUAL(RTree.Child(secondChild)->Child(secondPrime)->Bound()[1].Hi(), 0.9);
 }
 
 BOOST_AUTO_TEST_SUITE_END();



More information about the mlpack-git mailing list