[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