[mlpack-svn] r10877 - mlpack/trunk/src/mlpack/core/tree
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Sat Dec 17 02:07:12 EST 2011
Author: rcurtin
Date: 2011-12-17 02:07:12 -0500 (Sat, 17 Dec 2011)
New Revision: 10877
Modified:
mlpack/trunk/src/mlpack/core/tree/ballbound_impl.hpp
Log:
Implement operator|= correctly.
Modified: mlpack/trunk/src/mlpack/core/tree/ballbound_impl.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/tree/ballbound_impl.hpp 2011-12-17 07:06:02 UTC (rev 10876)
+++ mlpack/trunk/src/mlpack/core/tree/ballbound_impl.hpp 2011-12-17 07:07:12 UTC (rev 10877)
@@ -19,7 +19,10 @@
template<typename VecType>
math::Range BallBound<VecType>::operator[](const size_t i) const
{
- return math::Range(center[i] - radius, center[i] + radius);
+ if (radius < 0)
+ return math::Range();
+ else
+ return math::Range(center[i] - radius, center[i] + radius);
}
/**
@@ -28,7 +31,10 @@
template<typename VecType>
bool BallBound<VecType>::Contains(const VecType& point) const
{
- return metric::EuclideanDistance::Evaluate(center, point) <= radius;
+ if (radius < 0)
+ return false;
+ else
+ return metric::EuclideanDistance::Evaluate(center, point) <= radius;
}
/**
@@ -50,8 +56,11 @@
template<typename VecType>
double BallBound<VecType>::MinDistance(const VecType& point) const
{
- return math::ClampNonNegative(metric::EuclideanDistance::Evaluate(point,
- center) - radius);
+ if (radius < 0)
+ return DBL_MAX;
+ else
+ return math::ClampNonNegative(metric::EuclideanDistance::Evaluate(point,
+ center) - radius);
}
/**
@@ -60,9 +69,14 @@
template<typename VecType>
double BallBound<VecType>::MinDistance(const BallBound& other) const
{
- double delta = metric::EuclideanDistance::Evaluate(center, other.center)
- - radius - other.radius;
- return math::ClampNonNegative(delta);
+ if (radius < 0)
+ return DBL_MAX;
+ else
+ {
+ double delta = metric::EuclideanDistance::Evaluate(center, other.center)
+ - radius - other.radius;
+ return math::ClampNonNegative(delta);
+ }
}
/**
@@ -71,7 +85,10 @@
template<typename VecType>
double BallBound<VecType>::MaxDistance(const VecType& point) const
{
- return metric::EuclideanDistance::Evaluate(point, center) + radius;
+ if (radius < 0)
+ return DBL_MAX;
+ else
+ return metric::EuclideanDistance::Evaluate(point, center) + radius;
}
/**
@@ -80,8 +97,11 @@
template<typename VecType>
double BallBound<VecType>::MaxDistance(const BallBound& other) const
{
- return metric::EuclideanDistance::Evaluate(other.center, center) + radius
- + other.radius;
+ if (radius < 0)
+ return DBL_MAX;
+ else
+ return metric::EuclideanDistance::Evaluate(other.center, center) + radius
+ + other.radius;
}
/**
@@ -93,19 +113,29 @@
math::Range BallBound<VecType>::RangeDistance(const VecType& point)
const
{
- double dist = metric::EuclideanDistance::Evaluate(center, point);
- return math::Range(math::ClampNonNegative(dist - radius),
- dist + radius);
+ if (radius < 0)
+ return math::Range(DBL_MAX, DBL_MAX);
+ else
+ {
+ double dist = metric::EuclideanDistance::Evaluate(center, point);
+ return math::Range(math::ClampNonNegative(dist - radius),
+ dist + radius);
+ }
}
template<typename VecType>
math::Range BallBound<VecType>::RangeDistance(
const BallBound& other) const
{
- double dist = metric::EuclideanDistance::Evaluate(center, other.center);
- double sumradius = radius + other.radius;
- return math::Range(math::ClampNonNegative(dist - sumradius),
- dist + sumradius);
+ if (radius < 0)
+ return math::Range(DBL_MAX, DBL_MAX);
+ else
+ {
+ double dist = metric::EuclideanDistance::Evaluate(center, other.center);
+ double sumradius = radius + other.radius;
+ return math::Range(math::ClampNonNegative(dist - sumradius),
+ dist + sumradius);
+ }
}
/**
@@ -131,13 +161,31 @@
template<typename VecType>
template<typename MatType>
const BallBound<VecType>&
-BallBound<VecType>::operator|=(const MatType& point)
+BallBound<VecType>::operator|=(const MatType& data)
{
- double dist = metric::EuclideanDistance::Evaluate(center, point);
+ if (radius < 0)
+ {
+ center = data.col(0);
+ radius = 0;
+ }
- if (dist > radius)
- radius = dist;
+ // Now iteratively add points. There is probably a closed-form solution to
+ // find the minimum bounding circle, and it is probably faster.
+ for (size_t i = 1; i < data.n_cols; ++i)
+ {
+ double dist = metric::EuclideanDistance::Evaluate(center, (VecType)
+ data.col(i)) - radius;
+ if (dist > 0)
+ {
+ // Move (dist / 2) towards the new point and increase radius by
+ // (dist / 2).
+ arma::vec diff = data.col(i) - center;
+ center += 0.5 * diff;
+ radius += 0.5 * dist;
+ }
+ }
+
return *this;
}
More information about the mlpack-svn
mailing list