[mlpack] 09/35: Replace SortStruct by std::pair
Barak A. Pearlmutter
barak+git at pearlmutter.net
Thu Sep 15 23:29:39 UTC 2016
This is an automated email from the git hooks/post-receive script.
bap pushed a commit to branch master
in repository mlpack.
commit bbf092e4443c6fa8f7607a8e11ad7345af9b8095
Author: Mikhail Lozhnikov <lozhnikovma at gmail.com>
Date: Tue Jul 12 15:45:38 2016 +0300
Replace SortStruct by std::pair
(ported changes to HRectBound also)
---
src/mlpack/core/tree/hrectbound.hpp | 27 +-
src/mlpack/core/tree/hrectbound_impl.hpp | 85 +++++-
.../core/tree/rectangle_tree/r_star_tree_split.hpp | 20 --
.../tree/rectangle_tree/r_star_tree_split_impl.hpp | 269 ++++++++-----------
.../core/tree/rectangle_tree/x_tree_split.hpp | 21 --
.../core/tree/rectangle_tree/x_tree_split_impl.hpp | 297 +++++++++------------
6 files changed, 338 insertions(+), 381 deletions(-)
diff --git a/src/mlpack/core/tree/hrectbound.hpp b/src/mlpack/core/tree/hrectbound.hpp
index cf9f31a..7a0823f 100644
--- a/src/mlpack/core/tree/hrectbound.hpp
+++ b/src/mlpack/core/tree/hrectbound.hpp
@@ -5,13 +5,6 @@
*
* This file describes the interface for the HRectBound class, which implements
* a hyperrectangle bound.
- *
- * This file is part of mlpack 2.0.2.
- *
- * mlpack is free software; you may redistribute it and/or modify it under the
- * terms of the 3-clause BSD license. You should have received a copy of the
- * 3-clause BSD license along with mlpack. If not, see
- * http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_TREE_HRECTBOUND_HPP
#define MLPACK_CORE_TREE_HRECTBOUND_HPP
@@ -190,6 +183,26 @@ class HRectBound
bool Contains(const VecType& point) const;
/**
+ * Determines if this bound partially contains a bound.
+ */
+ bool Contains(const HRectBound& bound) const;
+
+ /**
+ * Returns the intersection of this bound and another.
+ */
+ HRectBound operator&(const HRectBound& bound) const;
+
+ /**
+ * Intersects this bound with another.
+ */
+ HRectBound& operator&=(const HRectBound& bound);
+
+ /**
+ * Returns the volume of overlap of this bound and another.
+ */
+ ElemType Overlap(const HRectBound& bound) const;
+
+ /**
* Returns the diameter of the hyperrectangle (that is, the longest diagonal).
*/
ElemType Diameter() const;
diff --git a/src/mlpack/core/tree/hrectbound_impl.hpp b/src/mlpack/core/tree/hrectbound_impl.hpp
index 758b621..ccfa026 100644
--- a/src/mlpack/core/tree/hrectbound_impl.hpp
+++ b/src/mlpack/core/tree/hrectbound_impl.hpp
@@ -5,13 +5,6 @@
* Template parameter Power is the metric to use; use 2 for Euclidean (L2).
*
* @experimental
- *
- * This file is part of mlpack 2.0.2.
- *
- * mlpack is free software; you may redistribute it and/or modify it under the
- * terms of the 3-clause BSD license. You should have received a copy of the
- * 3-clause BSD license along with mlpack. If not, see
- * http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_CORE_TREE_HRECTBOUND_IMPL_HPP
#define MLPACK_CORE_TREE_HRECTBOUND_IMPL_HPP
@@ -150,7 +143,12 @@ inline ElemType HRectBound<MetricType, ElemType>::Volume() const
{
ElemType volume = 1.0;
for (size_t i = 0; i < dim; ++i)
+ {
+ if (bounds[i].Lo() >= bounds[i].Hi())
+ return 0;
+
volume *= (bounds[i].Hi() - bounds[i].Lo());
+ }
return volume;
}
@@ -438,6 +436,79 @@ inline bool HRectBound<MetricType, ElemType>::Contains(const VecType& point) con
}
/**
+ * Determines if this bound partially contains a bound.
+ */
+template<typename MetricType, typename ElemType>
+inline bool HRectBound<MetricType, ElemType>::Contains(
+ const HRectBound& bound) const
+{
+ for (size_t i = 0; i < dim; i++)
+ {
+ const math::RangeType<ElemType>& r_a = bounds[i];
+ const math::RangeType<ElemType>& r_b = bound.bounds[i];
+
+ if (r_a.Hi() <= r_b.Lo() || r_a.Lo() >= r_b.Hi()) // If a does not overlap b at all.
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Returns the intersection of this bound and another.
+ */
+template<typename MetricType, typename ElemType>
+inline HRectBound<MetricType, ElemType> HRectBound<MetricType, ElemType>::
+operator&(const HRectBound& bound) const
+{
+ HRectBound<MetricType, ElemType> result(dim);
+
+ for (size_t k = 0; k < dim; k++)
+ {
+ result[k].Lo() = std::max(bounds[k].Lo(), bound.bounds[k].Lo());
+ result[k].Hi() = std::min(bounds[k].Hi(), bound.bounds[k].Hi());
+ }
+ return result;
+}
+
+/**
+ * Intersects this bound with another.
+ */
+template<typename MetricType, typename ElemType>
+inline HRectBound<MetricType, ElemType>& HRectBound<MetricType, ElemType>::
+operator&=(const HRectBound& bound)
+{
+ for (size_t k = 0; k < dim; k++)
+ {
+ bounds[k].Lo() = std::max(bounds[k].Lo(), bound.bounds[k].Lo());
+ bounds[k].Hi() = std::min(bounds[k].Hi(), bound.bounds[k].Hi());
+ }
+ return *this;
+}
+
+/**
+ * Returns the volume of overlap of this bound and another.
+ */
+template<typename MetricType, typename ElemType>
+inline ElemType HRectBound<MetricType, ElemType>::Overlap(
+ const HRectBound& bound) const
+{
+ ElemType volume = 1.0;
+
+ for (size_t k = 0; k < dim; k++)
+ {
+ ElemType lo = std::max(bounds[k].Lo(), bound.bounds[k].Lo());
+ ElemType hi = std::min(bounds[k].Hi(), bound.bounds[k].Hi());
+
+ if ( hi <= lo)
+ return 0;
+
+ volume *= hi - lo;
+ }
+ return volume;
+}
+
+/**
* Returns the diameter of the hyperrectangle (that is, the longest diagonal).
*/
template<typename MetricType, typename ElemType>
diff --git a/src/mlpack/core/tree/rectangle_tree/r_star_tree_split.hpp b/src/mlpack/core/tree/rectangle_tree/r_star_tree_split.hpp
index 8159943..a91cd87 100644
--- a/src/mlpack/core/tree/rectangle_tree/r_star_tree_split.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/r_star_tree_split.hpp
@@ -53,26 +53,6 @@ class RStarTreeSplit
private:
/**
- * Class to allow for faster sorting.
- */
- template<typename ElemType>
- struct SortStruct
- {
- ElemType d;
- int n;
- };
-
- /**
- * Comparator for sorting with SortStruct.
- */
- template<typename ElemType>
- static bool StructComp(const SortStruct<ElemType>& s1,
- const SortStruct<ElemType>& s2)
- {
- return s1.d < s2.d;
- }
-
- /**
* Insert a node into another node.
*/
static void InsertNodeIntoTree(TreeType* destTree, TreeType* srcNode);
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 962aeb5..2f5c008 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
@@ -33,6 +33,7 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
{
// Convenience typedef.
typedef typename TreeType::ElemType ElemType;
+ typedef bound::HRectBound<metric::EuclideanDistance, ElemType> BoundType;
// 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
@@ -69,23 +70,29 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
return;
}
- std::vector<SortStruct<ElemType>> sorted(tree->Count());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->Count());
arma::Col<ElemType> center;
tree->Bound().Center(center); // Modifies centroid.
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Metric().Evaluate(center,
+ sorted[i].first = tree->Metric().Evaluate(center,
tree->LocalDataset().col(i));
- sorted[i].n = i;
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), StructComp<ElemType>);
- std::vector<int> pointIndices(p);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
+ std::vector<size_t> pointIndices(p);
+
for (size_t i = 0; i < p; i++)
{
// We start from the end of sorted.
- pointIndices[i] = tree->Points()[sorted[sorted.size() - 1 - i].n];
- root->DeletePoint(tree->Points()[sorted[sorted.size() - 1 - i].n],
+ pointIndices[i] = tree->Points()[sorted[sorted.size() - 1 - i].second];
+ root->DeletePoint(tree->Points()[sorted[sorted.size() - 1 - i].second],
relevels);
}
@@ -108,14 +115,19 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
{
ElemType axisScore = 0.0;
// Since we only have points in the leaf nodes, we only need to sort once.
- std::vector<SortStruct<ElemType>> sorted(tree->Count());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->Count());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->LocalDataset().col(i)[j];
- sorted[i].n = i;
+ sorted[i].first = tree->LocalDataset().col(i)[j];
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), StructComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
// We'll store each of the three scores for each distribution.
std::vector<ElemType> areas(tree->MaxLeafSize() - 2 * tree->MinLeafSize() +
@@ -140,46 +152,21 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
size_t cutOff = tree->MinLeafSize() + i;
- // We'll calculate the max and min in each dimension by hand to save time.
- std::vector<ElemType> maxG1(tree->Bound().Dim());
- std::vector<ElemType> minG1(maxG1.size());
- std::vector<ElemType> maxG2(maxG1.size());
- std::vector<ElemType> minG2(maxG1.size());
- for (size_t k = 0; k < tree->Bound().Dim(); k++)
- {
- minG1[k] = maxG1[k] = tree->LocalDataset().col(sorted[0].n)[k];
- minG2[k] = maxG2[k] =
- tree->LocalDataset().col(sorted[sorted.size() - 1].n)[k];
+ BoundType bound1(tree->Bound().Dim());
+ BoundType bound2(tree->Bound().Dim());
- for (size_t l = 1; l < tree->Count() - 1; l++)
- {
- if (l < cutOff)
- {
- if (tree->LocalDataset().col(sorted[l].n)[k] < minG1[k])
- minG1[k] = tree->LocalDataset().col(sorted[l].n)[k];
- else if (tree->LocalDataset().col(sorted[l].n)[k] > maxG1[k])
- maxG1[k] = tree->LocalDataset().col(sorted[l].n)[k];
- }
- else
- {
- if (tree->LocalDataset().col(sorted[l].n)[k] < minG2[k])
- minG2[k] = tree->LocalDataset().col(sorted[l].n)[k];
- else if (tree->LocalDataset().col(sorted[l].n)[k] > maxG2[k])
- maxG2[k] = tree->LocalDataset().col(sorted[l].n)[k];
- }
- }
- }
+ for (size_t l = 0; l < cutOff; l++)
+ bound1 |= tree->LocalDataset().col(sorted[l].second);
- ElemType area1 = 1.0, area2 = 1.0;
- ElemType oArea = 1.0;
- for (size_t k = 0; k < maxG1.size(); k++)
- {
- margins[i] += maxG1[k] - minG1[k] + maxG2[k] - minG2[k];
- area1 *= maxG1[k] - minG1[k];
- area2 *= maxG2[k] - minG2[k];
- oArea *= (maxG1[k] < minG2[k] || maxG2[k] < minG1[k]) ? 0.0 :
- (std::min(maxG1[k], maxG2[k]) - std::max(minG1[k], minG2[k]));
- }
+ for (size_t l = cutOff; l < tree->Count(); l++)
+ bound2 |= tree->LocalDataset().col(sorted[l].second);
+
+ ElemType area1 = bound1.Volume();
+ ElemType area2 = bound2.Volume();
+ ElemType oArea = bound1.Overlap(bound2);
+
+ for (size_t k = 0; k < bound1.Dim(); k++)
+ margins[i] += bound1[k].Width() + bound2[k].Width();
areas[i] += area1 + area2;
overlapedAreas[i] += oArea;
@@ -212,14 +199,19 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
}
}
- std::vector<SortStruct<ElemType>> sorted(tree->Count());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->Count());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->LocalDataset().col(i)[bestAxis];
- sorted[i].n = i;
+ sorted[i].first = tree->LocalDataset().col(i)[bestAxis];
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), StructComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
TreeType* treeOne = new TreeType(tree->Parent());
TreeType* treeTwo = new TreeType(tree->Parent());
@@ -229,9 +221,9 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
for (size_t i = 0; i < tree->Count(); i++)
{
if (i < bestAreaIndexOnBestAxis + tree->MinLeafSize())
- treeOne->InsertPoint(tree->Points()[sorted[i].n]);
+ treeOne->InsertPoint(tree->Points()[sorted[i].second]);
else
- treeTwo->InsertPoint(tree->Points()[sorted[i].n]);
+ treeTwo->InsertPoint(tree->Points()[sorted[i].second]);
}
}
else
@@ -239,9 +231,9 @@ void RStarTreeSplit<TreeType>::SplitLeafNode(TreeType *tree,std::vector<bool>& r
for (size_t i = 0; i < tree->Count(); i++)
{
if (i < bestOverlapIndexOnBestAxis + tree->MinLeafSize())
- treeOne->InsertPoint(tree->Points()[sorted[i].n]);
+ treeOne->InsertPoint(tree->Points()[sorted[i].second]);
else
- treeTwo->InsertPoint(tree->Points()[sorted[i].n]);
+ treeTwo->InsertPoint(tree->Points()[sorted[i].second]);
}
}
@@ -281,6 +273,7 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
{
// Convenience typedef.
typedef typename TreeType::ElemType ElemType;
+ typedef bound::HRectBound<metric::EuclideanDistance, ElemType> BoundType;
// 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
@@ -372,14 +365,19 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
ElemType axisScore = 0.0;
// We'll do Bound().Lo() now and use Bound().Hi() later.
- std::vector<SortStruct<ElemType>> sorted(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->NumChildren());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[j].Lo();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[j].Lo();
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), StructComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
// We'll store each of the three scores for each distribution.
std::vector<ElemType> areas(tree->MaxNumChildren() -
@@ -404,49 +402,21 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
size_t cutOff = tree->MinNumChildren() + i;
- // We'll calculate the max and min in each dimension by hand to save time.
- std::vector<ElemType> maxG1(tree->Bound().Dim());
- std::vector<ElemType> minG1(maxG1.size());
- std::vector<ElemType> maxG2(maxG1.size());
- std::vector<ElemType> minG2(maxG1.size());
- for (size_t k = 0; k < tree->Bound().Dim(); k++)
- {
- minG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Lo();
- maxG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Hi();
- minG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Lo();
- maxG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Hi();
-
- for (size_t l = 1; l < tree->NumChildren() - 1; l++)
- {
- if (l < cutOff)
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG1[k])
- minG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG1[k])
- maxG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- else
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG2[k])
- minG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG2[k])
- maxG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- }
- }
+ BoundType bound1(tree->Bound().Dim());
+ BoundType bound2(tree->Bound().Dim());
- ElemType area1 = 1.0, area2 = 1.0;
- ElemType oArea = 1.0;
- for (size_t k = 0; k < maxG1.size(); k++)
- {
- margins[i] += maxG1[k] - minG1[k] + maxG2[k] - minG2[k];
- area1 *= maxG1[k] - minG1[k];
- area2 *= maxG2[k] - minG2[k];
- oArea *= (maxG1[k] < minG2[k] || maxG2[k] < minG1[k]) ? 0.0 :
- (std::min(maxG1[k], maxG2[k]) - std::max(minG1[k], minG2[k]));
- }
+ for (size_t l = 0; l < cutOff; l++)
+ bound1 |= tree->Child(sorted[l].second).Bound();
+
+ for (size_t l = cutOff; l < tree->NumChildren(); l++)
+ bound2 |= tree->Child(sorted[l].second).Bound();
+
+ ElemType area1 = bound1.Volume();
+ ElemType area2 = bound2.Volume();
+ ElemType oArea = bound1.Overlap(bound2);
+
+ for (size_t k = 0; k < bound1.Dim(); k++)
+ margins[i] += bound1[k].Width() + bound2[k].Width();
areas[i] += area1 + area2;
overlapedAreas[i] += oArea;
@@ -483,15 +453,19 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
{
ElemType axisScore = 0.0;
- // We'll do Bound().Lo() now and use Bound().Hi() later.
- std::vector<SortStruct<ElemType>> sorted(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->NumChildren());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[j].Hi();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[j].Hi();
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), StructComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
// We'll store each of the three scores for each distribution.
std::vector<ElemType> areas(tree->MaxNumChildren() -
@@ -516,51 +490,21 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
size_t cutOff = tree->MinNumChildren() + i;
- // We'll calculate the max and min in each dimension by hand to save time.
- std::vector<ElemType> maxG1(tree->Bound().Dim());
- std::vector<ElemType> minG1(maxG1.size());
- std::vector<ElemType> maxG2(maxG1.size());
- std::vector<ElemType> minG2(maxG1.size());
+ BoundType bound1(tree->Bound().Dim());
+ BoundType bound2(tree->Bound().Dim());
- for (size_t k = 0; k < tree->Bound().Dim(); k++)
- {
- minG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Lo();
- maxG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Hi();
- minG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Lo();
- maxG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Hi();
-
- for (size_t l = 1; l < tree->NumChildren() - 1; l++)
- {
- if (l < cutOff)
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG1[k])
- minG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG1[k])
- maxG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- else
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG2[k])
- minG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG2[k])
- maxG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- }
- }
+ for (size_t l = 0; l < cutOff; l++)
+ bound1 |= tree->Child(sorted[l].second).Bound();
- ElemType area1 = 1.0, area2 = 1.0;
- ElemType oArea = 1.0;
+ for (size_t l = cutOff; l < tree->NumChildren(); l++)
+ bound2 |= tree->Child(sorted[l].second).Bound();
- for (size_t k = 0; k < maxG1.size(); k++)
- {
- margins[i] += maxG1[k] - minG1[k] + maxG2[k] - minG2[k];
- area1 *= maxG1[k] - minG1[k];
- area2 *= maxG2[k] - minG2[k];
- oArea *= (maxG1[k] < minG2[k] || maxG2[k] < minG1[k]) ? 0.0 :
- (std::min(maxG1[k], maxG2[k]) - std::max(minG1[k], minG2[k]));
- }
+ ElemType area1 = bound1.Volume();
+ ElemType area2 = bound2.Volume();
+ ElemType oArea = bound1.Overlap(bound2);
+
+ for (size_t k = 0; k < bound1.Dim(); k++)
+ margins[i] += bound1[k].Width() + bound2[k].Width();
areas[i] += area1 + area2;
overlapedAreas[i] += oArea;
@@ -594,25 +538,30 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
}
}
- std::vector<SortStruct<ElemType>> sorted(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->NumChildren());
if (lowIsBest)
{
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[bestAxis].Lo();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[bestAxis].Lo();
+ sorted[i].second = i;
}
}
else
{
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[bestAxis].Hi();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[bestAxis].Hi();
+ sorted[i].second = i;
}
}
- std::sort(sorted.begin(), sorted.end(), StructComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
TreeType* treeOne = new TreeType(tree->Parent());
TreeType* treeTwo = new TreeType(tree->Parent());
@@ -622,9 +571,9 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
for (size_t i = 0; i < tree->NumChildren(); i++)
{
if (i < bestAreaIndexOnBestAxis + tree->MinNumChildren())
- InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].second]);
else
- InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].second]);
}
}
else
@@ -632,9 +581,9 @@ bool RStarTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
for (size_t i = 0; i < tree->NumChildren(); i++)
{
if (i < bestOverlapIndexOnBestAxis + tree->MinNumChildren())
- InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].second]);
else
- InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].second]);
}
}
diff --git a/src/mlpack/core/tree/rectangle_tree/x_tree_split.hpp b/src/mlpack/core/tree/rectangle_tree/x_tree_split.hpp
index 3028df1..e859b36 100644
--- a/src/mlpack/core/tree/rectangle_tree/x_tree_split.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/x_tree_split.hpp
@@ -91,27 +91,6 @@ class XTreeSplit
SplitHistoryStruct splitHistory;
/**
- * Class to allow for faster sorting.
- */
- template<typename ElemType>
- class sortStruct
- {
- public:
- ElemType d;
- int n;
- };
-
- /**
- * Comparator for sorting with sortStruct.
- */
- template<typename ElemType>
- static bool structComp(const sortStruct<ElemType>& s1,
- const sortStruct<ElemType>& s2)
- {
- return s1.d < s2.d;
- }
-
- /**
* Insert a node into another node.
*/
static void InsertNodeIntoTree(TreeType* destTree, TreeType* srcNode);
diff --git a/src/mlpack/core/tree/rectangle_tree/x_tree_split_impl.hpp b/src/mlpack/core/tree/rectangle_tree/x_tree_split_impl.hpp
index 79b7cc8..2865fc5 100644
--- a/src/mlpack/core/tree/rectangle_tree/x_tree_split_impl.hpp
+++ b/src/mlpack/core/tree/rectangle_tree/x_tree_split_impl.hpp
@@ -59,6 +59,7 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
{
// Convenience typedef.
typedef typename TreeType::ElemType ElemType;
+ typedef bound::HRectBound<metric::EuclideanDistance, ElemType> BoundType;
// 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
@@ -95,23 +96,29 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
return;
}
- std::vector<sortStruct<ElemType>> sorted(tree->Count());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->Count());
arma::Col<ElemType> center;
tree->Bound().Center(center); // Modifies centroid.
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Metric().Evaluate(center,
+ sorted[i].first = tree->Metric().Evaluate(center,
tree->LocalDataset().col(i));
- sorted[i].n = i;
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), structComp<ElemType>);
- std::vector<int> pointIndices(p);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
+ std::vector<size_t> pointIndices(p);
+
for (size_t i = 0; i < p; i++)
{
// We start from the end of sorted.
- pointIndices[i] = tree->Points()[sorted[sorted.size() - 1 - i].n];
- root->DeletePoint(tree->Points()[sorted[sorted.size() - 1 - i].n],
+ pointIndices[i] = tree->Points()[sorted[sorted.size() - 1 - i].second];
+ root->DeletePoint(tree->Points()[sorted[sorted.size() - 1 - i].second],
relevels);
}
@@ -145,13 +152,18 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
{
ElemType axisScore = 0.0;
// Since we only have points in the leaf nodes, we only need to sort once.
- std::vector<sortStruct<ElemType>> sorted(tree->Count());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->Count());
for (size_t i = 0; i < sorted.size(); i++) {
- sorted[i].d = tree->LocalDataset().col(i)[j];
- sorted[i].n = i;
+ sorted[i].first = tree->LocalDataset().col(i)[j];
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), structComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
// We'll store each of the three scores for each distribution.
std::vector<ElemType> areas(tree->MaxLeafSize() -
@@ -173,46 +185,23 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
// another. Then we calculate the three scores for that distribution.
size_t cutOff = tree->MinLeafSize() + i;
- // We'll calculate the max and min in each dimension by hand to save time.
- std::vector<ElemType> maxG1(tree->Bound().Dim());
- std::vector<ElemType> minG1(maxG1.size());
- std::vector<ElemType> maxG2(maxG1.size());
- std::vector<ElemType> minG2(maxG1.size());
- for (size_t k = 0; k < tree->Bound().Dim(); k++)
- {
- minG1[k] = maxG1[k] = tree->LocalDataset().col(sorted[0].n)[k];
- minG2[k] = maxG2[k] = tree->LocalDataset().col(
- sorted[sorted.size() - 1].n)[k];
- for (size_t l = 1; l < tree->Count() - 1; l++)
- {
- if (l < cutOff)
- {
- if (tree->LocalDataset().col(sorted[l].n)[k] < minG1[k])
- minG1[k] = tree->LocalDataset().col(sorted[l].n)[k];
- else if (tree->LocalDataset().col(sorted[l].n)[k] > maxG1[k])
- maxG1[k] = tree->LocalDataset().col(sorted[l].n)[k];
- }
- else
- {
- if (tree->LocalDataset().col(sorted[l].n)[k] < minG2[k])
- minG2[k] = tree->LocalDataset().col(sorted[l].n)[k];
- else if (tree->LocalDataset().col(sorted[l].n)[k] > maxG2[k])
- maxG2[k] = tree->LocalDataset().col(sorted[l].n)[k];
- }
- }
- }
+ BoundType bound1(tree->Bound().Dim());
+ BoundType bound2(tree->Bound().Dim());
+
+ for (size_t l = 0; l < cutOff; l++)
+ bound1 |= tree->LocalDataset().col(sorted[l].second);
+
+ for (size_t l = cutOff; l < tree->Count(); l++)
+ bound2 |= tree->LocalDataset().col(sorted[l].second);
+
+ ElemType area1 = bound1.Volume();
+ ElemType area2 = bound2.Volume();
+ ElemType oArea = bound1.Overlap(bound2);
+
+ for (size_t k = 0; k < bound1.Dim(); k++)
+ margins[i] += bound1[k].Width() + bound2[k].Width();
- ElemType area1 = 1.0, area2 = 1.0;
- ElemType oArea = 1.0;
- for (size_t k = 0; k < maxG1.size(); k++)
- {
- margins[i] += maxG1[k] - minG1[k] + maxG2[k] - minG2[k];
- area1 *= maxG1[k] - minG1[k];
- area2 *= maxG2[k] - minG2[k];
- oArea *= ((maxG1[k] < minG2[k]) || (maxG2[k] < minG1[k])) ? 0.0 :
- std::min(maxG1[k], maxG2[k]) - std::max(minG1[k], minG2[k]);
- }
areas[i] += area1 + area2;
overlapedAreas[i] += oArea;
axisScore += margins[i];
@@ -243,14 +232,19 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
}
}
- std::vector<sortStruct<ElemType>> sorted(tree->Count());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->Count());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->LocalDataset().col(i)[bestAxis];
- sorted[i].n = i;
+ sorted[i].first = tree->LocalDataset().col(i)[bestAxis];
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), structComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
TreeType* treeOne = new TreeType(tree->Parent(), NormalNodeMaxNumChildren());
TreeType* treeTwo = new TreeType(tree->Parent(), NormalNodeMaxNumChildren());
@@ -263,9 +257,9 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
for (size_t i = 0; i < tree->Count(); i++)
{
if (i < bestAreaIndexOnBestAxis + tree->MinLeafSize())
- treeOne->InsertPoint(tree->Points()[sorted[i].n]);
+ treeOne->InsertPoint(tree->Points()[sorted[i].second]);
else
- treeTwo->InsertPoint(tree->Points()[sorted[i].n]);
+ treeTwo->InsertPoint(tree->Points()[sorted[i].second]);
}
}
else
@@ -273,9 +267,9 @@ void XTreeSplit<TreeType>::SplitLeafNode(TreeType* tree,
for (size_t i = 0; i < tree->Count(); i++)
{
if (i < bestOverlapIndexOnBestAxis + tree->MinLeafSize())
- treeOne->InsertPoint(tree->Points()[sorted[i].n]);
+ treeOne->InsertPoint(tree->Points()[sorted[i].second]);
else
- treeTwo->InsertPoint(tree->Points()[sorted[i].n]);
+ treeTwo->InsertPoint(tree->Points()[sorted[i].second]);
}
}
@@ -331,6 +325,7 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
{
// Convenience typedef.
typedef typename TreeType::ElemType ElemType;
+ typedef bound::HRectBound<metric::EuclideanDistance, ElemType> BoundType;
// 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
@@ -413,14 +408,19 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
ElemType axisScore = 0.0;
// We'll do Bound().Lo() now and use Bound().Hi() later.
- std::vector<sortStruct<ElemType>> sorted(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->NumChildren());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[j].Lo();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[j].Lo();
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), structComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
// We'll store each of the three scores for each distribution.
std::vector<ElemType> areas(tree->MaxNumChildren() -
@@ -443,48 +443,23 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
// another. Then we calculate the three scores for that distribution.
size_t cutOff = tree->MinNumChildren() + i;
- // We'll calculate the max and min in each dimension by hand to save time.
- std::vector<ElemType> maxG1(tree->Bound().Dim());
- std::vector<ElemType> minG1(maxG1.size());
- std::vector<ElemType> maxG2(maxG1.size());
- std::vector<ElemType> minG2(maxG1.size());
- for (size_t k = 0; k < tree->Bound().Dim(); k++)
- {
- minG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Lo();
- maxG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Hi();
- minG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Lo();
- maxG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Hi();
- for (size_t l = 1; l < tree->NumChildren() - 1; l++)
- {
- if (l < cutOff)
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG1[k])
- minG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG1[k])
- maxG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- else
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG2[k])
- minG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG2[k])
- maxG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- }
- }
- ElemType area1 = 1.0, area2 = 1.0;
- ElemType oArea = 1.0;
- for (size_t k = 0; k < maxG1.size(); k++)
- {
- margins[i] += maxG1[k] - minG1[k] + maxG2[k] - minG2[k];
- area1 *= maxG1[k] - minG1[k];
- area2 *= maxG2[k] - minG2[k];
- oArea *= ((maxG1[k] < minG2[k]) || (maxG2[k] < minG1[k])) ? 0.0 :
- std::min(maxG1[k], maxG2[k]) - std::max(minG1[k], minG2[k]);
- }
+ BoundType bound1(tree->Bound().Dim());
+ BoundType bound2(tree->Bound().Dim());
+
+ for (size_t l = 0; l < cutOff; l++)
+ bound1 |= tree->Child(sorted[l].second).Bound();
+
+ for (size_t l = cutOff; l < tree->NumChildren(); l++)
+ bound2 |= tree->Child(sorted[l].second).Bound();
+
+ ElemType area1 = bound1.Volume();
+ ElemType area2 = bound2.Volume();
+ ElemType oArea = bound1.Overlap(bound2);
+
+ for (size_t k = 0; k < bound1.Dim(); k++)
+ margins[i] += bound1[k].Width() + bound2[k].Width();
+
areas[i] += area1 + area2;
overlapedAreas[i] += oArea;
axisScore += margins[i];
@@ -543,15 +518,19 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
{
ElemType axisScore = 0.0;
- // We'll do Bound().Lo() now and use Bound().Hi() later.
- std::vector<sortStruct<ElemType>> sorted(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->NumChildren());
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[j].Hi();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[j].Hi();
+ sorted[i].second = i;
}
- std::sort(sorted.begin(), sorted.end(), structComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
// We'll store each of the three scores for each distribution.
std::vector<ElemType> areas(tree->MaxNumChildren() -
@@ -574,48 +553,23 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
// another. Then we calculate the three scores for that distribution.
size_t cutOff = tree->MinNumChildren() + i;
- // We'll calculate the max and min in each dimension by hand to save time.
- std::vector<ElemType> maxG1(tree->Bound().Dim());
- std::vector<ElemType> minG1(maxG1.size());
- std::vector<ElemType> maxG2(maxG1.size());
- std::vector<ElemType> minG2(maxG1.size());
- for (size_t k = 0; k < tree->Bound().Dim(); k++)
- {
- minG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Lo();
- maxG1[k] = tree->Children()[sorted[0].n]->Bound()[k].Hi();
- minG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Lo();
- maxG2[k] =
- tree->Children()[sorted[sorted.size() - 1].n]->Bound()[k].Hi();
- for (size_t l = 1; l < tree->NumChildren() - 1; l++)
- {
- if (l < cutOff)
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG1[k])
- minG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG1[k])
- maxG1[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- else
- {
- if (tree->Children()[sorted[l].n]->Bound()[k].Lo() < minG2[k])
- minG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Lo();
- else if (tree->Children()[sorted[l].n]->Bound()[k].Hi() > maxG2[k])
- maxG2[k] = tree->Children()[sorted[l].n]->Bound()[k].Hi();
- }
- }
- }
- ElemType area1 = 1.0, area2 = 1.0;
- ElemType oArea = 1.0;
- for (size_t k = 0; k < maxG1.size(); k++)
- {
- margins[i] += maxG1[k] - minG1[k] + maxG2[k] - minG2[k];
- area1 *= maxG1[k] - minG1[k];
- area2 *= maxG2[k] - minG2[k];
- oArea *= ((maxG1[k] < minG2[k]) || (maxG2[k] < minG1[k])) ? 0.0 :
- std::min(maxG1[k], maxG2[k]) - std::max(minG1[k], minG2[k]);
- }
+ BoundType bound1(tree->Bound().Dim());
+ BoundType bound2(tree->Bound().Dim());
+
+ for (size_t l = 0; l < cutOff; l++)
+ bound1 |= tree->Child(sorted[l].second).Bound();
+
+ for (size_t l = cutOff; l < tree->NumChildren(); l++)
+ bound2 |= tree->Child(sorted[l].second).Bound();
+
+ ElemType area1 = bound1.Volume();
+ ElemType area2 = bound2.Volume();
+ ElemType oArea = bound1.Overlap(bound2);
+
+ for (size_t k = 0; k < bound1.Dim(); k++)
+ margins[i] += bound1[k].Width() + bound2[k].Width();
+
areas[i] += area1 + area2;
overlapedAreas[i] += oArea;
@@ -672,25 +626,30 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
}
}
- std::vector<sortStruct<ElemType>> sorted(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted(tree->NumChildren());
if (lowIsBest)
{
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[bestAxis].Lo();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[bestAxis].Lo();
+ sorted[i].second = i;
}
}
else
{
for (size_t i = 0; i < sorted.size(); i++)
{
- sorted[i].d = tree->Children()[i]->Bound()[bestAxis].Hi();
- sorted[i].n = i;
+ sorted[i].first = tree->Children()[i]->Bound()[bestAxis].Hi();
+ sorted[i].second = i;
}
}
- std::sort(sorted.begin(), sorted.end(), structComp<ElemType>);
+ std::sort(sorted.begin(), sorted.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
TreeType* treeOne = new TreeType(tree->Parent(), tree->MaxNumChildren());
TreeType* treeTwo = new TreeType(tree->Parent(), tree->MaxNumChildren());
@@ -704,9 +663,9 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
for (size_t i = 0; i < tree->NumChildren(); i++)
{
if (i < bestAreaIndexOnBestAxis + tree->MinNumChildren())
- InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].second]);
else
- InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].second]);
}
}
else
@@ -719,9 +678,9 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
for (size_t i = 0; i < tree->NumChildren(); i++)
{
if (i < bestOverlapIndexOnBestAxis + tree->MinNumChildren())
- InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].second]);
else
- InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].second]);
}
}
else
@@ -737,30 +696,36 @@ bool XTreeSplit<TreeType>::SplitNonLeafNode(TreeType* tree,
if ((minOverlapSplitDimension != tree->Bound().Dim()) &&
(bestScoreMinOverlapSplit / areaOfBestMinOverlapSplit < MAX_OVERLAP))
{
- std::vector<sortStruct<ElemType>> sorted2(tree->NumChildren());
+ std::vector<std::pair<ElemType, size_t>> sorted2(tree->NumChildren());
if (minOverlapSplitUsesHi)
{
for (size_t i = 0; i < sorted2.size(); i++)
{
- sorted2[i].d = tree->Children()[i]->Bound()[bestAxis].Hi();
- sorted2[i].n = i;
+ sorted2[i].first = tree->Children()[i]->Bound()[bestAxis].Hi();
+ sorted2[i].second = i;
}
}
else
{
for (size_t i = 0; i < sorted2.size(); i++)
{
- sorted2[i].d = tree->Children()[i]->Bound()[bestAxis].Lo();
- sorted2[i].n = i;
+ sorted2[i].first = tree->Children()[i]->Bound()[bestAxis].Lo();
+ sorted2[i].second = i;
}
}
- std::sort(sorted2.begin(), sorted2.end(), structComp<ElemType>);
+ std::sort(sorted2.begin(), sorted2.end(),
+ [] (const std::pair<ElemType, size_t>& p1,
+ const std::pair<ElemType, size_t>& p2)
+ {
+ return p1.first < p2.first;
+ });
+
for (size_t i = 0; i < tree->NumChildren(); i++)
{
if (i < bestIndexMinOverlapSplit + tree->MinNumChildren())
- InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeOne, tree->Children()[sorted[i].second]);
else
- InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].n]);
+ InsertNodeIntoTree(treeTwo, tree->Children()[sorted[i].second]);
}
}
else
--
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