[mlpack] 59/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 2f16596c5e73b48a9273c5fea2acbffdfdd9af7f
Author: andrewmw94 <andrewmw94 at 9d5b8971-822b-0410-80eb-d18c1038ef23>
Date: Fri Jun 13 16:40:16 2014 +0000
More bug fixes.
git-svn-id: http://svn.cc.gatech.edu/fastlab/mlpack/trunk@16688 9d5b8971-822b-0410-80eb-d18c1038ef23
---
.../core/tree/rectangle_tree/r_tree_split.hpp | 20 +--
.../core/tree/rectangle_tree/r_tree_split_impl.hpp | 141 +++++++++++----------
.../core/tree/rectangle_tree/rectangle_tree.hpp | 41 ++++--
.../tree/rectangle_tree/rectangle_tree_impl.hpp | 50 ++++----
4 files changed, 138 insertions(+), 114 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 08a3c9a..1d87cc6 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_tree_split.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_tree_split.hpp
@@ -31,7 +31,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(const RectangleTree<SplitType, DescentType, StatisticType, MatType>* tree);
private:
@@ -39,7 +39,7 @@ 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(const RectangleTree<SplitType, DescentType, StatisticType, MatType>* tree);
/**
* Get the seeds for splitting a leaf node.
@@ -55,9 +55,9 @@ static void GetBoundSeeds(const RectangleTree<SplitType, DescentType, StatisticT
* 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,
+ const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeOne,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeTwo,
const int intI,
const int intJ);
@@ -65,9 +65,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,
+ const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType> *treeOne,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType> *treeTwo,
const int intI,
const int intJ);
@@ -75,8 +75,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<SplitType, DescentType, StatisticType, MatType>* destTree,
+ RectangleTree<SplitType, 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 6318efa..d11cc3d 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
@@ -24,7 +24,7 @@ template<typename SplitType,
typename StatisticType,
typename MatType>
void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitLeafNode(
- const RectangleTree<SplitType, DescentType, StatisticType, MatType>& tree)
+ const RectangleTree<SplitType, 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.
@@ -33,15 +33,16 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitLeafNode(
int j = 0;
GetPointSeeds(tree, &i, &j);
- RectangleTree<SplitType, DescentType, StatisticType, MatType> treeOne = new
+ 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> *treeTwo = new
RectangleTree<SplitType, DescentType, StatisticType, MatType>(tree.Parent());
// This will assign the ith and jth point appropriately.
AssignPointDestNode(tree, treeOne, treeTwo, i, j);
- // create the parent node if necessary
+ // 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) {
}
@@ -49,23 +50,23 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitLeafNode(
//Remove this node and insert treeOne and treeTwo
RectangleTree<SplitType, 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->numOfChildren(); i++) {
+ if(par->getChildren()[i] == tree) {
index = i;
break;
}
}
- par.getChildren()[i] = treeOne;
- par.getChildren()[par.end++] = treeTwo;
+ par->getChildren()[i] = treeOne;
+ par->getChildren()[par->end++] = treeTwo;
//because we copied the points to treeOne and treeTwo, we can just delete this node
delete tree;
- // we only add one at a time, so should only need to test for equality
+ // we only add one at a time, so we should only need to test for equality
// just in case, we use an assert.
- assert(par.NumChildren() <= par.MaxNumChildren());
+ assert(par->NumChildren() <= par->MaxNumChildren());
- if(par.NumChildren() == par.MaxNumChildren()) {
+ if(par->NumChildren() == par->MaxNumChildren()) {
SplitNonLeafNode(par);
}
return;
@@ -83,15 +84,15 @@ template<typename SplitType,
typename StatisticType,
typename MatType>
bool RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitNonLeafNode(
- const RectangleTree<SplitType, DescentType, StatisticType, MatType>& tree)
+ const RectangleTree<SplitType, DescentType, StatisticType, MatType>* tree)
{
int i = 0;
int j = 0;
GetBoundSeeds(tree, &i, &j);
- RectangleTree<SplitType, DescentType, StatisticType, MatType> treeOne = new
+ 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>* treeTwo = new
RectangleTree<SplitType, DescentType, StatisticType, MatType>(tree.Parent());
// This will assign the ith and jth rectangles appropriately.
@@ -105,14 +106,14 @@ bool RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitNonLeafNod
//Remove this node and insert treeOne and treeTwo
RectangleTree<SplitType, 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->numOfChildren(); i++) {
+ if(par->getChildren()[i] == tree) {
index = i;
break;
}
}
- par.getChildren()[i] = treeOne;
- par.getChildren()[par.end++] = treeTwo;
+ par->getChildren()[i] = treeOne;
+ par->getChildren()[par->end++] = treeTwo;
// Because we now have pointers to the information stored under this tree,
// we need to delete this node carefully.
@@ -120,9 +121,9 @@ bool RTreeSplit<SplitType, DescentType, StatisticType, MatType>::SplitNonLeafNod
// we only add one at a time, so should only need to test for equality
// just in case, we use an assert.
- assert(par.NumChildren() <= par.MaxNumChildren());
+ assert(par->NumChildren() <= par->MaxNumChildren());
- if(par.NumChildren() == par.MaxNumChildren()) {
+ if(par->NumChildren() == par->MaxNumChildren()) {
SplitNonLeafNode(par);
}
return;
@@ -207,19 +208,19 @@ template<typename SplitType,
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,
+ const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeOne,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeTwo,
const int intI,
const int intJ)
{
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;
@@ -229,7 +230,7 @@ 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)) {
+ while(end > 1 && end < oldTree->minLeafSize() - std::min(numAssignedOne, numAssignedTwo)) {
int bestIndex = 0;
double bestScore = 0;
int bestRect = 0;
@@ -237,9 +238,9 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignPointDest
// Calculate the increase in volume for assigning this point to each rectangle.
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();
+ for(int i = 0; i < oldTree->Bound().Dim(); i++) {
+ 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
@@ -247,12 +248,12 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignPointDest
for(int index = 0; index < end; index++) {
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()));
+ 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()));
}
// Choose the rectangle that requires the lesser increase in volume.
@@ -274,22 +275,22 @@ 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(bestIndex));
else
- treeTwo.insertPoint(oldTree.dataset(bestIndex));
+ treeTwo->insertPoint(oldTree->dataset(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(i));
}
} else {
for(int i = 0; i < end; i++) {
- treeTwo.insertPoint(oldTree.dataset(i));
+ treeTwo->insertPoint(oldTree.dataset(i));
}
}
}
@@ -300,20 +301,20 @@ template<typename SplitType,
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,
+ const RectangleTree<SplitType, DescentType, StatisticType, MatType>* oldTree,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeOne,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* treeTwo,
const int intI,
const int intJ)
{
- int end = oldTree.getNumChildren();
+ int end = oldTree->getNumChildren();
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->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
int numAssignTreeOne = 1;
int numAssignTreeTwo = 1;
@@ -321,7 +322,7 @@ 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->getMinNumChildren() - std::min(numAssignTreeOne, numAssignTreeTwo)) {
int bestIndex = 0;
double bestScore = 0;
int bestRect = 0;
@@ -329,24 +330,24 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignNodeDestN
// 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();
+ for(int i = 0; i < oldTree->Bound().Dim(); i++) {
+ volOne *= treeOne->bound[i].width();
+ volTwo *= treeTwo->bound[i].width();
}
for(int index = 0; index < end; index++) {
double newVolOne = 1.0;
double newVolTwo = 1.0;
- for(int i = 0; i < oldTree.Bound().Dim(); i++) {
+ 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())));
+ 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())));
+ (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.
@@ -368,21 +369,21 @@ void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::AssignNodeDestN
// Assign the rectangle that causes the least increase in volume
// to the appropriate rectangle.
if(bestRect == 1)
- insertNodeIntoTree(treeOne, oldTree.Children()[bestIndex]);
+ insertNodeIntoTree(treeOne, oldTree->Children()[bestIndex]);
else
- insertNodeIntoTree(treeTwo, oldTree.Children()[bestIndex]);
+ insertNodeIntoTree(treeTwo, oldTree->Children()[bestIndex]);
- oldTree.Children()[bestIndex] = oldTree.Children()[--end]; // Decrement end.
+ oldTree->Children()[bestIndex] = oldTree->Children()[--end]; // Decrement end.
}
// See if we need to satisfy the minimum fill.
if(end > 1) {
if(numAssignTreeOne < numAssignTreeTwo) {
for(int i = 0; i < end; i++) {
- insertNodeIntoTree(treeOne, oldTree.Children()[i]);
+ insertNodeIntoTree(treeOne, oldTree->Children()[i]);
}
} else {
for(int i = 0; i < end; i++) {
- insertNodeIntoTree(treeTwo, oldTree.Children()[i]);
+ insertNodeIntoTree(treeTwo, oldTree->Children()[i]);
}
}
}
@@ -396,11 +397,11 @@ template<typename SplitType,
typename StatisticType,
typename MatType>
void RTreeSplit<SplitType, DescentType, StatisticType, MatType>::insertNodeIntoTree(
- RectangleTree<SplitType, DescentType, StatisticType, MatType>& destTree,
- RectangleTree<SplitType, DescentType, StatisticType, MatType>& srcNode)
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* destTree,
+ RectangleTree<SplitType, DescentType, StatisticType, MatType>* srcNode)
{
- destTree.Bound() |= srcNode.Bound();
- destTree.Children()[destTree.getNumOfChildren()++] = &srcNode;
+ destTree.Bound() |= srcNode->Bound();
+ destTree->Children()[destTree->getNumOfChildren()++] = &srcNode;
}
diff --git a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
index 5cc33f7..6f6875d 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree.hpp
@@ -12,10 +12,6 @@
#include "../hrectbound.hpp"
#include "../statistic.hpp"
-// #ifdef __MLPACK_CORE_TREE_HRECTBOUND_HPP
-// #define max(a, b) 5 //something to break the build
-// #endif
-
namespace mlpack {
namespace tree /** Trees and tree-building procedures. */ {
@@ -247,12 +243,37 @@ class RectangleTree
double& ParentDistance() { return parentDistance; }
/**
- * Return the specified child.
- *
- * @param child Index of child to return.
+ * Get the specified child.
+ *
+ * @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
+ {
+ return children[child];
+ }
+
+ /**
+ * Modify the specified child.
+ *
+ * @param child Index of child to return.
*/
- RectangleTree& Child(const size_t child) const;
-
+ 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)
+ {
+ return children[child];
+ }
+
//! Return the number of points in this node (returns 0 if this node is not a leaf).
size_t NumPoints() const;
@@ -360,7 +381,7 @@ class RectangleTree
private:
/**
* Private copy constructor, available only to fill (pad) the tree to a
- * specified level.
+ * specified level. TO BE REMOVED
*/
RectangleTree(const size_t begin,
const size_t count,
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 19ebf84..0a810c9 100644
--- a/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/rectangle_tree_impl.hpp
@@ -84,7 +84,7 @@ RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
*/
template<typename SplitType,
typename DescentType,
- typename StatisticType,
+ typename StatisticType,
typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::
~RectangleTree()
@@ -95,6 +95,18 @@ RectangleTree<SplitType, DescentType, StatisticType, MatType>::
delete dataset;
}
+/**
+ * Deletes this node but leaves the children untouched. Needed for when we
+ * split nodes and remove nodes (inserting and deleting points).
+ */
+template<typename SplitType,
+ typename DescentType,
+ typename StatisticType,
+ typename MatType>
+RectangleTree<SplitType, DescentType, StatisticType, MatType>::
+softDelete() {
+ /* do nothing. I'm not sure how to handle this yet, so for now, we will leak memory */
+}
/**
* Recurse through the tree and insert the point at the leaf node chosen
@@ -119,10 +131,10 @@ void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
// 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;
@@ -154,11 +166,14 @@ template<typename SplitType,
size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
TreeDepth() const
{
+ /* Because R trees are balanced, we could simplify this. However, X trees are not
+ guaranteed to be balanced so I keep it as is: */
+
// Recursively count the depth of each subtree. The plus one is
// because we have to count this node, too.
int maxSubDepth = 0;
for(int i = 0; i < numChildren; i++) {
- int d = children[i].depth();
+ int d = children[i].TreeDepth();
if(d > maxSubDepth)
maxSubDepth = d;
}
@@ -212,21 +227,7 @@ inline double RectangleTree<SplitType, DescentType, StatisticType, MatType>::
}
/**
- * Return the specified child.
- */
-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
-{
- return children[child];
-}
-
-/**
- * Return the number of points contained in this node. Zero if it is not a leaf.
+ * Return the number of points contained in this node. Zero if it is a non-leaf node.
*/
template<typename SplitType,
typename DescentType,
@@ -235,7 +236,7 @@ template<typename SplitType,
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
NumPoints() const
{
- if(numChildren == 0)
+ if(numChildren != 0) // This is not a leaf node.
return 0;
return count;
@@ -243,6 +244,7 @@ inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
/**
* Return the number of descendants contained in this node. MEANINIGLESS AS IT CURRENTLY STANDS.
+ * USE NumPoints() INSTEAD.
*/
template<typename SplitType,
typename DescentType,
@@ -311,12 +313,12 @@ void RectangleTree<SplitType, DescentType, StatisticType, MatType>::SplitNode()
// the split will be called from here but will take place in the SplitType code.
assert(numChildren == 0);
- // See if we are full.
+ // Check to see if we are full.
if(count < maxLeafSize)
- return;
+ return; // We don't need to split.
- // If we are full, then we need to move up the tree. The SplitType takes
- // care of this.
+ // 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);
}
--
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