[mlpack] 61/324: more bug fixes

Barak A. Pearlmutter barak+git at cs.nuim.ie
Sun Aug 17 08:21:56 UTC 2014


This is an automated email from the git hooks/post-receive script.

bap pushed a commit to branch svn-trunk
in repository mlpack.

commit 53fffdb3b28bcee163b3cf2efc8aedc4661ea47b
Author: andrewmw94 <andrewmw94 at 9d5b8971-822b-0410-80eb-d18c1038ef23>
Date:   Thu Jun 19 15:17:29 2014 +0000

    more bug fixes
    
    git-svn-id: http://svn.cc.gatech.edu/fastlab/mlpack/trunk@16692 9d5b8971-822b-0410-80eb-d18c1038ef23
---
 .../core/tree/rectangle_tree/r_tree_split.hpp      |  27 ++-
 .../core/tree/rectangle_tree/r_tree_split_impl.hpp | 218 +++++++++++----------
 .../core/tree/rectangle_tree/rectangle_tree.hpp    |  23 +--
 .../tree/rectangle_tree/rectangle_tree_impl.hpp    |  54 ++---
 src/mlpack/methods/neighbor_search/allknn_main.cpp |  10 +-
 .../methods/neighbor_search/neighbor_search.hpp    |   2 +-
 6 files changed, 163 insertions(+), 171 deletions(-)

