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