diff --git a/src/mlpack/core/tree/rectangle_tree/r_tree_split.hpp b/src/mlpack/core/tree/rectangle_tree/r_tree_split.hpp
index 1d87cc6..ccac982 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_tree_split.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_tree_split.hpp
@@ -18,8 +18,7 @@ namespace tree /** Trees and tree-building procedures. */ {
  * nodes overflow, we split them, moving up the tree and splitting nodes
  * as necessary.
  */
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
 class RTreeSplit
@@ -31,7 +30,7 @@ public:
  * upwards through the tree.  The methods for splitting non-leaf nodes are private since
  * they should only be called if a leaf node overflows.
  */
-static void SplitLeafNode(const RectangleTree<SplitType, DescentType, StatisticType, MatType>* tree);
+static void SplitLeafNode(RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* tree);
 
 private:
 
@@ -39,25 +38,25 @@ private:
  * Split a non-leaf node using the "default" algorithm.  If this is the root node and
  * we need to move up the tree, a new root node is created.
  */
-static bool SplitNonLeafNode(const RectangleTree<SplitType, DescentType, StatisticType, MatType>* tree);
+static bool SplitNonLeafNode(RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* tree);
 
 /**
  * Get the seeds for splitting a leaf node.
  */
-static void GetPointSeeds(const RectangleTree<SplitType, DescentType, StatisticType, MatType>& tree, int *i, int *j);
+static void GetPointSeeds(const RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>& tree, int *i, int *j);
 
 /**
  * Get the seeds for splitting a non-leaf node.
  */
-static void GetBoundSeeds(const RectangleTree<SplitType, DescentType, StatisticType, MatType>& tree, int *i, int *j);
+static void GetBoundSeeds(const RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>& tree, int *i, int *j);
 
 /**
  * Assign points to the two new nodes.
  */
 static void AssignPointDestNode(
-    const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeOne,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeTwo,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* oldTree,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* treeOne,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* treeTwo,
     const int intI,
     const int intJ);
 
@@ -65,9 +64,9 @@ static void AssignPointDestNode(
  * Assign nodes to the two new nodes.
  */
 static void AssignNodeDestNode(
-    const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType> *treeOne,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType> *treeTwo,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* oldTree,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType> *treeOne,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType> *treeTwo,
     const int intI,
     const int intJ);
 
@@ -75,8 +74,8 @@ static void AssignNodeDestNode(
   * Insert a node into another node.
   */
 static void insertNodeIntoTree(
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* destTree,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* srcNode);
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* destTree,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* srcNode);
 };
 
 }; // namespace tree
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 d11cc3d..565f7db 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
@@ -19,45 +19,45 @@ namespace tree {
  * Finally, we delete the old node and insert the new nodes into the tree, spliting the parent
  * if necessary.
  */
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitLeafNode(
-  const RectangleTree<SplitType, DescentType,  StatisticType, MatType>* tree)
+void RTreeSplit<DescentType, StatisticType, MatType>::SplitLeafNode(
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>* tree)
 {
   // Use the quadratic split method from: Guttman "R-Trees: A Dynamic Index Structure for
   // Spatial Searching"  It is simplified since we don't handle rectangles, only points.
   // It assumes that the tree uses Euclidean Distance.
   int i = 0;
   int j = 0;
-  GetPointSeeds(tree, &i, &j);
+  GetPointSeeds(*tree, &i, &j);
 
-  RectangleTree<SplitType, DescentType,  StatisticType, MatType> *treeOne = new 
-    RectangleTree<SplitType, DescentType,  StatisticType, MatType>(tree.Parent());
-  RectangleTree<SplitType, DescentType,  StatisticType, MatType> *treeTwo = new 
-    RectangleTree<SplitType, DescentType,  StatisticType, MatType>(tree.Parent());
-  
-  // This will assign the ith and jth point appropriately.
-  AssignPointDestNode(tree, treeOne, treeTwo, i, j);
-  
   // 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) {
+  if(tree->Parent() == NULL) {
     
+    return;
   }
   
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType> *treeOne = new 
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(*(tree->Parent()));
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType> *treeTwo = new 
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(*(tree->Parent()));
+  
+  // This will assign the ith and jth point appropriately.
+  AssignPointDestNode(tree, treeOne, treeTwo, i, j);
+  
   //Remove this node and insert treeOne and treeTwo
-  RectangleTree<SplitType, DescentType,  StatisticType, MatType>* par = tree.Parent();
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>* par = tree->Parent();
   int index = 0;
-  for(int i = 0; i < par->numOfChildren(); i++) {
-    if(par->getChildren()[i] == tree) {
+  for(int i = 0; i < par->NumChildren(); i++) {
+    if(par->Children()[i] == tree) {
       index = i;
       break;
     }
   }
-  par->getChildren()[i] = treeOne;
-  par->getChildren()[par->end++] = treeTwo;
+  par->Children()[index] = treeOne;
+  par->Children()[par->NumChildren()++] = treeTwo;
 
   //because we copied the points to treeOne and treeTwo, we can just delete this node
   delete tree;
@@ -79,45 +79,47 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitLeafNode(
  * and recurse up the tree if necessary.  We don't need to worry about the bounds
  * higher up the tree because they were already updated if necessary.
  */
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-bool RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitNonLeafNode(
-  const RectangleTree<SplitType, DescentType,  StatisticType, MatType>* tree)
+bool RTreeSplit<DescentType, StatisticType, MatType>::SplitNonLeafNode(
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>* tree)
 {
   int i = 0;
   int j = 0;
-  GetBoundSeeds(tree, &i, &j);
+  GetBoundSeeds(*tree, &i, &j);
   
-  RectangleTree<SplitType, DescentType,  StatisticType, MatType>* treeOne = new 
-    RectangleTree<SplitType, DescentType,  StatisticType, MatType>(tree.Parent());
-  RectangleTree<SplitType, DescentType,  StatisticType, MatType>* treeTwo = new 
-    RectangleTree<SplitType, DescentType,  StatisticType, MatType>(tree.Parent());
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>* treeOne = new 
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(*(tree->Parent()));
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>* treeTwo = new 
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(*(tree->Parent()));
   
   // This will assign the ith and jth rectangles appropriately.
   AssignNodeDestNode(tree, treeOne, treeTwo, i, j);
 
-  // create the parent node if necessary
-  if(tree.Parent() == NULL) {
-    tree.Parent() = new RectangleTree<SplitType, DescentType,  StatisticType, MatType>();
+  // 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) {
+    //tree->Parent() = new RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>(NULL);
+    
+    return true;
   }
   
   //Remove this node and insert treeOne and treeTwo
-  RectangleTree<SplitType, DescentType,  StatisticType, MatType>* par = tree.parent();
+  RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>* par = tree->Parent();
   int index = 0;
-  for(int i = 0; i < par->numOfChildren(); i++) {
-    if(par->getChildren()[i] == tree) {
+  for(int i = 0; i < par->NumChildren(); i++) {
+    if(par->Children()[i] == tree) {
       index = i;
       break;
     }
   }
-  par->getChildren()[i] = treeOne;
-  par->getChildren()[par->end++] = treeTwo;
+  par->Children()[index] = treeOne;
+  par->Children()[par->NumChildren()++] = treeTwo;
 
   // Because we now have pointers to the information stored under this tree,
   // we need to delete this node carefully.
-  tree.softDelete();
+  tree->softDelete();
 
   // we only add one at a time, so should only need to test for equality
   // just in case, we use an assert.
@@ -126,19 +128,18 @@ bool RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitNonLeafNod
   if(par->NumChildren() == par->MaxNumChildren()) {
     SplitNonLeafNode(par);
   }
-  return;
+  return false;
 }
 
 /**
  * Get the two points that will be used as seeds for the split of a leaf node.
  * The indices of these points will be stored in iRet and jRet.
  */
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::GetPointSeeds(
-  const RectangleTree<SplitType, DescentType,  StatisticType, MatType>& tree,
+void RTreeSplit<DescentType, StatisticType, MatType>::GetPointSeeds(
+  const RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>& tree,
   int* iRet,
   int* jRet)
 {
@@ -148,11 +149,11 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::GetPointSeeds(
   double worstPairScore = 0.0;
   int worstI = 0;
   int worstJ = 0;
-  for(int i = 0; i < tree.count; i++) {
-    for(int j = i+1; j < tree.count; j++) {
+  for(int i = 0; i < tree.Count(); i++) {
+    for(int j = i+1; j < tree.Count(); j++) {
       double score = 1.0;
       for(int k = 0; k < tree.Bound().Dim(); k++) {
-	score *= std::abs(tree.dataset[i][k] - tree.dataset[j][k]);
+	score *= std::abs(tree.Dataset().at(k, i) - tree.Dataset().at(k, j)); // Points are stored by column, but this function takes (row, col).
       }
       if(score > worstPairScore) {
 	worstPairScore = score;
@@ -171,24 +172,23 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::GetPointSeeds(
  * Get the two bounds that will be used as seeds for the split of the node.
  * The indices of the bounds will be stored in iRet and jRet.
  */
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::GetBoundSeeds(
-  const RectangleTree<SplitType, DescentType,  StatisticType, MatType>& tree,
+void RTreeSplit<DescentType, StatisticType, MatType>::GetBoundSeeds(
+  const RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType,  StatisticType, MatType>& tree,
   int* iRet,
   int* jRet)
 {
   double worstPairScore = 0.0;
   int worstI = 0;
   int worstJ = 0;
-  for(int i = 0; i < tree.numChildren; i++) {
-    for(int j = i+1; j < tree.numChildren; j++) {
+  for(int i = 0; i < tree.NumChildren(); i++) {
+    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.children[i].bound[k].hi(), tree.children[j].bound[k].hi) - 
-	  std::min(tree.children[i].bound[k].low(), tree.children[j].bound[k].low());
+	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;
@@ -203,24 +203,23 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::GetBoundSeeds(
   return;
 }
 
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignPointDestNode(
-    const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeOne,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeTwo,
+void RTreeSplit<DescentType, StatisticType, MatType>::AssignPointDestNode(
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* oldTree,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* treeOne,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* treeTwo,
     const int intI,
     const int intJ)
 {
-  int end = oldTree.count;
+  int end = oldTree->Count();
   assert(end > 1); // If this isn't true, the tree is really weird.
 
-  treeOne->insertPoint(oldTree->dataset.col(intI));
-  oldTree->dataset.col(intI) = oldTree->dataset.col(--end); // decrement end
-  treeTwo->insertPoint(oldTree->dataset.col(intJ));
-  oldTree->dataset.col(intJ) = oldTree->dataset.col(--end); // decrement end
+  treeOne->InsertPoint(oldTree->Dataset().col(intI));
+  oldTree->Dataset().col(intI) = oldTree->Dataset().col(--end); // decrement end
+  treeTwo->InsertPoint(oldTree->Dataset().col(intJ));
+  oldTree->Dataset().col(intJ) = oldTree->Dataset().col(--end); // decrement end
   
 
   int numAssignedOne = 1;
@@ -230,17 +229,22 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignPointDest
   // increase of volume when added to one of the rectangles.  We then add it to that
   // rectangle.  We stop when we run out of points or when all of the remaining points
   // need to be assigned to the same rectangle to satisfy the minimum fill requirement.
-  while(end > 1 && end < oldTree->minLeafSize() - std::min(numAssignedOne, numAssignedTwo)) {
+  
+  // 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 > 1 && end < oldTree->MinLeafSize() - std::min(numAssignedOne, numAssignedTwo)) {
     int bestIndex = 0;
-    double bestScore = 0;
-    int bestRect = 0;
+    double bestScore = DBL_MAX;
+    int bestRect = 1;
 
     // Calculate the increase in volume for assigning this point to each rectangle.
+    
+    // First, calculate the starting volume.
     double volOne = 1.0;
     double volTwo = 1.0;
     for(int i = 0; i < oldTree->Bound().Dim(); i++) {
-      volOne *= treeOne->bound[i].width();
-      volTwo *= treeTwo->bound[i].width();
+      volOne *= treeOne->Bound()[i].Width();
+      volTwo *= treeTwo->Bound()[i].Width();
     }
 
     // Find the point that, when assigned to one of the two new rectangles, minimizes the increase
@@ -249,11 +253,11 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignPointDest
       double newVolOne = 1.0;
       double newVolTwo = 1.0;
       for(int i = 0; i < oldTree->Bound().Dim(); i++) {
-	double c = oldTree->dataset.col(index)[i];      
-	newVolOne *= treeOne->bound[i].contains(c) ? treeOne->bound[i].width() :
-	  (c < treeOne->bound[i].low() ? (treeOne->bound[i].high() - c) : (c - treeOne->bound[i].low()));
-	newVolTwo *= treeTwo->bound[i].contains(c) ? treeTwo->bound[i].width() :
-	  (c < treeTwo->bound[i].low() ? (treeTwo->bound[i].high() - c) : (c - treeTwo->bound[i].low()));
+	double c = oldTree->Dataset().col(index)[i];      
+	newVolOne *= treeOne->Bound()[i].Contains(c) ? treeOne->Bound()[i].Width() :
+	  (c < treeOne->Bound()[i].Lo() ? (treeOne->Bound()[i].Hi() - c) : (c - treeOne->Bound()[i].Lo()));
+	newVolTwo *= treeTwo->Bound()[i].Contains(c) ? treeTwo->Bound()[i].Width() :
+	  (c < treeTwo->Bound()[i].Lo() ? (treeTwo->Bound()[i].Hi() - c) : (c - treeTwo->Bound()[i].Lo()));
       }
     
       // Choose the rectangle that requires the lesser increase in volume.
@@ -275,46 +279,45 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignPointDest
     // Assign the point that causes the least increase in volume 
     // to the appropriate rectangle.
     if(bestRect == 1)
-      treeOne->insertPoint(oldTree->dataset(bestIndex));
+      treeOne->InsertPoint(oldTree->Dataset().col(bestIndex));
     else
-      treeTwo->insertPoint(oldTree->dataset(bestIndex));
+      treeTwo->InsertPoint(oldTree->Dataset().col(bestIndex));
 
-    oldTree->dataset.col(bestIndex) = oldTree->dataset.col(--end); // decrement end.
+    oldTree->Dataset().col(bestIndex) = oldTree->Dataset().col(--end); // decrement end.
   }
 
   // See if we need to satisfy the minimum fill.
   if(end > 1) {
     if(numAssignedOne < numAssignedTwo) {
       for(int i = 0; i < end; i++) {
-        treeOne->insertPoint(oldTree.dataset(i));
+        treeOne->InsertPoint(oldTree->Dataset().col(i));
       }
     } else {
       for(int i = 0; i < end; i++) {
-        treeTwo->insertPoint(oldTree.dataset(i));
+        treeTwo->InsertPoint(oldTree->Dataset().col(i));
       }
     }
   }
 }
 
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignNodeDestNode(
-    const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeOne,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeTwo,
+void RTreeSplit<DescentType, StatisticType, MatType>::AssignNodeDestNode(
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* oldTree,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* treeOne,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* treeTwo,
     const int intI,
     const int intJ)
 {
   
-  int end = oldTree->getNumChildren();
+  int end = oldTree->NumChildren();
   assert(end > 1); // If this isn't true, the tree is really weird.
 
-  treeOne->getChildren()[0] = oldTree->getChildren()[intI];
-  oldTree->getChildren[intI] = oldTree->getChildren()[--end]; // decrement end
-  treeTwo->getChildren()[0] = oldTree->getChildren()[intJ];
-  oldTree->getChildren()[intJ] = oldTree->getChildren()[--end]; // decrement end
+  treeOne->Children()[0] = oldTree->Children()[intI];
+  oldTree->Children()[intI] = oldTree->Children()[--end]; // decrement end
+  treeTwo->Children()[0] = oldTree->Children()[intJ];
+  oldTree->Children()[intJ] = oldTree->Children()[--end]; // decrement end
  
   int numAssignTreeOne = 1;
   int numAssignTreeTwo = 1;
@@ -322,17 +325,17 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignNodeDestN
   // In each iteration, we go through all of the nodes and find the one that causes the least
   // increase of volume when added to one of the two new rectangles.  We then add it to that
   // rectangle.
-  while(end > 1 && end < oldTree->getMinNumChildren() - std::min(numAssignTreeOne, numAssignTreeTwo)) {
+  while(end > 1 && end < oldTree->MinNumChildren() - std::min(numAssignTreeOne, numAssignTreeTwo)) {
     int bestIndex = 0;
-    double bestScore = 0;
+    double bestScore = DBL_MAX;
     int bestRect = 0;
 
     // Calculate the increase in volume for assigning this node to each of the new rectangles.
     double volOne = 1.0;
     double volTwo = 1.0;
     for(int i = 0; i < oldTree->Bound().Dim(); i++) {
-      volOne *= treeOne->bound[i].width();
-      volTwo *= treeTwo->bound[i].width();
+      volOne *= treeOne->Bound()[i].Width();
+      volTwo *= treeTwo->Bound()[i].Width();
     }
 
     for(int index = 0; index < end; index++) {
@@ -341,13 +344,13 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignNodeDestN
       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->getChildren()[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())));
-	newVolTwo *= treeTwo.Bound(i).Contains(range) ? treeTwo.bound[i].width() :
-	  (range.Contains(treeTwo->Bound(i)) ? range.Width() : (range.lo() < treeTwo->Bound(i).lo() ? (treeTwo->Bound(i).hi() - range.lo()) : 
-		(range.hi() - treeTwo->Bound(i).lo())));
+	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())));
+	newVolTwo *= treeTwo->Bound()[i].Contains(range) ? treeTwo->Bound()[i].Width() :
+	  (range.Contains(treeTwo->Bound()[i]) ? range.Width() : (range.Lo() < treeTwo->Bound()[i].Lo() ? (treeTwo->Bound()[i].Hi() - range.Lo()) : 
+		(range.Hi() - treeTwo->Bound()[i].Lo())));
       }
     
       // Choose the rectangle that requires the lesser increase in volume.
@@ -392,16 +395,15 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignNodeDestN
 /**
   * Insert a node into another node.  Expanding the bounds and updating the numberOfChildren.
   */
-template<typename SplitType,
-	 typename DescentType,
+template<typename DescentType,
 	 typename StatisticType,
 	 typename MatType>
-void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::insertNodeIntoTree(
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* destTree,
-    RectangleTree<SplitType, DescentType, StatisticType, MatType>* srcNode)
+void RTreeSplit<DescentType, StatisticType, MatType>::insertNodeIntoTree(
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* destTree,
+    RectangleTree<RTreeSplit<DescentType, StatisticType, MatType>, DescentType, StatisticType, MatType>* srcNode)
 {
-  destTree.Bound() |= srcNode->Bound();
-  destTree->Children()[destTree->getNumOfChildren()++] = &srcNode;
+  destTree->Bound() |= srcNode->Bound();
+  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 6f6875d..1095c8a 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
@@ -71,7 +71,7 @@ class RectangleTree
   //! The discance to the furthest descendant, cached to speed things up.
   double furthestDescendantDistance;
   //! The dataset.
-  MatType& dataset;
+  MatType* dataset;
   
  public:
   //! So other classes can use TreeType::Mat.
@@ -108,7 +108,7 @@ class RectangleTree
    *
    * @param parentNode The parent of the node that is being constructed.
    */
-  RectangleTree(const RectangleTree<SplitType, DescentType, StatisticType, MatType>& parentNode);
+  RectangleTree(RectangleTree<SplitType, DescentType, StatisticType, MatType>* parentNode);
 
 
   //TODO implement the oldFromNew stuff if applicable.
@@ -200,9 +200,9 @@ class RectangleTree
   RectangleTree*& Parent() { return parent; }
 
   //! Get the dataset which the tree is built on.
-  const arma::mat& Dataset() const { return dataset; }
+  const arma::mat& Dataset() const { return *dataset; }
   //! Modify the dataset which the tree is built on.  Be careful!
-  arma::mat& Dataset() { return dataset; }
+  arma::mat& Dataset() { return *dataset; }
 
   //! Get the metric which the tree uses.
   typename HRectBound<>::MetricType Metric() const { return bound.Metric(); }
@@ -247,13 +247,9 @@ class RectangleTree
     *
     * @param child Index of child to return.
     */
-  template<typename SplitType,
-           typename DescentType,
-  	 typename StatisticType,
-           typename MatType>
+
   inline RectangleTree<SplitType, DescentType, StatisticType, MatType>*
-      RectangleTree<SplitType, DescentType, StatisticType, MatType>::
-          Child(const size_t child) const
+    Child(const size_t child) const
   {
     return children[child];
   }
@@ -263,13 +259,8 @@ class RectangleTree
     *
     * @param child Index of child to return.
    */
-  template<typename SplitType,
-           typename DescentType,
-           typename StatisticType,
-           typename MatType>
   inline RectangleTree<SplitType, DescentType, StatisticType, MatType>*&
-      RectangleTree<SplitType, DescentType, StatisticType, MatType>::
-          Child(const size_t child)
+    Child(const size_t child)
   {
     return children[child];
   }
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 0a810c9..be06f4a 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
@@ -38,18 +38,17 @@ RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
     maxLeafSize(maxLeafSize),
     minLeafSize(minLeafSize),
     bound(data.n_rows),
-    parentDistance(0)
-
+    parentDistance(0),
+    dataset(new MatType(data.n_rows, static_cast<int>(maxLeafSize)+1)) // Add one to make splitting the node simpler
 {
-  this.stat = EmptyStatistic(*this);
-  this.dataset = new MatType(maxLeafSize+1); // Add one to make splitting the node simpler
+  stat = StatisticType(*this);
   
   // For now, just insert the points in order.
   RectangleTree* root = this;
   for(int i = firstDataIndex; i < data.n_cols; i++) {
-    root.insertPoint(data.col(i));
-    if(root.Parent() != NULL) {
-      root = root.Parent(); // OK since the level increases by at most one per iteration.
+    root->InsertPoint(data.col(i));
+    if(root->Parent() != NULL) {
+      root = root->Parent(); // OK since the level increases by at most one per iteration.
     }
   }
   
@@ -60,22 +59,22 @@ template<typename SplitType,
 	 typename StatisticType,
 	 typename MatType>
 RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
-  const RectangleTree<SplitType, DescentType, StatisticType, MatType>& parentNode):
+  RectangleTree<SplitType, DescentType, StatisticType, MatType>* parentNode):
   maxNumChildren(parentNode.MaxNumChildren()),
   minNumChildren(parentNode.MinNumChildren()),
   numChildren(0),
   children(maxNumChildren+1),
-  parent(&parentNode),
+  parent(parentNode),
   begin(0),
   count(0),
-  maxLeafSize(parentNode.MaxLeafSize()),
-  minLeafSize(parentNode.MinLeafSize()),
-  bound(parentNode.Bound().Dim()),
-  parentDistance(0)
-  {
-    this.stat = EmptyStatistic(*this);
-    this.dataset = new MatType(maxLeafSize+1); // Add one to make splitting the node simpler
-  }
+  maxLeafSize(parentNode->MaxLeafSize()),
+  minLeafSize(parentNode->MinLeafSize()),
+  bound(parentNode->Bound().Dim()),
+  parentDistance(0),
+  dataset(new MatType(static_cast<int>(parentNode->Bound().Dim()), static_cast<int>((maxLeafSize)+1))) // Add one to make splitting the node simpler
+{
+  stat = StatisticType(*this);
+}
 
 /**
  * Deletes this node, deallocating the memory for the children and calling
@@ -103,8 +102,9 @@ template<typename SplitType,
                   typename DescentType,
                   typename StatisticType,
                   typename MatType>
-RectangleTree<SplitType, DescentType, StatisticType, MatType>::
-softDelete() {
+void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
+    softDelete()
+{
   /* do nothing.  I'm not sure how to handle this yet, so for now, we will leak memory */
 }
 
@@ -124,23 +124,23 @@ void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
   
   // If this is a leaf node, we stop here and add the point.
   if(numChildren == 0) {
-    dataset.col(count++) = point;
+    dataset->col(count++) = point;
     SplitNode();
     return;
   }
 
   // If it is not a leaf node, we use the DescentHeuristic to choose a child
   // to which we recurse.
-  double minScore = DescentType::EvalNode(children[0].Bound(), point);
+  double minScore = DescentType::EvalNode(children[0]->Bound(), point);
   int bestIndex = 0;
   for(int i = 1; i < numChildren; i++) {
-    double score = DescentType::EvalNode(children[i].Bound(), point);
+    double score = DescentType::EvalNode(children[i]->Bound(), point);
     if(score < minScore) {
       minScore = score;
       bestIndex = i;
     }
   }
-  children[bestIndex].InsertPoint(point);
+  children[bestIndex]->InsertPoint(point);
 }
 
 template<typename SplitType,
@@ -152,7 +152,7 @@ size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
 {
   int n = 0;
   for(int i = 0; i < numChildren; i++) {
-    n += children[i].TreeSize();
+    n += children[i]->TreeSize();
   }
   return n + 1; // we add one for this node
 }
@@ -173,7 +173,7 @@ size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
   // because we have to count this node, too.
   int maxSubDepth = 0;
   for(int i = 0; i < numChildren; i++) {
-    int d = children[i].TreeDepth();
+    int d = children[i]->TreeDepth();
     if(d > maxSubDepth)
       maxSubDepth = d;
   }
@@ -294,7 +294,7 @@ inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::End
 {
   if(numChildren)
     return begin + count;
-  return children[numChildren-1].End();
+  return children[numChildren-1]->End();
 }
 
   //have functions for returning the list of modified indices if we end up doing it that way.
@@ -346,7 +346,7 @@ std::string RectangleTree<SplitType, DescentType, StatisticType, MatType>::ToStr
   // How many levels should we print?  This will print the root and it's children.
   if(parent == NULL) {
     for(int i = 0; i < numChildren; i++) {
-      convert << children[i].ToString();
+      convert << children[i]->ToString();
     }
   }
   return convert.str();
diff --git a/src/mlpack/methods/neighbor_search/allknn_main.cpp b/src/mlpack/methods/neighbor_search/allknn_main.cpp
index 9ede7c7..23448b8 100644
--- a/src/mlpack/methods/neighbor_search/allknn_main.cpp
+++ b/src/mlpack/methods/neighbor_search/allknn_main.cpp
@@ -272,11 +272,11 @@ int main(int argc, char *argv[])
       // Build the reference tree.
       Log::Info << "Building reference tree..." << endl;
       Timer::Start("tree_building");
-//        RectangleTree<NeighborSearchStat<NearestNeighborSort>,
-//                                   arma::mat,
-//                                   tree::RTreeSplit,
-//                                   tree::RTreeDescentHeuristic>
-//        refTree(referenceData, leafSize);
+        RectangleTree<tree::RTreeSplit<tree::RTreeDescentHeuristic, NeighborSearchStat<NearestNeighborSort>, arma::mat>,
+                      tree::RTreeDescentHeuristic,
+                      NeighborSearchStat<NearestNeighborSort>,
+                      arma::mat>
+        refTree(referenceData, leafSize, leafSize/3, 5, 2, 0);
       Timer::Stop("tree_building");
         
     }
diff --git a/src/mlpack/methods/neighbor_search/neighbor_search.hpp b/src/mlpack/methods/neighbor_search/neighbor_search.hpp
index a931957..64f71a2 100644
--- a/src/mlpack/methods/neighbor_search/neighbor_search.hpp
+++ b/src/mlpack/methods/neighbor_search/neighbor_search.hpp
@@ -13,7 +13,7 @@
 #include <string>
 
 #include <mlpack/core/tree/binary_space_tree.hpp>
-//#include <mlpack/core/tree/rectangle_tree.hpp>
+#include <mlpack/core/tree/rectangle_tree.hpp>
 
 #include <mlpack/core/metrics/lmetric.hpp>
 #include "neighbor_search_stat.hpp"

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mlpack.git



More information about the debian-science-commits mailing list