Move metrics to distances/ and dists to distributions/. And adapt... everything.
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# The DistanceType policy in mlpack
|
||||
|
||||
Many machine learning methods operate with some sort of distance metric, and
|
||||
often, this distance metric can be any arbitrary distance metric. For instance,
|
||||
consider the problem of nearest neighbor search; one can find the nearest
|
||||
neighbor of a point with respect to the standard Euclidean distance, or the
|
||||
Manhattan (city-block) distance. The actual search techniques, though, remain
|
||||
the same. And this is true of many machine learning methods: the specific
|
||||
distance metric that is used can be any valid distance metric.
|
||||
|
||||
mlpack algorithms, when relevant, allow the use of an arbitrary metric via the
|
||||
use of the `DistanceType` template parameter. Any distance metric passed as a
|
||||
`DistanceType` template parameter will need to have
|
||||
|
||||
- an `Evaluate()` function
|
||||
- a default constructor.
|
||||
|
||||
The signature of the `Evaluate()` function is straightforward:
|
||||
|
||||
```c++
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double Evaluate(const VecTypeA& a, const VecTypeB& b);
|
||||
```
|
||||
|
||||
The function takes two vector arguments, `a` and `b`, and returns a `double`
|
||||
that is the evaluation of the distance metric between the two arguments. So,
|
||||
for a particular distance metric `d`, the `Evaluate()` function should return
|
||||
`d(a, b)`.
|
||||
|
||||
The arguments `a` and `b`, of types `VecTypeA` and `VecTypeB`, respectively,
|
||||
will be an Armadillo-like vector type (usually `arma::vec`, `arma::sp_vec`, or
|
||||
similar). In general it should be valid to assume that `VecTypeA` is a class
|
||||
with the same API as `arma::vec`.
|
||||
|
||||
Note that for distance metrics that do not hold any state, the `Evaluate()`
|
||||
method can be marked as `static`.
|
||||
|
||||
Overall, the `DistanceType` template policy is quite simple (much like the
|
||||
[KernelType policy](kernels.md)). Below is an example distance metric class,
|
||||
which implements the L2 distance:
|
||||
|
||||
```c++
|
||||
class ExampleDistance
|
||||
{
|
||||
// Default constructor is required.
|
||||
ExampleDistance() { }
|
||||
|
||||
// The example metric holds no state, so we can mark Evaluate() as static.
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
static double Evaluate(const VecTypeA& a, const VecTypeB& b)
|
||||
{
|
||||
// Return the L2 norm of the difference between the points, which is the
|
||||
// same as the L2 distance.
|
||||
return arma::norm(a - b);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Then, this distance metric can easily be used inside of other mlpack algorithms.
|
||||
For example, the code below runs range search on a random dataset with the
|
||||
`ExampleDistance`, by instantiating a `RangeSearch` object that uses the
|
||||
`ExampleDistance`. Then, the number of results are printed. The `RangeSearch`
|
||||
class takes three template parameters: `DistanceType`, `MatType`, and
|
||||
`TreeType`. (All three have defaults, so we will just leave `MatType` and
|
||||
`TreeType` to their defaults.)
|
||||
|
||||
```c++
|
||||
#include <mlpack.hpp>
|
||||
#include "example_distance.hpp" // A file that contains ExampleDistance.
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Create a random dataset with 10 dimensions and 5000 points.
|
||||
arma::mat data = arma::randu<arma::mat>(10, 5000);
|
||||
|
||||
// Instantiate the RangeSearch object with the ExampleDistance.
|
||||
RangeSearch<ExampleDistance> rs(data);
|
||||
|
||||
// These vectors will store the results.
|
||||
vector<vector<size_t>> neighbors;
|
||||
vector<vector<double>> distances;
|
||||
|
||||
// Create a random 10-dimensional query point.
|
||||
arma::vec query = arma::randu<arma::vec>(10);
|
||||
|
||||
// Find those points with distance (according to ExampleDistance) between 1
|
||||
// and 2 from the query point.
|
||||
rs.Search(query, Range(1.0, 2.0), neighbors, distances);
|
||||
|
||||
// Now, print the number of points inside the desired range. We know that
|
||||
// neighbors and distances will have length 1, since there was only one query
|
||||
// point.
|
||||
cout << neighbors[0].size() << " points within the range [1.0, 2.0] of the "
|
||||
<< "query point!" << endl;
|
||||
}
|
||||
```
|
||||
|
||||
mlpack comes with a number of pre-written distance metrics that satisfy the
|
||||
`DistanceType` policy:
|
||||
|
||||
<!-- TODO: link to the core.md documentation -->
|
||||
|
||||
- `ManhattanDistance`
|
||||
- `EuclideanDistance`
|
||||
- `ChebyshevDistance`
|
||||
- `MahalanobisDistance`
|
||||
- `LMetric` (for arbitrary L-metrics)
|
||||
- `IPMetric` (requires a [KernelType](kernels.md) parameter)
|
||||
@@ -16,7 +16,7 @@ including
|
||||
|
||||
mlpack implements a number of kernel methods and, accordingly, each of these
|
||||
methods allows arbitrary kernels to be used via the `KernelType` template
|
||||
parameter. Like the [MetricType policy](metrics.md), the requirements are
|
||||
parameter. Like the [DistanceType policy](distances.md), the requirements are
|
||||
quite simple: a class implementing the `KernelType` policy must have
|
||||
|
||||
- an `Evaluate()` function
|
||||
@@ -42,7 +42,7 @@ Note that for kernels that do not hold any state, the `Evaluate()` method can be
|
||||
marked as `static`.
|
||||
|
||||
Overall, the `KernelType` template policy is quite simple (much like the
|
||||
[MetricType policy](metrics.md)). Below is an example kernel class, which
|
||||
[DistanceType policy](distances.md)). Below is an example kernel class, which
|
||||
outputs `1` if the vectors are close and `0` otherwise.
|
||||
|
||||
```c++
|
||||
@@ -149,4 +149,4 @@ These kernels (or a custom kernel) may be used in a variety of mlpack methods:
|
||||
- `KernelPCA` - kernel principal components analysis
|
||||
- `FastMKS` - fast max-kernel search
|
||||
- `NystroemMethod` - the Nystroem method for sampling
|
||||
- `IPMetric` - a metric built on a kernel
|
||||
- `IPMetric` - a distance metric built on a kernel
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
# The MetricType policy in mlpack
|
||||
|
||||
Many machine learning methods operate with some sort of metric, and often, this
|
||||
metric can be any arbitrary metric. For instance, consider the problem of
|
||||
nearest neighbor search; one can find the nearest neighbor of a point with
|
||||
respect to the standard Euclidean distance, or the Manhattan (city-block)
|
||||
distance. The actual search techniques, though, remain the same. And this is
|
||||
true of many machine learning methods: the specific metric that is used can be
|
||||
any valid metric.
|
||||
|
||||
mlpack algorithms, when relevant, allow the use of an arbitrary metric via the
|
||||
use of the `MetricType` template parameter. Any metric passed as a `MetricType`
|
||||
template parameter will need to have
|
||||
|
||||
- an `Evaluate()` function
|
||||
- a default constructor.
|
||||
|
||||
The signature of the `Evaluate()` function is straightforward:
|
||||
|
||||
```c++
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double Evaluate(const VecTypeA& a, const VecTypeB& b);
|
||||
```
|
||||
|
||||
The function takes two vector arguments, `a` and `b`, and returns a `double`
|
||||
that is the evaluation of the metric between the two arguments. So, for a
|
||||
particular metric `d`, the `Evaluate()` function should return `d(a, b)`.
|
||||
|
||||
The arguments `a` and `b`, of types `VecTypeA` and `VecTypeB`, respectively,
|
||||
will be an Armadillo-like vector type (usually `arma::vec`, `arma::sp_vec`, or
|
||||
similar). In general it should be valid to assume that `VecTypeA` is a class
|
||||
with the same API as `arma::vec`.
|
||||
|
||||
Note that for metrics that do not hold any state, the `Evaluate()` method can
|
||||
be marked as `static`.
|
||||
|
||||
Overall, the `MetricType` template policy is quite simple (much like the
|
||||
[KernelType policy](kernels.md)). Below is an example metric class, which
|
||||
implements the L2 distance:
|
||||
|
||||
```c++
|
||||
class ExampleMetric
|
||||
{
|
||||
// Default constructor is required.
|
||||
ExampleMetric() { }
|
||||
|
||||
// The example metric holds no state, so we can mark Evaluate() as static.
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
static double Evaluate(const VecTypeA& a, const VecTypeB& b)
|
||||
{
|
||||
// Return the L2 norm of the difference between the points, which is the
|
||||
// same as the L2 distance.
|
||||
return arma::norm(a - b);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
Then, this metric can easily be used inside of other mlpack algorithms. For
|
||||
example, the code below runs range search on a random dataset with the
|
||||
`ExampleKernel`, by instantiating a `RangeSearch` object that uses the
|
||||
`ExampleKernel`. Then, the number of results are printed. The `RangeSearch`
|
||||
class takes three template parameters: `MetricType`, `MatType`, and `TreeType`.
|
||||
(All three have defaults, so we will just leave `MatType` and `TreeType` to
|
||||
their defaults.)
|
||||
|
||||
```c++
|
||||
#include <mlpack.hpp>
|
||||
#include "example_metric.hpp" // A file that contains ExampleKernel.
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Create a random dataset with 10 dimensions and 5000 points.
|
||||
arma::mat data = arma::randu<arma::mat>(10, 5000);
|
||||
|
||||
// Instantiate the RangeSearch object with the ExampleKernel.
|
||||
RangeSearch<ExampleKernel> rs(data);
|
||||
|
||||
// These vectors will store the results.
|
||||
vector<vector<size_t>> neighbors;
|
||||
vector<vector<double>> distances;
|
||||
|
||||
// Create a random 10-dimensional query point.
|
||||
arma::vec query = arma::randu<arma::vec>(10);
|
||||
|
||||
// Find those points with distance (according to ExampleMetric) between 1 and
|
||||
// 2 from the query point.
|
||||
rs.Search(query, Range(1.0, 2.0), neighbors, distances);
|
||||
|
||||
// Now, print the number of points inside the desired range. We know that
|
||||
// neighbors and distances will have length 1, since there was only one query
|
||||
// point.
|
||||
cout << neighbors[0].size() << " points within the range [1.0, 2.0] of the "
|
||||
<< "query point!" << endl;
|
||||
}
|
||||
```
|
||||
|
||||
mlpack comes with a number of pre-written metrics that satisfy the `MetricType`
|
||||
policy:
|
||||
|
||||
- `ManhattanDistance`
|
||||
- `EuclideanDistance`
|
||||
- `ChebyshevDistance`
|
||||
- `MahalanobisDistance`
|
||||
- `LMetric` (for arbitrary L-metrics)
|
||||
- `IPMetric` (requires a [KernelType](kernels.md) parameter)
|
||||
+65
-63
@@ -89,10 +89,10 @@ parameters, and trees are no exception. In order to ease usage of high-level
|
||||
mlpack algorithms, each `TreeType` itself must be a template class taking three
|
||||
parameters:
|
||||
|
||||
- `MetricType` -- the underlying metric that the tree will be built on (see
|
||||
[the MetricType policy documentation](metrics.md))
|
||||
- `StatisticType` -- holds any auxiliary information that individual
|
||||
algorithms may need
|
||||
- `DistanceType` -- the underlying distance metric that the tree will be built
|
||||
on (see [the DistanceType policy documentation](distances.md))
|
||||
- `StatisticType` -- holds any auxiliary information that individual algorithms
|
||||
may need
|
||||
- `MatType` -- the type of the matrix used to represent the data
|
||||
|
||||
The reason that these three template parameters are necessary is so that each
|
||||
@@ -101,11 +101,11 @@ simplify the required syntax for instantiating mlpack algorithms. By using
|
||||
template template parameters, a user needs only to write
|
||||
|
||||
```c++
|
||||
// The RangeSearch class takes a MetricType and a TreeType template parameter.
|
||||
// The RangeSearch class takes a DistanceType and a TreeType template parameter.
|
||||
|
||||
// This code instantiates RangeSearch with the ManhattanDistance and a
|
||||
// QuadTree. Note that the QuadTree itself is a template, and takes a
|
||||
// MetricType, StatisticType, and MatType, just like the policy requires.
|
||||
// DistanceType, StatisticType, and MatType, just like the policy requires.
|
||||
|
||||
// This example ignores the constructor parameters, for the sake of simplicity.
|
||||
RangeSearch<ManhattanDistance, QuadTree> rs(...);
|
||||
@@ -124,17 +124,18 @@ RangeSearch<ManhattanDistance,
|
||||
Unfortunately, the price to pay for this user convenience is that *every*
|
||||
`TreeType` must have three template parameters, and they must be in exactly
|
||||
that order. Fortunately, there is an additional benefit: we are guaranteed that
|
||||
the tree is built using the same metric as the method (that is, a user can't
|
||||
specify different metric types to the algorithm and to the tree, which they can
|
||||
without template template parameters).
|
||||
the tree is built using the same distance metric as the method (that is, a user
|
||||
can't specify different metric types to the algorithm and to the tree, which
|
||||
they can without template template parameters).
|
||||
|
||||
There are two important notes about this:
|
||||
|
||||
- Not every possible input of `MetricType`, `StatisticType`, and/or `MatType`
|
||||
- Not every possible input of `DistanceType`, `StatisticType`, and/or `MatType`
|
||||
necessarily need to be valid or work correctly for each type of tree. For
|
||||
instance, the `QuadTree` is limited to Euclidean metrics and will not work
|
||||
otherwise. Either compile-time static checks or detailed documentation can
|
||||
help keep users from using invalid combinations of template arguments.
|
||||
instance, the `QuadTree` is limited to Euclidean distance metrics and will
|
||||
not work otherwise. Either compile-time static checks or detailed
|
||||
documentation can help keep users from using invalid combinations of template
|
||||
arguments.
|
||||
|
||||
- Some types of trees have more template parameters than just these three. One
|
||||
example is the generalized binary space tree, where the bounding shape of
|
||||
@@ -150,7 +151,7 @@ There are two important notes about this:
|
||||
```c++
|
||||
// This is the definition of the BinarySpaceTree class, which has five template
|
||||
// parameters.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename BoundType,
|
||||
@@ -160,12 +161,12 @@ class BinarySpaceTree;
|
||||
// The 'using' keyword gives us a template typedef, so we can define the
|
||||
// MeanSplitKDTree template class, which has three parameters and is a valid
|
||||
// TreeType policy class.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using MeanSplitKDTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using MeanSplitKDTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HRectBound<MetricType>
|
||||
MeanSplit<BoundType, MetricType>>;
|
||||
HRectBound<DistanceType>
|
||||
MeanSplit<BoundType, DistanceType>>;
|
||||
```
|
||||
|
||||
Now, the `MeanSplitKDTree` class has only three template parameters and can be
|
||||
@@ -188,7 +189,7 @@ afterwards.)
|
||||
```c++
|
||||
// The three template parameters will be supplied by the user, and are detailed
|
||||
// in the previous section.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType>
|
||||
class ExampleTree
|
||||
@@ -199,12 +200,12 @@ class ExampleTree
|
||||
//////////////////////
|
||||
|
||||
// This batch constructor does not modify the dataset, and builds the entire
|
||||
// tree using a default-constructed MetricType.
|
||||
// tree using a default-constructed DistanceType.
|
||||
ExampleTree(const MatType& data);
|
||||
|
||||
// This batch constructor does not modify the dataset, and builds the entire
|
||||
// tree using the given MetricType.
|
||||
ExampleTree(const MatType& data, MetricType& metric);
|
||||
// tree using the given DistanceType.
|
||||
ExampleTree(const MatType& data, DistanceType& distance);
|
||||
|
||||
// Initialize the tree from a given cereal archive. SFINAE (the
|
||||
// second argument) is necessary to ensure that the archive is loading, not
|
||||
@@ -224,8 +225,8 @@ class ExampleTree
|
||||
// Get the dataset that the tree is built on.
|
||||
const MatType& Dataset();
|
||||
|
||||
// Get the metric that the tree is built with.
|
||||
MetricType& Metric();
|
||||
// Get the distance metric that the tree is built with.
|
||||
DistanceType& Distance();
|
||||
|
||||
// Get/modify the StatisticType for this node.
|
||||
StatisticType& Stat();
|
||||
@@ -364,8 +365,8 @@ a few important points about the implications of this API:
|
||||
Making this all work requires a protected constructor (part of the API) and
|
||||
generally makes it impossible to hold references instead of pointers
|
||||
internally, because if a tree is loaded from a file then it must own the
|
||||
dataset it is built on and the metric it uses (this also means that a
|
||||
destructor must exist for freeing these resources).
|
||||
dataset it is built on and the distance metric it uses (this also means that
|
||||
a destructor must exist for freeing these resources).
|
||||
|
||||
Now, we can consider each part of the API more rigorously.
|
||||
|
||||
@@ -378,24 +379,25 @@ This section is divided into five parts, detailing each of the parts of the API
|
||||
An earlier section discussed the three different template parameters that are
|
||||
required by the `TreeType` policy.
|
||||
|
||||
The [MetricType policy](metrics.md) provides one method that will be useful for
|
||||
tree building and other operations:
|
||||
The [DistanceType policy](distances.md) provides one method that will be useful
|
||||
for tree building and other operations:
|
||||
|
||||
```c++
|
||||
// This function is required by the MetricType policy.
|
||||
// Evaluate the metric between two points (which may be of different types).
|
||||
// This function is required by the DistanceType policy.
|
||||
// Evaluate the distance metric between two points (which may be of different
|
||||
// types).
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double Evaluate(const VecTypeA& a, const VecTypeB& b);
|
||||
```
|
||||
|
||||
Note that this method is not necessarily static, so a `MetricType` object should
|
||||
be held internally and its `Evaluate()` method should be called whenever the
|
||||
distance between two points is required. *It is generally a bad idea to
|
||||
Note that this method is not necessarily static, so a `DistanceType` object
|
||||
should be held internally and its `Evaluate()` method should be called whenever
|
||||
the distance between two points is required. *It is generally a bad idea to
|
||||
hardcode any distance calculation in your tree.* This will make the tree unable
|
||||
to generalize to arbitrary metrics. If your tree must depend on certain
|
||||
assumptions holding about the metric (i.e. the metric is a Euclidean metric),
|
||||
then make that clear in the documentation of the tree, so users do not try to
|
||||
use the tree with an inappropriate metric.
|
||||
to generalize to arbitrary distance metrics. If your tree must depend on
|
||||
certain assumptions holding about the distance metric (i.e. the distance metric
|
||||
is a Euclidean metric), then make that clear in the documentation of the tree,
|
||||
so users do not try to use the tree with an inappropriate distance metric.
|
||||
|
||||
The second template parameter, `StatisticType`, is for auxiliary information
|
||||
that is required by certain algorithms. For instance, consider an algorithm
|
||||
@@ -437,20 +439,20 @@ The first two constructors are variations of the same idea:
|
||||
|
||||
```c++
|
||||
// This batch constructor does not modify the dataset, and builds the entire
|
||||
// tree using a default-constructed MetricType.
|
||||
// tree using a default-constructed DistanceType.
|
||||
ExampleTree(const MatType& data);
|
||||
|
||||
// This batch constructor does not modify the dataset, and builds the entire
|
||||
// tree using the given MetricType.
|
||||
ExampleTree(const MatType& data, MetricType& metric);
|
||||
// tree using the given DistanceType.
|
||||
ExampleTree(const MatType& data, DistanceType& distance);
|
||||
```
|
||||
|
||||
All that is required here is that a constructor is available that takes a
|
||||
dataset and optionally an instantiated metric. If no metric is provided, then
|
||||
it should be assumed that the `MetricType` class has a default constructor and
|
||||
a default-constructed metric should be used. The constructor *must* return a
|
||||
valid, fully-constructed, ready-to-use tree that satisfies the definition
|
||||
of *space tree* that was given earlier in the document.
|
||||
dataset and optionally an instantiated distance metric. If no distance metric
|
||||
is provided, then it should be assumed that the `DistanceType` class has a
|
||||
default constructor and a default-constructed distance metric should be used.
|
||||
The constructor *must* return a valid, fully-constructed, ready-to-use tree that
|
||||
satisfies the definition of *space tree* that was given earlier in the document.
|
||||
|
||||
The third constructor requires the tree to be initializable from a `cereal`
|
||||
archive:
|
||||
@@ -494,9 +496,9 @@ template<typename Archive>
|
||||
ExampleTree(MatType&& data);
|
||||
```
|
||||
|
||||
(and another overload that takes an instantiated metric), and then the user can
|
||||
use `std::move()` to build the tree without copying the data matrix, although
|
||||
the data matrix will be modified:
|
||||
(and another overload that takes an instantiated distance metric), and then the
|
||||
user can use `std::move()` to build the tree without copying the data matrix,
|
||||
although the data matrix will be modified:
|
||||
|
||||
```c++
|
||||
ExampleTree exTree(std::move(dataset));
|
||||
@@ -520,13 +522,13 @@ must store a pointer to the dataset (this is not the only option, but it is the
|
||||
most obvious option).
|
||||
|
||||
```c++
|
||||
// Get the metric that the tree is built with.
|
||||
MetricType& Metric();
|
||||
// Get the distance metric that the tree is built with.
|
||||
DistanceType& Distance();
|
||||
```
|
||||
|
||||
Each node must also store an instantiated metric or a pointer to one (note that
|
||||
this is required even for metrics that have no state and have a `static`
|
||||
`Evaluate()` function).
|
||||
Each node must also store an instantiated distance metric or a pointer to one
|
||||
(note that this is required even for metrics that have no state and have a
|
||||
`static` `Evaluate()` function).
|
||||
|
||||
```c++
|
||||
// Get/modify the StatisticType for this node.
|
||||
@@ -704,7 +706,7 @@ which could be calculated as below:
|
||||
double trueMinDist = DBL_MAX;
|
||||
for (size_t i = 0; i < node.NumDescendants(); ++i)
|
||||
{
|
||||
const double dist = node.Metric().Evaluate(vec,
|
||||
const double dist = node.Distance().Evaluate(vec,
|
||||
node.Dataset().col(node.Descendant(i)));
|
||||
if (dist < trueMinDist)
|
||||
trueMinDist = dist;
|
||||
@@ -716,16 +718,16 @@ for (size_t i = 0; i < node.NumDescendants(); ++i)
|
||||
Often the bounding shape of a node will allow a quick calculation that will make
|
||||
a reasonable bound. For instance, if the node's bounding shape is a ball with
|
||||
radius `r` and center `ctr`, the calculation is simply
|
||||
`(node.Metric().Evaluate(vec, ctr) - r)`. Usually a good `MinDistance()` or
|
||||
`(node.Distance().Evaluate(vec, ctr) - r)`. Usually a good `MinDistance()` or
|
||||
`MaxDistance()` function will make only one call to the `Evaluate()` function of
|
||||
the metric.
|
||||
the distance metric.
|
||||
|
||||
The `RangeDistance()` function allows a way for both bounds to be calculated at
|
||||
once. It is possible to implement this as a call to `MinDistance()` followed by
|
||||
a call to `MaxDistance()`, but this may incur more metric `Evaluate()` calls
|
||||
than necessary. Often calculating both bounds at once can be more efficient and
|
||||
can be done with fewer `Evaluate()` calls than calling both `MinDistance()` and
|
||||
`MaxDistance()`.
|
||||
a call to `MaxDistance()`, but this may incur more distance metric `Evaluate()`
|
||||
calls than necessary. Often calculating both bounds at once can be more
|
||||
efficient and can be done with fewer `Evaluate()` calls than calling both
|
||||
`MinDistance()` and `MaxDistance()`.
|
||||
|
||||
### Serialization
|
||||
|
||||
@@ -799,16 +801,16 @@ class TreeTraits
|
||||
};
|
||||
```
|
||||
|
||||
An example specialization for the `:KDTree` class is given below. Note that
|
||||
An example specialization for the `KDTree` class is given below. Note that
|
||||
`KDTree` is itself a template class (like every class satisfying the `TreeType`
|
||||
policy), so we are specializing to a template parameter.
|
||||
|
||||
```c++
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType>
|
||||
template<>
|
||||
class TreeTraits<KDTree<MetricType, StatisticType, MatType>>
|
||||
class TreeTraits<KDTree<DistanceType, StatisticType, MatType>>
|
||||
{
|
||||
public:
|
||||
// The regions represented by the two children of a node may not overlap.
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ Throughout the codebase, mlpack uses some common template parameter policies.
|
||||
These are documented below.
|
||||
|
||||
* [The `ElemType` policy](developer/elemtype.md): element types for data
|
||||
* [The `MetricType` policy](developer/metrics.md): distance metrics
|
||||
* [The `DistanceType` policy](developer/distances.md): distance metrics
|
||||
* [The `KernelType` policy](developer/kernels.md): kernel functions
|
||||
* [The `TreeType` policy](developer/trees.md): space trees (ball trees,
|
||||
KD-trees, etc.)
|
||||
|
||||
+16
-16
@@ -414,7 +414,7 @@ The `KMeans<>` class also takes three template parameters, which can be
|
||||
modified to change the behavior of the k-means algorithm. There are three
|
||||
template parameters:
|
||||
|
||||
- `MetricType`: controls the distance metric used for clustering (by default,
|
||||
- `DistanceType`: controls the distance metric used for clustering (by default,
|
||||
the squared Euclidean distance is used)
|
||||
- `InitialPartitionPolicy`: the method by which initial clusters are set; by
|
||||
default, `SampleInitialization` is used
|
||||
@@ -445,42 +445,42 @@ how to modify them.
|
||||
|
||||
Most machine learning algorithms in mlpack support modifying the distance
|
||||
metric, and `KMeans<>` is no exception. Similar to `NeighborSearch` (see the
|
||||
"MetricType policy class" section in the
|
||||
"DistanceType policy class" section in the
|
||||
[NeighborSearch tutorial](neighbor_search.md)), any of mlpack's
|
||||
metric classes (found in `mlpack/core/metrics/`) can be given as an argument.
|
||||
The `LMetric` class is a good example implementation.
|
||||
|
||||
A class fulfilling the [MetricType policy](../developer/metrics.md) must
|
||||
A class fulfilling the [DistanceType policy](../developer/distances.md) must
|
||||
provide the following two functions:
|
||||
|
||||
```c++
|
||||
// Empty constructor is required.
|
||||
MetricType();
|
||||
DistanceType();
|
||||
|
||||
// Compute the distance between two points.
|
||||
template<typename VecType>
|
||||
double Evaluate(const VecType& a, const VecType& b);
|
||||
```
|
||||
|
||||
Most of the standard metrics that could be used are stateless and therefore the
|
||||
`Evaluate()` method is implemented statically. However, there are metrics, such
|
||||
as the Mahalanobis distance (`MahalanobisDistance`), that store state. To this
|
||||
end, an instantiated `MetricType` object is stored within the `KMeans` class.
|
||||
The example below shows how to pass an instantiated `MahalanobisDistance` in the
|
||||
constructor.
|
||||
Most of the standard distance metrics that could be used are stateless and
|
||||
therefore the `Evaluate()` method is implemented statically. However, there are
|
||||
metrics, such as the Mahalanobis distance (`MahalanobisDistance`), that store
|
||||
state. To this end, an instantiated `DistanceType` object is stored within the
|
||||
`KMeans` class. The example below shows how to pass an instantiated
|
||||
`MahalanobisDistance` in the constructor.
|
||||
|
||||
```c++
|
||||
// The initialized Mahalanobis distance.
|
||||
extern MahalanobisDistance distance;
|
||||
|
||||
// We keep the default arguments for the maximum number of iterations, but pass
|
||||
// our instantiated metric.
|
||||
// our instantiated distance metric.
|
||||
KMeans<MahalanobisDistance> k(1000, distance);
|
||||
```
|
||||
|
||||
***Note***: While the `MetricType` policy only requires two methods, one of
|
||||
***Note***: While the `DistanceType` policy only requires two methods, one of
|
||||
which is an empty constructor, more can always be added. `MahalanobisDistance`
|
||||
also has constructors with parameters, because it is a stateful metric.
|
||||
also has constructors with parameters, because it is a stateful distance metric.
|
||||
|
||||
### Changing the initial partitioning strategy used for k-means
|
||||
|
||||
@@ -546,7 +546,7 @@ not work very well for most settings. See the documentation for
|
||||
If the `Cluster()` method returns point assignments instead of centroids, then
|
||||
valid initial assignments must be returned for every point in the dataset.
|
||||
|
||||
As with the `MetricType` template parameter, an initialized
|
||||
As with the `DistanceType` template parameter, an initialized
|
||||
`InitialPartitionPolicy` can be passed to the constructor of `KMeans` as a
|
||||
fourth argument.
|
||||
|
||||
@@ -603,12 +603,12 @@ the `LloydStepType` policy:
|
||||
Note that the `LloydStepType` policy is itself a template template parameter,
|
||||
and must accept two template parameters of its own:
|
||||
|
||||
- `MetricType`: the type of metric to use
|
||||
- `DistanceType`: the type of distance metric to use
|
||||
- `MatType`: the type of data matrix to use
|
||||
|
||||
The `LloydStepType` policy also mandates three functions:
|
||||
|
||||
- a constructor: `LloydStepType(const MatType& dataset, MetricType& metric);`
|
||||
- a constructor: `LloydStepType(const MatType& dataset, DistanceType& distance);`
|
||||
- an `Iterate()` function:
|
||||
|
||||
```c++
|
||||
|
||||
@@ -296,13 +296,13 @@ arguments:
|
||||
```c++
|
||||
template<
|
||||
typename SortPolicy = NearestNeighborSort,
|
||||
typename MetricType = EuclideanDistance,
|
||||
typename DistanceType = EuclideanDistance,
|
||||
typename MatType = arma::mat,
|
||||
template<typename TreeMetricType,
|
||||
template<typename TreeDistanceType,
|
||||
typename TreeStatType,
|
||||
typename TreeMatType> class TreeType = KDTree,
|
||||
template<typename RuleType> class TraversalType =
|
||||
TreeType<MetricType, NeighborSearchStat<SortPolicy>,
|
||||
TreeType<DistanceType, NeighborSearchStat<SortPolicy>,
|
||||
MatType>::template DualTreeTraverser>
|
||||
>
|
||||
class NeighborSearch;
|
||||
@@ -341,29 +341,29 @@ The `FurthestNeighborSort` class is another implementation, which is used to
|
||||
create the `KFN` typedef class, which finds the furthest neighbors, as opposed
|
||||
to the nearest neighbors.
|
||||
|
||||
## `MetricType` policy class
|
||||
## `DistanceType` policy class
|
||||
|
||||
The `MetricType` policy class allows the neighbor search to take place in any
|
||||
The `DistanceType` policy class allows the neighbor search to take place in any
|
||||
arbitrary metric space. The `LMetric` class is a good example implementation.
|
||||
A `MetricType` class must provide the following functions:
|
||||
A `DistanceType` class must provide the following functions:
|
||||
|
||||
```c++
|
||||
// Empty constructor is required.
|
||||
MetricType();
|
||||
DistanceType();
|
||||
|
||||
// Compute the distance between two points.
|
||||
template<typename VecType>
|
||||
double Evaluate(const VecType& a, const VecType& b);
|
||||
```
|
||||
|
||||
Internally, the `NeighborSearch` class keeps an instantiated `MetricType` class
|
||||
(which can be given in the constructor). This is useful for a metric like the
|
||||
Mahalanobis distance (`MahalanobisDistance`), which must store state (the
|
||||
covariance matrix). Therefore, you can write a non-static MetricType class and
|
||||
use it seamlessly with `NeighborSearch`.
|
||||
Internally, the `NeighborSearch` class keeps an instantiated `DistanceType` class
|
||||
(which can be given in the constructor). This is useful for a distance metric
|
||||
like the Mahalanobis distance (`MahalanobisDistance`), which must store state
|
||||
(the covariance matrix). Therefore, you can write a non-static DistanceType
|
||||
class and use it seamlessly with `NeighborSearch`.
|
||||
|
||||
For more information on the `MetricType` policy, see the [documentation for
|
||||
`MetricType`](../developer/metrics.md).
|
||||
For more information on the `DistanceType` policy, see the [documentation for
|
||||
`DistanceType`](../developer/distances.md).
|
||||
|
||||
### `MatType` policy class
|
||||
|
||||
|
||||
@@ -311,9 +311,9 @@ Similar to the [`NeighborSearch` class](neighbor_search.md), the `RangeSearch`
|
||||
class is very extensible, having the following template arguments:
|
||||
|
||||
```c++
|
||||
template<typename MetricType = EuclideanDistance,
|
||||
template<typename DistanceType = EuclideanDistance,
|
||||
typename MatType = arma::mat,
|
||||
template<typename TreeMetricType,
|
||||
template<typename TreeDistanceType,
|
||||
typename TreeStatType,
|
||||
typename TreeMatType> class TreeType = KDTree>
|
||||
class RangeSearch;
|
||||
@@ -322,29 +322,29 @@ class RangeSearch;
|
||||
By choosing different components for each of these template classes, a very
|
||||
arbitrary range searching object can be constructed.
|
||||
|
||||
### `MetricType` policy class
|
||||
### `DistanceType` policy class
|
||||
|
||||
The `MetricType` policy class allows the range search to take place in any
|
||||
The `DistanceType` policy class allows the range search to take place in any
|
||||
arbitrary metric space. The `LMetric` class is a good example implementation.
|
||||
A `MetricType` class must provide the following functions:
|
||||
A `DistanceType` class must provide the following functions:
|
||||
|
||||
```c++
|
||||
// Empty constructor is required.
|
||||
MetricType();
|
||||
DistanceType();
|
||||
|
||||
// Compute the distance between two points.
|
||||
template<typename VecType>
|
||||
double Evaluate(const VecType& a, const VecType& b);
|
||||
```
|
||||
|
||||
Internally, the `RangeSearch` class keeps an instantiated `MetricType` class
|
||||
(which can be given in the constructor). This is useful for a metric like the
|
||||
Mahalanobis distance (`MahalanobisDistance`), which must store state (the
|
||||
covariance matrix). Therefore, you can write a non-static `MetricType` class
|
||||
and use it seamlessly with `RangeSearch`.
|
||||
Internally, the `RangeSearch` class keeps an instantiated `DistanceType` class
|
||||
(which can be given in the constructor). This is useful for a distance metric
|
||||
like the Mahalanobis distance (`MahalanobisDistance`), which must store state
|
||||
(the covariance matrix). Therefore, you can write a non-static `DistanceType`
|
||||
class and use it seamlessly with `RangeSearch`.
|
||||
|
||||
See also the [documentation for the `MetricType`
|
||||
policy](../developer/metrics.md).
|
||||
See also the
|
||||
[documentation for the `DistanceType` policy](../developer/distances.md).
|
||||
|
||||
### `MatType` policy class
|
||||
|
||||
|
||||
+427
-103
@@ -6,8 +6,8 @@ classes, each of which are documented on this page.
|
||||
|
||||
* [Core math utilities](#core-math-utilities): utility classes for mathematical
|
||||
purposes
|
||||
* [Distances](#distances): distance metrics for geometric algorithms
|
||||
* [Distributions](#distributions): probability distributions
|
||||
* [Metrics](#metrics): distance metrics for geometric algorithms
|
||||
* [Kernels](#kernels): Mercer kernels for kernel-based algorithms
|
||||
|
||||
## Core math utilities
|
||||
@@ -851,6 +851,432 @@ std::cout << "with label " << shuffledLabels[0] << " and weight "
|
||||
|
||||
---
|
||||
|
||||
## Distances
|
||||
|
||||
mlpack includes a number of distance metrics for its distance-based techniques.
|
||||
These all implement the [same API](../developer/distances.md), providing one
|
||||
`Evaluate()` method, and can be used with a variety of different techniques,
|
||||
including:
|
||||
|
||||
<!-- TODO: better names for each link -->
|
||||
|
||||
* [`NeighborSearch`](/src/mlpack/methods/neighbor_search/neighbor_search.hpp)
|
||||
* [`RangeSearch`](/src/mlpack/methods/range_search/range_search.hpp)
|
||||
* [`LMNN`](/src/mlpack/methods/lmnn/lmnn.hpp)
|
||||
* [`EMST`](/src/mlpack/methods/emst/emst.hpp)
|
||||
* [`NCA`](/src/mlpack/methods/nca/nca.hpp)
|
||||
* [`RANN`](/src/mlpack/methods/rann/rann.hpp)
|
||||
* [`KMeans`](/src/mlpack/methods/kmeans/kmeans.hpp)
|
||||
|
||||
Supported metrics:
|
||||
|
||||
* [`LMetric`](#lmetric): generalized L-metric/Lp-metric, including
|
||||
Manhattan/Euclidean/Chebyshev distances
|
||||
* [`IoUDistance`](#ioudistance): intersection-over-union distance
|
||||
* [`IPMetric<KernelType>`](#ipmetric): inner product metric (e.g. induced
|
||||
metric over a [Mercer kernel](#kernels))
|
||||
* [`MahalanobisDistance`](#mahalanobisdistance): weighted Euclidean distance
|
||||
with weights specified by a covariance matrix
|
||||
* [Implement a custom metric](../developer/distances.md)
|
||||
|
||||
### `LMetric`
|
||||
|
||||
The `LMetric` template class implements a [generalized
|
||||
L-metric](https://en.wikipedia.org/wiki/Lp_space#Definition)
|
||||
(L1-metric, L2-metric, etc.). The class has two template parameters:
|
||||
|
||||
```
|
||||
LMetric<Power, TakeRoot>
|
||||
```
|
||||
|
||||
* `Power` is an `int` representing the type of the metric; e.g., `2` would
|
||||
represent the L2-metric (Euclidean distance).
|
||||
- `Power` must be `1` or greater.
|
||||
- If `Power` is `INT_MAX`, the metric is the L-infinity distance (Chebyshev
|
||||
distance).
|
||||
|
||||
* `TakeRoot` is a `bool` (default `true`) indicating whether the root of the
|
||||
distance should be taken.
|
||||
- If set to `false`, the metric will no longer satisfy the triangle
|
||||
inequality.
|
||||
|
||||
---
|
||||
|
||||
Several convenient typedefs are available:
|
||||
|
||||
* `ManhattanDistance` (defined as `LMetric<1>`)
|
||||
* `EuclideanDistance` (defined as `LMetric<2>`)
|
||||
* `SquaredEuclideanDistance` (defined as `LMetric<2, false>`)
|
||||
* `ChebyshevDistance` (defined as `LMetric<INT_MAX>`)
|
||||
|
||||
---
|
||||
|
||||
The static `Evaluate()` method can be used to compute the distance between two
|
||||
vectors.
|
||||
|
||||
*Note:* The vectors given to `Evaluate()` can have any type so long as the type
|
||||
implements the Armadillo API (e.g. `arma::fvec`, `arma::sp_fvec`, etc.).
|
||||
|
||||
---
|
||||
|
||||
*Example usage:*
|
||||
|
||||
```c++
|
||||
// Create two vectors: [0, 1.0, 5.0] and [1.0, 3.0, 5.0].
|
||||
arma::vec a("0.0 1.0 5.0");
|
||||
arma::vec b("1.0 3.0 5.0");
|
||||
|
||||
const double d1 = mlpack::ManhattanDistance::Evaluate(a, b); // d1 = 3.0
|
||||
const double d2 = mlpack::EuclideanDistance::Evaluate(a, b); // d2 = 2.24
|
||||
const double d3 = mlpack::SquaredEuclideanDistance::Evaluate(a, b); // d3 = 5.0
|
||||
const double d4 = mlpack::ChebyshevDistance::Evaluate(a, b); // d4 = 2.0
|
||||
const double d5 = mlpack::LMetric<4>::Evaluate(a, b); // d5 = 2.03
|
||||
const double d6 = mlpack::LMetric<3, false>::Evaluate(a, b); // d6 = 9.0
|
||||
|
||||
std::cout << "Manhattan distance: " << d1 << "." << std::endl;
|
||||
std::cout << "Euclidean distance: " << d2 << "." << std::endl;
|
||||
std::cout << "Squared Euclidean distance: " << d3 << "." << std::endl;
|
||||
std::cout << "Chebyshev distance: " << d4 << "." << std::endl;
|
||||
std::cout << "L4-distance: " << d5 << "." << std::endl;
|
||||
std::cout << "Cubed L3-distance: " << d6 << "." << std::endl;
|
||||
|
||||
// Compute the distance between two random 10-dimensional vectors in a matrix.
|
||||
arma::mat m(10, 100, arma::fill::randu);
|
||||
|
||||
const double d7 = mlpack::EuclideanDistance::Evaluate(m.col(0), m.col(7));
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Distance between two random vectors: " << d7 << "." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Compute the distance between two 32-bit precision `float` vectors.
|
||||
arma::fvec fa("0.0 1.0 5.0");
|
||||
arma::fvec fb("1.0 3.0 5.0");
|
||||
|
||||
const double d8 = mlpack::EuclideanDistance::Evaluate(fa, fb); // d8 = 2.236
|
||||
|
||||
std::cout << "Euclidean distance (fvec): " << d8 << "." << std::endl;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `IoUDistance`
|
||||
|
||||
The `IoUDistance` class implements the intersection-over-union distance metric,
|
||||
a measure of the overlap between two bounding boxes related to the
|
||||
[Jaccard index](https://en.wikipedia.org/wiki/Jaccard_index).
|
||||
|
||||
For two bounding boxes, the `IoUDistance` is computed as `1 - (area of
|
||||
intersection / area of union)`. If the bounding boxes overlap completely, the
|
||||
distance is 0; if they do not overlap at all, the distance is 1.
|
||||
|
||||
---
|
||||
|
||||
The class has a boolean template parameter `UseCoordinates` that controls how
|
||||
bounding boxes are specified.
|
||||
|
||||
* `IoUDistance<>` (or `IoUDistance<false>`) expects bounding boxes to be
|
||||
provided to the `Evaluate()` as four-element vectors of the form
|
||||
`[x0, y0, h, w]`, where:
|
||||
- `(x0, y0)` is the lower left corner of the bounding box,
|
||||
- `h` is the height of the bounding box, and
|
||||
- `w` is the width of the bounding box.
|
||||
|
||||
* `IoUDistance<true>` expects bounding boxes to be provided to the `Evaluate()`
|
||||
as four-element vectors of the form `[x0, y0, x1, y1]`, where:
|
||||
- `(x0, y0)` is the lower left corner of the bounding box, and
|
||||
- `(x1, y1)` is the upper right corner of the bounding box.
|
||||
|
||||
---
|
||||
|
||||
The static `Evaluate()` method can be used to compute the IoU distance between
|
||||
two bounding boxes.
|
||||
|
||||
If either input vector does not have four elements, an exception will be thrown.
|
||||
|
||||
*Note:* The vectors given to `Evaluate()` can have any type so long as the type
|
||||
implements the Armadillo API (e.g. `arma::vec`, `arma::fvec`, etc.). The use of
|
||||
sparse objects is not recommended to represent bounding boxes (as they are in
|
||||
general not sparse).
|
||||
|
||||
---
|
||||
|
||||
*Example usage:*
|
||||
|
||||
```c++
|
||||
// Create three bounding boxes by representing the lower left and size.
|
||||
arma::vec bb1("0.0 0.0 3.0 5.0"); // Lower left at (0, 0), height=3, width=5.
|
||||
arma::vec bb2("2.0 2.0 5.0 2.0"); // Lower left at (2, 2), height=5, width=2.
|
||||
arma::vec bb3("1.0 1.0 1.5 1.0"); // Lower left at (1, 1), height=1.5, width=1.
|
||||
|
||||
// Represent the same three bounding boxes in lower left/upper right form.
|
||||
arma::vec bb1Coord("0.0 0.0 5.0 3.0"); // Upper right is (5, 3).
|
||||
arma::vec bb2Coord("2.0 2.0 4.0 7.0"); // Upper right is (4, 7).
|
||||
arma::vec bb3Coord("1.0 1.0 2.0 2.5"); // Upper right is (2, 2.5).
|
||||
|
||||
// Compute the distance between each of the bounding boxes using the
|
||||
// height/width representation.
|
||||
const double d1 = mlpack::IoUDistance<>::Evaluate(bb1, bb2);
|
||||
const double d2 = mlpack::IoUDistance<>::Evaluate(bb2, bb3);
|
||||
const double d3 = mlpack::IoUDistance<>::Evaluate(bb1, bb3);
|
||||
|
||||
std::cout << "IoUDistance with width/height bounding box representations:"
|
||||
<< std::endl;
|
||||
std::cout << " - ll=(0, 0), h=3, w=5 and ll=(2, 2), h=5, w=2: " << d1
|
||||
<< "." << std::endl;
|
||||
std::cout << " - ll=(0, 0), h=3, w=5 and ll=(1, 1), h=1.5, w=1: " << d3
|
||||
<< "." << std::endl;
|
||||
std::cout << " - ll=(2, 2), h=5, w=2 and ll=(1, 1), h=1.5, w=1: " << d2
|
||||
<< "." << std::endl;
|
||||
|
||||
// Now compute the same distances with the other representation.
|
||||
const double d1Coord = mlpack::IoUDistance<true>::Evaluate(bb1Coord, bb2Coord);
|
||||
const double d2Coord = mlpack::IoUDistance<true>::Evaluate(bb2Coord, bb3Coord);
|
||||
const double d3Coord = mlpack::IoUDistance<true>::Evaluate(bb1Coord, bb3Coord);
|
||||
|
||||
std::cout << "IoUDistance with two-coordinate bounding box representations:"
|
||||
<< std::endl;
|
||||
std::cout << "(same bounding boxes as above)" << std::endl;
|
||||
std::cout << " - ll=(0, 0), ur=(5, 3) and ll=(2, 2), ur=(4, 7): " << d1Coord
|
||||
<< "." << std::endl;
|
||||
std::cout << " - ll=(0, 0), ur=(5, 3) and ll=(1, 1), ur=(2, 2.5): " << d3Coord
|
||||
<< "." << std::endl;
|
||||
std::cout << " - ll=(2, 2), ur=(4, 7) and ll=(1, 1), ur=(2, 2.5): " << d2Coord
|
||||
<< "." << std::endl;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `IPMetric<KernelType>`
|
||||
|
||||
The `IPMetric<KernelType>` class implements the distance metric induced by the
|
||||
given [`KernelType`](#kernels). This computes distances in
|
||||
[kernel space](https://en.wikipedia.org/wiki/Kernel_method#Mathematics:_the_kernel_trick).
|
||||
Using the fact that a kernel `k(x, y)` (represented by `KernelType`) implements
|
||||
an inner product in kernel space, the `IPMetric` distance is defined as
|
||||
|
||||
```
|
||||
d(x, y) = sqrt(k(x, x) + k(y, y) - 2 k(x, y)).
|
||||
```
|
||||
|
||||
The template parameter `KernelType` can be any of mlpack's [kernels](#kernels),
|
||||
or a [custom kernel](#implement-a-custom-kernel).
|
||||
|
||||
This metric is used by the [FastMKS](/src/mlpack/methods/fastmks/fastmks.hpp)
|
||||
method (fast max-kernel search).
|
||||
|
||||
---
|
||||
|
||||
#### Constructors and properties
|
||||
|
||||
* `d = IPMetric<KernelType>()`
|
||||
- Construct a new `IPMetric` using a default-constructed `KernelType`.
|
||||
- A default constructor for `KernelType` must be available (e.g. `k =
|
||||
KernelType()`).
|
||||
|
||||
* `d = IPMetric<KernelType>(kernel)`
|
||||
- Construct a new `IPMetric` using the given `kernel` (a `KernelType`
|
||||
object).
|
||||
- `kernel` is not copied; ensure that `kernel` does not go out of scope while
|
||||
`d` is in use.
|
||||
|
||||
* `d = IPMetric<KernelType>(other)`
|
||||
- Copy constructor: create a new `IPMetric` from the given `IPMetric`
|
||||
`other`.
|
||||
- This copies the internally-held `KernelType`.
|
||||
|
||||
* The copy operator (`d = other;`) will also copy the internally-held
|
||||
`KernelType`.
|
||||
|
||||
* The internally-held `KernelType` can be accessed with `d.Kernel()`.
|
||||
|
||||
---
|
||||
|
||||
#### Distance evaluation
|
||||
|
||||
* `d.Evaluate(x1, x2)`
|
||||
- Evaluate and return the distance in kernel space between two vectors `x1`
|
||||
and `x2`.
|
||||
- `x1` and `x2` should be vector types that implement the Armadillo API (e.g.
|
||||
`arma::vec`, `arma::sp_vec`, etc.).
|
||||
- `x1` and `x2` must be valid inputs to the `Evaluate()` function of the
|
||||
given `KernelType`.
|
||||
|
||||
---
|
||||
|
||||
*Example usage:*
|
||||
|
||||
```c++
|
||||
// Create a few random points.
|
||||
arma::vec x1(3, arma::fill::randu);
|
||||
arma::vec x2(3, arma::fill::randu);
|
||||
arma::vec x3(3, arma::fill::randu);
|
||||
|
||||
// Create a metric on the Epanechnikov kernel.
|
||||
mlpack::EpanechnikovKernel ek(1.5 /* bandwidth */);
|
||||
mlpack::IPMetric<mlpack::EpanechnikovKernel> ip1(ek);
|
||||
|
||||
// Compute distances in kernel space, and compare with kernel evaluations.
|
||||
std::cout << "x1: " << x1.t();
|
||||
std::cout << "x2: " << x2.t();
|
||||
std::cout << "x3: " << x3.t();
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << " ek(x1, x2): " << ek.Evaluate(x1, x2) << "." << std::endl;
|
||||
std::cout << " ip(x1, x2): " << ip1.Evaluate(x1, x2) << "." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << " ek(x2, x3): " << ek.Evaluate(x2, x3) << "." << std::endl;
|
||||
std::cout << " ip(x2, x3): " << ip1.Evaluate(x2, x3) << "." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << " ek(x1, x3): " << ek.Evaluate(x1, x3) << "." << std::endl;
|
||||
std::cout << " ip(x1, x3): " << ip1.Evaluate(x1, x3) << "." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Now create a metric on the LinearKernel.
|
||||
// This one is a bit of a trick! For the LinearKernel, the induced metric is
|
||||
// exactly the Euclidean distance.
|
||||
mlpack::IPMetric<mlpack::LinearKernel> ip2;
|
||||
|
||||
std::cout << " Euclidean distance between x1/x2: "
|
||||
<< mlpack::EuclideanDistance::Evaluate(x1, x2) << "." << std::endl;
|
||||
std::cout << " IPMetric<LinearKernel> between x1/x2: "
|
||||
<< ip2.Evaluate(x1, x2) << "." << std::endl;
|
||||
|
||||
// Compute the kernel space distance between two floating-point vectors.
|
||||
arma::fvec fx1(10, arma::fill::randu);
|
||||
arma::fvec fx2(10, arma::fill::randu);
|
||||
|
||||
std::cout << "IPMetric<EpanechnikovKernel> result between two random "
|
||||
<< "10-dimensional 32-bit floating point vectors:" << std::endl;
|
||||
std::cout << " " << ip1.Evaluate(fx1, fx2) << "." << std::endl;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `MahalanobisDistance`
|
||||
|
||||
The `MahalanobisDistance` class implements the weighted Euclidean distance known
|
||||
as the
|
||||
[Mahalanobis distance](https://en.wikipedia.org/wiki/Mahalanobis_distance).
|
||||
This distance requires an inverse covariance matrix `Q` that controls the
|
||||
weighting of individual dimensions in the distance calculation. The metric is
|
||||
defined as:
|
||||
|
||||
```
|
||||
d_Q(x, y) = sqrt((x - y)^T Q (x - y))
|
||||
```
|
||||
|
||||
The class has two template parameters:
|
||||
|
||||
```
|
||||
MahalanobisDistance<TakeRoot = true, MatType = arma::mat>
|
||||
```
|
||||
|
||||
* When `TakeRoot` is manually specified as `false`, the `sqrt()` is omitted.
|
||||
This is slightly faster, but will cause the distance to no longer satisfy the
|
||||
triangle inequality.
|
||||
|
||||
* `MatType` is the matrix type used to represent `Q`, and should be a matrix
|
||||
type satisfying the Armadillo API (e.g. `arma::mat`, `arma::fmat`).
|
||||
|
||||
***Notes:***
|
||||
|
||||
- Many descriptions of the Mahalanobis distance use the term `C^-1` instead of
|
||||
`Q` as used here. Ensure that the given `Q` matrix is the inverted
|
||||
covariance (you can use, e.g.,
|
||||
[`arma::pinv()`](https://arma.sourceforge.net/docs.html#pinv)).
|
||||
|
||||
- Instead of using `MahalanobisDistance` directly as a distance metric for
|
||||
mlpack machine learning algorithms, it can often be faster to simply multiply
|
||||
the dataset by the equivalent transformation implied by `Q` and then use that
|
||||
modified dataset with the Euclidean distance directly. See the example usage
|
||||
below.
|
||||
|
||||
---
|
||||
|
||||
#### Constructors and properties
|
||||
|
||||
* `md = MahalanobisDistance()`
|
||||
- Create a `MahalanobisDistance` object without initializing the inverse
|
||||
covariance `Q`.
|
||||
- Call `Q()` to set the matrix before calling `Evaluate()`.
|
||||
|
||||
* `md = MahalanobisDistance(dimensionality)`
|
||||
- Create a `MahalanobisDistance` where `Q` is the identity matrix of the
|
||||
given `dimensionality`.
|
||||
- This distance metric will be equivalent to the Euclidean distance.
|
||||
|
||||
* `md = MahalanobisDistance(matQ)`
|
||||
- Create a `MahalanobisDistance` with the given `Q` matrix.
|
||||
- `matQ` must be positive definite and symmetric.
|
||||
|
||||
* `md.Q()`
|
||||
- Access or modify the `Q` matrix.
|
||||
- For instance, to set the `Q` matrix, `md.Q() = myCustomQ;` can be used.
|
||||
- The `Q` matrix must be positive definite and symmetric.
|
||||
|
||||
---
|
||||
|
||||
#### Distance evaluation
|
||||
|
||||
* `md.Evaluate(x1, x2)`
|
||||
- Evaluate and return the Mahalanobis distance between two vectors `x1` and
|
||||
`x2`.
|
||||
- `x1` and `x2` should be vector types with element type equivalent to the
|
||||
element type of `MatType` (e.g. `arma::vec`, `arma::fvec`, etc.).
|
||||
|
||||
---
|
||||
|
||||
*Example usage:*
|
||||
|
||||
```c++
|
||||
// Create random 10-dimensional data.
|
||||
arma::mat dataset(10, 100, arma::fill::randu);
|
||||
|
||||
// Create a positive-definite Q matrix by using a weighting matrix W such that
|
||||
// Q = W^T W.
|
||||
arma::mat W(10, 10, arma::fill::randu);
|
||||
arma::mat Q = W.t() * W;
|
||||
|
||||
// Create a MahalanobisDistance object with the given Q.
|
||||
mlpack::MahalanobisDistance md(std::move(Q));
|
||||
|
||||
std::cout << "Mahalanobis distance between points 3 and 4: "
|
||||
<< md.Evaluate(dataset.col(3), dataset.col(4)) << "." << std::endl;
|
||||
|
||||
// Now compare the Mahalanobis distance with the Euclidean distance on the
|
||||
// dataset transformed with W. (They are the same!)
|
||||
arma::mat transformedDataset = W * dataset;
|
||||
std::cout << "Mahalanobis distance between points 2 and 71: "
|
||||
<< md.Evaluate(dataset.col(2), dataset.col(71)) << "." << std::endl;
|
||||
std::cout << "Euclidean distance between transformed points 2 and 71: "
|
||||
<< mlpack::EuclideanDistance::Evaluate(transformedDataset.col(2),
|
||||
transformedDataset.col(71))
|
||||
<< "." << std::endl;
|
||||
|
||||
// Create a Mahalanobis distance for 32-bit floating point data.
|
||||
arma::fmat floatDataset(20, 100, arma::fill::randn);
|
||||
|
||||
// Use a random diagonal matrix as Q.
|
||||
arma::fmat fQ = arma::diagmat(arma::randu<arma::fvec>(20));
|
||||
|
||||
mlpack::MahalanobisDistance<false /* do not take square root */,
|
||||
arma::fmat> fmd;
|
||||
fmd.Q() = std::move(fQ);
|
||||
|
||||
const double d1 = fmd.Evaluate(floatDataset.col(3), floatDataset.col(5));
|
||||
const double d2 = fmd.Evaluate(floatDataset.col(11), floatDataset.col(31));
|
||||
|
||||
std::cout << "Squared Mahalanobis distance on 32-bit floating point data:"
|
||||
<< std::endl;
|
||||
std::cout << " - Points 3 and 5: " << d1 << "." << std::endl;
|
||||
std::cout << " - Points 11 and 31: " << d2 << "." << std::endl;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Distributions
|
||||
|
||||
<!-- TODO: link to the completed HMM documentation -->
|
||||
@@ -1130,108 +1556,6 @@ std::cout << "Average probability is: " << arma::mean(probabilities) << "."
|
||||
<< std::endl;
|
||||
```
|
||||
|
||||
## Metrics
|
||||
|
||||
mlpack includes a number of distance metrics for its distance-based techniques.
|
||||
These all implement the [same API](../developer/metrics.md), providing one
|
||||
`Evaluate()` method, and can be used with a variety of different techniques,
|
||||
including:
|
||||
|
||||
<!-- TODO: better names for each link -->
|
||||
|
||||
* [`NeighborSearch`](/src/mlpack/methods/neighbor_search/neighbor_search.hpp)
|
||||
* [`RangeSearch`](/src/mlpack/methods/range_search/range_search.hpp)
|
||||
* [`LMNN`](/src/mlpack/methods/lmnn/lmnn.hpp)
|
||||
* [`EMST`](/src/mlpack/methods/emst/emst.hpp)
|
||||
* [`NCA`](/src/mlpack/methods/nca/nca.hpp)
|
||||
* [`RANN`](/src/mlpack/methods/rann/rann.hpp)
|
||||
* [`KMeans`](/src/mlpack/methods/kmeans/kmeans.hpp)
|
||||
|
||||
Supported metrics:
|
||||
|
||||
* [`LMetric`](#lmetric): generalized L-metric/Lp-metric, including
|
||||
Manhattan/Euclidean/Chebyshev distances
|
||||
* [Implement a custom metric](../developer/metrics.md)
|
||||
|
||||
### `LMetric`
|
||||
|
||||
The `LMetric` template class implements a [generalized
|
||||
L-metric](https://en.wikipedia.org/wiki/Lp_space#Definition)
|
||||
(L1-metric, L2-metric, etc.). The class has two template parameters:
|
||||
|
||||
```
|
||||
LMetric<Power, TakeRoot>
|
||||
```
|
||||
|
||||
* `Power` is an `int` representing the type of the metric; e.g., `2` would
|
||||
represent the L2-metric (Euclidean distance).
|
||||
- `Power` must be `1` or greater.
|
||||
- If `Power` is `INT_MAX`, the metric is the L-infinity distance (Chebyshev
|
||||
distance).
|
||||
|
||||
* `TakeRoot` is a `bool` (default `true`) indicating whether the root of the
|
||||
distance should be taken.
|
||||
- If set to `false`, the metric will no longer satisfy the triangle
|
||||
inequality.
|
||||
|
||||
---
|
||||
|
||||
Several convenient typedefs are available:
|
||||
|
||||
* `ManhattanDistance` (defined as `LMetric<1>`)
|
||||
* `EuclideanDistance` (defined as `LMetric<2>`)
|
||||
* `SquaredEuclideanDistance` (defined as `LMetric<2, false>`)
|
||||
* `ChebyshevDistance` (defined as `LMetric<INT_MAX>`)
|
||||
|
||||
---
|
||||
|
||||
The static `Evaluate()` method can be used to compute the distance between two
|
||||
vectors.
|
||||
|
||||
*Note:* The vectors given to `Evaluate()` can have any type so long as the type
|
||||
implements the Armadillo API (e.g. `arma::fvec`, `arma::sp_fvec`, etc.).
|
||||
|
||||
---
|
||||
|
||||
*Example usage:*
|
||||
|
||||
```c++
|
||||
// Create two vectors: [0, 1.0, 5.0] and [1.0, 3.0, 5.0].
|
||||
arma::vec a("0.0 1.0 5.0");
|
||||
arma::vec b("1.0 3.0 5.0");
|
||||
|
||||
const double d1 = mlpack::ManhattanDistance::Evaluate(a, b); // d1 = 3.0
|
||||
const double d2 = mlpack::EuclideanDistance::Evaluate(a, b); // d2 = 2.24
|
||||
const double d3 = mlpack::SquaredEuclideanDistance::Evaluate(a, b); // d3 = 5.0
|
||||
const double d4 = mlpack::ChebyshevDistance::Evaluate(a, b); // d4 = 2.0
|
||||
const double d5 = mlpack::LMetric<4>::Evaluate(a, b); // d5 = 2.03
|
||||
const double d6 = mlpack::LMetric<3, false>::Evaluate(a, b); // d6 = 9.0
|
||||
|
||||
std::cout << "Manhattan distance: " << d1 << "." << std::endl;
|
||||
std::cout << "Euclidean distance: " << d2 << "." << std::endl;
|
||||
std::cout << "Squared Euclidean distance: " << d3 << "." << std::endl;
|
||||
std::cout << "Chebyshev distance: " << d4 << "." << std::endl;
|
||||
std::cout << "L4-distance: " << d5 << "." << std::endl;
|
||||
std::cout << "Cubed L3-distance: " << d6 << "." << std::endl;
|
||||
|
||||
// Compute the distance between two random 10-dimensional vectors in a matrix.
|
||||
arma::mat m(10, 100, arma::fill::randu);
|
||||
|
||||
const double d7 = mlpack::EuclideanDistance::Evaluate(m.col(0), m.col(7));
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "Distance between two random vectors: " << d7 << "." << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// Compute the distance between two 32-bit precision `float` vectors.
|
||||
arma::fvec fa("0.0 1.0 5.0");
|
||||
arma::fvec fb("1.0 3.0 5.0");
|
||||
|
||||
const double d8 = mlpack::EuclideanDistance::Evaluate(fa, fb); // d8 = 2.236
|
||||
|
||||
std::cout << "Euclidean distance (fvec): " << d8 << "." << std::endl;
|
||||
```
|
||||
|
||||
## Kernels
|
||||
|
||||
mlpack includes a number of Mercer kernels for its kernel-based techniques.
|
||||
|
||||
+2
-1
@@ -50,7 +50,8 @@
|
||||
#include <mlpack/core/util/backtrace.hpp>
|
||||
#endif
|
||||
|
||||
#include <mlpack/core/dists/dists.hpp>
|
||||
#include <mlpack/core/distances/distances.hpp>
|
||||
#include <mlpack/core/distributions/distributions.hpp>
|
||||
#include <mlpack/core/kernels/kernels.hpp>
|
||||
#include <mlpack/core/metrics/metrics.hpp>
|
||||
#include <mlpack/core/tree/tree.hpp>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#define MLPACK_CORE_CV_METRICS_FACILITIES_HPP
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
@@ -24,16 +24,16 @@ namespace mlpack {
|
||||
* @param data Column-major matrix.
|
||||
* @param metric Distance metric to be used.
|
||||
*/
|
||||
template<typename DataType, typename Metric>
|
||||
template<typename DataType, typename DistanceType>
|
||||
DataType PairwiseDistances(const DataType& data,
|
||||
const Metric& metric)
|
||||
const DistanceType& distance)
|
||||
{
|
||||
DataType distances = DataType(data.n_cols, data.n_cols, arma::fill::none);
|
||||
for (size_t i = 0; i < data.n_cols; i++)
|
||||
{
|
||||
for (size_t j = 0; j < i; j++)
|
||||
{
|
||||
distances(i, j) = metric.Evaluate(data.col(i), data.col(j));
|
||||
distances(i, j) = distance.Evaluate(data.col(i), data.col(j));
|
||||
distances(j, i) = distances(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/metrics/ip_metric.hpp
|
||||
* @file core/distances/ip_metric.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Inner product induced metric. If given a kernel function, this gives the
|
||||
@@ -10,8 +10,8 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_FASTMKS_IP_METRIC_HPP
|
||||
#define MLPACK_METHODS_FASTMKS_IP_METRIC_HPP
|
||||
#ifndef MLPACK_CORE_DISTANCES_IP_METRIC_HPP
|
||||
#define MLPACK_CORE_DISTANCES_IP_METRIC_HPP
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/metrics/ip_metric_impl.hpp
|
||||
* @file core/distances/ip_metric_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of the IPMetric.
|
||||
@@ -9,13 +9,13 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_FASTMKS_IP_METRIC_IMPL_HPP
|
||||
#define MLPACK_METHODS_FASTMKS_IP_METRIC_IMPL_HPP
|
||||
#ifndef MLPACK_CORE_DISTANCES_IP_METRIC_IMPL_HPP
|
||||
#define MLPACK_CORE_DISTANCES_IP_METRIC_IMPL_HPP
|
||||
|
||||
// In case it hasn't been included yet.
|
||||
#include "ip_metric.hpp"
|
||||
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include <mlpack/core/kernels/linear_kernel.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/metrics/lmetric.hpp
|
||||
* @file core/distances/lmetric.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Generalized L-metric, allowing both squared distances to be returned as well
|
||||
@@ -12,8 +12,8 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_METRICS_LMETRIC_HPP
|
||||
#define MLPACK_CORE_METRICS_LMETRIC_HPP
|
||||
#ifndef MLPACK_CORE_DISTANCES_LMETRIC_HPP
|
||||
#define MLPACK_CORE_DISTANCES_LMETRIC_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/metrics/lmetric_impl.hpp
|
||||
* @file core/distances/lmetric_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of template specializations of LMetric class.
|
||||
@@ -9,8 +9,8 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_METRICS_LMETRIC_IMPL_HPP
|
||||
#define MLPACK_CORE_METRICS_LMETRIC_IMPL_HPP
|
||||
#ifndef MLPACK_CORE_DISTANCES_LMETRIC_IMPL_HPP
|
||||
#define MLPACK_CORE_DISTANCES_LMETRIC_IMPL_HPP
|
||||
|
||||
// In case it hasn't been included.
|
||||
#include "lmetric.hpp"
|
||||
+40
-38
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/metrics/mahalanobis_distance.hpp
|
||||
* @file core/distances/mahalanobis_distance.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* The Mahalanobis distance.
|
||||
@@ -9,8 +9,8 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_METRICS_MAHALANOBIS_DISTANCE_HPP
|
||||
#define MLPACK_CORE_METRICS_MAHALANOBIS_DISTANCE_HPP
|
||||
#ifndef MLPACK_CORE_DISTANCES_MAHALANOBIS_DISTANCE_HPP
|
||||
#define MLPACK_CORE_DISTANCES_MAHALANOBIS_DISTANCE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
@@ -18,21 +18,21 @@ namespace mlpack {
|
||||
|
||||
/**
|
||||
* The Mahalanobis distance, which is essentially a stretched Euclidean
|
||||
* distance. Given a square covariance matrix @f$ Q @f$ of size @f$ d @f$ x
|
||||
* @f$ d @f$, where @f$ d @f$ is the dimensionality of the points it will be
|
||||
* evaluating, and given two vectors @f$ x @f$ and @f$ y @f$ also of
|
||||
* distance. Given a square inverse covariance matrix @f$ Q @f$ of size @f$ d
|
||||
* @f$ x @f$ d @f$, where @f$ d @f$ is the dimensionality of the points it will
|
||||
* be evaluating, and given two vectors @f$ x @f$ and @f$ y @f$ also of
|
||||
* dimensionality @f$ d @f$,
|
||||
*
|
||||
* @f[
|
||||
* d(x, y) = \sqrt{(x - y)^T Q (x - y)}
|
||||
* @f]
|
||||
*
|
||||
* where Q is the covariance matrix.
|
||||
* where Q is the inverse covariance matrix.
|
||||
*
|
||||
* Because each evaluation multiplies (x_1 - x_2) by the covariance matrix, it
|
||||
* is typically much quicker to use an LMetric and simply stretch the actual
|
||||
* dataset itself before performing any evaluations. However, this class is
|
||||
* provided for convenience.
|
||||
* Because each evaluation multiplies (x_1 - x_2) by the inverse covariance
|
||||
* matrix, it is typically much quicker to use an LMetric and simply stretch the
|
||||
* actual dataset itself before performing any evaluations. However, this class
|
||||
* is provided for convenience.
|
||||
*
|
||||
* If you wish to use the KNN class or other tree-based algorithms with this
|
||||
* distance, it is recommended to instead stretch the dataset first, by
|
||||
@@ -55,13 +55,15 @@ namespace mlpack {
|
||||
* not satisfy the triangle inequality and may not be usable for methods that
|
||||
* expect a true metric.
|
||||
*/
|
||||
template<bool TakeRoot = true>
|
||||
template<bool TakeRoot = true, typename MatType = arma::mat>
|
||||
class MahalanobisDistance
|
||||
{
|
||||
public:
|
||||
typedef typename GetColType<MatType>::type VecType;
|
||||
|
||||
/**
|
||||
* Initialize the Mahalanobis distance with the empty matrix as covariance.
|
||||
* Don't call Evaluate() until you set the covariance with Covariance()!
|
||||
* Initialize the Mahalanobis distance with the empty matrix as Q.
|
||||
* Don't call Evaluate() until you set the Q matrix with Q()!
|
||||
*/
|
||||
MahalanobisDistance() { }
|
||||
|
||||
@@ -69,25 +71,24 @@ class MahalanobisDistance
|
||||
* Initialize the Mahalanobis distance with the identity matrix of the given
|
||||
* dimensionality.
|
||||
*
|
||||
* @param dimensionality Dimesnsionality of the covariance matrix.
|
||||
* @param dimensionality Dimensionality of the Q matrix.
|
||||
*/
|
||||
MahalanobisDistance(const size_t dimensionality) :
|
||||
covariance(arma::eye<arma::mat>(dimensionality, dimensionality)) { }
|
||||
q(arma::eye<MatType>(dimensionality, dimensionality)) { }
|
||||
|
||||
/**
|
||||
* Initialize the Mahalanobis distance with the given covariance matrix. The
|
||||
* given covariance matrix will be copied (this is not optimal).
|
||||
* Initialize the Mahalanobis distance with the given Q matrix. The given Q
|
||||
* matrix will be copied (this is not optimal).
|
||||
*
|
||||
* @param covariance The covariance matrix to use for this distance.
|
||||
* @param matQ The Q matrix to use for this distance.
|
||||
*/
|
||||
MahalanobisDistance(arma::mat covariance) :
|
||||
covariance(std::move(covariance)) { }
|
||||
MahalanobisDistance(MatType matQ) : q(std::move(matQ)) { }
|
||||
|
||||
/**
|
||||
* Evaluate the distance between the two given points using this Mahalanobis
|
||||
* distance. If the covariance matrix has not been set (i.e. if you used the
|
||||
* empty constructor and did not later modify the covariance matrix), calling
|
||||
* this method will probably result in a crash.
|
||||
* distance. If the Q matrix has not been set (i.e. if you used the empty
|
||||
* constructor and did not later modify the Q matrix), calling this method
|
||||
* will throw an exception.
|
||||
*
|
||||
* @param a First vector.
|
||||
* @param b Second vector.
|
||||
@@ -95,31 +96,32 @@ class MahalanobisDistance
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double Evaluate(const VecTypeA& a, const VecTypeB& b);
|
||||
|
||||
/**
|
||||
* Access the covariance matrix.
|
||||
*
|
||||
* @return Constant reference to the covariance matrix.
|
||||
*/
|
||||
const arma::mat& Covariance() const { return covariance; }
|
||||
// Access the Q matrix.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0. Use Q() instead")]]
|
||||
const MatType& Covariance() const { return q; }
|
||||
// Modify the Q matrix.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0. Use Q() instead")]]
|
||||
MatType& Covariance() { return q; }
|
||||
|
||||
/**
|
||||
* Modify the covariance matrix.
|
||||
*
|
||||
* @return Reference to the covariance matrix.
|
||||
*/
|
||||
arma::mat& Covariance() { return covariance; }
|
||||
// Access the Q matrix.
|
||||
const MatType& Q() const { return q; }
|
||||
// Modify the Q matrix.
|
||||
MatType& Q() { return q; }
|
||||
|
||||
//! Serialize the Mahalanobis distance.
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const uint32_t version);
|
||||
|
||||
private:
|
||||
//! The covariance matrix associated with this distance.
|
||||
arma::mat covariance;
|
||||
//! The inverse covariance matrix associated with this distance.
|
||||
MatType q;
|
||||
};
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
CEREAL_TEMPLATE_CLASS_VERSION((bool TakeRoot, typename MatType),
|
||||
(mlpack::MahalanobisDistance<TakeRoot, MatType>), (1));
|
||||
|
||||
#include "mahalanobis_distance_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file core/distances/mahalanobis_distance_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of the Mahalanobis distance.
|
||||
*
|
||||
* 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_DISTANCES_MAHALANOBIS_DISTANCE_IMPL_HPP
|
||||
#define MLPACK_CORE_DISTANCES_MAHALANOBIS_DISTANCE_IMPL_HPP
|
||||
|
||||
#include "mahalanobis_distance.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
/**
|
||||
* Specialization for non-rooted case.
|
||||
*/
|
||||
template<bool TakeRoot, typename MatType>
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double MahalanobisDistance<TakeRoot, MatType>::Evaluate(
|
||||
const VecTypeA& a, const VecTypeB& b)
|
||||
{
|
||||
// Check if Q matrix has been initialized.
|
||||
if (q.n_rows != a.n_elem)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "MahalanobisDistance::Evaluate(): given vector dimensionality ("
|
||||
<< a.n_elem << ") does not match Q dimensionality (" << q.n_rows
|
||||
<< ")!";
|
||||
throw std::runtime_error(oss.str());
|
||||
}
|
||||
|
||||
VecType m = (a - b);
|
||||
if (TakeRoot == true)
|
||||
return std::sqrt(as_scalar(m.t() * q * m));
|
||||
else
|
||||
return as_scalar(m.t() * q * m); // 1x1
|
||||
}
|
||||
|
||||
// Serialize the Mahalanobis distance.
|
||||
template<bool TakeRoot, typename MatType>
|
||||
template<typename Archive>
|
||||
void MahalanobisDistance<TakeRoot, MatType>::serialize(
|
||||
Archive& ar, const uint32_t version)
|
||||
{
|
||||
if (Archive::is_loading::value && version == 0)
|
||||
{
|
||||
// Older versions of MahalanobisDistance always serialized as an arma::mat
|
||||
// named "covariance".
|
||||
arma::mat qTmp;
|
||||
ar(cereal::make_nvp("covariance", qTmp));
|
||||
q = arma::conv_to<MatType>::from(qTmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ar(CEREAL_NVP(q));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/diagonal_gaussian_distribution.hpp
|
||||
* @file core/distributions/diagonal_gaussian_distribution.hpp
|
||||
* @author Kim SangYeon
|
||||
*
|
||||
* Implementation of the Gaussian distribution with diagonal covariance.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/diagonal_gaussian_distribution_impl.hpp
|
||||
* @file core/distributions/diagonal_gaussian_distribution_impl.hpp
|
||||
* @author Kim SangYeon
|
||||
*
|
||||
* Implementation of Gaussian distribution class with diagonal covariance.
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/discrete_distribution.hpp
|
||||
* @file core/distributions/discrete_distribution.hpp
|
||||
* @author Ryan Curtin
|
||||
* @author Rohan Raj
|
||||
*
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/discrete_distribution_impl.hpp
|
||||
* @file core/distributions/discrete_distribution_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
* @author Rohan Raj
|
||||
*
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/dists.hpp
|
||||
* @file core/distributions/distributions.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Convenience include for all distributions.
|
||||
@@ -9,8 +9,8 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_DISTS_DISTS_HPP
|
||||
#define MLPACK_CORE_DISTS_DISTS_HPP
|
||||
#ifndef MLPACK_CORE_DISTRIBUTIONS_DISTRIBUTIONS_HPP
|
||||
#define MLPACK_CORE_DISTRIBUTIONS_DISTRIBUTIONS_HPP
|
||||
|
||||
#include "diagonal_gaussian_distribution.hpp"
|
||||
#include "discrete_distribution.hpp"
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/gamma_distribution.hpp
|
||||
* @file core/distributions/gamma_distribution.hpp
|
||||
* @author Yannis Mentekidis
|
||||
* @author Rohan Raj
|
||||
*
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/gamma_distribution_impl.hpp
|
||||
* @file core/distributions/gamma_distribution_impl.hpp
|
||||
* @author Yannis Mentekidis
|
||||
* @author Rohan Raj
|
||||
*
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/gaussian_distribution.hpp
|
||||
* @file core/distributions/gaussian_distribution.hpp
|
||||
* @author Ryan Curtin
|
||||
* @author Michael Fox
|
||||
*
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/gaussian_distribution_impl.hpp
|
||||
* @file core/distributions/gaussian_distribution_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
* @author Michael Fox
|
||||
*
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* @file core/dists/laplace_distribution.hpp
|
||||
* @file core/distributions/laplace_distribution.hpp
|
||||
* @author Zhihao Lou
|
||||
* @author Rohan Raj
|
||||
*
|
||||
@@ -10,7 +10,6 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
|
||||
#ifndef MLPACK_CORE_DISTRIBUTIONS_LAPLACE_DISTRIBUTION_HPP
|
||||
#define MLPACK_CORE_DISTRIBUTIONS_LAPLACE_DISTRIBUTION_HPP
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* @file core/dists/laplace_distribution_impl.hpp
|
||||
* @file core/distributions/laplace_distribution_impl.hpp
|
||||
* @author Zhihao Lou
|
||||
* @author Rohan Raj
|
||||
*
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/regression_distribution.hpp
|
||||
* @file core/distributions/regression_distribution.hpp
|
||||
* @author Michael Fox
|
||||
*
|
||||
* Implementation of conditional Gaussian distribution for HMM regression
|
||||
@@ -10,11 +10,11 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_DISTS_REGRESSION_DISTRIBUTION_HPP
|
||||
#define MLPACK_CORE_DISTS_REGRESSION_DISTRIBUTION_HPP
|
||||
#ifndef MLPACK_CORE_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP
|
||||
#define MLPACK_CORE_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/dists/gaussian_distribution.hpp>
|
||||
#include <mlpack/core/distributions/gaussian_distribution.hpp>
|
||||
#include <mlpack/methods/linear_regression/linear_regression.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file core/dists/regression_distribution_impl.hpp
|
||||
* @file core/distributions/regression_distribution_impl.hpp
|
||||
* @author Michael Fox
|
||||
*
|
||||
* Implementation of conditional Gaussian distribution for HMM regression
|
||||
@@ -10,8 +10,8 @@
|
||||
* 3-clause BSD license along with mlpack. If not, see
|
||||
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
|
||||
*/
|
||||
#ifndef MLPACK_CORE_DISTS_REGRESSION_DISTRIBUTION_IMPL_HPP
|
||||
#define MLPACK_CORE_DISTS_REGRESSION_DISTRIBUTION_IMPL_HPP
|
||||
#ifndef MLPACK_CORE_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_IMPL_HPP
|
||||
#define MLPACK_CORE_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_IMPL_HPP
|
||||
|
||||
#include "regression_distribution.hpp"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define MLPACK_CORE_KERNELS_CAUCHY_KERNEL_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include <mlpack/core/kernels/kernel_traits.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "epanechnikov_kernel.hpp"
|
||||
#include <mlpack/core/util/log.hpp>
|
||||
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define MLPACK_CORE_KERNELS_GAUSSIAN_KERNEL_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include <mlpack/core/kernels/kernel_traits.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define MLPACK_CORE_KERNELS_TRIANGULAR_KERNEL_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
#ifndef MLPACK_CORE_METRICS_IOU_HPP
|
||||
#define MLPACK_CORE_METRICS_IOU_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
@@ -29,21 +30,15 @@ namespace mlpack {
|
||||
* Where x0 and y0 are bottom left bounding box coordinates and h, w are
|
||||
* height and width of the bounding box.
|
||||
*
|
||||
* @tparam useCoordinates Toggles between the two representation of bounding box.
|
||||
* If true, each value in vector represents a coordinate
|
||||
* in the formate x0, y0, x1, y1. Else the bounding box is
|
||||
* represented as x0, y0, h, w.
|
||||
* @tparam useCoordinates Toggles between the two representation of bounding
|
||||
* box. If true, each value in vector represents a coordinate in the
|
||||
* format x0, y0, x1, y1. Else the bounding box is represented as x0, y0,
|
||||
* h, w.
|
||||
*/
|
||||
template<bool UseCoordinates = false>
|
||||
class IoU
|
||||
{
|
||||
public:
|
||||
//! Default constructor required to satisfy the Metric policy.
|
||||
IoU()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the Intersection over Union metric between of two
|
||||
* bounding boxes having pattern bx, by, h, w.
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/**
|
||||
* @file core/metrics/mahalanobis_distance_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of the Mahalanobis distance.
|
||||
*
|
||||
* 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_METRICS_MAHALANOBIS_DISTANCE_IMPL_HPP
|
||||
#define MLPACK_CORE_METRICS_MAHALANOBIS_DISTANCE_IMPL_HPP
|
||||
|
||||
#include "mahalanobis_distance.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
/**
|
||||
* Specialization for non-rooted case.
|
||||
*/
|
||||
template<>
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double MahalanobisDistance<false>::Evaluate(const VecTypeA& a,
|
||||
const VecTypeB& b)
|
||||
{
|
||||
arma::vec m = (a - b);
|
||||
arma::mat out = trans(m) * covariance * m; // 1x1
|
||||
return out[0];
|
||||
}
|
||||
/**
|
||||
* Specialization for rooted case. This requires one extra evaluation of
|
||||
* sqrt().
|
||||
*/
|
||||
template<>
|
||||
template<typename VecTypeA, typename VecTypeB>
|
||||
double MahalanobisDistance<true>::Evaluate(const VecTypeA& a,
|
||||
const VecTypeB& b)
|
||||
{
|
||||
// Check if covariance matrix has been initialized.
|
||||
if (covariance.n_rows == 0)
|
||||
covariance = arma::eye<arma::mat>(a.n_elem, a.n_elem);
|
||||
|
||||
arma::vec m = (a - b);
|
||||
arma::mat out = trans(m) * covariance * m; // 1x1;
|
||||
return std::sqrt(out[0]);
|
||||
}
|
||||
|
||||
// Serialize the Mahalanobis distance.
|
||||
template<bool TakeRoot>
|
||||
template<typename Archive>
|
||||
void MahalanobisDistance<TakeRoot>::serialize(Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
ar(CEREAL_NVP(covariance));
|
||||
}
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -2,8 +2,10 @@
|
||||
* @file core/metrics/metrics.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Include all distance metrics implemented by mlpack. Note that these are not
|
||||
* performance metrics for models---see core/cv/metrics/metrics.hpp instead.
|
||||
* Include all performance metrics and scoring functions implemented by mlpack.
|
||||
* For distance metrics (e.g. distances in metric spaces that satisfy the
|
||||
* triangle inequality and formal definition of distance metric), see
|
||||
* core/distances/ instead.
|
||||
*
|
||||
* 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
|
||||
@@ -15,9 +17,6 @@
|
||||
|
||||
#include "bleu.hpp" // Technically this should go somewhere else...
|
||||
#include "iou_metric.hpp"
|
||||
#include "ip_metric.hpp"
|
||||
#include "lmetric.hpp"
|
||||
#include "mahalanobis_distance.hpp"
|
||||
#include "non_maximal_suppression.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,20 +13,20 @@
|
||||
#define MLPACK_CORE_TREE_BALLBOUND_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include "bound_traits.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
/**
|
||||
* Ball bound encloses a set of points at a specific distance (radius) from a
|
||||
* specific point (center). MetricType is the custom metric type that defaults
|
||||
* to the Euclidean (L2) distance.
|
||||
* specific point (center). DistanceType is the custom distance metric type that
|
||||
* defaults to the Euclidean (L2) distance.
|
||||
*
|
||||
* @tparam MetricType metric type used in the distance measure.
|
||||
* @tparam DistanceType distance metric type used in the distance measure.
|
||||
* @tparam VecType Type of vector (arma::vec or arma::sp_vec or similar).
|
||||
*/
|
||||
template<typename MetricType = LMetric<2, true>,
|
||||
template<typename DistanceType = LMetric<2, true>,
|
||||
typename VecType = arma::vec>
|
||||
class BallBound
|
||||
{
|
||||
@@ -42,15 +42,15 @@ class BallBound
|
||||
//! The center of the ball bound.
|
||||
VecType center;
|
||||
//! The metric used in this bound.
|
||||
MetricType* metric;
|
||||
DistanceType* distance;
|
||||
|
||||
/**
|
||||
* To know whether this object allocated memory to the metric member
|
||||
* To know whether this object allocated memory to the distance metric member
|
||||
* variable. This will be true except in the copy constructor and the
|
||||
* overloaded assignment operator. We need this to know whether we should
|
||||
* delete the metric member variable in the destructor.
|
||||
* delete the distance metric member variable in the destructor.
|
||||
*/
|
||||
bool ownsMetric;
|
||||
bool ownsDistance;
|
||||
|
||||
public:
|
||||
//! Empty Constructor.
|
||||
@@ -199,9 +199,16 @@ class BallBound
|
||||
ElemType Diameter() const { return 2 * radius; }
|
||||
|
||||
//! Returns the distance metric used in this bound.
|
||||
const MetricType& Metric() const { return *metric; }
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
const DistanceType& Metric() const { return *distance; }
|
||||
//! Modify the distance metric used in this bound.
|
||||
MetricType& Metric() { return *metric; }
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType& Metric() { return *distance; }
|
||||
|
||||
//! Returns the distance metric used in this bound.
|
||||
const DistanceType& Distance() const { return *distance; }
|
||||
//! Modify the distance metric used in this bound.
|
||||
DistanceType& Distance() { return *distance; }
|
||||
|
||||
//! Serialize the bound.
|
||||
template<typename Archive>
|
||||
@@ -209,8 +216,8 @@ class BallBound
|
||||
};
|
||||
|
||||
//! A specialization of BoundTraits for this bound type.
|
||||
template<typename MetricType, typename VecType>
|
||||
struct BoundTraits<BallBound<MetricType, VecType>>
|
||||
template<typename DistanceType, typename VecType>
|
||||
struct BoundTraits<BallBound<DistanceType, VecType>>
|
||||
{
|
||||
//! These bounds are potentially loose in some dimensions.
|
||||
const static bool HasTightBounds = false;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file core/tree/ballbound_impl.hpp
|
||||
*
|
||||
* Bounds that are useful for binary space partitioning trees.
|
||||
* Implementation of BallBound ball bound metric policy class.
|
||||
* Implementation of BallBound ball bound policy class.
|
||||
*
|
||||
* 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
|
||||
@@ -20,11 +20,11 @@
|
||||
namespace mlpack {
|
||||
|
||||
//! Empty Constructor.
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>::BallBound() :
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>::BallBound() :
|
||||
radius(std::numeric_limits<ElemType>::lowest()),
|
||||
metric(new MetricType()),
|
||||
ownsMetric(true)
|
||||
distance(new DistanceType()),
|
||||
ownsDistance(true)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
/**
|
||||
@@ -32,12 +32,12 @@ BallBound<MetricType, VecType>::BallBound() :
|
||||
*
|
||||
* @param dimension Dimensionality of ball bound.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>::BallBound(const size_t dimension) :
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>::BallBound(const size_t dimension) :
|
||||
radius(std::numeric_limits<ElemType>::lowest()),
|
||||
center(dimension),
|
||||
metric(new MetricType()),
|
||||
ownsMetric(true)
|
||||
distance(new DistanceType()),
|
||||
ownsDistance(true)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
/**
|
||||
@@ -46,86 +46,86 @@ BallBound<MetricType, VecType>::BallBound(const size_t dimension) :
|
||||
* @param radius Radius of ball bound.
|
||||
* @param center Center of ball bound.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>::BallBound(const ElemType radius,
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>::BallBound(const ElemType radius,
|
||||
const VecType& center) :
|
||||
radius(radius),
|
||||
center(center),
|
||||
metric(new MetricType()),
|
||||
ownsMetric(true)
|
||||
distance(new DistanceType()),
|
||||
ownsDistance(true)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
//! Copy Constructor. To prevent memory leaks.
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>::BallBound(const BallBound& other) :
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>::BallBound(const BallBound& other) :
|
||||
radius(other.radius),
|
||||
center(other.center),
|
||||
metric(other.metric),
|
||||
ownsMetric(false)
|
||||
distance(other.distance),
|
||||
ownsDistance(false)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
//! For the same reason as the copy constructor: to prevent memory leaks.
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>& BallBound<MetricType, VecType>::operator=(
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>& BallBound<DistanceType, VecType>::operator=(
|
||||
const BallBound& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
radius = other.radius;
|
||||
center = other.center;
|
||||
metric = other.metric;
|
||||
ownsMetric = false;
|
||||
distance = other.distance;
|
||||
ownsDistance = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Move constructor.
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>::BallBound(BallBound&& other) :
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>::BallBound(BallBound&& other) :
|
||||
radius(other.radius),
|
||||
center(other.center),
|
||||
metric(other.metric),
|
||||
ownsMetric(other.ownsMetric)
|
||||
distance(other.distance),
|
||||
ownsDistance(other.ownsDistance)
|
||||
{
|
||||
// Fix the other bound.
|
||||
other.radius = 0.0;
|
||||
other.center = VecType();
|
||||
other.metric = NULL;
|
||||
other.ownsMetric = false;
|
||||
other.distance = NULL;
|
||||
other.ownsDistance = false;
|
||||
}
|
||||
|
||||
//! Move assignment operator.
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>& BallBound<MetricType, VecType>::operator=(
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>& BallBound<DistanceType, VecType>::operator=(
|
||||
BallBound&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
radius = other.radius;
|
||||
center = std::move(other.center);
|
||||
metric = other.metric;
|
||||
ownsMetric = other.ownsMetric;
|
||||
distance = other.distance;
|
||||
ownsDistance = other.ownsDistance;
|
||||
|
||||
other.radius = 0.0;
|
||||
other.center = VecType();
|
||||
other.metric = nullptr;
|
||||
other.ownsMetric = false;
|
||||
other.distance = nullptr;
|
||||
other.ownsDistance = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Destructor to release allocated memory.
|
||||
template<typename MetricType, typename VecType>
|
||||
BallBound<MetricType, VecType>::~BallBound()
|
||||
template<typename DistanceType, typename VecType>
|
||||
BallBound<DistanceType, VecType>::~BallBound()
|
||||
{
|
||||
if (ownsMetric)
|
||||
delete metric;
|
||||
if (ownsDistance)
|
||||
delete distance;
|
||||
}
|
||||
|
||||
//! Get the range in a certain dimension.
|
||||
template<typename MetricType, typename VecType>
|
||||
RangeType<typename BallBound<MetricType, VecType>::ElemType>
|
||||
BallBound<MetricType, VecType>::operator[](const size_t i) const
|
||||
template<typename DistanceType, typename VecType>
|
||||
RangeType<typename BallBound<DistanceType, VecType>::ElemType>
|
||||
BallBound<DistanceType, VecType>::operator[](const size_t i) const
|
||||
{
|
||||
if (radius < 0)
|
||||
return Range();
|
||||
@@ -136,44 +136,44 @@ BallBound<MetricType, VecType>::operator[](const size_t i) const
|
||||
/**
|
||||
* Determines if a point is within the bound.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
bool BallBound<MetricType, VecType>::Contains(const VecType& point) const
|
||||
template<typename DistanceType, typename VecType>
|
||||
bool BallBound<DistanceType, VecType>::Contains(const VecType& point) const
|
||||
{
|
||||
if (radius < 0)
|
||||
return false;
|
||||
else
|
||||
return metric->Evaluate(center, point) <= radius;
|
||||
return distance->Evaluate(center, point) <= radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates minimum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
template<typename OtherVecType>
|
||||
typename BallBound<MetricType, VecType>::ElemType
|
||||
BallBound<MetricType, VecType>::MinDistance(
|
||||
typename BallBound<DistanceType, VecType>::ElemType
|
||||
BallBound<DistanceType, VecType>::MinDistance(
|
||||
const OtherVecType& point,
|
||||
typename std::enable_if_t<IsVector<OtherVecType>::value>* /* junk */) const
|
||||
{
|
||||
if (radius < 0)
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
return std::max(metric->Evaluate(point, center) - radius, (ElemType) 0.0);
|
||||
return std::max(distance->Evaluate(point, center) - radius, (ElemType) 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates minimum bound-to-bound squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
typename BallBound<MetricType, VecType>::ElemType
|
||||
BallBound<MetricType, VecType>::MinDistance(const BallBound& other)
|
||||
template<typename DistanceType, typename VecType>
|
||||
typename BallBound<DistanceType, VecType>::ElemType
|
||||
BallBound<DistanceType, VecType>::MinDistance(const BallBound& other)
|
||||
const
|
||||
{
|
||||
if (radius < 0)
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
{
|
||||
const ElemType delta = metric->Evaluate(center, other.center) - radius -
|
||||
const ElemType delta = distance->Evaluate(center, other.center) - radius -
|
||||
other.radius;
|
||||
return std::max(delta, (ElemType) 0.0);
|
||||
}
|
||||
@@ -182,31 +182,31 @@ BallBound<MetricType, VecType>::MinDistance(const BallBound& other)
|
||||
/**
|
||||
* Computes maximum distance.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
template<typename OtherVecType>
|
||||
typename BallBound<MetricType, VecType>::ElemType
|
||||
BallBound<MetricType, VecType>::MaxDistance(
|
||||
typename BallBound<DistanceType, VecType>::ElemType
|
||||
BallBound<DistanceType, VecType>::MaxDistance(
|
||||
const OtherVecType& point,
|
||||
typename std::enable_if_t<IsVector<OtherVecType>::value>* /* junk */) const
|
||||
{
|
||||
if (radius < 0)
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
return metric->Evaluate(point, center) + radius;
|
||||
return distance->Evaluate(point, center) + radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes maximum distance.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
typename BallBound<MetricType, VecType>::ElemType
|
||||
BallBound<MetricType, VecType>::MaxDistance(const BallBound& other)
|
||||
template<typename DistanceType, typename VecType>
|
||||
typename BallBound<DistanceType, VecType>::ElemType
|
||||
BallBound<DistanceType, VecType>::MaxDistance(const BallBound& other)
|
||||
const
|
||||
{
|
||||
if (radius < 0)
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
return metric->Evaluate(other.center, center) + radius + other.radius;
|
||||
return distance->Evaluate(other.center, center) + radius + other.radius;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,10 +214,10 @@ BallBound<MetricType, VecType>::MaxDistance(const BallBound& other)
|
||||
*
|
||||
* Example: bound1.MinDistanceSq(other) for minimum squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
template<typename OtherVecType>
|
||||
RangeType<typename BallBound<MetricType, VecType>::ElemType>
|
||||
BallBound<MetricType, VecType>::RangeDistance(
|
||||
RangeType<typename BallBound<DistanceType, VecType>::ElemType>
|
||||
BallBound<DistanceType, VecType>::RangeDistance(
|
||||
const OtherVecType& point,
|
||||
typename std::enable_if_t<IsVector<OtherVecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -226,14 +226,14 @@ BallBound<MetricType, VecType>::RangeDistance(
|
||||
std::numeric_limits<ElemType>::max());
|
||||
else
|
||||
{
|
||||
const ElemType dist = metric->Evaluate(center, point);
|
||||
const ElemType dist = distance->Evaluate(center, point);
|
||||
return Range(std::max(dist - radius, (ElemType) 0.0), dist + radius);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MetricType, typename VecType>
|
||||
RangeType<typename BallBound<MetricType, VecType>::ElemType>
|
||||
BallBound<MetricType, VecType>::RangeDistance(
|
||||
template<typename DistanceType, typename VecType>
|
||||
RangeType<typename BallBound<DistanceType, VecType>::ElemType>
|
||||
BallBound<DistanceType, VecType>::RangeDistance(
|
||||
const BallBound& other) const
|
||||
{
|
||||
if (radius < 0)
|
||||
@@ -241,39 +241,22 @@ BallBound<MetricType, VecType>::RangeDistance(
|
||||
std::numeric_limits<ElemType>::max());
|
||||
else
|
||||
{
|
||||
const ElemType dist = metric->Evaluate(center, other.center);
|
||||
const ElemType dist = distance->Evaluate(center, other.center);
|
||||
const ElemType sumradius = radius + other.radius;
|
||||
return Range(std::max(dist - sumradius, (ElemType) 0.0), dist + sumradius);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the bound to include the given bound.
|
||||
*
|
||||
template<typename MetricType, typename VecType>
|
||||
const BallBound<VecType>&
|
||||
BallBound<MetricType, VecType>::operator|=(
|
||||
const BallBound<VecType>& other)
|
||||
{
|
||||
double dist = metric->Evaluate(center, other);
|
||||
|
||||
// Now expand the radius as necessary.
|
||||
if (dist > radius)
|
||||
radius = dist;
|
||||
|
||||
return *this;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Expand the bound to include the given point. Algorithm adapted from
|
||||
* Jack Ritter, "An Efficient Bounding Sphere" in Graphics Gems (1990).
|
||||
* The difference lies in the way we initialize the ball bound. The way we
|
||||
* expand the bound is same.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
template<typename MatType>
|
||||
const BallBound<MetricType, VecType>&
|
||||
BallBound<MetricType, VecType>::operator|=(const MatType& data)
|
||||
const BallBound<DistanceType, VecType>&
|
||||
BallBound<DistanceType, VecType>::operator|=(const MatType& data)
|
||||
{
|
||||
if (radius < 0)
|
||||
{
|
||||
@@ -284,7 +267,7 @@ BallBound<MetricType, VecType>::operator|=(const MatType& data)
|
||||
// Now iteratively add points.
|
||||
for (size_t i = 0; i < data.n_cols; ++i)
|
||||
{
|
||||
const ElemType dist = metric->Evaluate(center, (VecType) data.col(i));
|
||||
const ElemType dist = distance->Evaluate(center, (VecType) data.col(i));
|
||||
|
||||
// See if the new point lies outside the bound.
|
||||
if (dist > radius)
|
||||
@@ -301,9 +284,9 @@ BallBound<MetricType, VecType>::operator|=(const MatType& data)
|
||||
}
|
||||
|
||||
//! Serialize the BallBound.
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
template<typename Archive>
|
||||
void BallBound<MetricType, VecType>::serialize(
|
||||
void BallBound<DistanceType, VecType>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
@@ -312,13 +295,14 @@ void BallBound<MetricType, VecType>::serialize(
|
||||
|
||||
if (cereal::is_loading<Archive>())
|
||||
{
|
||||
// If we're loading, delete the local metric since we'll have a new one.
|
||||
if (ownsMetric)
|
||||
delete metric;
|
||||
// If we're loading, delete the local distance metric since we'll have a new
|
||||
// one.
|
||||
if (ownsDistance)
|
||||
delete distance;
|
||||
}
|
||||
|
||||
ar(CEREAL_POINTER(metric));
|
||||
ar(CEREAL_NVP(ownsMetric));
|
||||
ar(CEREAL_POINTER(distance));
|
||||
ar(CEREAL_NVP(ownsDistance));
|
||||
}
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -31,22 +31,22 @@ namespace mlpack {
|
||||
* This tree does take one runtime parameter in the constructor, which is the
|
||||
* max leaf size to be used.
|
||||
*
|
||||
* @tparam MetricType The metric used for tree-building. The BoundType may
|
||||
* place restrictions on the metrics that can be used.
|
||||
* @tparam DistanceType The distance metric used for tree-building. The
|
||||
* BoundType may place restrictions on the metrics that can be used.
|
||||
* @tparam StatisticType Extra data contained in the node. See statistic.hpp
|
||||
* for the necessary skeleton interface.
|
||||
* @tparam MatType The dataset class.
|
||||
* @tparam BoundType The bound used for each node. HRectBound, the default,
|
||||
* requires that an LMetric<> is used for MetricType (so, EuclideanDistance,
|
||||
* ManhattanDistance, etc.).
|
||||
* requires that an LMetric<> is used for DistanceType (so,
|
||||
* EuclideanDistance, ManhattanDistance, etc.).
|
||||
* @tparam SplitType The class that partitions the dataset/points at a
|
||||
* particular node into two parts. Its definition decides the way this split
|
||||
* is done.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType = EmptyStatistic,
|
||||
typename MatType = arma::mat,
|
||||
template<typename BoundMetricType, typename...> class BoundType =
|
||||
template<typename BoundDistanceType, typename...> class BoundType =
|
||||
HRectBound,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType = MidpointSplit>
|
||||
@@ -58,7 +58,7 @@ class BinarySpaceTree
|
||||
//! The type of element held in MatType.
|
||||
typedef typename MatType::elem_type ElemType;
|
||||
|
||||
typedef SplitType<BoundType<MetricType>, MatType> Split;
|
||||
typedef SplitType<BoundType<DistanceType>, MatType> Split;
|
||||
|
||||
private:
|
||||
//! The left child node.
|
||||
@@ -74,7 +74,7 @@ class BinarySpaceTree
|
||||
//! children).
|
||||
size_t count;
|
||||
//! The bound object for this node.
|
||||
BoundType<MetricType> bound;
|
||||
BoundType<DistanceType> bound;
|
||||
//! Any extra data contained in the node.
|
||||
StatisticType stat;
|
||||
//! The distance from the centroid of this node to the centroid of the parent.
|
||||
@@ -210,7 +210,7 @@ class BinarySpaceTree
|
||||
BinarySpaceTree(BinarySpaceTree* parent,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter,
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter,
|
||||
const size_t maxLeafSize = 20);
|
||||
|
||||
/**
|
||||
@@ -236,7 +236,7 @@ class BinarySpaceTree
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter,
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter,
|
||||
const size_t maxLeafSize = 20);
|
||||
|
||||
/**
|
||||
@@ -266,7 +266,7 @@ class BinarySpaceTree
|
||||
const size_t count,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
std::vector<size_t>& newFromOld,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter,
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter,
|
||||
const size_t maxLeafSize = 20);
|
||||
|
||||
/**
|
||||
@@ -315,9 +315,9 @@ class BinarySpaceTree
|
||||
~BinarySpaceTree();
|
||||
|
||||
//! Return the bound object for this node.
|
||||
const BoundType<MetricType>& Bound() const { return bound; }
|
||||
const BoundType<DistanceType>& Bound() const { return bound; }
|
||||
//! Return the bound object for this node.
|
||||
BoundType<MetricType>& Bound() { return bound; }
|
||||
BoundType<DistanceType>& Bound() { return bound; }
|
||||
|
||||
//! Return the statistic object for this node.
|
||||
const StatisticType& Stat() const { return stat; }
|
||||
@@ -348,7 +348,11 @@ class BinarySpaceTree
|
||||
MatType& Dataset() { return *dataset; }
|
||||
|
||||
//! Get the metric that the tree uses.
|
||||
MetricType Metric() const { return MetricType(); }
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType Metric() const { return DistanceType(); }
|
||||
|
||||
//! Get the metric that the tree uses.
|
||||
DistanceType Distance() const { return DistanceType(); }
|
||||
|
||||
//! Return the number of children in this node.
|
||||
size_t NumChildren() const;
|
||||
@@ -514,7 +518,7 @@ class BinarySpaceTree
|
||||
* @param splitter Instantiated SplitType object.
|
||||
*/
|
||||
void SplitNode(const size_t maxLeafSize,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter);
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter);
|
||||
|
||||
/**
|
||||
* Splits the current node, assigning its left and right children recursively.
|
||||
@@ -526,7 +530,7 @@ class BinarySpaceTree
|
||||
*/
|
||||
void SplitNode(std::vector<size_t>& oldFromNew,
|
||||
const size_t maxLeafSize,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter);
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter);
|
||||
|
||||
/**
|
||||
* Update the bound of the current node. This method does not take into
|
||||
@@ -543,7 +547,7 @@ class BinarySpaceTree
|
||||
*
|
||||
* @param boundToUpdate The bound to update.
|
||||
*/
|
||||
void UpdateBound(HollowBallBound<MetricType>& boundToUpdate);
|
||||
void UpdateBound(HollowBallBound<DistanceType>& boundToUpdate);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
||||
@@ -21,13 +21,13 @@ namespace mlpack {
|
||||
|
||||
// Each of these overloads is kept as a separate function to keep the overhead
|
||||
// from the two std::vectors out, if possible.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
const MatType& data,
|
||||
const size_t maxLeafSize) :
|
||||
@@ -41,20 +41,20 @@ BinarySpaceTree(
|
||||
dataset(new MatType(data)) // Copies the dataset.
|
||||
{
|
||||
// Do the actual splitting of this node.
|
||||
SplitType<BoundType<MetricType>, MatType> splitter;
|
||||
SplitType<BoundType<DistanceType>, MatType> splitter;
|
||||
SplitNode(maxLeafSize, splitter);
|
||||
|
||||
// Create the statistic depending on if we are a leaf or not.
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
const MatType& data,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
@@ -74,20 +74,20 @@ BinarySpaceTree(
|
||||
oldFromNew[i] = i; // Fill with unharmed indices.
|
||||
|
||||
// Now do the actual splitting.
|
||||
SplitType<BoundType<MetricType>, MatType> splitter;
|
||||
SplitType<BoundType<DistanceType>, MatType> splitter;
|
||||
SplitNode(oldFromNew, maxLeafSize, splitter);
|
||||
|
||||
// Create the statistic depending on if we are a leaf or not.
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
const MatType& data,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
@@ -108,7 +108,7 @@ BinarySpaceTree(
|
||||
oldFromNew[i] = i; // Fill with unharmed indices.
|
||||
|
||||
// Now do the actual splitting.
|
||||
SplitType<BoundType<MetricType>, MatType> splitter;
|
||||
SplitType<BoundType<DistanceType>, MatType> splitter;
|
||||
SplitNode(oldFromNew, maxLeafSize, splitter);
|
||||
|
||||
// Create the statistic depending on if we are a leaf or not.
|
||||
@@ -120,13 +120,13 @@ BinarySpaceTree(
|
||||
newFromOld[oldFromNew[i]] = i;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(MatType&& data, const size_t maxLeafSize) :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -138,20 +138,20 @@ BinarySpaceTree(MatType&& data, const size_t maxLeafSize) :
|
||||
dataset(new MatType(std::move(data)))
|
||||
{
|
||||
// Do the actual splitting of this node.
|
||||
SplitType<BoundType<MetricType>, MatType> splitter;
|
||||
SplitType<BoundType<DistanceType>, MatType> splitter;
|
||||
SplitNode(maxLeafSize, splitter);
|
||||
|
||||
// Create the statistic depending on if we are a leaf or not.
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
MatType&& data,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
@@ -171,20 +171,20 @@ BinarySpaceTree(
|
||||
oldFromNew[i] = i; // Fill with unharmed indices.
|
||||
|
||||
// Now do the actual splitting.
|
||||
SplitType<BoundType<MetricType>, MatType> splitter;
|
||||
SplitType<BoundType<DistanceType>, MatType> splitter;
|
||||
SplitNode(oldFromNew, maxLeafSize, splitter);
|
||||
|
||||
// Create the statistic depending on if we are a leaf or not.
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
MatType&& data,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
@@ -205,7 +205,7 @@ BinarySpaceTree(
|
||||
oldFromNew[i] = i; // Fill with unharmed indices.
|
||||
|
||||
// Now do the actual splitting.
|
||||
SplitType<BoundType<MetricType>, MatType> splitter;
|
||||
SplitType<BoundType<DistanceType>, MatType> splitter;
|
||||
SplitNode(oldFromNew, maxLeafSize, splitter);
|
||||
|
||||
// Create the statistic depending on if we are a leaf or not.
|
||||
@@ -217,18 +217,18 @@ BinarySpaceTree(
|
||||
newFromOld[oldFromNew[i]] = i;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
BinarySpaceTree* parent,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter,
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter,
|
||||
const size_t maxLeafSize) :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -245,19 +245,19 @@ BinarySpaceTree(
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
BinarySpaceTree* parent,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter,
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter,
|
||||
const size_t maxLeafSize) :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -278,20 +278,20 @@ BinarySpaceTree(
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
BinarySpaceTree* parent,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
std::vector<size_t>& newFromOld,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter,
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter,
|
||||
const size_t maxLeafSize) :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -321,13 +321,13 @@ BinarySpaceTree(
|
||||
* Create a binary space tree by copying the other tree. Be careful! This can
|
||||
* take a long time and use a lot of memory.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
const BinarySpaceTree& other) :
|
||||
left(NULL),
|
||||
@@ -381,14 +381,14 @@ BinarySpaceTree(
|
||||
/**
|
||||
* Copy assignment operator: copy the given other tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
operator=(const BinarySpaceTree& other)
|
||||
{
|
||||
// Return if it's the same tree.
|
||||
@@ -453,14 +453,14 @@ operator=(const BinarySpaceTree& other)
|
||||
/**
|
||||
* Move assignment operator: take ownership of the given tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
operator=(BinarySpaceTree&& other)
|
||||
{
|
||||
// Return if it's the same tree.
|
||||
@@ -501,13 +501,13 @@ operator=(BinarySpaceTree&& other)
|
||||
/**
|
||||
* Move constructor.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(BinarySpaceTree&& other) :
|
||||
left(other.left),
|
||||
right(other.right),
|
||||
@@ -543,14 +543,14 @@ BinarySpaceTree(BinarySpaceTree&& other) :
|
||||
/**
|
||||
* Initialize the tree from an archive.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename Archive>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree(
|
||||
Archive& ar,
|
||||
const typename std::enable_if_t<cereal::is_loading<Archive>()>*) :
|
||||
@@ -566,13 +566,13 @@ BinarySpaceTree(
|
||||
* destructors in turn. This will invalidate any pointers or references to any
|
||||
* nodes which are children of this one.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
~BinarySpaceTree()
|
||||
{
|
||||
delete left;
|
||||
@@ -583,13 +583,13 @@ BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
delete dataset;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline bool BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline bool BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::IsLeaf() const
|
||||
{
|
||||
return !left;
|
||||
@@ -598,13 +598,13 @@ inline bool BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
/**
|
||||
* Returns the number of children in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::NumChildren() const
|
||||
{
|
||||
if (left && right)
|
||||
@@ -619,14 +619,14 @@ inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* Return the index of the nearest child node to the given query point. If
|
||||
* this is a leaf node, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename VecType>
|
||||
size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::GetNearestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
@@ -643,14 +643,14 @@ size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* Return the index of the furthest child node to the given query point. If
|
||||
* this is a leaf node, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename VecType>
|
||||
size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::GetFurthestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
@@ -667,13 +667,13 @@ size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* Return the index of the nearest child node to the given query node. If it
|
||||
* can't decide, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::GetNearestChild(const BinarySpaceTree& queryNode)
|
||||
{
|
||||
if (IsLeaf() || !left || !right)
|
||||
@@ -692,13 +692,13 @@ size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* Return the index of the furthest child node to the given query node. If it
|
||||
* can't decide, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::GetFurthestChild(const BinarySpaceTree& queryNode)
|
||||
{
|
||||
if (IsLeaf() || !left || !right)
|
||||
@@ -717,16 +717,16 @@ size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* Return a bound on the furthest point in the node from the center. This
|
||||
* returns 0 unless the node is a leaf.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline
|
||||
typename BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
typename BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::ElemType
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::FurthestPointDistance() const
|
||||
{
|
||||
if (!IsLeaf())
|
||||
@@ -743,32 +743,32 @@ BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* furthest descendant distance may be less than what this method returns (but
|
||||
* it will never be greater than this).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline
|
||||
typename BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
typename BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::ElemType
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::FurthestDescendantDistance() const
|
||||
{
|
||||
return furthestDescendantDistance;
|
||||
}
|
||||
|
||||
//! Return the minimum distance from the center to any bound edge.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline
|
||||
typename BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
typename BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::ElemType
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::MinimumBoundDistance() const
|
||||
{
|
||||
return bound.MinWidth() / 2.0;
|
||||
@@ -777,15 +777,15 @@ BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
/**
|
||||
* Return the specified child.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>&
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::Child(const size_t child) const
|
||||
{
|
||||
if (child == 0)
|
||||
@@ -797,13 +797,13 @@ inline BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
/**
|
||||
* Return the number of points contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::NumPoints() const
|
||||
{
|
||||
if (left)
|
||||
@@ -815,13 +815,13 @@ inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
/**
|
||||
* Return the number of descendants contained in the node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::NumDescendants() const
|
||||
{
|
||||
return count;
|
||||
@@ -830,13 +830,13 @@ inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
/**
|
||||
* Return the index of a particular descendant contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::Descendant(const size_t index) const
|
||||
{
|
||||
return (begin + index);
|
||||
@@ -845,27 +845,28 @@ inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
/**
|
||||
* Return the index of a particular point contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
inline size_t BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::Point(const size_t index) const
|
||||
{
|
||||
return (begin + index);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
SplitNode(const size_t maxLeafSize,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter)
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter)
|
||||
{
|
||||
// We need to expand the bounds of this node properly.
|
||||
UpdateBound(bound);
|
||||
@@ -914,25 +915,26 @@ void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
left->Center(leftCenter);
|
||||
right->Center(rightCenter);
|
||||
|
||||
const ElemType leftParentDistance = bound.Metric().Evaluate(center,
|
||||
const ElemType leftParentDistance = bound.Distance().Evaluate(center,
|
||||
leftCenter);
|
||||
const ElemType rightParentDistance = bound.Metric().Evaluate(center,
|
||||
const ElemType rightParentDistance = bound.Distance().Evaluate(center,
|
||||
rightCenter);
|
||||
|
||||
left->ParentDistance() = leftParentDistance;
|
||||
right->ParentDistance() = rightParentDistance;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
SplitNode(std::vector<size_t>& oldFromNew,
|
||||
const size_t maxLeafSize,
|
||||
SplitType<BoundType<MetricType>, MatType>& splitter)
|
||||
SplitType<BoundType<DistanceType>, MatType>& splitter)
|
||||
{
|
||||
// We need to expand the bounds of this node properly.
|
||||
UpdateBound(bound);
|
||||
@@ -982,37 +984,39 @@ SplitNode(std::vector<size_t>& oldFromNew,
|
||||
left->Center(leftCenter);
|
||||
right->Center(rightCenter);
|
||||
|
||||
const ElemType leftParentDistance = bound.Metric().Evaluate(center,
|
||||
const ElemType leftParentDistance = bound.Distance().Evaluate(center,
|
||||
leftCenter);
|
||||
const ElemType rightParentDistance = bound.Metric().Evaluate(center,
|
||||
const ElemType rightParentDistance = bound.Distance().Evaluate(center,
|
||||
rightCenter);
|
||||
|
||||
left->ParentDistance() = leftParentDistance;
|
||||
right->ParentDistance() = rightParentDistance;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename BoundType2>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
UpdateBound(BoundType2& boundToUpdate)
|
||||
{
|
||||
if (count > 0)
|
||||
boundToUpdate |= dataset->cols(begin, begin + count - 1);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
UpdateBound(HollowBallBound<MetricType>& boundToUpdate)
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
UpdateBound(HollowBallBound<DistanceType>& boundToUpdate)
|
||||
{
|
||||
if (!parent)
|
||||
{
|
||||
@@ -1032,13 +1036,13 @@ UpdateBound(HollowBallBound<MetricType>& boundToUpdate)
|
||||
}
|
||||
|
||||
// Default constructor (private), for cereal.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree() :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -1056,14 +1060,15 @@ BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
/**
|
||||
* Serialize the tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename Archive>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
serialize(Archive& ar, const uint32_t /* version */)
|
||||
{
|
||||
// If we're loading, and we have children, they need to be deleted.
|
||||
|
||||
@@ -32,14 +32,14 @@ struct QueueFrame
|
||||
TraversalInfoType traversalInfo;
|
||||
};
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
class BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
class BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::BreadthFirstDualTreeTraverser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BreadthFirstDualTreeTraverser<RuleType>::BreadthFirstDualTreeTraverser(
|
||||
RuleType& rule) :
|
||||
rule(rule),
|
||||
@@ -47,18 +47,19 @@ bool operator<(const QueueFrame<TreeType, TraversalInfoType>& a,
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BreadthFirstDualTreeTraverser<RuleType>::Traverse(
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
queryRoot,
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
referenceRoot)
|
||||
{
|
||||
// Increment the visit counter.
|
||||
@@ -87,16 +88,16 @@ BreadthFirstDualTreeTraverser<RuleType>::Traverse(
|
||||
Traverse(queryRoot, queue);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BreadthFirstDualTreeTraverser<RuleType>::Traverse(
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
queryNode,
|
||||
std::priority_queue<QueueFrameType>& referenceQueue)
|
||||
{
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
class BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
class BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::DualTreeTraverser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
DualTreeTraverser<RuleType>::DualTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0),
|
||||
@@ -35,18 +35,19 @@ DualTreeTraverser<RuleType>::DualTreeTraverser(RuleType& rule) :
|
||||
numBaseCases(0)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
DualTreeTraverser<RuleType>::Traverse(
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
queryNode,
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
referenceNode)
|
||||
{
|
||||
// Increment the visit counter.
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
class BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
class BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
SplitType>::SingleTreeTraverser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -21,30 +21,31 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
SingleTreeTraverser<RuleType>::SingleTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType>
|
||||
void BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>::
|
||||
void
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>::
|
||||
SingleTreeTraverser<RuleType>::Traverse(
|
||||
const size_t queryIndex,
|
||||
BinarySpaceTree<MetricType, StatisticType, MatType, BoundType, SplitType>&
|
||||
BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType, SplitType>&
|
||||
referenceNode)
|
||||
{
|
||||
// If we are a leaf, run the base case as necessary.
|
||||
|
||||
@@ -23,14 +23,14 @@ namespace mlpack {
|
||||
* help write tree-independent (but still optimized) tree-based algorithms. See
|
||||
* mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
SplitType>>
|
||||
class TreeTraits<BinarySpaceTree<
|
||||
DistanceType, StatisticType, MatType, BoundType, SplitType>>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -77,12 +77,12 @@ class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* projection tree. The only difference with general BinarySpaceTree is that the
|
||||
* tree can have overlapping children.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType>
|
||||
class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
RPTreeMaxSplit>>
|
||||
template<typename BoundDistanceType, typename...> class BoundType>
|
||||
class TreeTraits<BinarySpaceTree<
|
||||
DistanceType, StatisticType, MatType, BoundType, RPTreeMaxSplit>>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -127,11 +127,11 @@ class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* projection tree. The only difference with general BinarySpaceTree is that the
|
||||
* tree can have overlapping children.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename BoundMetricType, typename...> class BoundType>
|
||||
class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
template<typename BoundDistanceType, typename...> class BoundType>
|
||||
class TreeTraits<BinarySpaceTree<DistanceType, StatisticType, MatType, BoundType,
|
||||
RPTreeMeanSplit>>
|
||||
{
|
||||
public:
|
||||
@@ -178,13 +178,13 @@ class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BoundType,
|
||||
* overlapping children.
|
||||
* See mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BallBound,
|
||||
SplitType>>
|
||||
class TreeTraits<BinarySpaceTree<
|
||||
DistanceType, StatisticType, MatType, BallBound, SplitType>>
|
||||
{
|
||||
public:
|
||||
static const bool HasOverlappingChildren = true;
|
||||
@@ -202,13 +202,13 @@ class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, BallBound,
|
||||
* The only difference with general BinarySpaceTree is that the tree can have
|
||||
* overlapping children.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType,
|
||||
HollowBallBound, SplitType>>
|
||||
class TreeTraits<BinarySpaceTree<
|
||||
DistanceType, StatisticType, MatType, HollowBallBound, SplitType>>
|
||||
{
|
||||
public:
|
||||
static const bool HasOverlappingChildren = true;
|
||||
@@ -226,13 +226,13 @@ class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType,
|
||||
* overlapping children.
|
||||
* See mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename SplitBoundType, typename SplitMatType>
|
||||
class SplitType>
|
||||
class TreeTraits<BinarySpaceTree<MetricType, StatisticType, MatType, CellBound,
|
||||
SplitType>>
|
||||
class TreeTraits<BinarySpaceTree<
|
||||
DistanceType, StatisticType, MatType, CellBound, SplitType>>
|
||||
{
|
||||
public:
|
||||
static const bool HasOverlappingChildren = true;
|
||||
|
||||
@@ -54,8 +54,8 @@ namespace mlpack {
|
||||
*
|
||||
* @see @ref trees, BinarySpaceTree, MeanSplitKDTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using KDTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using KDTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HRectBound,
|
||||
@@ -71,8 +71,8 @@ using KDTree = BinarySpaceTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, BinarySpaceTree, KDTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using MeanSplitKDTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using MeanSplitKDTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HRectBound,
|
||||
@@ -103,8 +103,8 @@ using MeanSplitKDTree = BinarySpaceTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, BinarySpaceTree, KDTree, MeanSplitBallTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using BallTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using BallTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
BallBound,
|
||||
@@ -132,8 +132,8 @@ using BallTree = BinarySpaceTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, BinarySpaceTree, BallTree, MeanSplitKDTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using MeanSplitBallTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using MeanSplitBallTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
BallBound,
|
||||
@@ -190,8 +190,8 @@ template<typename BoundType,
|
||||
typename MatType = arma::mat>
|
||||
using VPTreeSplit = VantagePointSplit<BoundType, MatType, 100>;
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using VPTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using VPTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HollowBallBound,
|
||||
@@ -223,8 +223,8 @@ using VPTree = BinarySpaceTree<MetricType,
|
||||
* @see @ref trees, BinarySpaceTree, BallTree, MeanSplitKDTree
|
||||
*/
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using MaxRPTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using MaxRPTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HRectBound,
|
||||
@@ -257,8 +257,8 @@ using MaxRPTree = BinarySpaceTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, BinarySpaceTree, BallTree, MeanSplitKDTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using RPTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using RPTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HRectBound,
|
||||
@@ -292,8 +292,8 @@ using RPTree = BinarySpaceTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, BinarySpaceTree, BallTree, MeanSplitKDTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using UBTree = BinarySpaceTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using UBTree = BinarySpaceTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
CellBound,
|
||||
|
||||
@@ -34,7 +34,7 @@ class VantagePointSplit
|
||||
//! The matrix element type.
|
||||
typedef typename MatType::elem_type ElemType;
|
||||
//! The bounding shape type.
|
||||
typedef typename BoundType::MetricType MetricType;
|
||||
typedef typename BoundType::DistanceType DistanceType;
|
||||
//! A struct that contains an information about the split.
|
||||
struct SplitInfo
|
||||
{
|
||||
@@ -42,20 +42,20 @@ class VantagePointSplit
|
||||
arma::Col<ElemType> vantagePoint;
|
||||
//! The median distance according to which the node will be split.
|
||||
ElemType mu;
|
||||
//! An instance of the MetricType class.
|
||||
const MetricType* metric;
|
||||
//! An instance of the DistanceType class.
|
||||
const DistanceType* distance;
|
||||
|
||||
SplitInfo() :
|
||||
mu(0),
|
||||
metric(NULL)
|
||||
distance(NULL)
|
||||
{ }
|
||||
|
||||
template<typename VecType>
|
||||
SplitInfo(const MetricType& metric, const VecType& vantagePoint,
|
||||
SplitInfo(const DistanceType& distance, const VecType& vantagePoint,
|
||||
ElemType mu) :
|
||||
vantagePoint(vantagePoint),
|
||||
mu(mu),
|
||||
metric(&metric)
|
||||
distance(&distance)
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -135,7 +135,7 @@ class VantagePointSplit
|
||||
static bool AssignToLeftNode(const VecType& point,
|
||||
const SplitInfo& splitInfo)
|
||||
{
|
||||
return (splitInfo.metric->Evaluate(splitInfo.vantagePoint, point) <
|
||||
return (splitInfo.distance->Evaluate(splitInfo.vantagePoint, point) <
|
||||
splitInfo.mu);
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ class VantagePointSplit
|
||||
* second moment and selects the point with the largest moment. Each random
|
||||
* point belongs to the node.
|
||||
*
|
||||
* @param metric The metric used by the tree.
|
||||
* @param distance The distance metric used by the tree.
|
||||
* @param data The dataset used by the tree.
|
||||
* @param begin Index of the starting point in the dataset that belongs to
|
||||
* this node.
|
||||
@@ -157,7 +157,7 @@ class VantagePointSplit
|
||||
* @param mu The median value of distance form the vantage point to
|
||||
* a number of random points.
|
||||
*/
|
||||
static void SelectVantagePoint(const MetricType& metric,
|
||||
static void SelectVantagePoint(const DistanceType& distance,
|
||||
const MatType& data,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
|
||||
@@ -27,20 +27,21 @@ SplitNode(const BoundType& bound, MatType& data, const size_t begin,
|
||||
size_t vantagePointIndex = 0;
|
||||
|
||||
// Find the best vantage point.
|
||||
SelectVantagePoint(bound.Metric(), data, begin, count, vantagePointIndex, mu);
|
||||
SelectVantagePoint(bound.Distance(), data, begin, count, vantagePointIndex,
|
||||
mu);
|
||||
|
||||
// If all points are equal, we can't split.
|
||||
if (mu == 0)
|
||||
return false;
|
||||
|
||||
splitInfo = SplitInfo(bound.Metric(), data.col(vantagePointIndex), mu);
|
||||
splitInfo = SplitInfo(bound.Distance(), data.col(vantagePointIndex), mu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename BoundType, typename MatType, size_t MaxNumSamples>
|
||||
void VantagePointSplit<BoundType, MatType, MaxNumSamples>::
|
||||
SelectVantagePoint(const MetricType& metric, const MatType& data,
|
||||
SelectVantagePoint(const DistanceType& distance, const MatType& data,
|
||||
const size_t begin, const size_t count, size_t& vantagePoint, ElemType& mu)
|
||||
{
|
||||
arma::Col<ElemType> distances(MaxNumSamples);
|
||||
@@ -74,7 +75,7 @@ SelectVantagePoint(const MetricType& metric, const MatType& data,
|
||||
distances.set_size(samples.n_elem);
|
||||
|
||||
for (size_t j = 0; j < samples.n_elem; ++j)
|
||||
distances[j] = metric.Evaluate(data.col(vantagePointCandidates[i]),
|
||||
distances[j] = distance.Evaluate(data.col(vantagePointCandidates[i]),
|
||||
data.col(samples[j]));
|
||||
|
||||
const ElemType spread = sum(distances % distances) / samples.n_elem;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#define MLPACK_CORE_TREE_BOUNDS_HPP
|
||||
|
||||
#include <mlpack/core/math/range.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
|
||||
#include "bound_traits.hpp"
|
||||
#include "hrectbound.hpp"
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/math/range.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include "bound_traits.hpp"
|
||||
#include "address.hpp"
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace mlpack {
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
template<typename MetricType = LMetric<2, true>,
|
||||
template<typename DistanceType = LMetric<2, true>,
|
||||
typename ElemType = double>
|
||||
class CellBound
|
||||
{
|
||||
@@ -143,10 +143,17 @@ class CellBound
|
||||
//! Modify the minimum width of the bound.
|
||||
ElemType& MinWidth() { return minWidth; }
|
||||
|
||||
//! Get the metric associated with this bound.
|
||||
const MetricType& Metric() const { return metric; }
|
||||
//! Modify the metric associated with this bound.
|
||||
MetricType& Metric() { return metric; }
|
||||
//! Get the distance metric associated with this bound.
|
||||
[[deprecated("Will be removed in 5.0.0; use Distance()")]]
|
||||
const DistanceType& Metric() const { return distance; }
|
||||
//! Modify the distance metric associated with this bound.
|
||||
[[deprecated("Will be removed in 5.0.0; use Distance()")]]
|
||||
DistanceType& Metric() { return distance; }
|
||||
|
||||
//! Get the distance metric associated with this bound.
|
||||
const DistanceType& Distance() const { return distance; }
|
||||
//! Modify the distance metric associated with this bound.
|
||||
DistanceType& Distance() { return distance; }
|
||||
|
||||
/**
|
||||
* Calculates the center of the range, placing it into the given vector.
|
||||
@@ -274,8 +281,8 @@ class CellBound
|
||||
arma::Col<AddressElemType> hiAddress;
|
||||
//! The minimal width of the outer rectangle.
|
||||
ElemType minWidth;
|
||||
//! The instantiated metric (likely has size 0).
|
||||
MetricType metric;
|
||||
//! The instantiated distance metric (likely has size 0).
|
||||
DistanceType distance;
|
||||
|
||||
/**
|
||||
* Add a subrectangle to the bound.
|
||||
@@ -312,8 +319,8 @@ class CellBound
|
||||
};
|
||||
|
||||
// A specialization of BoundTraits for this class.
|
||||
template<typename MetricType, typename ElemType>
|
||||
struct BoundTraits<CellBound<MetricType, ElemType>>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
struct BoundTraits<CellBound<DistanceType, ElemType>>
|
||||
{
|
||||
//! These bounds are always tight for each dimension.
|
||||
const static bool HasTightBounds = true;
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace mlpack {
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline CellBound<MetricType, ElemType>::CellBound() :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<DistanceType, ElemType>::CellBound() :
|
||||
dim(0),
|
||||
bounds(NULL),
|
||||
loBound(arma::Mat<ElemType>()),
|
||||
@@ -39,8 +39,8 @@ inline CellBound<MetricType, ElemType>::CellBound() :
|
||||
* Initializes to specified dimensionality with each dimension the empty
|
||||
* set.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline CellBound<MetricType, ElemType>::CellBound(const size_t dimension) :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<DistanceType, ElemType>::CellBound(const size_t dimension) :
|
||||
dim(dimension),
|
||||
bounds(new RangeType<ElemType>[dim]),
|
||||
loBound(arma::Mat<ElemType>(dim, maxNumBounds)),
|
||||
@@ -60,9 +60,9 @@ inline CellBound<MetricType, ElemType>::CellBound(const size_t dimension) :
|
||||
/**
|
||||
* Copy constructor necessary to prevent memory leaks.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline CellBound<MetricType, ElemType>::CellBound(
|
||||
const CellBound<MetricType, ElemType>& other) :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<DistanceType, ElemType>::CellBound(
|
||||
const CellBound<DistanceType, ElemType>& other) :
|
||||
dim(other.Dim()),
|
||||
bounds(new RangeType<ElemType>[dim]),
|
||||
loBound(other.loBound),
|
||||
@@ -80,11 +80,11 @@ inline CellBound<MetricType, ElemType>::CellBound(
|
||||
/**
|
||||
* Same as the copy constructor.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<
|
||||
MetricType,
|
||||
ElemType>& CellBound<MetricType, ElemType>::operator=(
|
||||
const CellBound<MetricType, ElemType>& other)
|
||||
DistanceType,
|
||||
ElemType>& CellBound<DistanceType, ElemType>::operator=(
|
||||
const CellBound<DistanceType, ElemType>& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
@@ -116,9 +116,9 @@ inline CellBound<
|
||||
/**
|
||||
* Move constructor: take possession of another bound's information.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline CellBound<MetricType, ElemType>::CellBound(
|
||||
CellBound<MetricType, ElemType>&& other) :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<DistanceType, ElemType>::CellBound(
|
||||
CellBound<DistanceType, ElemType>&& other) :
|
||||
dim(other.dim),
|
||||
bounds(other.bounds),
|
||||
loBound(std::move(other.loBound)),
|
||||
@@ -137,8 +137,8 @@ inline CellBound<MetricType, ElemType>::CellBound(
|
||||
/**
|
||||
* Destructor: clean up memory.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline CellBound<MetricType, ElemType>::~CellBound()
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<DistanceType, ElemType>::~CellBound()
|
||||
{
|
||||
if (bounds)
|
||||
delete[] bounds;
|
||||
@@ -147,8 +147,8 @@ inline CellBound<MetricType, ElemType>::~CellBound()
|
||||
/**
|
||||
* Resets all dimensions to the empty set.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline void CellBound<MetricType, ElemType>::Clear()
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline void CellBound<DistanceType, ElemType>::Clear()
|
||||
{
|
||||
for (size_t k = 0; k < dim; ++k)
|
||||
{
|
||||
@@ -166,8 +166,8 @@ inline void CellBound<MetricType, ElemType>::Clear()
|
||||
*
|
||||
* @param centroid Vector which the centroid will be written to.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline void CellBound<MetricType, ElemType>::Center(
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline void CellBound<DistanceType, ElemType>::Center(
|
||||
arma::Col<ElemType>& center) const
|
||||
{
|
||||
// Set size correctly if necessary.
|
||||
@@ -178,9 +178,9 @@ inline void CellBound<MetricType, ElemType>::Center(
|
||||
center(i) = bounds[i].Mid();
|
||||
}
|
||||
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
void CellBound<MetricType, ElemType>::AddBound(
|
||||
void CellBound<DistanceType, ElemType>::AddBound(
|
||||
const arma::Col<ElemType>& loCorner,
|
||||
const arma::Col<ElemType>& hiCorner,
|
||||
const MatType& data)
|
||||
@@ -223,9 +223,9 @@ void CellBound<MetricType, ElemType>::AddBound(
|
||||
}
|
||||
|
||||
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
void CellBound<MetricType, ElemType>::InitHighBound(size_t numEqualBits,
|
||||
void CellBound<DistanceType, ElemType>::InitHighBound(size_t numEqualBits,
|
||||
const MatType& data)
|
||||
{
|
||||
arma::Col<AddressElemType> tmpHiAddress(hiAddress);
|
||||
@@ -312,9 +312,9 @@ void CellBound<MetricType, ElemType>::InitHighBound(size_t numEqualBits,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
void CellBound<MetricType, ElemType>::InitLowerBound(size_t numEqualBits,
|
||||
void CellBound<DistanceType, ElemType>::InitLowerBound(size_t numEqualBits,
|
||||
const MatType& data)
|
||||
{
|
||||
arma::Col<AddressElemType> tmpHiAddress(loAddress);
|
||||
@@ -402,9 +402,9 @@ void CellBound<MetricType, ElemType>::InitLowerBound(size_t numEqualBits,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
void CellBound<MetricType, ElemType>::UpdateAddressBounds(const MatType& data)
|
||||
void CellBound<DistanceType, ElemType>::UpdateAddressBounds(const MatType& data)
|
||||
{
|
||||
numBounds = 0;
|
||||
|
||||
@@ -470,9 +470,9 @@ void CellBound<MetricType, ElemType>::UpdateAddressBounds(const MatType& data)
|
||||
/**
|
||||
* Calculates minimum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline ElemType CellBound<MetricType, ElemType>::MinDistance(
|
||||
inline ElemType CellBound<DistanceType, ElemType>::MinDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -495,9 +495,9 @@ inline ElemType CellBound<MetricType, ElemType>::MinDistance(
|
||||
// each's absolute value to itself and then sum those two, our
|
||||
// result is the non negative half of the equation times two;
|
||||
// then we raise to power Power.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += lower + std::fabs(lower) + higher + std::fabs(higher);
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
ElemType dist = lower + std::fabs(lower) + higher + std::fabs(higher);
|
||||
sum += dist * dist;
|
||||
@@ -505,7 +505,7 @@ inline ElemType CellBound<MetricType, ElemType>::MinDistance(
|
||||
else
|
||||
{
|
||||
sum += std::pow((lower + std::fabs(lower)) +
|
||||
(higher + std::fabs(higher)), (ElemType) MetricType::Power);
|
||||
(higher + std::fabs(higher)), (ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
if (sum >= minSum)
|
||||
@@ -520,30 +520,30 @@ inline ElemType CellBound<MetricType, ElemType>::MinDistance(
|
||||
// to be); then cancel out the constant of 2 (which may have been squared now)
|
||||
// that was introduced earlier. The compiler should optimize out the if
|
||||
// statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return minSum * 0.5;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::sqrt(minSum) * 0.5;
|
||||
else
|
||||
return minSum * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::pow((double) minSum,
|
||||
1.0 / (double) MetricType::Power) / 2.0;
|
||||
1.0 / (double) DistanceType::Power) / 2.0;
|
||||
else
|
||||
return minSum / std::pow(2.0, MetricType::Power);
|
||||
return minSum / std::pow(2.0, DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates minimum bound-to-bound squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
ElemType CellBound<MetricType, ElemType>::MinDistance(const CellBound& other)
|
||||
template<typename DistanceType, typename ElemType>
|
||||
ElemType CellBound<DistanceType, ElemType>::MinDistance(const CellBound& other)
|
||||
const
|
||||
{
|
||||
Log::Assert(dim == other.dim);
|
||||
@@ -565,9 +565,9 @@ ElemType CellBound<MetricType, ElemType>::MinDistance(const CellBound& other)
|
||||
// (x * 2)^2 / 4 = x^2
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += (lower + std::fabs(lower)) + (higher + std::fabs(higher));
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
ElemType dist = lower + std::fabs(lower) + higher + std::fabs(higher);
|
||||
sum += dist * dist;
|
||||
@@ -575,7 +575,7 @@ ElemType CellBound<MetricType, ElemType>::MinDistance(const CellBound& other)
|
||||
else
|
||||
{
|
||||
sum += std::pow((lower + std::fabs(lower)) +
|
||||
(higher + std::fabs(higher)), (ElemType) MetricType::Power);
|
||||
(higher + std::fabs(higher)), (ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
if (sum >= minSum)
|
||||
@@ -587,31 +587,31 @@ ElemType CellBound<MetricType, ElemType>::MinDistance(const CellBound& other)
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return minSum * 0.5;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::sqrt(minSum) * 0.5;
|
||||
else
|
||||
return minSum * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::pow((double) minSum,
|
||||
1.0 / (double) MetricType::Power) / 2.0;
|
||||
1.0 / (double) DistanceType::Power) / 2.0;
|
||||
else
|
||||
return minSum / std::pow(2.0, MetricType::Power);
|
||||
return minSum / std::pow(2.0, DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates maximum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
inline ElemType CellBound<DistanceType, ElemType>::MaxDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -627,12 +627,12 @@ inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
ElemType v = std::max(fabs(point[d] - loBound(d, i)),
|
||||
fabs(hiBound(d, i) - point[d]));
|
||||
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += v; // v is non-negative.
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
sum += v * v;
|
||||
else
|
||||
sum += std::pow(v, (ElemType) MetricType::Power);
|
||||
sum += std::pow(v, (ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
if (sum > maxSum)
|
||||
@@ -640,15 +640,15 @@ inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return maxSum;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return (ElemType) std::sqrt(maxSum);
|
||||
else
|
||||
return (ElemType) std::pow((double) maxSum, 1.0 /
|
||||
(double) MetricType::Power);
|
||||
(double) DistanceType::Power);
|
||||
}
|
||||
|
||||
return maxSum;
|
||||
@@ -657,8 +657,8 @@ inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
/**
|
||||
* Computes maximum distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline ElemType CellBound<DistanceType, ElemType>::MaxDistance(
|
||||
const CellBound& other)
|
||||
const
|
||||
{
|
||||
@@ -677,12 +677,12 @@ inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
fabs(hiBound(d, i) - other.loBound(d, j)));
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += v; // v is non-negative.
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
sum += v * v;
|
||||
else
|
||||
sum += std::pow(v, (ElemType) MetricType::Power);
|
||||
sum += std::pow(v, (ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
if (sum > maxSum)
|
||||
@@ -690,15 +690,15 @@ inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return maxSum;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return (ElemType) std::sqrt(maxSum);
|
||||
else
|
||||
return (ElemType) std::pow((double) maxSum, 1.0 /
|
||||
(double) MetricType::Power);
|
||||
(double) DistanceType::Power);
|
||||
}
|
||||
|
||||
return maxSum;
|
||||
@@ -707,9 +707,9 @@ inline ElemType CellBound<MetricType, ElemType>::MaxDistance(
|
||||
/**
|
||||
* Calculates minimum and maximum bound-to-bound squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline RangeType<ElemType>
|
||||
CellBound<MetricType, ElemType>::RangeDistance(
|
||||
CellBound<DistanceType, ElemType>::RangeDistance(
|
||||
const CellBound& other) const
|
||||
{
|
||||
ElemType minLoSum = std::numeric_limits<ElemType>::max();
|
||||
@@ -741,20 +741,20 @@ CellBound<MetricType, ElemType>::RangeDistance(
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
{
|
||||
loSum += vLo; // vLo is non-negative.
|
||||
hiSum += vHi; // vHi is non-negative.
|
||||
}
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
loSum += vLo * vLo;
|
||||
hiSum += vHi * vHi;
|
||||
}
|
||||
else
|
||||
{
|
||||
loSum += std::pow(vLo, (ElemType) MetricType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) MetricType::Power);
|
||||
loSum += std::pow(vLo, (ElemType) DistanceType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -764,20 +764,20 @@ CellBound<MetricType, ElemType>::RangeDistance(
|
||||
maxHiSum = hiSum;
|
||||
}
|
||||
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return RangeType<ElemType>(minLoSum, maxHiSum);
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return RangeType<ElemType>((ElemType) std::sqrt(minLoSum),
|
||||
(ElemType) std::sqrt(maxHiSum));
|
||||
else
|
||||
{
|
||||
return RangeType<ElemType>(
|
||||
(ElemType) std::pow((double) minLoSum, 1.0 /
|
||||
(double) MetricType::Power),
|
||||
(double) DistanceType::Power),
|
||||
(ElemType) std::pow((double) maxHiSum, 1.0 /
|
||||
(double) MetricType::Power));
|
||||
(double) DistanceType::Power));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,10 +787,10 @@ CellBound<MetricType, ElemType>::RangeDistance(
|
||||
/**
|
||||
* Calculates minimum and maximum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline RangeType<ElemType>
|
||||
CellBound<MetricType, ElemType>::RangeDistance(
|
||||
CellBound<DistanceType, ElemType>::RangeDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -830,20 +830,20 @@ CellBound<MetricType, ElemType>::RangeDistance(
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
{
|
||||
loSum += vLo; // vLo is non-negative.
|
||||
hiSum += vHi; // vHi is non-negative.
|
||||
}
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
loSum += vLo * vLo;
|
||||
hiSum += vHi * vHi;
|
||||
}
|
||||
else
|
||||
{
|
||||
loSum += std::pow(vLo, (ElemType) MetricType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) MetricType::Power);
|
||||
loSum += std::pow(vLo, (ElemType) DistanceType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) DistanceType::Power);
|
||||
}
|
||||
}
|
||||
if (loSum < minLoSum)
|
||||
@@ -852,20 +852,20 @@ CellBound<MetricType, ElemType>::RangeDistance(
|
||||
maxHiSum = hiSum;
|
||||
}
|
||||
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return RangeType<ElemType>(minLoSum, maxHiSum);
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return RangeType<ElemType>((ElemType) std::sqrt(minLoSum),
|
||||
(ElemType) std::sqrt(maxHiSum));
|
||||
else
|
||||
{
|
||||
return RangeType<ElemType>(
|
||||
(ElemType) std::pow((double) minLoSum, 1.0 /
|
||||
(double) MetricType::Power),
|
||||
(double) DistanceType::Power),
|
||||
(ElemType) std::pow((double) maxHiSum, 1.0 /
|
||||
(double) MetricType::Power));
|
||||
(double) DistanceType::Power));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,10 +875,10 @@ CellBound<MetricType, ElemType>::RangeDistance(
|
||||
/**
|
||||
* Expands this region to include a new point.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
inline CellBound<MetricType, ElemType>&
|
||||
CellBound<MetricType, ElemType>::operator|=(const MatType& data)
|
||||
inline CellBound<DistanceType, ElemType>&
|
||||
CellBound<DistanceType, ElemType>::operator|=(const MatType& data)
|
||||
{
|
||||
Log::Assert(data.n_rows == dim);
|
||||
|
||||
@@ -905,9 +905,9 @@ CellBound<MetricType, ElemType>::operator|=(const MatType& data)
|
||||
/**
|
||||
* Expands this region to encompass another bound.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline CellBound<MetricType, ElemType>&
|
||||
CellBound<MetricType, ElemType>::operator|=(const CellBound& other)
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline CellBound<DistanceType, ElemType>&
|
||||
CellBound<DistanceType, ElemType>::operator|=(const CellBound& other)
|
||||
{
|
||||
assert(other.dim == dim);
|
||||
|
||||
@@ -943,9 +943,9 @@ CellBound<MetricType, ElemType>::operator|=(const CellBound& other)
|
||||
/**
|
||||
* Determines if a point is within this bound.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline bool CellBound<MetricType, ElemType>::Contains(
|
||||
inline bool CellBound<DistanceType, ElemType>::Contains(
|
||||
const VecType& point) const
|
||||
{
|
||||
for (size_t i = 0; i < point.n_elem; ++i)
|
||||
@@ -968,24 +968,24 @@ inline bool CellBound<MetricType, ElemType>::Contains(
|
||||
/**
|
||||
* Returns the diameter of the hyperrectangle (that is, the longest diagonal).
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline ElemType CellBound<MetricType, ElemType>::Diameter() const
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline ElemType CellBound<DistanceType, ElemType>::Diameter() const
|
||||
{
|
||||
ElemType d = 0;
|
||||
for (size_t i = 0; i < dim; ++i)
|
||||
d += std::pow(bounds[i].Hi() - bounds[i].Lo(),
|
||||
(ElemType) MetricType::Power);
|
||||
(ElemType) DistanceType::Power);
|
||||
|
||||
if (MetricType::TakeRoot)
|
||||
return (ElemType) std::pow((double) d, 1.0 / (double) MetricType::Power);
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::pow((double) d, 1.0 / (double) DistanceType::Power);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
//! Serialize the bound object.
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename Archive>
|
||||
void CellBound<MetricType, ElemType>::serialize(
|
||||
void CellBound<DistanceType, ElemType>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
@@ -996,7 +996,7 @@ void CellBound<MetricType, ElemType>::serialize(
|
||||
ar(CEREAL_NVP(numBounds));
|
||||
ar(CEREAL_NVP(loAddress));
|
||||
ar(CEREAL_NVP(hiAddress));
|
||||
ar(CEREAL_NVP(metric));
|
||||
ar(CEREAL_NVP(distance));
|
||||
}
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -78,20 +78,20 @@ namespace mlpack {
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* The CoverTree class offers three template parameters; a custom metric type
|
||||
* can be used with MetricType (this class defaults to the L2-squared metric).
|
||||
* The root node's point can be chosen with the RootPointPolicy; by default, the
|
||||
* FirstPointIsRoot policy is used, meaning the first point in the dataset is
|
||||
* used. The StatisticType policy allows you to define statistics which can be
|
||||
* gathered during the creation of the tree.
|
||||
* The CoverTree class offers three template parameters; a custom distance
|
||||
* metric type can be used with DistanceType (this class defaults to the
|
||||
* L2-squared metric). The root node's point can be chosen with the
|
||||
* RootPointPolicy; by default, the FirstPointIsRoot policy is used, meaning the
|
||||
* first point in the dataset is used. The StatisticType policy allows you to
|
||||
* define statistics which can be gathered during the creation of the tree.
|
||||
*
|
||||
* @tparam MetricType Metric type to use during tree construction.
|
||||
* @tparam DistanceType Metric type to use during tree construction.
|
||||
* @tparam RootPointPolicy Determines which point to use as the root node.
|
||||
* @tparam StatisticType Statistic to be used during tree creation.
|
||||
* @tparam MatType Type of matrix to build the tree on (generally mat or
|
||||
* sp_mat).
|
||||
*/
|
||||
template<typename MetricType = LMetric<2, true>,
|
||||
template<typename DistanceType = LMetric<2, true>,
|
||||
typename StatisticType = EmptyStatistic,
|
||||
typename MatType = arma::mat,
|
||||
typename RootPointPolicy = FirstPointIsRoot>
|
||||
@@ -112,23 +112,23 @@ class CoverTree
|
||||
*
|
||||
* @param dataset Reference to the dataset to build a tree on.
|
||||
* @param base Base to use during tree building (default 2.0).
|
||||
* @param metric Metric to use (default NULL).
|
||||
* @param distance Distance metric to use (default NULL).
|
||||
*/
|
||||
CoverTree(const MatType& dataset,
|
||||
const ElemType base = 2.0,
|
||||
MetricType* metric = NULL);
|
||||
DistanceType* distance = NULL);
|
||||
|
||||
/**
|
||||
* Create the cover tree with the given dataset and the given instantiated
|
||||
* metric. Optionally, set the base. The dataset will not be modified during
|
||||
* the building procedure (unlike BinarySpaceTree).
|
||||
* distance metric. Optionally, set the base. The dataset will not be
|
||||
* modified during the building procedure (unlike BinarySpaceTree).
|
||||
*
|
||||
* @param dataset Reference to the dataset to build a tree on.
|
||||
* @param metric Instantiated metric to use during tree building.
|
||||
* @param distance Instantiated distance metric to use during tree building.
|
||||
* @param base Base to use during tree building (default 2.0).
|
||||
*/
|
||||
CoverTree(const MatType& dataset,
|
||||
MetricType& metric,
|
||||
DistanceType& distance,
|
||||
const ElemType base = 2.0);
|
||||
|
||||
/**
|
||||
@@ -143,14 +143,15 @@ class CoverTree
|
||||
|
||||
/**
|
||||
* Create the cover tree with the given dataset and the given instantiated
|
||||
* metric, taking ownership of the dataset. Optionally, set the base.
|
||||
* distance metric, taking ownership of the dataset. Optionally, set the
|
||||
* base.
|
||||
*
|
||||
* @param dataset Reference to the dataset to build a tree on.
|
||||
* @param metric Instantiated metric to use during tree building.
|
||||
* @param distance Instantiated distance metric to use during tree building.
|
||||
* @param base Base to use during tree building (default 2.0).
|
||||
*/
|
||||
CoverTree(MatType&& dataset,
|
||||
MetricType& metric,
|
||||
DistanceType& distance,
|
||||
const ElemType base = 2.0);
|
||||
|
||||
/**
|
||||
@@ -183,7 +184,7 @@ class CoverTree
|
||||
* @param farSetSize Size of the far set; may be modified (if this node uses
|
||||
* any points in the far set).
|
||||
* @param usedSetSize The number of points used will be added to this number.
|
||||
* @param metric Metric to use (default NULL).
|
||||
* @param distance Distance metric to use (default NULL).
|
||||
*/
|
||||
CoverTree(const MatType& dataset,
|
||||
const ElemType base,
|
||||
@@ -196,7 +197,7 @@ class CoverTree
|
||||
size_t nearSetSize,
|
||||
size_t& farSetSize,
|
||||
size_t& usedSetSize,
|
||||
MetricType& metric = NULL);
|
||||
DistanceType& distance = NULL);
|
||||
|
||||
/**
|
||||
* Manually construct a cover tree node; no tree assembly is done in this
|
||||
@@ -212,7 +213,7 @@ class CoverTree
|
||||
* @param parent Parent node (NULL indicates no parent).
|
||||
* @param parentDistance Distance to parent node point.
|
||||
* @param furthestDescendantDistance Distance to furthest descendant point.
|
||||
* @param metric Instantiated metric (optional).
|
||||
* @param distance Instantiated distance metric (optional).
|
||||
*/
|
||||
CoverTree(const MatType& dataset,
|
||||
const ElemType base,
|
||||
@@ -221,7 +222,7 @@ class CoverTree
|
||||
CoverTree* parent,
|
||||
const ElemType parentDistance,
|
||||
const ElemType furthestDescendantDistance,
|
||||
MetricType* metric = NULL);
|
||||
DistanceType* distance = NULL);
|
||||
|
||||
/**
|
||||
* Create a cover tree from another tree. Be careful! This may use a lot of
|
||||
@@ -429,8 +430,12 @@ class CoverTree
|
||||
center = arma::vec(dataset->col(point));
|
||||
}
|
||||
|
||||
//! Get the instantiated metric.
|
||||
MetricType& Metric() const { return *metric; }
|
||||
//! Get the instantiated distance metric.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType& Metric() const { return *distance; }
|
||||
|
||||
//! Get the instantiated distance metric.
|
||||
DistanceType& Distance() const { return *distance; }
|
||||
|
||||
private:
|
||||
//! Reference to the matrix which this tree is built on.
|
||||
@@ -453,12 +458,12 @@ class CoverTree
|
||||
ElemType parentDistance;
|
||||
//! Distance to the furthest descendant.
|
||||
ElemType furthestDescendantDistance;
|
||||
//! Whether or not we need to destroy the metric in the destructor.
|
||||
bool localMetric;
|
||||
//! Whether or not we need to destroy the distance metric in the destructor.
|
||||
bool localDistance;
|
||||
//! If true, we own the dataset and need to destroy it in the destructor.
|
||||
bool localDataset;
|
||||
//! The metric used for this tree.
|
||||
MetricType* metric;
|
||||
//! The distance metric used for this tree.
|
||||
DistanceType* distance;
|
||||
|
||||
/**
|
||||
* Create the children for this node.
|
||||
|
||||
@@ -34,15 +34,15 @@ void BuildStatistics(TreeType* node)
|
||||
|
||||
// Create the cover tree.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
const MatType& dataset,
|
||||
const ElemType base,
|
||||
MetricType* metric) :
|
||||
DistanceType* distance) :
|
||||
dataset(&dataset),
|
||||
point(RootPointPolicy::ChooseRoot(dataset)),
|
||||
scale(INT_MAX),
|
||||
@@ -51,14 +51,15 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(NULL),
|
||||
parentDistance(0),
|
||||
furthestDescendantDistance(0),
|
||||
localMetric(metric == NULL),
|
||||
localDistance(distance == NULL),
|
||||
localDataset(false),
|
||||
metric(metric),
|
||||
distance(distance),
|
||||
distanceComps(0)
|
||||
{
|
||||
// If we need to create a metric, do that. We'll just do it on the heap.
|
||||
if (localMetric)
|
||||
this->metric = new MetricType();
|
||||
// If we need to create a distance metric, do that. We'll just do it on the
|
||||
// heap.
|
||||
if (localDistance)
|
||||
this->distance = new DistanceType();
|
||||
|
||||
// If there is only one point or zero points in the dataset... uh, we're done.
|
||||
// Technically, if the dataset has zero points, our node is not correct...
|
||||
@@ -134,14 +135,14 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
const MatType& dataset,
|
||||
MetricType& metric,
|
||||
DistanceType& distance,
|
||||
const ElemType base) :
|
||||
dataset(&dataset),
|
||||
point(RootPointPolicy::ChooseRoot(dataset)),
|
||||
@@ -151,9 +152,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(NULL),
|
||||
parentDistance(0),
|
||||
furthestDescendantDistance(0),
|
||||
localMetric(true),
|
||||
localDistance(true),
|
||||
localDataset(false),
|
||||
metric(new MetricType(metric)),
|
||||
distance(new DistanceType(distance)),
|
||||
distanceComps(0)
|
||||
{
|
||||
// If there is only one point or zero points in the dataset... uh, we're done.
|
||||
@@ -230,12 +231,12 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
MatType&& data,
|
||||
const ElemType base) :
|
||||
dataset(new MatType(std::move(data))),
|
||||
@@ -246,12 +247,12 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(NULL),
|
||||
parentDistance(0),
|
||||
furthestDescendantDistance(0),
|
||||
localMetric(true),
|
||||
localDistance(true),
|
||||
localDataset(true),
|
||||
distanceComps(0)
|
||||
{
|
||||
// We need to create a metric. We'll just do it on the heap.
|
||||
this->metric = new MetricType();
|
||||
// We need to create a distance metric. We'll just do it on the heap.
|
||||
this->distance = new DistanceType();
|
||||
|
||||
// If there is only one point or zero points in the dataset... uh, we're done.
|
||||
// Technically, if the dataset has zero points, our node is not correct...
|
||||
@@ -327,14 +328,14 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
MatType&& data,
|
||||
MetricType& metric,
|
||||
DistanceType& distance,
|
||||
const ElemType base) :
|
||||
dataset(new MatType(std::move(data))),
|
||||
point(RootPointPolicy::ChooseRoot(dataset)),
|
||||
@@ -344,9 +345,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(NULL),
|
||||
parentDistance(0),
|
||||
furthestDescendantDistance(0),
|
||||
localMetric(true),
|
||||
localDistance(true),
|
||||
localDataset(true),
|
||||
metric(new MetricType(metric)),
|
||||
distance(new DistanceType(distance)),
|
||||
distanceComps(0)
|
||||
{
|
||||
// If there is only one point or zero points in the dataset... uh, we're done.
|
||||
@@ -423,12 +424,12 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
const MatType& dataset,
|
||||
const ElemType base,
|
||||
const size_t pointIndex,
|
||||
@@ -440,7 +441,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
size_t nearSetSize,
|
||||
size_t& farSetSize,
|
||||
size_t& usedSetSize,
|
||||
MetricType& metric) :
|
||||
DistanceType& distance) :
|
||||
dataset(&dataset),
|
||||
point(pointIndex),
|
||||
scale(scale),
|
||||
@@ -449,9 +450,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(parent),
|
||||
parentDistance(parentDistance),
|
||||
furthestDescendantDistance(0),
|
||||
localMetric(false),
|
||||
localDistance(false),
|
||||
localDataset(false),
|
||||
metric(&metric),
|
||||
distance(&distance),
|
||||
distanceComps(0)
|
||||
{
|
||||
// If the size of the near set is 0, this is a leaf.
|
||||
@@ -468,12 +469,12 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
|
||||
// Manually create a cover tree node.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
const MatType& dataset,
|
||||
const ElemType base,
|
||||
const size_t pointIndex,
|
||||
@@ -481,7 +482,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree* parent,
|
||||
const ElemType parentDistance,
|
||||
const ElemType furthestDescendantDistance,
|
||||
MetricType* metric) :
|
||||
DistanceType* distance) :
|
||||
dataset(&dataset),
|
||||
point(pointIndex),
|
||||
scale(scale),
|
||||
@@ -490,24 +491,24 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(parent),
|
||||
parentDistance(parentDistance),
|
||||
furthestDescendantDistance(furthestDescendantDistance),
|
||||
localMetric(metric == NULL),
|
||||
localDistance(distance == NULL),
|
||||
localDataset(false),
|
||||
metric(metric),
|
||||
distance(distance),
|
||||
distanceComps(0)
|
||||
{
|
||||
// If necessary, create a local metric.
|
||||
if (localMetric)
|
||||
this->metric = new MetricType();
|
||||
// If necessary, create a local distance metric.
|
||||
if (localDistance)
|
||||
this->distance = new DistanceType();
|
||||
}
|
||||
|
||||
// Copy Constructor.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
const CoverTree& other) :
|
||||
dataset((other.parent == NULL && other.localDataset) ?
|
||||
new MatType(*other.dataset) : other.dataset),
|
||||
@@ -519,9 +520,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(other.parent),
|
||||
parentDistance(other.parentDistance),
|
||||
furthestDescendantDistance(other.furthestDescendantDistance),
|
||||
localMetric(other.localMetric),
|
||||
localDistance(other.localDistance),
|
||||
localDataset(other.parent == NULL && other.localDataset),
|
||||
metric((other.localMetric ? new MetricType() : other.metric)),
|
||||
distance((other.localDistance ? new DistanceType() : other.distance)),
|
||||
distanceComps(0)
|
||||
{
|
||||
// Copy each child by hand.
|
||||
@@ -553,13 +554,13 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
|
||||
// Copy assignment operator: copy the given other tree.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>&
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>&
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
operator=(const CoverTree& other)
|
||||
{
|
||||
if (this == &other)
|
||||
@@ -569,8 +570,8 @@ operator=(const CoverTree& other)
|
||||
if (localDataset)
|
||||
delete dataset;
|
||||
|
||||
if (localMetric)
|
||||
delete metric;
|
||||
if (localDistance)
|
||||
delete distance;
|
||||
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
delete children[i];
|
||||
@@ -586,9 +587,9 @@ operator=(const CoverTree& other)
|
||||
parent = other.parent;
|
||||
parentDistance = other.parentDistance;
|
||||
furthestDescendantDistance = other.furthestDescendantDistance;
|
||||
localMetric = other.localMetric;
|
||||
localDistance = other.localDistance;
|
||||
localDataset = (other.parent == NULL && other.localDataset);
|
||||
metric = (other.localMetric ? new MetricType() : other.metric);
|
||||
distance = (other.localDistance ? new DistanceType() : other.distance);
|
||||
distanceComps = 0;
|
||||
|
||||
// Copy each child by hand.
|
||||
@@ -622,12 +623,12 @@ operator=(const CoverTree& other)
|
||||
|
||||
// Move Constructor.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree&& other) :
|
||||
dataset(other.dataset),
|
||||
point(other.point),
|
||||
@@ -639,9 +640,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
parent(other.parent),
|
||||
parentDistance(other.parentDistance),
|
||||
furthestDescendantDistance(other.furthestDescendantDistance),
|
||||
localMetric(other.localMetric),
|
||||
localDistance(other.localDistance),
|
||||
localDataset(other.localDataset),
|
||||
metric(other.metric),
|
||||
distance(other.distance),
|
||||
distanceComps(other.distanceComps)
|
||||
{
|
||||
// Set proper parent pointer.
|
||||
@@ -656,20 +657,20 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
other.parent = NULL;
|
||||
other.parentDistance = 0;
|
||||
other.furthestDescendantDistance = 0;
|
||||
other.localMetric = false;
|
||||
other.localDistance = false;
|
||||
other.localDataset = false;
|
||||
other.metric = NULL;
|
||||
other.distance = NULL;
|
||||
}
|
||||
|
||||
// Move assignment operator: take ownership of the given tree.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>&
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>&
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
operator=(CoverTree&& other)
|
||||
{
|
||||
if (this == &other)
|
||||
@@ -679,8 +680,8 @@ operator=(CoverTree&& other)
|
||||
if (localDataset)
|
||||
delete dataset;
|
||||
|
||||
if (localMetric)
|
||||
delete metric;
|
||||
if (localDistance)
|
||||
delete distance;
|
||||
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
delete children[i];
|
||||
@@ -695,9 +696,9 @@ operator=(CoverTree&& other)
|
||||
parent = other.parent;
|
||||
parentDistance = other.parentDistance;
|
||||
furthestDescendantDistance = other.furthestDescendantDistance;
|
||||
localMetric = other.localMetric;
|
||||
localDistance = other.localDistance;
|
||||
localDataset = other.localDataset;
|
||||
metric = other.metric;
|
||||
distance = other.distance;
|
||||
distanceComps = other.distanceComps;
|
||||
|
||||
// Set proper parent pointer.
|
||||
@@ -712,22 +713,22 @@ operator=(CoverTree&& other)
|
||||
other.parent = NULL;
|
||||
other.parentDistance = 0;
|
||||
other.furthestDescendantDistance = 0;
|
||||
other.localMetric = false;
|
||||
other.localDistance = false;
|
||||
other.localDataset = false;
|
||||
other.metric = NULL;
|
||||
other.distance = NULL;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Construct from a cereal archive.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename Archive>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
Archive& ar,
|
||||
const typename std::enable_if_t<cereal::is_loading<Archive>()>*) :
|
||||
CoverTree() // Create an empty CoverTree.
|
||||
@@ -738,20 +739,20 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree(
|
||||
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::~CoverTree()
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::~CoverTree()
|
||||
{
|
||||
// Delete each child.
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
delete children[i];
|
||||
|
||||
// Delete the local metric, if necessary.
|
||||
if (localMetric)
|
||||
delete metric;
|
||||
// Delete the local distance metric, if necessary.
|
||||
if (localDistance)
|
||||
delete distance;
|
||||
|
||||
// Delete the local dataset, if necessary.
|
||||
if (localDataset)
|
||||
@@ -760,13 +761,13 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::~CoverTree()
|
||||
|
||||
//! Return the number of descendant points.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
inline size_t
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
NumDescendants() const
|
||||
{
|
||||
return numDescendants;
|
||||
@@ -774,13 +775,13 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
|
||||
//! Return the index of a particular descendant point.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
inline size_t
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::Descendant(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::Descendant(
|
||||
const size_t index) const
|
||||
{
|
||||
// The first descendant is the point contained within this node.
|
||||
@@ -808,12 +809,12 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::Descendant(
|
||||
* Return the index of the nearest child node to the given query point. If
|
||||
* this is a leaf node, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy>
|
||||
template<typename VecType>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
GetNearestChild(const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
{
|
||||
@@ -838,12 +839,12 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
* Return the index of the furthest child node to the given query point. If
|
||||
* this is a leaf node, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy>
|
||||
template<typename VecType>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
GetFurthestChild(const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
{
|
||||
@@ -868,11 +869,11 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
* Return the index of the nearest child node to the given query node. If it
|
||||
* can't decide, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
GetNearestChild(const CoverTree& queryNode)
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -896,11 +897,11 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
* Return the index of the furthest child node to the given query node. If it
|
||||
* can't decide, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
GetFurthestChild(const CoverTree& queryNode)
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -921,31 +922,31 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MinDistance(const CoverTree& other) const
|
||||
{
|
||||
// Every cover tree node will contain points up to base^(scale + 1) away.
|
||||
return std::max(metric->Evaluate(dataset->col(point),
|
||||
return std::max(distance->Evaluate(dataset->col(point),
|
||||
other.Dataset().col(other.Point())) -
|
||||
furthestDescendantDistance - other.FurthestDescendantDistance(), 0.0);
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MinDistance(const CoverTree& other, const ElemType distance) const
|
||||
{
|
||||
// We already have the distance as evaluated by the metric.
|
||||
@@ -954,59 +955,59 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MinDistance(const arma::vec& other) const
|
||||
{
|
||||
return std::max(metric->Evaluate(dataset->col(point), other) -
|
||||
return std::max(distance->Evaluate(dataset->col(point), other) -
|
||||
furthestDescendantDistance, 0.0);
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MinDistance(const arma::vec& /* other */, const ElemType distance) const
|
||||
{
|
||||
return std::max(distance - furthestDescendantDistance, 0.0);
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MaxDistance(const CoverTree& other) const
|
||||
{
|
||||
return metric->Evaluate(dataset->col(point),
|
||||
return distance->Evaluate(dataset->col(point),
|
||||
other.Dataset().col(other.Point())) +
|
||||
furthestDescendantDistance + other.FurthestDescendantDistance();
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MaxDistance(const CoverTree& other, const ElemType distance) const
|
||||
{
|
||||
// We already have the distance as evaluated by the metric.
|
||||
@@ -1015,29 +1016,29 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MaxDistance(const arma::vec& other) const
|
||||
{
|
||||
return metric->Evaluate(dataset->col(point), other) +
|
||||
return distance->Evaluate(dataset->col(point), other) +
|
||||
furthestDescendantDistance;
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
typename CoverTree<MetricType, StatisticType, MatType,
|
||||
typename CoverTree<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy>::ElemType
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MaxDistance(const arma::vec& /* other */, const ElemType distance) const
|
||||
{
|
||||
return distance + furthestDescendantDistance;
|
||||
@@ -1045,23 +1046,23 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
|
||||
//! Return the minimum and maximum distance to another node.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
RangeType<typename
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
RangeDistance(const CoverTree& other) const
|
||||
{
|
||||
const ElemType distance = metric->Evaluate(dataset->col(point),
|
||||
const ElemType dist = distance->Evaluate(dataset->col(point),
|
||||
other.Dataset().col(other.Point()));
|
||||
|
||||
RangeType<ElemType> result;
|
||||
result.Lo() = std::max(distance - furthestDescendantDistance -
|
||||
result.Lo() = std::max(dist - furthestDescendantDistance -
|
||||
other.FurthestDescendantDistance(), 0.0);
|
||||
result.Hi() = distance + furthestDescendantDistance +
|
||||
result.Hi() = dist + furthestDescendantDistance +
|
||||
other.FurthestDescendantDistance();
|
||||
|
||||
return result;
|
||||
@@ -1070,14 +1071,14 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
//! Return the minimum and maximum distance to another node given that the
|
||||
//! point-to-point distance has already been calculated.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
RangeType<typename
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
RangeDistance(const CoverTree& other,
|
||||
const ElemType distance) const
|
||||
{
|
||||
@@ -1092,34 +1093,34 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
|
||||
//! Return the minimum and maximum distance to another point.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
RangeType<typename
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
RangeDistance(const arma::vec& other) const
|
||||
{
|
||||
const ElemType distance = metric->Evaluate(dataset->col(point), other);
|
||||
const ElemType dist = distance->Evaluate(dataset->col(point), other);
|
||||
|
||||
return RangeType<ElemType>(
|
||||
std::max(distance - furthestDescendantDistance, 0.0),
|
||||
distance + furthestDescendantDistance);
|
||||
std::max(dist - furthestDescendantDistance, 0.0),
|
||||
dist + furthestDescendantDistance);
|
||||
}
|
||||
|
||||
//! Return the minimum and maximum distance to another point given that the
|
||||
//! point-to-point distance has already been calculated.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
RangeType<typename
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::ElemType>
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
RangeDistance(const arma::vec& /* other */,
|
||||
const ElemType distance) const
|
||||
{
|
||||
@@ -1130,13 +1131,13 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
|
||||
//! For a newly initialized node, create children using the near and far set.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
inline void
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
arma::Col<size_t>& indices,
|
||||
arma::vec& distances,
|
||||
size_t nearSetSize,
|
||||
@@ -1159,7 +1160,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
// This should not modify farSetSize or usedSetSize.
|
||||
size_t tempSize = 0;
|
||||
children.push_back(new CoverTree(*dataset, base, point, INT_MIN, this, 0,
|
||||
indices, distances, 0, tempSize, usedSetSize, *metric));
|
||||
indices, distances, 0, tempSize, usedSetSize, *distance));
|
||||
distanceComps += children.back()->DistanceComps();
|
||||
|
||||
// Every point in the near set should be a leaf.
|
||||
@@ -1168,7 +1169,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
// farSetSize and usedSetSize will not be modified.
|
||||
children.push_back(new CoverTree(*dataset, base, indices[i],
|
||||
INT_MIN, this, distances[i], indices, distances, 0, tempSize,
|
||||
usedSetSize, *metric));
|
||||
usedSetSize, *distance));
|
||||
distanceComps += children.back()->DistanceComps();
|
||||
usedSetSize++;
|
||||
}
|
||||
@@ -1200,7 +1201,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
size_t childUsedSetSize = 0;
|
||||
children.push_back(new CoverTree(*dataset, base, point, nextScale, this, 0,
|
||||
indices, distances, childNearSetSize, childFarSetSize, childUsedSetSize,
|
||||
*metric));
|
||||
*distance));
|
||||
// Don't double-count the self-child (so, subtract one).
|
||||
numDescendants += children[0]->NumDescendants();
|
||||
|
||||
@@ -1258,7 +1259,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
size_t childNearSetSize = 0;
|
||||
children.push_back(new CoverTree(*dataset, base, indices[0], nextScale,
|
||||
this, distances[0], indices, distances, childNearSetSize, farSetSize,
|
||||
usedSetSize, *metric));
|
||||
usedSetSize, *distance));
|
||||
distanceComps += children.back()->DistanceComps();
|
||||
numDescendants += children.back()->NumDescendants();
|
||||
|
||||
@@ -1300,7 +1301,7 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
childUsedSetSize = 1; // Mark self point as used.
|
||||
children.push_back(new CoverTree(*dataset, base, indices[0], nextScale,
|
||||
this, distances[0], childIndices, childDistances, childNearSetSize,
|
||||
childFarSetSize, childUsedSetSize, *metric));
|
||||
childFarSetSize, childUsedSetSize, *distance));
|
||||
numDescendants += children.back()->NumDescendants();
|
||||
|
||||
// Remove any implicit nodes.
|
||||
@@ -1325,12 +1326,12 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CreateChildren(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
SplitNearFar(arma::Col<size_t>& indices,
|
||||
arma::vec& distances,
|
||||
const ElemType bound,
|
||||
@@ -1383,12 +1384,12 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
|
||||
// Returns the maximum distance between points.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
ComputeDistances(const size_t pointIndex,
|
||||
const arma::Col<size_t>& indices,
|
||||
arma::vec& distances,
|
||||
@@ -1399,18 +1400,18 @@ void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
distanceComps += pointSetSize;
|
||||
for (size_t i = 0; i < pointSetSize; ++i)
|
||||
{
|
||||
distances[i] = metric->Evaluate(dataset->col(pointIndex),
|
||||
distances[i] = distance->Evaluate(dataset->col(pointIndex),
|
||||
dataset->col(indices[i]));
|
||||
}
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
SortPointSet(arma::Col<size_t>& indices,
|
||||
arma::vec& distances,
|
||||
const size_t childFarSetSize,
|
||||
@@ -1470,12 +1471,12 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
MoveToUsedSet(arma::Col<size_t>& indices,
|
||||
arma::vec& distances,
|
||||
size_t& nearSetSize,
|
||||
@@ -1616,12 +1617,12 @@ void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
size_t CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
PruneFarSet(arma::Col<size_t>& indices,
|
||||
arma::vec& distances,
|
||||
const ElemType bound,
|
||||
@@ -1662,12 +1663,12 @@ size_t CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
* implicit nodes that have been created.
|
||||
*/
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
inline void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
inline void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
RemoveNewImplicitNodes()
|
||||
{
|
||||
// If we created an implicit node, take its self-child instead (this could
|
||||
@@ -1697,12 +1698,12 @@ inline void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
* Default constructor, only for use with cereal.
|
||||
*/
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree() :
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::CoverTree() :
|
||||
dataset(NULL),
|
||||
point(0),
|
||||
scale(INT_MIN),
|
||||
@@ -1711,9 +1712,9 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree() :
|
||||
parent(NULL),
|
||||
parentDistance(0.0),
|
||||
furthestDescendantDistance(0.0),
|
||||
localMetric(false),
|
||||
localDistance(false),
|
||||
localDataset(false),
|
||||
metric(NULL),
|
||||
distance(NULL),
|
||||
distanceComps(0)
|
||||
{
|
||||
// Nothing to do.
|
||||
@@ -1723,25 +1724,26 @@ CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::CoverTree() :
|
||||
* Serialize to/from a cereal archive.
|
||||
*/
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename Archive>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::serialize(
|
||||
void
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
// If we're loading, and we have children, they need to be deleted. We may
|
||||
// also need to delete the local metric and dataset.
|
||||
// also need to delete the local distance metric and dataset.
|
||||
if (cereal::is_loading<Archive>())
|
||||
{
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
delete children[i];
|
||||
|
||||
if (localMetric && metric)
|
||||
delete metric;
|
||||
if (localDistance && distance)
|
||||
delete distance;
|
||||
if (localDataset && dataset)
|
||||
delete dataset;
|
||||
|
||||
@@ -1761,11 +1763,11 @@ void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::serialize(
|
||||
ar(CEREAL_NVP(numDescendants));
|
||||
ar(CEREAL_NVP(parentDistance));
|
||||
ar(CEREAL_NVP(furthestDescendantDistance));
|
||||
ar(CEREAL_POINTER(metric));
|
||||
ar(CEREAL_POINTER(distance));
|
||||
|
||||
if (cereal::is_loading<Archive>() && !hasParent)
|
||||
{
|
||||
localMetric = true;
|
||||
localDistance = true;
|
||||
localDataset = true;
|
||||
}
|
||||
|
||||
@@ -1777,7 +1779,7 @@ void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::serialize(
|
||||
// Look through each child individually.
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
{
|
||||
children[i]->localMetric = false;
|
||||
children[i]->localDistance = false;
|
||||
children[i]->localDataset = false;
|
||||
children[i]->Parent() = this;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
namespace mlpack {
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
class CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
class CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
DualTreeTraverser
|
||||
{
|
||||
public:
|
||||
@@ -63,7 +63,7 @@ class CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
struct DualCoverTreeMapEntry
|
||||
{
|
||||
//! The node this entry refers to.
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>*
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>*
|
||||
referenceNode;
|
||||
//! The score of the node.
|
||||
double score;
|
||||
|
||||
@@ -18,26 +18,26 @@
|
||||
namespace mlpack {
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
DualTreeTraverser<RuleType>::DualTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
DualTreeTraverser<RuleType>::Traverse(CoverTree& queryNode,
|
||||
CoverTree& referenceNode)
|
||||
{
|
||||
@@ -60,13 +60,13 @@ DualTreeTraverser<RuleType>::Traverse(CoverTree& queryNode,
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
DualTreeTraverser<RuleType>::Traverse(
|
||||
CoverTree& queryNode,
|
||||
std::map<int, std::vector<DualCoverTreeMapEntry>, std::greater<int>>&
|
||||
@@ -150,13 +150,13 @@ DualTreeTraverser<RuleType>::Traverse(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
DualTreeTraverser<RuleType>::PruneMap(
|
||||
CoverTree& queryNode,
|
||||
std::map<int, std::vector<DualCoverTreeMapEntry>, std::greater<int>>&
|
||||
@@ -271,13 +271,13 @@ DualTreeTraverser<RuleType>::PruneMap(
|
||||
}
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
DualTreeTraverser<RuleType>::ReferenceRecursion(
|
||||
CoverTree& queryNode,
|
||||
std::map<int, std::vector<DualCoverTreeMapEntry>, std::greater<int>>&
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
namespace mlpack {
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
class CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
class CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
SingleTreeTraverser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace mlpack {
|
||||
|
||||
//! This is the structure the cover tree map will use for traversal.
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
@@ -30,7 +30,7 @@ template<
|
||||
struct CoverTreeMapEntry
|
||||
{
|
||||
//! The node this entry refers to.
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>* node;
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>* node;
|
||||
//! The score of the node.
|
||||
double score;
|
||||
//! The index of the parent node.
|
||||
@@ -46,34 +46,34 @@ struct CoverTreeMapEntry
|
||||
};
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
SingleTreeTraverser<RuleType>::SingleTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
template<
|
||||
typename MetricType,
|
||||
typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy
|
||||
>
|
||||
template<typename RuleType>
|
||||
void CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>::
|
||||
void CoverTree<DistanceType, StatisticType, MatType, RootPointPolicy>::
|
||||
SingleTreeTraverser<RuleType>::Traverse(
|
||||
const size_t queryIndex,
|
||||
CoverTree& referenceNode)
|
||||
{
|
||||
// This is a non-recursive implementation (which should be faster than a
|
||||
// recursive implementation).
|
||||
typedef CoverTreeMapEntry<MetricType, StatisticType, MatType, RootPointPolicy>
|
||||
MapEntryType;
|
||||
typedef CoverTreeMapEntry<DistanceType, StatisticType, MatType,
|
||||
RootPointPolicy> MapEntryType;
|
||||
|
||||
// We will use this map as a priority queue. Each key represents the scale,
|
||||
// and then the vector is all the nodes in that scale which need to be
|
||||
|
||||
@@ -23,11 +23,12 @@ namespace mlpack {
|
||||
* tree-independent (but still optimized) tree-based algorithms. See
|
||||
* mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename RootPointPolicy>
|
||||
class TreeTraits<CoverTree<MetricType, StatisticType, MatType, RootPointPolicy>>
|
||||
class TreeTraits<CoverTree<
|
||||
DistanceType, StatisticType, MatType, RootPointPolicy>>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace mlpack {
|
||||
*
|
||||
* @see @ref trees, CoverTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using StandardCoverTree = CoverTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using StandardCoverTree = CoverTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
FirstPointIsRoot>;
|
||||
|
||||
@@ -33,11 +33,12 @@ namespace mlpack {
|
||||
* in the order given below. More template parameters are fine, but they must
|
||||
* come after the first three.
|
||||
*
|
||||
* @tparam MetricType This defines the space in which the tree will be built.
|
||||
* For some trees, arbitrary metrics cannot be used, and a template
|
||||
* metaprogramming approach should be used to issue a compile-time error if
|
||||
* a metric cannot be used with a specific tree type. One example is the
|
||||
* BinarySpaceTree tree type, which cannot work with the IPMetric class.
|
||||
* @tparam DistanceType This defines the space in which the tree will be built.
|
||||
* For some trees, arbitrary distance metrics cannot be used, and a
|
||||
* template metaprogramming approach should be used to issue a compile-time
|
||||
* error if a distance metric cannot be used with a specific tree type.
|
||||
* One example is the BinarySpaceTree tree type, which cannot work with the
|
||||
* IPMetric class.
|
||||
* @tparam StatisticType A tree node can hold a statistic, which is sometimes
|
||||
* useful for various dual-tree algorithms. The tree itself does not need
|
||||
* to know anything about how the statistic works, but it needs to hold a
|
||||
@@ -48,7 +49,7 @@ namespace mlpack {
|
||||
* matrix type. When the tree is written it should be assumed that MatType
|
||||
* has the same functionality as arma::mat.
|
||||
*/
|
||||
template<typename MetricType = LMetric<2, true>,
|
||||
template<typename DistanceType = LMetric<2, true>,
|
||||
typename StatisticType = EmptyStatistic,
|
||||
typename MatType = arma::mat>
|
||||
class ExampleTree
|
||||
@@ -56,25 +57,27 @@ class ExampleTree
|
||||
public:
|
||||
/**
|
||||
* This constructor will build the tree given a dataset and an instantiated
|
||||
* metric. Note that the parameter is a MatType& and not an arma::mat&. The
|
||||
* dataset is not modified by the tree-building process (if it is, see the
|
||||
* documentation for TreeTraits::RearrangesDataset for how to deal with that
|
||||
* situation). The MetricType parameter is necessary even though some metrics
|
||||
* do not hold any state. This is so that the tree does not have to worry
|
||||
* about instantiating the metric (if the tree had to worry about this, this
|
||||
* would almost certainly incur additional runtime complexity and a larger
|
||||
* runtime size of the tree node objects, which is to be avoided). The metric
|
||||
* can't be const, in case MetricType::Evaluate() is non-const.
|
||||
* distance metric. Note that the parameter is a MatType& and not an
|
||||
* arma::mat&. The dataset is not modified by the tree-building process (if
|
||||
* it is, see the documentation for TreeTraits::RearrangesDataset for how to
|
||||
* deal with that situation). The DistanceType parameter is necessary even
|
||||
* though some distance metrics do not hold any state. This is so that the
|
||||
* tree does not have to worry about instantiating the metric (if the tree had
|
||||
* to worry about this, this would almost certainly incur additional runtime
|
||||
* complexity and a larger runtime size of the tree node objects, which is to
|
||||
* be avoided). The metric can't be const, in case DistanceType::Evaluate()
|
||||
* is non-const.
|
||||
*
|
||||
* When this constructor is finished, the entire tree will be built and ready
|
||||
* to use. The constructor should call the constructor of the statistic for
|
||||
* each node that is built (see EmptyStatistic for more information).
|
||||
*
|
||||
* @param dataset The dataset that the tree will be built on.
|
||||
* @param metric The instantiated metric to use to build the dataset.
|
||||
* @param distance The instantiated distance metric to use to build the
|
||||
* dataset.
|
||||
*/
|
||||
ExampleTree(const MatType& dataset,
|
||||
MetricType& metric);
|
||||
DistanceType& distance);
|
||||
|
||||
//! Return the number of children of this node.
|
||||
size_t NumChildren() const;
|
||||
@@ -124,10 +127,10 @@ class ExampleTree
|
||||
//! Modify the statistic for this node.
|
||||
StatisticType& Stat();
|
||||
|
||||
//! Get the instantiated metric for this node.
|
||||
const MetricType& Metric() const;
|
||||
//! Modify the instantiated metric for this node.
|
||||
MetricType& Metric();
|
||||
//! Get the instantiated distance for this node.
|
||||
const DistanceType& Distance() const;
|
||||
//! Modify the instantiated distance for this node.
|
||||
DistanceType& Distance();
|
||||
|
||||
/**
|
||||
* Return the minimum distance between this node and a point. It is not
|
||||
@@ -224,11 +227,11 @@ class ExampleTree
|
||||
/**
|
||||
* This member is just here so the ExampleTree compiles without warnings. It
|
||||
* is not required to be a member in every type of tree. Be aware that
|
||||
* storing the metric as a member and not a reference may mean that for some
|
||||
* metrics (such as MahalanobisDistance in high dimensionality) may incur lots
|
||||
* of unnecessary matrix copying.
|
||||
* storing the distance metric as a member and not a reference may mean that
|
||||
* for some distance metrics (such as MahalanobisDistance in high
|
||||
* dimensionality) may incur lots of unnecessary matrix copying.
|
||||
*/
|
||||
MetricType& metric;
|
||||
DistanceType& metric;
|
||||
};
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @file core/tree/hollow_ball_bound.hpp
|
||||
*
|
||||
* Bounds that are useful for binary space partitioning trees.
|
||||
* Interface to a ball bound that works in arbitrary metric spaces.
|
||||
* Interface to a hollow ball bound that works in arbitrary metric spaces.
|
||||
*
|
||||
* 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
|
||||
@@ -13,7 +13,7 @@
|
||||
#define MLPACK_CORE_TREE_HOLLOW_BALL_BOUND_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include "bound_traits.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
@@ -21,19 +21,19 @@ namespace mlpack {
|
||||
/**
|
||||
* Hollow ball bound encloses a set of points at a specific distance (radius)
|
||||
* from a specific point (center) except points at a specific distance from
|
||||
* another point (the center of the hole). MetricType is the custom metric type
|
||||
* that defaults to the Euclidean (L2) distance.
|
||||
* another point (the center of the hole). DistanceType is the custom distance
|
||||
* metric type that defaults to the Euclidean (L2) distance.
|
||||
*
|
||||
* @tparam TMetricType metric type used in the distance measure.
|
||||
* @tparam TDistanceType metric type used in the distance measure.
|
||||
* @tparam ElemType Type of element (float or double or similar).
|
||||
*/
|
||||
template<typename TMetricType = LMetric<2, true>,
|
||||
template<typename TDistanceType = LMetric<2, true>,
|
||||
typename ElemType = double>
|
||||
class HollowBallBound
|
||||
{
|
||||
public:
|
||||
//! A public version of the metric type.
|
||||
typedef TMetricType MetricType;
|
||||
typedef TDistanceType DistanceType;
|
||||
|
||||
private:
|
||||
//! The inner and the outer radii of the bound.
|
||||
@@ -42,16 +42,16 @@ class HollowBallBound
|
||||
arma::Col<ElemType> center;
|
||||
//! The center of the hollow.
|
||||
arma::Col<ElemType> hollowCenter;
|
||||
//! The metric used in this bound.
|
||||
MetricType* metric;
|
||||
//! The distance metric used in this bound.
|
||||
DistanceType* distance;
|
||||
|
||||
/**
|
||||
* To know whether this object allocated memory to the metric member
|
||||
* To know whether this object allocated memory to the distance member
|
||||
* variable. This will be true except in the copy constructor and the
|
||||
* overloaded assignment operator. We need this to know whether we should
|
||||
* delete the metric member variable in the destructor.
|
||||
* delete the distance member variable in the destructor.
|
||||
*/
|
||||
bool ownsMetric;
|
||||
bool ownsDistance;
|
||||
|
||||
public:
|
||||
//! Empty Constructor.
|
||||
@@ -228,9 +228,16 @@ class HollowBallBound
|
||||
ElemType Diameter() const { return 2 * radii.Hi(); }
|
||||
|
||||
//! Returns the distance metric used in this bound.
|
||||
const MetricType& Metric() const { return *metric; }
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
const DistanceType& Metric() const { return *distance; }
|
||||
//! Modify the distance metric used in this bound.
|
||||
MetricType& Metric() { return *metric; }
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType& Metric() { return *distance; }
|
||||
|
||||
//! Returns the distance metric used in this bound.
|
||||
const DistanceType& Distance() const { return *distance; }
|
||||
//! Modify the distance metric used in this bound.
|
||||
DistanceType& Distance() { return *distance; }
|
||||
|
||||
//! Serialize the bound.
|
||||
template<typename Archive>
|
||||
@@ -238,8 +245,8 @@ class HollowBallBound
|
||||
};
|
||||
|
||||
//! A specialization of BoundTraits for this bound type.
|
||||
template<typename MetricType, typename ElemType>
|
||||
struct BoundTraits<HollowBallBound<MetricType, ElemType>>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
struct BoundTraits<HollowBallBound<DistanceType, ElemType>>
|
||||
{
|
||||
//! These bounds are potentially loose in some dimensions.
|
||||
const static bool HasTightBounds = false;
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
namespace mlpack {
|
||||
|
||||
//! Empty Constructor.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>::HollowBallBound() :
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>::HollowBallBound() :
|
||||
radii(std::numeric_limits<ElemType>::lowest(),
|
||||
std::numeric_limits<ElemType>::lowest()),
|
||||
metric(new MetricType()),
|
||||
ownsMetric(true)
|
||||
distance(new DistanceType()),
|
||||
ownsDistance(true)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
/**
|
||||
@@ -31,15 +31,15 @@ HollowBallBound<TMetricType, ElemType>::HollowBallBound() :
|
||||
*
|
||||
* @param dimension Dimensionality of ball bound.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>::
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>::
|
||||
HollowBallBound(const size_t dimension) :
|
||||
radii(std::numeric_limits<ElemType>::lowest(),
|
||||
std::numeric_limits<ElemType>::lowest()),
|
||||
center(dimension),
|
||||
hollowCenter(dimension),
|
||||
metric(new MetricType()),
|
||||
ownsMetric(true)
|
||||
distance(new DistanceType()),
|
||||
ownsDistance(true)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
/**
|
||||
@@ -49,9 +49,9 @@ HollowBallBound(const size_t dimension) :
|
||||
* @param outerRadius Outer radius of hollow ball bound.
|
||||
* @param center Center of hollow ball bound.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
HollowBallBound<TMetricType, ElemType>::
|
||||
HollowBallBound<TDistanceType, ElemType>::
|
||||
HollowBallBound(const ElemType innerRadius,
|
||||
const ElemType outerRadius,
|
||||
const VecType& center) :
|
||||
@@ -59,62 +59,62 @@ HollowBallBound(const ElemType innerRadius,
|
||||
outerRadius),
|
||||
center(center),
|
||||
hollowCenter(center),
|
||||
metric(new MetricType()),
|
||||
ownsMetric(true)
|
||||
distance(new DistanceType()),
|
||||
ownsDistance(true)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
//! Copy Constructor. To prevent memory leaks.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>::HollowBallBound(
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>::HollowBallBound(
|
||||
const HollowBallBound& other) :
|
||||
radii(other.radii),
|
||||
center(other.center),
|
||||
hollowCenter(other.hollowCenter),
|
||||
metric(other.metric),
|
||||
ownsMetric(false)
|
||||
distance(other.distance),
|
||||
ownsDistance(false)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
//! For the same reason as the copy constructor: to prevent memory leaks.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>& HollowBallBound<TMetricType, ElemType>::
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>& HollowBallBound<TDistanceType, ElemType>::
|
||||
operator=(const HollowBallBound& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if (ownsMetric)
|
||||
delete metric;
|
||||
if (ownsDistance)
|
||||
delete distance;
|
||||
|
||||
radii = other.radii;
|
||||
center = other.center;
|
||||
hollowCenter = other.hollowCenter;
|
||||
metric = other.metric;
|
||||
ownsMetric = false;
|
||||
distance = other.distance;
|
||||
ownsDistance = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Move constructor.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>::HollowBallBound(
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>::HollowBallBound(
|
||||
HollowBallBound&& other) :
|
||||
radii(other.radii),
|
||||
center(std::move(other.center)),
|
||||
hollowCenter(std::move(other.hollowCenter)),
|
||||
metric(other.metric),
|
||||
ownsMetric(other.ownsMetric)
|
||||
distance(other.distance),
|
||||
ownsDistance(other.ownsDistance)
|
||||
{
|
||||
// Fix the other bound.
|
||||
other.radii.Hi() = 0.0;
|
||||
other.radii.Lo() = 0.0;
|
||||
other.center = arma::Col<ElemType>();
|
||||
other.hollowCenter = arma::Col<ElemType>();
|
||||
other.metric = NULL;
|
||||
other.ownsMetric = false;
|
||||
other.distance = NULL;
|
||||
other.ownsDistance = false;
|
||||
}
|
||||
|
||||
//! Move assignment operator.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>& HollowBallBound<TMetricType, ElemType>::
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>& HollowBallBound<TDistanceType, ElemType>::
|
||||
operator=(HollowBallBound&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
@@ -122,30 +122,30 @@ operator=(HollowBallBound&& other)
|
||||
radii = other.radii;
|
||||
center = std::move(other.center);
|
||||
hollowCenter = std::move(other.hollowCenter);
|
||||
metric = other.metric;
|
||||
ownsMetric = other.ownsMetric;
|
||||
distance = other.distance;
|
||||
ownsDistance = other.ownsDistance;
|
||||
|
||||
other.radii.Hi() = 0.0;
|
||||
other.radii.Lo() = 0.0;
|
||||
other.center = arma::Col<ElemType>();
|
||||
other.hollowCenter = arma::Col<ElemType>();
|
||||
other.metric = nullptr;
|
||||
other.ownsMetric = false;
|
||||
other.distance = nullptr;
|
||||
other.ownsDistance = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Destructor to release allocated memory.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
HollowBallBound<TMetricType, ElemType>::~HollowBallBound()
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
HollowBallBound<TDistanceType, ElemType>::~HollowBallBound()
|
||||
{
|
||||
if (ownsMetric)
|
||||
delete metric;
|
||||
if (ownsDistance)
|
||||
delete distance;
|
||||
}
|
||||
|
||||
//! Get the range in a certain dimension.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::operator[](
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
RangeType<ElemType> HollowBallBound<TDistanceType, ElemType>::operator[](
|
||||
const size_t i) const
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
@@ -157,21 +157,21 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::operator[](
|
||||
/**
|
||||
* Determines if a point is within the bound.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
bool HollowBallBound<TMetricType, ElemType>::Contains(
|
||||
bool HollowBallBound<TDistanceType, ElemType>::Contains(
|
||||
const VecType& point) const
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
ElemType dist = metric->Evaluate(center, point);
|
||||
ElemType dist = distance->Evaluate(center, point);
|
||||
if (dist > radii.Hi())
|
||||
return false; // The point is situated outside the outer ball.
|
||||
|
||||
// Check if the point is situated outside the hole.
|
||||
dist = metric->Evaluate(hollowCenter, point);
|
||||
dist = distance->Evaluate(hollowCenter, point);
|
||||
|
||||
return (dist >= radii.Lo());
|
||||
}
|
||||
@@ -180,18 +180,18 @@ bool HollowBallBound<TMetricType, ElemType>::Contains(
|
||||
/**
|
||||
* Determines if another bound is within this bound.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
bool HollowBallBound<TMetricType, ElemType>::Contains(
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
bool HollowBallBound<TDistanceType, ElemType>::Contains(
|
||||
const HollowBallBound& other) const
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
const ElemType dist = metric->Evaluate(center, other.center);
|
||||
const ElemType hollowCenterDist = metric->Evaluate(hollowCenter,
|
||||
const ElemType dist = distance->Evaluate(center, other.center);
|
||||
const ElemType hollowCenterDist = distance->Evaluate(hollowCenter,
|
||||
other.center);
|
||||
const ElemType hollowHollowDist = metric->Evaluate(hollowCenter,
|
||||
const ElemType hollowHollowDist = distance->Evaluate(hollowCenter,
|
||||
other.hollowCenter);
|
||||
|
||||
// The outer ball of the second bound does not contain the hole of the first
|
||||
@@ -215,9 +215,9 @@ bool HollowBallBound<TMetricType, ElemType>::Contains(
|
||||
/**
|
||||
* Calculates minimum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
ElemType HollowBallBound<TDistanceType, ElemType>::MinDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -225,14 +225,15 @@ ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
{
|
||||
const ElemType outerDistance = metric->Evaluate(point, center) - radii.Hi();
|
||||
const ElemType outerDistance = distance->Evaluate(point, center) -
|
||||
radii.Hi();
|
||||
|
||||
if (outerDistance >= 0)
|
||||
return outerDistance; // The outer ball does not contain the point.
|
||||
|
||||
// Check if the point is situated in the hole.
|
||||
const ElemType innerDistance = std::max(radii.Lo() -
|
||||
metric->Evaluate(point, hollowCenter), (ElemType) 0.0);
|
||||
distance->Evaluate(point, hollowCenter), (ElemType) 0.0);
|
||||
|
||||
return innerDistance;
|
||||
}
|
||||
@@ -241,8 +242,8 @@ ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
/**
|
||||
* Calculates minimum bound-to-bound squared distance.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
ElemType HollowBallBound<TDistanceType, ElemType>::MinDistance(
|
||||
const HollowBallBound& other)
|
||||
const
|
||||
{
|
||||
@@ -250,7 +251,7 @@ ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
{
|
||||
const ElemType outerDistance = metric->Evaluate(center, other.center) -
|
||||
const ElemType outerDistance = distance->Evaluate(center, other.center) -
|
||||
radii.Hi() - other.radii.Hi();
|
||||
if (outerDistance >= 0)
|
||||
return outerDistance; // The outer hollows do not overlap.
|
||||
@@ -258,14 +259,14 @@ ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
// Check if the hole of the second bound contains the outer ball of the
|
||||
// first bound.
|
||||
const ElemType innerDistance1 = other.radii.Lo() -
|
||||
metric->Evaluate(center, other.hollowCenter) - radii.Hi();
|
||||
distance->Evaluate(center, other.hollowCenter) - radii.Hi();
|
||||
if (innerDistance1 >= 0)
|
||||
return innerDistance1;
|
||||
|
||||
// Check if the hole of the first bound contains the outer ball of the
|
||||
// second bound.
|
||||
const ElemType innerDistance2 = std::max(radii.Lo() -
|
||||
metric->Evaluate(hollowCenter, other.center) - other.radii.Hi(),
|
||||
distance->Evaluate(hollowCenter, other.center) - other.radii.Hi(),
|
||||
(ElemType) 0.0);
|
||||
|
||||
return innerDistance2;
|
||||
@@ -275,30 +276,30 @@ ElemType HollowBallBound<TMetricType, ElemType>::MinDistance(
|
||||
/**
|
||||
* Computes maximum distance.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
ElemType HollowBallBound<TMetricType, ElemType>::MaxDistance(
|
||||
ElemType HollowBallBound<TDistanceType, ElemType>::MaxDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
return metric->Evaluate(point, center) + radii.Hi();
|
||||
return distance->Evaluate(point, center) + radii.Hi();
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes maximum distance.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
ElemType HollowBallBound<TMetricType, ElemType>::MaxDistance(
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
ElemType HollowBallBound<TDistanceType, ElemType>::MaxDistance(
|
||||
const HollowBallBound& other)
|
||||
const
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
return std::numeric_limits<ElemType>::max();
|
||||
else
|
||||
return metric->Evaluate(other.center, center) + radii.Hi() +
|
||||
return distance->Evaluate(other.center, center) + radii.Hi() +
|
||||
other.radii.Hi();
|
||||
}
|
||||
|
||||
@@ -307,9 +308,9 @@ ElemType HollowBallBound<TMetricType, ElemType>::MaxDistance(
|
||||
*
|
||||
* Example: bound1.MinDistanceSq(other) for minimum squared distance.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
RangeType<ElemType> HollowBallBound<TDistanceType, ElemType>::RangeDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -319,7 +320,7 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
else
|
||||
{
|
||||
RangeType<ElemType> range;
|
||||
const ElemType dist = metric->Evaluate(point, center);
|
||||
const ElemType dist = distance->Evaluate(point, center);
|
||||
|
||||
if (dist >= radii.Hi()) // The outer ball does not contain the point.
|
||||
range.Lo() = dist - radii.Hi();
|
||||
@@ -327,7 +328,7 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
{
|
||||
// Check if the point is situated in the hole.
|
||||
range.Lo() = std::max(radii.Lo() -
|
||||
metric->Evaluate(point, hollowCenter), (ElemType) 0.0);
|
||||
distance->Evaluate(point, hollowCenter), (ElemType) 0.0);
|
||||
}
|
||||
range.Hi() = dist + radii.Hi();
|
||||
|
||||
@@ -335,8 +336,8 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TMetricType, typename ElemType>
|
||||
RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
RangeType<ElemType> HollowBallBound<TDistanceType, ElemType>::RangeDistance(
|
||||
const HollowBallBound& other) const
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
@@ -346,7 +347,7 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
{
|
||||
RangeType<ElemType> range;
|
||||
|
||||
const ElemType dist = metric->Evaluate(center, other.center);
|
||||
const ElemType dist = distance->Evaluate(center, other.center);
|
||||
|
||||
const ElemType outerDistance = dist - radii.Hi() - other.radii.Hi();
|
||||
if (outerDistance >= 0)
|
||||
@@ -354,7 +355,7 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
else
|
||||
{
|
||||
const ElemType innerDistance1 = other.radii.Lo() -
|
||||
metric->Evaluate(center, other.hollowCenter) - radii.Hi();
|
||||
distance->Evaluate(center, other.hollowCenter) - radii.Hi();
|
||||
// Check if the outer ball of the first bound is contained in the
|
||||
// hole of the second bound.
|
||||
if (innerDistance1 >= 0)
|
||||
@@ -364,7 +365,7 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
// Check if the outer ball of the second bound is contained in the
|
||||
// hole of the first bound.
|
||||
range.Lo() = std::max(radii.Lo() -
|
||||
metric->Evaluate(hollowCenter, other.center) - other.radii.Hi(),
|
||||
distance->Evaluate(hollowCenter, other.center) - other.radii.Hi(),
|
||||
(ElemType) 0.0);
|
||||
}
|
||||
}
|
||||
@@ -379,10 +380,10 @@ RangeType<ElemType> HollowBallBound<TMetricType, ElemType>::RangeDistance(
|
||||
* The difference lies in the way we initialize the ball bound. The way we
|
||||
* expand the bound is same.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
const HollowBallBound<TMetricType, ElemType>&
|
||||
HollowBallBound<TMetricType, ElemType>::operator|=(const MatType& data)
|
||||
const HollowBallBound<TDistanceType, ElemType>&
|
||||
HollowBallBound<TDistanceType, ElemType>::operator|=(const MatType& data)
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
{
|
||||
@@ -397,8 +398,8 @@ HollowBallBound<TMetricType, ElemType>::operator|=(const MatType& data)
|
||||
// Now iteratively add points.
|
||||
for (size_t i = 0; i < data.n_cols; ++i)
|
||||
{
|
||||
const ElemType dist = metric->Evaluate(center, data.col(i));
|
||||
const ElemType hollowDist = metric->Evaluate(hollowCenter, data.col(i));
|
||||
const ElemType dist = distance->Evaluate(center, data.col(i));
|
||||
const ElemType hollowDist = distance->Evaluate(hollowCenter, data.col(i));
|
||||
|
||||
// See if the new point lies outside the bound.
|
||||
if (dist > radii.Hi())
|
||||
@@ -419,9 +420,9 @@ HollowBallBound<TMetricType, ElemType>::operator|=(const MatType& data)
|
||||
/**
|
||||
* Expand the bound to include the given bound.
|
||||
*/
|
||||
template<typename TMetricType, typename ElemType>
|
||||
const HollowBallBound<TMetricType, ElemType>&
|
||||
HollowBallBound<TMetricType, ElemType>::operator|=(const HollowBallBound& other)
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
const HollowBallBound<TDistanceType, ElemType>&
|
||||
HollowBallBound<TDistanceType, ElemType>::operator|=(const HollowBallBound& other)
|
||||
{
|
||||
if (radii.Hi() < 0)
|
||||
{
|
||||
@@ -432,13 +433,13 @@ HollowBallBound<TMetricType, ElemType>::operator|=(const HollowBallBound& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ElemType dist = metric->Evaluate(center, other.center);
|
||||
const ElemType dist = distance->Evaluate(center, other.center);
|
||||
// Check if the outer balls overlap.
|
||||
if (radii.Hi() < dist + other.radii.Hi())
|
||||
radii.Hi() = dist + other.radii.Hi();
|
||||
|
||||
const ElemType innerDist = std::max(other.radii.Lo() -
|
||||
metric->Evaluate(hollowCenter, other.hollowCenter), (ElemType) 0.0);
|
||||
distance->Evaluate(hollowCenter, other.hollowCenter), (ElemType) 0.0);
|
||||
// Check if the hole of the first bound is not contained in the hole of the
|
||||
// second bound.
|
||||
if (radii.Lo() > innerDist)
|
||||
@@ -449,23 +450,23 @@ HollowBallBound<TMetricType, ElemType>::operator|=(const HollowBallBound& other)
|
||||
|
||||
|
||||
//! Serialize the BallBound.
|
||||
template<typename TMetricType, typename ElemType>
|
||||
template<typename TDistanceType, typename ElemType>
|
||||
template<typename Archive>
|
||||
void HollowBallBound<TMetricType, ElemType>::serialize(
|
||||
void HollowBallBound<TDistanceType, ElemType>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
ar(CEREAL_NVP(radii));
|
||||
ar(CEREAL_NVP(center));
|
||||
ar(CEREAL_NVP(hollowCenter));
|
||||
ar(CEREAL_POINTER(metric));
|
||||
ar(CEREAL_POINTER(distance));
|
||||
if (cereal::is_loading<Archive>())
|
||||
{
|
||||
// If we're loading, delete the local metric since we'll have a new one.
|
||||
if (ownsMetric)
|
||||
delete metric;
|
||||
// If we're loading, delete the local distance since we'll have a new one.
|
||||
if (ownsDistance)
|
||||
delete distance;
|
||||
|
||||
ownsMetric = true;
|
||||
ownsDistance = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/math/range.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <mlpack/core/distances/lmetric.hpp>
|
||||
#include "bound_traits.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
//! Utility struct where Value is true if and only if the argument is of type
|
||||
//! LMetric.
|
||||
template<typename MetricType>
|
||||
template<typename DistanceType>
|
||||
struct IsLMetric
|
||||
{
|
||||
static const bool Value = false;
|
||||
@@ -41,15 +41,15 @@ struct IsLMetric<LMetric<Power, TakeRoot>>
|
||||
* with the LMetric class. Be sure to use the same template parameters for
|
||||
* LMetric as you do for HRectBound -- otherwise odd results may occur.
|
||||
*
|
||||
* @tparam MetricType Type of metric to use; must be of type LMetric.
|
||||
* @tparam DistanceType Type of distance metric to use; must be of type LMetric.
|
||||
* @tparam ElemType Element type (double/float/int/etc.).
|
||||
*/
|
||||
template<typename MetricType = LMetric<2, true>,
|
||||
template<typename DistanceType = LMetric<2, true>,
|
||||
typename ElemType = double>
|
||||
class HRectBound
|
||||
{
|
||||
// It is required that HRectBound have an LMetric as the given MetricType.
|
||||
static_assert(IsLMetric<MetricType>::Value == true,
|
||||
// It is required that HRectBound have an LMetric as the given DistanceType.
|
||||
static_assert(IsLMetric<DistanceType>::Value == true,
|
||||
"HRectBound can only be used with the LMetric<> metric type.");
|
||||
|
||||
public:
|
||||
@@ -102,10 +102,17 @@ class HRectBound
|
||||
//! Modify the minimum width of the bound.
|
||||
ElemType& MinWidth() { return minWidth; }
|
||||
|
||||
//! Get the instantiated metric associated with the bound.
|
||||
const MetricType& Metric() const { return metric; }
|
||||
//! Modify the instantiated metric associated with the bound.
|
||||
MetricType& Metric() { return metric; }
|
||||
//! Get the instantiated distance metric associated with the bound.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
const DistanceType& Metric() const { return distance; }
|
||||
//! Modify the instantiated distance metric associated with the bound.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType& Metric() { return distance; }
|
||||
|
||||
//! Get the instantiated distance metric associated with the bound.
|
||||
const DistanceType& Distance() const { return distance; }
|
||||
//! Modify the instantiated distance metric associated with the bound.
|
||||
DistanceType& Distance() { return distance; }
|
||||
|
||||
/**
|
||||
* Calculates the center of the range, placing it into the given vector.
|
||||
@@ -237,13 +244,13 @@ class HRectBound
|
||||
RangeType<ElemType>* bounds;
|
||||
//! Cached minimum width of bound.
|
||||
ElemType minWidth;
|
||||
//! Instantiated metric (likely has size 0).
|
||||
MetricType metric;
|
||||
//! Instantiated distance metric (likely has size 0).
|
||||
DistanceType distance;
|
||||
};
|
||||
|
||||
// A specialization of BoundTraits for this class.
|
||||
template<typename MetricType, typename ElemType>
|
||||
struct BoundTraits<HRectBound<MetricType, ElemType>>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
struct BoundTraits<HRectBound<DistanceType, ElemType>>
|
||||
{
|
||||
//! These bounds are always tight for each dimension.
|
||||
const static bool HasTightBounds = true;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* @file core/tree/hrectbound_impl.hpp
|
||||
*
|
||||
* Implementation of hyper-rectangle bound policy class.
|
||||
* Template parameter Power is the metric to use; use 2 for Euclidean (L2).
|
||||
*
|
||||
* 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
|
||||
@@ -22,8 +21,8 @@ namespace mlpack {
|
||||
/**
|
||||
* Empty constructor.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>::HRectBound() :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>::HRectBound() :
|
||||
dim(0),
|
||||
bounds(NULL),
|
||||
minWidth(0)
|
||||
@@ -33,8 +32,8 @@ inline HRectBound<MetricType, ElemType>::HRectBound() :
|
||||
* Initializes to specified dimensionality with each dimension the empty
|
||||
* set.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>::HRectBound(const size_t dimension) :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>::HRectBound(const size_t dimension) :
|
||||
dim(dimension),
|
||||
bounds(new RangeType<ElemType>[dim]),
|
||||
minWidth(0)
|
||||
@@ -43,9 +42,9 @@ inline HRectBound<MetricType, ElemType>::HRectBound(const size_t dimension) :
|
||||
/**
|
||||
* Copy constructor necessary to prevent memory leaks.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>::HRectBound(
|
||||
const HRectBound<MetricType, ElemType>& other) :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>::HRectBound(
|
||||
const HRectBound<DistanceType, ElemType>& other) :
|
||||
dim(other.Dim()),
|
||||
bounds(new RangeType<ElemType>[dim]),
|
||||
minWidth(other.MinWidth())
|
||||
@@ -58,11 +57,11 @@ inline HRectBound<MetricType, ElemType>::HRectBound(
|
||||
/**
|
||||
* Same as the copy constructor.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<
|
||||
MetricType,
|
||||
ElemType>& HRectBound<MetricType,
|
||||
ElemType>::operator=(const HRectBound<MetricType, ElemType>& other)
|
||||
DistanceType,
|
||||
ElemType>& HRectBound<DistanceType,
|
||||
ElemType>::operator=(const HRectBound<DistanceType, ElemType>& other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
@@ -89,9 +88,9 @@ inline HRectBound<
|
||||
/**
|
||||
* Move constructor: take possession of another bound's information.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>::HRectBound(
|
||||
HRectBound<MetricType, ElemType>&& other) :
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>::HRectBound(
|
||||
HRectBound<DistanceType, ElemType>&& other) :
|
||||
dim(other.dim),
|
||||
bounds(other.bounds),
|
||||
minWidth(other.minWidth)
|
||||
@@ -105,10 +104,10 @@ inline HRectBound<MetricType, ElemType>::HRectBound(
|
||||
/**
|
||||
* Move assignment operator.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>&
|
||||
HRectBound<MetricType, ElemType>::operator=(
|
||||
HRectBound<MetricType, ElemType>&& other)
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>&
|
||||
HRectBound<DistanceType, ElemType>::operator=(
|
||||
HRectBound<DistanceType, ElemType>&& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
@@ -125,8 +124,8 @@ HRectBound<MetricType, ElemType>::operator=(
|
||||
/**
|
||||
* Destructor: clean up memory.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>::~HRectBound()
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>::~HRectBound()
|
||||
{
|
||||
if (bounds)
|
||||
delete[] bounds;
|
||||
@@ -135,8 +134,8 @@ inline HRectBound<MetricType, ElemType>::~HRectBound()
|
||||
/**
|
||||
* Resets all dimensions to the empty set.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline void HRectBound<MetricType, ElemType>::Clear()
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline void HRectBound<DistanceType, ElemType>::Clear()
|
||||
{
|
||||
for (size_t i = 0; i < dim; ++i)
|
||||
bounds[i] = RangeType<ElemType>();
|
||||
@@ -148,8 +147,8 @@ inline void HRectBound<MetricType, ElemType>::Clear()
|
||||
*
|
||||
* @param centroid Vector which the centroid will be written to.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline void HRectBound<MetricType, ElemType>::Center(
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline void HRectBound<DistanceType, ElemType>::Center(
|
||||
arma::Col<ElemType>& center) const
|
||||
{
|
||||
// Set size correctly if necessary.
|
||||
@@ -165,8 +164,8 @@ inline void HRectBound<MetricType, ElemType>::Center(
|
||||
*
|
||||
* @return Volume of the hyperrectangle.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline ElemType HRectBound<MetricType, ElemType>::Volume() const
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline ElemType HRectBound<DistanceType, ElemType>::Volume() const
|
||||
{
|
||||
ElemType volume = 1.0;
|
||||
for (size_t i = 0; i < dim; ++i)
|
||||
@@ -183,9 +182,9 @@ inline ElemType HRectBound<MetricType, ElemType>::Volume() const
|
||||
/**
|
||||
* Calculates minimum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline ElemType HRectBound<MetricType, ElemType>::MinDistance(
|
||||
inline ElemType HRectBound<DistanceType, ElemType>::MinDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -202,9 +201,9 @@ inline ElemType HRectBound<MetricType, ElemType>::MinDistance(
|
||||
// Since only one of 'lower' or 'higher' is negative, if we add each's
|
||||
// absolute value to itself and then sum those two, our result is the
|
||||
// nonnegative half of the equation times two; then we raise to power Power.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += (lower + std::fabs(lower)) + (higher + std::fabs(higher));
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
ElemType dist = (lower + std::fabs(lower)) + (higher + std::fabs(higher));
|
||||
sum += dist * dist;
|
||||
@@ -212,7 +211,7 @@ inline ElemType HRectBound<MetricType, ElemType>::MinDistance(
|
||||
else
|
||||
{
|
||||
sum += std::pow((lower + std::fabs(lower)) + (higher + std::fabs(higher)),
|
||||
(ElemType) MetricType::Power);
|
||||
(ElemType) DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,30 +219,30 @@ inline ElemType HRectBound<MetricType, ElemType>::MinDistance(
|
||||
// to be); then cancel out the constant of 2 (which may have been squared now)
|
||||
// that was introduced earlier. The compiler should optimize out the if
|
||||
// statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return sum * 0.5;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::sqrt(sum) * 0.5;
|
||||
else
|
||||
return sum * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::pow((double) sum,
|
||||
1.0 / (double) MetricType::Power) / 2.0;
|
||||
1.0 / (double) DistanceType::Power) / 2.0;
|
||||
else
|
||||
return sum / std::pow(2.0, MetricType::Power);
|
||||
return sum / std::pow(2.0, DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates minimum bound-to-bound squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
ElemType HRectBound<MetricType, ElemType>::MinDistance(const HRectBound& other)
|
||||
template<typename DistanceType, typename ElemType>
|
||||
ElemType HRectBound<DistanceType, ElemType>::MinDistance(const HRectBound& other)
|
||||
const
|
||||
{
|
||||
Log::Assert(dim == other.dim);
|
||||
@@ -262,9 +261,9 @@ ElemType HRectBound<MetricType, ElemType>::MinDistance(const HRectBound& other)
|
||||
// (x * 2)^2 / 4 = x^2
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += (lower + std::fabs(lower)) + (higher + std::fabs(higher));
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
ElemType dist = (lower + std::fabs(lower)) + (higher + std::fabs(higher));
|
||||
sum += dist * dist;
|
||||
@@ -272,7 +271,7 @@ ElemType HRectBound<MetricType, ElemType>::MinDistance(const HRectBound& other)
|
||||
else
|
||||
{
|
||||
sum += std::pow((lower + std::fabs(lower)) + (higher + std::fabs(higher)),
|
||||
(ElemType) MetricType::Power);
|
||||
(ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
// Move bound pointers.
|
||||
@@ -281,31 +280,31 @@ ElemType HRectBound<MetricType, ElemType>::MinDistance(const HRectBound& other)
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return sum * 0.5;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::sqrt(sum) * 0.5;
|
||||
else
|
||||
return sum * 0.25;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::pow((double) sum,
|
||||
1.0 / (double) MetricType::Power) / 2.0;
|
||||
1.0 / (double) DistanceType::Power) / 2.0;
|
||||
else
|
||||
return sum / std::pow(2.0, MetricType::Power);
|
||||
return sum / std::pow(2.0, DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates maximum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline ElemType HRectBound<MetricType, ElemType>::MaxDistance(
|
||||
inline ElemType HRectBound<DistanceType, ElemType>::MaxDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -319,24 +318,24 @@ inline ElemType HRectBound<MetricType, ElemType>::MaxDistance(
|
||||
fabs(bounds[d].Hi() - point[d]));
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += v; // v is non-negative.
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
sum += v * v;
|
||||
else
|
||||
sum += std::pow(v, (ElemType) MetricType::Power);
|
||||
sum += std::pow(v, (ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return sum;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return (ElemType) std::sqrt(sum);
|
||||
else
|
||||
return (ElemType) std::pow((double) sum, 1.0 /
|
||||
(double) MetricType::Power);
|
||||
(double) DistanceType::Power);
|
||||
}
|
||||
else
|
||||
return sum;
|
||||
@@ -345,8 +344,8 @@ inline ElemType HRectBound<MetricType, ElemType>::MaxDistance(
|
||||
/**
|
||||
* Computes maximum distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline ElemType HRectBound<MetricType, ElemType>::MaxDistance(
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline ElemType HRectBound<DistanceType, ElemType>::MaxDistance(
|
||||
const HRectBound& other)
|
||||
const
|
||||
{
|
||||
@@ -361,24 +360,24 @@ inline ElemType HRectBound<MetricType, ElemType>::MaxDistance(
|
||||
fabs(bounds[d].Hi() - other.bounds[d].Lo()));
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
sum += v; // v is non-negative.
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
sum += v * v;
|
||||
else
|
||||
sum += std::pow(v, (ElemType) MetricType::Power);
|
||||
sum += std::pow(v, (ElemType) DistanceType::Power);
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return sum;
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return (ElemType) std::sqrt(sum);
|
||||
else
|
||||
return (ElemType) std::pow((double) sum, 1.0 /
|
||||
(double) MetricType::Power);
|
||||
(double) DistanceType::Power);
|
||||
}
|
||||
else
|
||||
return sum;
|
||||
@@ -387,9 +386,9 @@ inline ElemType HRectBound<MetricType, ElemType>::MaxDistance(
|
||||
/**
|
||||
* Calculates minimum and maximum bound-to-bound squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline RangeType<ElemType>
|
||||
HRectBound<MetricType, ElemType>::RangeDistance(
|
||||
HRectBound<DistanceType, ElemType>::RangeDistance(
|
||||
const HRectBound& other) const
|
||||
{
|
||||
ElemType loSum = 0;
|
||||
@@ -415,36 +414,36 @@ HRectBound<MetricType, ElemType>::RangeDistance(
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
{
|
||||
loSum += vLo; // vLo is non-negative.
|
||||
hiSum += vHi; // vHi is non-negative.
|
||||
}
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
loSum += vLo * vLo;
|
||||
hiSum += vHi * vHi;
|
||||
}
|
||||
else
|
||||
{
|
||||
loSum += std::pow(vLo, (ElemType) MetricType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) MetricType::Power);
|
||||
loSum += std::pow(vLo, (ElemType) DistanceType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return RangeType<ElemType>(loSum, hiSum);
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return RangeType<ElemType>((ElemType) std::sqrt(loSum),
|
||||
(ElemType) std::sqrt(hiSum));
|
||||
else
|
||||
{
|
||||
return RangeType<ElemType>(
|
||||
(ElemType) std::pow((double) loSum, 1.0 / (double) MetricType::Power),
|
||||
(ElemType) std::pow((double) loSum, 1.0 / (double) DistanceType::Power),
|
||||
(ElemType) std::pow((double) hiSum,
|
||||
1.0 / (double) MetricType::Power));
|
||||
1.0 / (double) DistanceType::Power));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -454,10 +453,10 @@ HRectBound<MetricType, ElemType>::RangeDistance(
|
||||
/**
|
||||
* Calculates minimum and maximum bound-to-point squared distance.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline RangeType<ElemType>
|
||||
HRectBound<MetricType, ElemType>::RangeDistance(
|
||||
HRectBound<DistanceType, ElemType>::RangeDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>* /* junk */) const
|
||||
{
|
||||
@@ -492,36 +491,36 @@ HRectBound<MetricType, ElemType>::RangeDistance(
|
||||
}
|
||||
|
||||
// The compiler should optimize out this if statement entirely.
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
{
|
||||
loSum += vLo; // vLo is non-negative.
|
||||
hiSum += vHi; // vHi is non-negative.
|
||||
}
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
{
|
||||
loSum += vLo * vLo;
|
||||
hiSum += vHi * vHi;
|
||||
}
|
||||
else
|
||||
{
|
||||
loSum += std::pow(vLo, (ElemType) MetricType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) MetricType::Power);
|
||||
loSum += std::pow(vLo, (ElemType) DistanceType::Power);
|
||||
hiSum += std::pow(vHi, (ElemType) DistanceType::Power);
|
||||
}
|
||||
}
|
||||
|
||||
if (MetricType::TakeRoot)
|
||||
if (DistanceType::TakeRoot)
|
||||
{
|
||||
if (MetricType::Power == 1)
|
||||
if (DistanceType::Power == 1)
|
||||
return RangeType<ElemType>(loSum, hiSum);
|
||||
else if (MetricType::Power == 2)
|
||||
else if (DistanceType::Power == 2)
|
||||
return RangeType<ElemType>((ElemType) std::sqrt(loSum),
|
||||
(ElemType) std::sqrt(hiSum));
|
||||
else
|
||||
{
|
||||
return RangeType<ElemType>(
|
||||
(ElemType) std::pow((double) loSum, 1.0 / (double) MetricType::Power),
|
||||
(ElemType) std::pow((double) loSum, 1.0 / (double) DistanceType::Power),
|
||||
(ElemType) std::pow((double) hiSum,
|
||||
1.0 / (double) MetricType::Power));
|
||||
1.0 / (double) DistanceType::Power));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -531,10 +530,10 @@ HRectBound<MetricType, ElemType>::RangeDistance(
|
||||
/**
|
||||
* Expands this region to include a new point.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename MatType>
|
||||
inline HRectBound<MetricType, ElemType>&
|
||||
HRectBound<MetricType, ElemType>::operator|=(const MatType& data)
|
||||
inline HRectBound<DistanceType, ElemType>&
|
||||
HRectBound<DistanceType, ElemType>::operator|=(const MatType& data)
|
||||
{
|
||||
Log::Assert(data.n_rows == dim);
|
||||
|
||||
@@ -556,9 +555,9 @@ HRectBound<MetricType, ElemType>::operator|=(const MatType& data)
|
||||
/**
|
||||
* Expands this region to encompass another bound.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>&
|
||||
HRectBound<MetricType, ElemType>::operator|=(const HRectBound& other)
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>&
|
||||
HRectBound<DistanceType, ElemType>::operator|=(const HRectBound& other)
|
||||
{
|
||||
assert(other.dim == dim);
|
||||
|
||||
@@ -577,9 +576,9 @@ HRectBound<MetricType, ElemType>::operator|=(const HRectBound& other)
|
||||
/**
|
||||
* Determines if a point is within this bound.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename VecType>
|
||||
inline bool HRectBound<MetricType, ElemType>::Contains(
|
||||
inline bool HRectBound<DistanceType, ElemType>::Contains(
|
||||
const VecType& point) const
|
||||
{
|
||||
for (size_t i = 0; i < point.n_elem; ++i)
|
||||
@@ -594,8 +593,8 @@ inline bool HRectBound<MetricType, ElemType>::Contains(
|
||||
/**
|
||||
* Determines if this bound partially contains a bound.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline bool HRectBound<MetricType, ElemType>::Contains(
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline bool HRectBound<DistanceType, ElemType>::Contains(
|
||||
const HRectBound& bound) const
|
||||
{
|
||||
for (size_t i = 0; i < dim; ++i)
|
||||
@@ -614,11 +613,11 @@ inline bool HRectBound<MetricType, ElemType>::Contains(
|
||||
/**
|
||||
* 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
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>
|
||||
HRectBound<DistanceType, ElemType>::operator&(const HRectBound& bound) const
|
||||
{
|
||||
HRectBound<MetricType, ElemType> result(dim);
|
||||
HRectBound<DistanceType, ElemType> result(dim);
|
||||
|
||||
for (size_t k = 0; k < dim; ++k)
|
||||
{
|
||||
@@ -631,9 +630,9 @@ HRectBound<MetricType, ElemType>::operator&(const HRectBound& bound) const
|
||||
/**
|
||||
* Intersects this bound with another.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline HRectBound<MetricType, ElemType>&
|
||||
HRectBound<MetricType, ElemType>::operator&=(const HRectBound& bound)
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline HRectBound<DistanceType, ElemType>&
|
||||
HRectBound<DistanceType, ElemType>::operator&=(const HRectBound& bound)
|
||||
{
|
||||
for (size_t k = 0; k < dim; ++k)
|
||||
{
|
||||
@@ -646,8 +645,8 @@ HRectBound<MetricType, ElemType>::operator&=(const HRectBound& bound)
|
||||
/**
|
||||
* Returns the volume of overlap of this bound and another.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline ElemType HRectBound<MetricType, ElemType>::Overlap(
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline ElemType HRectBound<DistanceType, ElemType>::Overlap(
|
||||
const HRectBound& bound) const
|
||||
{
|
||||
ElemType volume = 1.0;
|
||||
@@ -668,31 +667,31 @@ inline ElemType HRectBound<MetricType, ElemType>::Overlap(
|
||||
/**
|
||||
* Returns the diameter of the hyperrectangle (that is, the longest diagonal).
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
inline ElemType HRectBound<MetricType, ElemType>::Diameter() const
|
||||
template<typename DistanceType, typename ElemType>
|
||||
inline ElemType HRectBound<DistanceType, ElemType>::Diameter() const
|
||||
{
|
||||
ElemType d = 0;
|
||||
for (size_t i = 0; i < dim; ++i)
|
||||
d += std::pow(bounds[i].Hi() - bounds[i].Lo(),
|
||||
(ElemType) MetricType::Power);
|
||||
(ElemType) DistanceType::Power);
|
||||
|
||||
if (MetricType::TakeRoot)
|
||||
return (ElemType) std::pow((double) d, 1.0 / (double) MetricType::Power);
|
||||
if (DistanceType::TakeRoot)
|
||||
return (ElemType) std::pow((double) d, 1.0 / (double) DistanceType::Power);
|
||||
else
|
||||
return d;
|
||||
}
|
||||
|
||||
//! Serialize the bound object.
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
template<typename Archive>
|
||||
void HRectBound<MetricType, ElemType>::serialize(
|
||||
void HRectBound<DistanceType, ElemType>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
// We can't serialize a raw array directly, so wrap it.
|
||||
ar(CEREAL_POINTER_ARRAY(bounds, dim));
|
||||
ar(CEREAL_NVP(minWidth));
|
||||
ar(CEREAL_NVP(metric));
|
||||
ar(CEREAL_NVP(distance));
|
||||
}
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType>
|
||||
template<typename RuleType>
|
||||
class Octree<MetricType, StatisticType, MatType>::DualTreeTraverser
|
||||
class Octree<DistanceType, StatisticType, MatType>::DualTreeTraverser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename RuleType>
|
||||
Octree<MetricType, StatisticType, MatType>::DualTreeTraverser<RuleType>::
|
||||
Octree<DistanceType, StatisticType, MatType>::DualTreeTraverser<RuleType>::
|
||||
DualTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0),
|
||||
@@ -30,9 +30,9 @@ Octree<MetricType, StatisticType, MatType>::DualTreeTraverser<RuleType>::
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename RuleType>
|
||||
void Octree<MetricType, StatisticType, MatType>::DualTreeTraverser<RuleType>::
|
||||
void Octree<DistanceType, StatisticType, MatType>::DualTreeTraverser<RuleType>::
|
||||
Traverse(Octree& queryNode, Octree& referenceNode)
|
||||
{
|
||||
// Increment the visit counter.
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType = EuclideanDistance,
|
||||
template<typename DistanceType = EuclideanDistance,
|
||||
typename StatisticType = EmptyStatistic,
|
||||
typename MatType = arma::mat>
|
||||
class Octree
|
||||
@@ -49,7 +49,7 @@ class Octree
|
||||
size_t count;
|
||||
//! The minimum bounding rectangle of the points held in the node (and its
|
||||
//! children).
|
||||
HRectBound<MetricType> bound;
|
||||
HRectBound<DistanceType> bound;
|
||||
//! The dataset.
|
||||
MatType* dataset;
|
||||
//! The parent (NULL if this node is the root).
|
||||
@@ -60,8 +60,8 @@ class Octree
|
||||
ElemType parentDistance;
|
||||
//! The distance to the furthest descendant, cached to speed things up.
|
||||
ElemType furthestDescendantDistance;
|
||||
//! An instantiated metric.
|
||||
MetricType metric;
|
||||
//! An instantiated distance metric.
|
||||
DistanceType distance;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -257,9 +257,9 @@ class Octree
|
||||
Octree*& Parent() { return parent; }
|
||||
|
||||
//! Return the bound object for this node.
|
||||
const HRectBound<MetricType>& Bound() const { return bound; }
|
||||
const HRectBound<DistanceType>& Bound() const { return bound; }
|
||||
//! Modify the bound object for this node.
|
||||
HRectBound<MetricType>& Bound() { return bound; }
|
||||
HRectBound<DistanceType>& Bound() { return bound; }
|
||||
|
||||
//! Return the statistic object for this node.
|
||||
const StatisticType& Stat() const { return stat; }
|
||||
@@ -269,8 +269,12 @@ class Octree
|
||||
//! Return the number of children in this node.
|
||||
size_t NumChildren() const;
|
||||
|
||||
//! Return the metric that this tree uses.
|
||||
MetricType Metric() const { return MetricType(); }
|
||||
//! Return the distance metric that this tree uses.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType Metric() const { return distance; }
|
||||
|
||||
//! Return the distance metric that this tree uses.
|
||||
DistanceType Distance() const { return distance; }
|
||||
|
||||
/**
|
||||
* Return the index of the nearest child node to the given query point. If
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
namespace mlpack {
|
||||
|
||||
//! Construct the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(const MatType& dataset,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(const MatType& dataset,
|
||||
const size_t maxLeafSize) :
|
||||
begin(0),
|
||||
count(dataset.n_cols),
|
||||
@@ -55,8 +55,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(const MatType& dataset,
|
||||
}
|
||||
|
||||
//! Construct the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
const MatType& dataset,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
const size_t maxLeafSize) :
|
||||
@@ -97,8 +97,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
}
|
||||
|
||||
//! Construct the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
const MatType& dataset,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
std::vector<size_t>& newFromOld,
|
||||
@@ -145,8 +145,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
}
|
||||
|
||||
//! Construct the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(MatType&& dataset,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(MatType&& dataset,
|
||||
const size_t maxLeafSize) :
|
||||
begin(0),
|
||||
count(dataset.n_cols),
|
||||
@@ -181,8 +181,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(MatType&& dataset,
|
||||
}
|
||||
|
||||
//! Construct the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
MatType&& dataset,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
const size_t maxLeafSize) :
|
||||
@@ -223,8 +223,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
}
|
||||
|
||||
//! Construct the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
MatType&& dataset,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
std::vector<size_t>& newFromOld,
|
||||
@@ -271,8 +271,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
}
|
||||
|
||||
//! Construct a child node.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
Octree* parent,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
@@ -296,7 +296,7 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
arma::vec trueCenter, parentCenter;
|
||||
bound.Center(trueCenter);
|
||||
parent->Bound().Center(parentCenter);
|
||||
parentDistance = metric.Evaluate(trueCenter, parentCenter);
|
||||
parentDistance = distance.Evaluate(trueCenter, parentCenter);
|
||||
|
||||
furthestDescendantDistance = 0.5 * bound.Diameter();
|
||||
|
||||
@@ -305,8 +305,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
}
|
||||
|
||||
//! Construct a child node.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
Octree* parent,
|
||||
const size_t begin,
|
||||
const size_t count,
|
||||
@@ -331,7 +331,7 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
arma::vec trueCenter, parentCenter;
|
||||
bound.Center(trueCenter);
|
||||
parent->Bound().Center(parentCenter);
|
||||
parentDistance = metric.Evaluate(trueCenter, parentCenter);
|
||||
parentDistance = distance.Evaluate(trueCenter, parentCenter);
|
||||
|
||||
furthestDescendantDistance = 0.5 * bound.Diameter();
|
||||
|
||||
@@ -340,8 +340,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
}
|
||||
|
||||
//! Copy the given tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(const Octree& other) :
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(const Octree& other) :
|
||||
begin(other.begin),
|
||||
count(other.count),
|
||||
bound(other.bound),
|
||||
@@ -350,7 +350,7 @@ Octree<MetricType, StatisticType, MatType>::Octree(const Octree& other) :
|
||||
stat(other.stat),
|
||||
parentDistance(other.parentDistance),
|
||||
furthestDescendantDistance(other.furthestDescendantDistance),
|
||||
metric(other.metric)
|
||||
distance(other.distance)
|
||||
{
|
||||
// If we have any children, we need to create them, and then ensure that their
|
||||
// parent links are set right.
|
||||
@@ -363,9 +363,9 @@ Octree<MetricType, StatisticType, MatType>::Octree(const Octree& other) :
|
||||
}
|
||||
|
||||
//! Copy assignment operator: copy the given other tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>&
|
||||
Octree<MetricType, StatisticType, MatType>::
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>&
|
||||
Octree<DistanceType, StatisticType, MatType>::
|
||||
operator=(const Octree& other)
|
||||
{
|
||||
// Return if it's the same tree.
|
||||
@@ -386,7 +386,7 @@ operator=(const Octree& other)
|
||||
stat = other.stat;
|
||||
parentDistance = other.ParentDistance();
|
||||
furthestDescendantDistance = other.FurthestDescendantDistance();
|
||||
metric = other.metric;
|
||||
distance = other.distance;
|
||||
|
||||
// If we have any children, we need to create them, and then ensure that their
|
||||
// parent links are set right.
|
||||
@@ -400,8 +400,8 @@ operator=(const Octree& other)
|
||||
}
|
||||
|
||||
//! Move the given tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(Octree&& other) :
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(Octree&& other) :
|
||||
children(std::move(other.children)),
|
||||
begin(other.begin),
|
||||
count(other.count),
|
||||
@@ -411,7 +411,7 @@ Octree<MetricType, StatisticType, MatType>::Octree(Octree&& other) :
|
||||
stat(std::move(other.stat)),
|
||||
parentDistance(other.parentDistance),
|
||||
furthestDescendantDistance(other.furthestDescendantDistance),
|
||||
metric(std::move(other.metric))
|
||||
distance(std::move(other.distance))
|
||||
{
|
||||
// Update the parent pointers of the direct children.
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
@@ -426,9 +426,9 @@ Octree<MetricType, StatisticType, MatType>::Octree(Octree&& other) :
|
||||
}
|
||||
|
||||
//! Move assignment operator: take ownership of the given tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>&
|
||||
Octree<MetricType, StatisticType, MatType>::
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>&
|
||||
Octree<DistanceType, StatisticType, MatType>::
|
||||
operator=(Octree&& other)
|
||||
{
|
||||
// Return if it's the same tree.
|
||||
@@ -450,7 +450,7 @@ operator=(Octree&& other)
|
||||
stat = std::move(other.stat);
|
||||
parentDistance = other.ParentDistance();
|
||||
furthestDescendantDistance = other.furthestDescendantDistance();
|
||||
metric = std::move(other.metric);
|
||||
distance = std::move(other.distance);
|
||||
|
||||
// Update the parent pointers of the direct children.
|
||||
for (size_t i = 0; i < children.size(); ++i)
|
||||
@@ -467,8 +467,8 @@ operator=(Octree&& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree() :
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree() :
|
||||
begin(0),
|
||||
count(0),
|
||||
bound(0),
|
||||
@@ -480,9 +480,9 @@ Octree<MetricType, StatisticType, MatType>::Octree() :
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename Archive>
|
||||
Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
Octree<DistanceType, StatisticType, MatType>::Octree(
|
||||
Archive& ar,
|
||||
const typename std::enable_if_t<cereal::is_loading<Archive>()>*) :
|
||||
Octree() // Create an empty tree.
|
||||
@@ -491,8 +491,8 @@ Octree<MetricType, StatisticType, MatType>::Octree(
|
||||
ar(CEREAL_NVP(*this));
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
Octree<MetricType, StatisticType, MatType>::~Octree()
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
Octree<DistanceType, StatisticType, MatType>::~Octree()
|
||||
{
|
||||
// Delete the dataset if we aren't the parent.
|
||||
if (!parent)
|
||||
@@ -504,15 +504,15 @@ Octree<MetricType, StatisticType, MatType>::~Octree()
|
||||
children.clear();
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::NumChildren() const
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::NumChildren() const
|
||||
{
|
||||
return children.size();
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename VecType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::GetNearestChild(
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::GetNearestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*) const
|
||||
{
|
||||
@@ -533,9 +533,9 @@ size_t Octree<MetricType, StatisticType, MatType>::GetNearestChild(
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename VecType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::GetFurthestChild(
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::GetFurthestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*) const
|
||||
{
|
||||
@@ -556,8 +556,8 @@ size_t Octree<MetricType, StatisticType, MatType>::GetFurthestChild(
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::GetNearestChild(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::GetNearestChild(
|
||||
const Octree& queryNode) const
|
||||
{
|
||||
// It's possible that this could be improved by caching which children we have
|
||||
@@ -577,8 +577,8 @@ size_t Octree<MetricType, StatisticType, MatType>::GetNearestChild(
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::GetFurthestChild(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::GetFurthestChild(
|
||||
const Octree& queryNode) const
|
||||
{
|
||||
// It's possible that this could be improved by caching which children we have
|
||||
@@ -598,9 +598,9 @@ size_t Octree<MetricType, StatisticType, MatType>::GetFurthestChild(
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::FurthestPointDistance()
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::FurthestPointDistance()
|
||||
const
|
||||
{
|
||||
// If we are not a leaf, then this distance is 0. Otherwise, return the
|
||||
@@ -608,85 +608,85 @@ Octree<MetricType, StatisticType, MatType>::FurthestPointDistance()
|
||||
return (children.size() > 0) ? 0.0 : furthestDescendantDistance;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::FurthestDescendantDistance() const
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::FurthestDescendantDistance() const
|
||||
{
|
||||
return furthestDescendantDistance;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::MinimumBoundDistance() const
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::MinimumBoundDistance() const
|
||||
{
|
||||
return bound.MinWidth() / 2.0;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::NumPoints() const
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::NumPoints() const
|
||||
{
|
||||
// We have no points unless we are a leaf;
|
||||
return (children.size() > 0) ? 0 : count;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::NumDescendants() const
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::NumDescendants() const
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::Descendant(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::Descendant(
|
||||
const size_t index) const
|
||||
{
|
||||
return begin + index;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
size_t Octree<MetricType, StatisticType, MatType>::Point(const size_t index)
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
size_t Octree<DistanceType, StatisticType, MatType>::Point(const size_t index)
|
||||
const
|
||||
{
|
||||
return begin + index;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::MinDistance(const Octree& other)
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::MinDistance(const Octree& other)
|
||||
const
|
||||
{
|
||||
return bound.MinDistance(other.Bound());
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::MaxDistance(const Octree& other)
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::MaxDistance(const Octree& other)
|
||||
const
|
||||
{
|
||||
return bound.MaxDistance(other.Bound());
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
RangeType<typename Octree<MetricType, StatisticType, MatType>::ElemType>
|
||||
Octree<MetricType, StatisticType, MatType>::RangeDistance(const Octree& other)
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
RangeType<typename Octree<DistanceType, StatisticType, MatType>::ElemType>
|
||||
Octree<DistanceType, StatisticType, MatType>::RangeDistance(const Octree& other)
|
||||
const
|
||||
{
|
||||
return bound.RangeDistance(other.Bound());
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename VecType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::MinDistance(
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::MinDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*) const
|
||||
{
|
||||
return bound.MinDistance(point);
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename VecType>
|
||||
typename Octree<MetricType, StatisticType, MatType>::ElemType
|
||||
Octree<MetricType, StatisticType, MatType>::MaxDistance(
|
||||
typename Octree<DistanceType, StatisticType, MatType>::ElemType
|
||||
Octree<DistanceType, StatisticType, MatType>::MaxDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*) const
|
||||
{
|
||||
@@ -694,10 +694,10 @@ Octree<MetricType, StatisticType, MatType>::MaxDistance(
|
||||
}
|
||||
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename VecType>
|
||||
RangeType<typename Octree<MetricType, StatisticType, MatType>::ElemType>
|
||||
Octree<MetricType, StatisticType, MatType>::RangeDistance(
|
||||
RangeType<typename Octree<DistanceType, StatisticType, MatType>::ElemType>
|
||||
Octree<DistanceType, StatisticType, MatType>::RangeDistance(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*) const
|
||||
{
|
||||
@@ -705,9 +705,9 @@ Octree<MetricType, StatisticType, MatType>::RangeDistance(
|
||||
}
|
||||
|
||||
//! Serialize the tree.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename Archive>
|
||||
void Octree<MetricType, StatisticType, MatType>::serialize(
|
||||
void Octree<DistanceType, StatisticType, MatType>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
{
|
||||
@@ -732,7 +732,7 @@ void Octree<MetricType, StatisticType, MatType>::serialize(
|
||||
ar(CEREAL_NVP(stat));
|
||||
ar(CEREAL_NVP(parentDistance));
|
||||
ar(CEREAL_NVP(furthestDescendantDistance));
|
||||
ar(CEREAL_NVP(metric));
|
||||
ar(CEREAL_NVP(distance));
|
||||
ar(CEREAL_NVP(hasParent));
|
||||
if (!hasParent)
|
||||
{
|
||||
@@ -770,8 +770,8 @@ void Octree<MetricType, StatisticType, MatType>::serialize(
|
||||
}
|
||||
|
||||
//! Split the node.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
void Octree<MetricType, StatisticType, MatType>::SplitNode(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
void Octree<DistanceType, StatisticType, MatType>::SplitNode(
|
||||
const arma::vec& center,
|
||||
const double width,
|
||||
const size_t maxLeafSize)
|
||||
@@ -871,8 +871,8 @@ void Octree<MetricType, StatisticType, MatType>::SplitNode(
|
||||
}
|
||||
|
||||
//! Split the node, and store mappings.
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
void Octree<MetricType, StatisticType, MatType>::SplitNode(
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
void Octree<DistanceType, StatisticType, MatType>::SplitNode(
|
||||
const arma::vec& center,
|
||||
const double width,
|
||||
std::vector<size_t>& oldFromNew,
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename RuleType>
|
||||
class Octree<MetricType, StatisticType, MatType>::SingleTreeTraverser
|
||||
class Octree<DistanceType, StatisticType, MatType>::SingleTreeTraverser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename RuleType>
|
||||
Octree<MetricType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
Octree<DistanceType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
SingleTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
@@ -27,9 +27,10 @@ Octree<MetricType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
template<typename RuleType>
|
||||
void Octree<MetricType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
void
|
||||
Octree<DistanceType, StatisticType, MatType>::SingleTreeTraverser<RuleType>::
|
||||
Traverse(const size_t queryIndex, Octree& referenceNode)
|
||||
{
|
||||
// If we are a leaf, run the base cases.
|
||||
|
||||
@@ -22,10 +22,10 @@ namespace mlpack {
|
||||
* tree-independent (but still optimized) tree-based algorithms. See
|
||||
* mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType>
|
||||
class TreeTraits<Octree<MetricType, StatisticType, MatType>>
|
||||
class TreeTraits<Octree<DistanceType, StatisticType, MatType>>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename RuleType>
|
||||
class RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
class RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::DualTreeTraverser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename RuleType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
DualTreeTraverser<RuleType>::DualTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
@@ -38,14 +38,14 @@ DualTreeTraverser<RuleType>::DualTreeTraverser(RuleType& rule) :
|
||||
numBaseCases(0)
|
||||
{ /* Nothing to do */ }
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename RuleType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
DualTreeTraverser<RuleType>::Traverse(RectangleTree& queryNode,
|
||||
RectangleTree& referenceNode)
|
||||
|
||||
@@ -51,7 +51,7 @@ size_t RStarTreeSplit::ReinsertPoints(TreeType* tree,
|
||||
tree->Bound().Center(center);
|
||||
for (size_t i = 0; i < sorted.size(); ++i)
|
||||
{
|
||||
sorted[i].first = tree->Metric().Evaluate(center,
|
||||
sorted[i].first = tree->Distance().Evaluate(center,
|
||||
tree->Dataset().col(tree->Point(i)));
|
||||
sorted[i].second = tree->Point(i);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace mlpack {
|
||||
*
|
||||
* This tree does allow growth, so you can add and delete nodes from it.
|
||||
*
|
||||
* @tparam MetricType This *must* be EuclideanDistance, but the template
|
||||
* @tparam DistanceType This *must* be EuclideanDistance, but the template
|
||||
* parameter is required to satisfy the TreeType API.
|
||||
* @tparam StatisticType Extra data contained in the node. See statistic.hpp
|
||||
* for the necessary skeleton interface.
|
||||
@@ -43,7 +43,7 @@ namespace mlpack {
|
||||
* in the node. This information depends on the type of the RectangleTree.
|
||||
*/
|
||||
|
||||
template<typename MetricType = EuclideanDistance,
|
||||
template<typename DistanceType = EuclideanDistance,
|
||||
typename StatisticType = EmptyStatistic,
|
||||
typename MatType = arma::mat,
|
||||
typename SplitType = RTreeSplit,
|
||||
@@ -52,9 +52,9 @@ template<typename MetricType = EuclideanDistance,
|
||||
NoAuxiliaryInformation>
|
||||
class RectangleTree
|
||||
{
|
||||
// The metric *must* be the euclidean distance.
|
||||
static_assert(std::is_same<MetricType, EuclideanDistance>::value,
|
||||
"RectangleTree: MetricType must be EuclideanDistance.");
|
||||
// The distance metric *must* be the euclidean distance.
|
||||
static_assert(std::is_same<DistanceType, EuclideanDistance>::value,
|
||||
"RectangleTree: DistanceType must be EuclideanDistance.");
|
||||
|
||||
public:
|
||||
//! So other classes can use TreeType::Mat.
|
||||
@@ -311,9 +311,9 @@ class RectangleTree
|
||||
RectangleTree* FindByBeginCount(size_t begin, size_t count);
|
||||
|
||||
//! Return the bound object for this node.
|
||||
const HRectBound<MetricType>& Bound() const { return bound; }
|
||||
const HRectBound<DistanceType>& Bound() const { return bound; }
|
||||
//! Modify the bound object for this node.
|
||||
HRectBound<MetricType>& Bound() { return bound; }
|
||||
HRectBound<DistanceType>& Bound() { return bound; }
|
||||
|
||||
//! Return the statistic object for this node.
|
||||
const StatisticType& Stat() const { return stat; }
|
||||
@@ -360,8 +360,12 @@ class RectangleTree
|
||||
//! Modify the dataset which the tree is built on. Be careful!
|
||||
MatType& Dataset() { return const_cast<MatType&>(*dataset); }
|
||||
|
||||
//! Get the metric which the tree uses.
|
||||
MetricType Metric() const { return MetricType(); }
|
||||
//! Get the distance metric which the tree uses.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType Metric() const { return DistanceType(); }
|
||||
|
||||
//! Get the distance metric which the tree uses.
|
||||
DistanceType Distance() const { return DistanceType(); }
|
||||
|
||||
//! Get the centroid of the node and store it in the given vector.
|
||||
void Center(arma::vec& center) { bound.Center(center); }
|
||||
@@ -618,7 +622,7 @@ class RectangleTree
|
||||
* shrinking.
|
||||
* @return true if the bound needed to be changed, false if it did not.
|
||||
*/
|
||||
bool ShrinkBoundForBound(const HRectBound<MetricType>& changedBound);
|
||||
bool ShrinkBoundForBound(const HRectBound<DistanceType>& changedBound);
|
||||
|
||||
/**
|
||||
* Make an exact copy of this node, pointers and everything.
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
namespace mlpack {
|
||||
|
||||
// Build the statistics, bottom-up.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
BuildStatistics(RectangleTree* node)
|
||||
{
|
||||
@@ -38,13 +38,13 @@ BuildStatistics(RectangleTree* node)
|
||||
node->Stat() = StatisticType(*node);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree(const MatType& data,
|
||||
const size_t maxLeafSize,
|
||||
@@ -79,13 +79,13 @@ RectangleTree(const MatType& data,
|
||||
BuildStatistics(this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree(MatType&& data,
|
||||
const size_t maxLeafSize,
|
||||
@@ -120,16 +120,16 @@ RectangleTree(MatType&& data,
|
||||
BuildStatistics(this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree(
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>*
|
||||
parentNode, const size_t numMaxChildren) :
|
||||
maxNumChildren(numMaxChildren > 0 ? numMaxChildren :
|
||||
@@ -158,13 +158,13 @@ RectangleTree(
|
||||
* Create a rectangle tree by copying the other tree. Be careful! This can
|
||||
* take a long time and use a lot of memory.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree(
|
||||
const RectangleTree& other,
|
||||
@@ -205,13 +205,13 @@ RectangleTree(
|
||||
/**
|
||||
* Move constructor.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree(RectangleTree&& other) :
|
||||
maxNumChildren(other.MaxNumChildren()),
|
||||
@@ -264,15 +264,15 @@ RectangleTree(RectangleTree&& other) :
|
||||
/**
|
||||
* Copy assignment operator: copy the given other tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>&
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
operator=(const RectangleTree& other)
|
||||
{
|
||||
@@ -317,15 +317,15 @@ operator=(const RectangleTree& other)
|
||||
/**
|
||||
* Move assignment operator: take ownership of the given tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>&
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
operator=(RectangleTree&& other)
|
||||
{
|
||||
@@ -379,14 +379,14 @@ operator=(RectangleTree&& other)
|
||||
/**
|
||||
* Construct the tree from a cereal archive.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename Archive>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree(
|
||||
Archive& ar,
|
||||
@@ -402,13 +402,13 @@ RectangleTree(
|
||||
* their destructors in turn. This will invalidate any pointers or references
|
||||
* to any nodes which are children of this one.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
~RectangleTree()
|
||||
{
|
||||
@@ -423,13 +423,13 @@ RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Deletes this node but leaves the children untouched. Needed for when we
|
||||
* split nodes and remove nodes (inserting and deleting points).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
SoftDelete()
|
||||
{
|
||||
@@ -445,13 +445,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
/**
|
||||
* Nullify the auxiliary information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
NullifyData()
|
||||
{
|
||||
@@ -462,13 +462,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Recurse through the tree and insert the point at the leaf node chosen
|
||||
* by the heuristic.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
InsertPoint(const size_t point)
|
||||
{
|
||||
@@ -499,13 +499,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
/**
|
||||
* Inserts a point into the tree, tracking which levels have been inserted into.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
InsertPoint(const size_t point, std::vector<bool>& relevels)
|
||||
{
|
||||
@@ -539,13 +539,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* @param relevels The levels that have been reinserted to on this top level
|
||||
* insertion.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
InsertNode(RectangleTree* node,
|
||||
const size_t level,
|
||||
@@ -575,13 +575,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Recurse through the tree to remove the point. Once we find the point, we
|
||||
* shrink the rectangles if necessary.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
bool RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
DeletePoint(const size_t point)
|
||||
{
|
||||
@@ -627,13 +627,13 @@ bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Recurse through the tree to remove the point. Once we find the point, we
|
||||
* shrink the rectangles if necessary.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
bool RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
DeletePoint(const size_t point, std::vector<bool>& relevels)
|
||||
{
|
||||
@@ -672,13 +672,13 @@ bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Recurse through the tree to remove the node. Once we find the node, we
|
||||
* shrink the rectangles if necessary.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
bool RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RemoveNode(const RectangleTree* node, std::vector<bool>& relevels)
|
||||
{
|
||||
@@ -712,13 +712,13 @@ bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::TreeSize() const
|
||||
{
|
||||
int n = 0;
|
||||
@@ -728,13 +728,13 @@ size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
return n + 1; // Add one for this node.
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::TreeDepth() const
|
||||
{
|
||||
int n = 1;
|
||||
@@ -749,13 +749,13 @@ size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
inline bool RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
inline bool RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::IsLeaf() const
|
||||
{
|
||||
return (numChildren == 0);
|
||||
@@ -765,14 +765,14 @@ inline bool RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
* Return the index of the nearest child node to the given query point. If
|
||||
* this is a leaf node, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename VecType>
|
||||
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::GetNearestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
@@ -798,14 +798,14 @@ size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Return the index of the furthest child node to the given query point. If
|
||||
* this is a leaf node, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename VecType>
|
||||
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::GetFurthestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
@@ -831,13 +831,13 @@ size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Return the index of the nearest child node to the given query node. If it
|
||||
* can't decide, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::GetNearestChild(const RectangleTree& queryNode)
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -861,13 +861,13 @@ size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Return the index of the furthest child node to the given query node. If it
|
||||
* can't decide, it will return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::GetFurthestChild(const RectangleTree& queryNode)
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -891,16 +891,16 @@ size_t RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
* Return a bound on the furthest point in the node form the centroid.
|
||||
* This returns 0 unless the node is a leaf.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
inline
|
||||
typename RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
typename RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::ElemType
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::FurthestPointDistance() const
|
||||
{
|
||||
if (!IsLeaf())
|
||||
@@ -917,16 +917,16 @@ RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
* furthest descendant distance may be less than what this method returns (but
|
||||
* it will never be greater than this).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
inline
|
||||
typename RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
typename RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::ElemType
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::FurthestDescendantDistance() const
|
||||
{
|
||||
// Return the distance from the centroid to a corner of the bound.
|
||||
@@ -937,13 +937,13 @@ RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
* Return the number of points contained in this node. Zero if it is a non-leaf
|
||||
* node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
inline size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
inline size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::NumPoints() const
|
||||
{
|
||||
if (numChildren != 0) // This is not a leaf node.
|
||||
@@ -955,13 +955,13 @@ inline size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
/**
|
||||
* Return the number of descendants under or in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
inline size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
inline size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::NumDescendants() const
|
||||
{
|
||||
return numDescendants;
|
||||
@@ -970,13 +970,13 @@ inline size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
/**
|
||||
* Return the index of a particular descendant contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
inline size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
inline size_t RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::Descendant(const size_t index) const
|
||||
{
|
||||
// I think this may be inefficient...
|
||||
@@ -1004,13 +1004,13 @@ inline size_t RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
* Split the tree. This calls the SplitType code to split a node. This method
|
||||
* should only be called on a leaf node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
SplitNode(std::vector<bool>& relevels)
|
||||
{
|
||||
@@ -1036,13 +1036,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
}
|
||||
|
||||
//! Default constructor for cereal.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
RectangleTree() :
|
||||
maxNumChildren(0), // Try to give sensible defaults, but it shouldn't matter
|
||||
@@ -1065,13 +1065,13 @@ RectangleTree() :
|
||||
* Condense the tree. This shrinks the bounds and moves up the tree if
|
||||
* applicable. If a node goes below minimum fill, this code will deal with it.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
CondenseTree(const arma::vec& point,
|
||||
std::vector<bool>& relevels,
|
||||
@@ -1249,13 +1249,13 @@ void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
/**
|
||||
* Shrink the bound so it fits tightly after the removal of this point.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
bool RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
ShrinkBoundForPoint(const arma::vec& point)
|
||||
{
|
||||
@@ -1347,15 +1347,15 @@ bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
/**
|
||||
* Shrink the bound so it fits tightly after the removal of another bound.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
bool RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
ShrinkBoundForBound(const HRectBound<MetricType>& /* b */)
|
||||
ShrinkBoundForBound(const HRectBound<DistanceType>& /* b */)
|
||||
{
|
||||
// Using the sum is safe since none of the dimensions can increase.
|
||||
ElemType sum = 0;
|
||||
@@ -1383,14 +1383,14 @@ bool RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
/**
|
||||
* Serialize the tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename Archive>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::serialize(
|
||||
Archive& ar,
|
||||
const uint32_t /* version */)
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename RuleType>
|
||||
class RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
class RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>::SingleTreeTraverser
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -21,28 +21,28 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename RuleType>
|
||||
RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
SingleTreeTraverser<RuleType>::SingleTreeTraverser(RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
{ /* Nothing to do */ }
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
template<typename RuleType>
|
||||
void RectangleTree<MetricType, StatisticType, MatType, SplitType, DescentType,
|
||||
void RectangleTree<DistanceType, StatisticType, MatType, SplitType, DescentType,
|
||||
AuxiliaryInformationType>::
|
||||
SingleTreeTraverser<RuleType>::Traverse(
|
||||
const size_t queryIndex,
|
||||
|
||||
@@ -22,13 +22,13 @@ namespace mlpack {
|
||||
* help write tree-independent (but still optimized) tree-based algorithms. See
|
||||
* mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
class TreeTraits<RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
class TreeTraits<RectangleTree<DistanceType, StatisticType, MatType, SplitType,
|
||||
DescentType, AuxiliaryInformationType>>
|
||||
{
|
||||
public:
|
||||
@@ -75,14 +75,14 @@ class TreeTraits<RectangleTree<MetricType, StatisticType, MatType, SplitType,
|
||||
* Since the R+/R++ tree can not have overlapping children, we should define
|
||||
* traits for the R+/R++ tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
typename SplitPolicyType,
|
||||
template<typename> class SweepType,
|
||||
typename DescentType,
|
||||
template<typename> class AuxiliaryInformationType>
|
||||
class TreeTraits<RectangleTree<MetricType,
|
||||
class TreeTraits<RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
RPlusTreeSplit<SplitPolicyType,
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace mlpack {
|
||||
*
|
||||
* @see @ref trees, RStarTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using RTree = RectangleTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using RTree = RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
RTreeSplit,
|
||||
@@ -65,8 +65,8 @@ using RTree = RectangleTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, RTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using RStarTree = RectangleTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using RStarTree = RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
RStarTreeSplit,
|
||||
@@ -91,8 +91,8 @@ using RStarTree = RectangleTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, RTree, RStarTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using XTree = RectangleTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using XTree = RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
XTreeSplit,
|
||||
@@ -126,8 +126,8 @@ template<typename TreeType>
|
||||
using DiscreteHilbertRTreeAuxiliaryInformation =
|
||||
HilbertRTreeAuxiliaryInformation<TreeType, DiscreteHilbertValue>;
|
||||
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using HilbertRTree = RectangleTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using HilbertRTree = RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
HilbertRTreeSplit<2>,
|
||||
@@ -157,8 +157,8 @@ using HilbertRTree = RectangleTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, RTree, RTree, RPlusTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using RPlusTree = RectangleTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using RPlusTree = RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
RPlusTreeSplit<RPlusTreeSplitPolicy,
|
||||
@@ -186,8 +186,8 @@ using RPlusTree = RectangleTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, RTree, RTree, RPlusTree, RPlusPlusTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using RPlusPlusTree = RectangleTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using RPlusPlusTree = RectangleTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
RPlusTreeSplit<RPlusPlusTreeSplitPolicy,
|
||||
|
||||
@@ -139,15 +139,15 @@ class HyperplaneBase
|
||||
/**
|
||||
* AxisOrthogonalHyperplane represents a hyperplane orthogonal to an axis.
|
||||
*/
|
||||
template<typename MetricType>
|
||||
using AxisOrthogonalHyperplane = HyperplaneBase<HRectBound<MetricType>,
|
||||
template<typename DistanceType>
|
||||
using AxisOrthogonalHyperplane = HyperplaneBase<HRectBound<DistanceType>,
|
||||
AxisParallelProjVector>;
|
||||
|
||||
/**
|
||||
* Hyperplane represents a general hyperplane (not necessarily axis-orthogonal).
|
||||
*/
|
||||
template<typename MetricType>
|
||||
using Hyperplane = HyperplaneBase<BallBound<MetricType>, ProjVector>;
|
||||
template<typename DistanceType>
|
||||
using Hyperplane = HyperplaneBase<BallBound<DistanceType>, ProjVector>;
|
||||
|
||||
} // namespace mlpack
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
template<typename DistanceType, typename MatType>
|
||||
class MeanSpaceSplit
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
template<typename DistanceType, typename MatType>
|
||||
template<typename HyperplaneType>
|
||||
bool MeanSpaceSplit<MetricType, MatType>::SplitSpace(
|
||||
bool MeanSpaceSplit<DistanceType, MatType>::SplitSpace(
|
||||
const typename HyperplaneType::BoundType& bound,
|
||||
const MatType& data,
|
||||
const arma::Col<size_t>& points,
|
||||
@@ -29,7 +29,7 @@ bool MeanSpaceSplit<MetricType, MatType>::SplitSpace(
|
||||
typename HyperplaneType::ProjVectorType projVector;
|
||||
double midValue;
|
||||
|
||||
if (!SpaceSplit<MetricType, MatType>::GetProjVector(bound, data, points,
|
||||
if (!SpaceSplit<DistanceType, MatType>::GetProjVector(bound, data, points,
|
||||
projVector, midValue))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
template<typename DistanceType, typename MatType>
|
||||
class MidpointSpaceSplit
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
template<typename DistanceType, typename MatType>
|
||||
template<typename HyperplaneType>
|
||||
bool MidpointSpaceSplit<MetricType, MatType>::SplitSpace(
|
||||
bool MidpointSpaceSplit<DistanceType, MatType>::SplitSpace(
|
||||
const typename HyperplaneType::BoundType& bound,
|
||||
const MatType& data,
|
||||
const arma::Col<size_t>& points,
|
||||
@@ -29,7 +29,7 @@ bool MidpointSpaceSplit<MetricType, MatType>::SplitSpace(
|
||||
typename HyperplaneType::ProjVectorType projVector;
|
||||
double midValue;
|
||||
|
||||
if (!SpaceSplit<MetricType, MatType>::GetProjVector(bound, data, points,
|
||||
if (!SpaceSplit<DistanceType, MatType>::GetProjVector(bound, data, points,
|
||||
projVector, midValue))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ class AxisParallelProjVector
|
||||
* @param bound Bound to be projected.
|
||||
* @return Range of projected values.
|
||||
*/
|
||||
template<typename MetricType, typename ElemType>
|
||||
template<typename DistanceType, typename ElemType>
|
||||
RangeType<ElemType> Project(
|
||||
const HRectBound<MetricType, ElemType>& bound) const
|
||||
const HRectBound<DistanceType, ElemType>& bound) const
|
||||
{
|
||||
return bound[dim];
|
||||
}
|
||||
@@ -67,9 +67,9 @@ class AxisParallelProjVector
|
||||
* @param bound Bound to be projected.
|
||||
* @return Range of projected values.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
RangeType<typename VecType::elem_type> Project(
|
||||
const BallBound<MetricType, VecType>& bound) const
|
||||
const BallBound<DistanceType, VecType>& bound) const
|
||||
{
|
||||
return bound[dim];
|
||||
}
|
||||
@@ -128,9 +128,9 @@ class ProjVector
|
||||
* @param bound Bound to be projected.
|
||||
* @return Range of projected values.
|
||||
*/
|
||||
template<typename MetricType, typename VecType>
|
||||
template<typename DistanceType, typename VecType>
|
||||
RangeType<typename VecType::elem_type> Project(
|
||||
const BallBound<MetricType, VecType>& bound) const
|
||||
const BallBound<DistanceType, VecType>& bound) const
|
||||
{
|
||||
typedef typename VecType::elem_type ElemType;
|
||||
const double center = Project(bound.Center());
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
template<typename DistanceType, typename MatType>
|
||||
class SpaceSplit
|
||||
{
|
||||
public:
|
||||
@@ -35,7 +35,7 @@ class SpaceSplit
|
||||
* @return Flag to determine if it is possible.
|
||||
*/
|
||||
static bool GetProjVector(
|
||||
const HRectBound<MetricType>& bound,
|
||||
const HRectBound<DistanceType>& bound,
|
||||
const MatType& data,
|
||||
const arma::Col<size_t>& points,
|
||||
AxisParallelProjVector& projVector,
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
bool SpaceSplit<MetricType, MatType>::GetProjVector(
|
||||
const HRectBound<MetricType>& bound,
|
||||
template<typename DistanceType, typename MatType>
|
||||
bool SpaceSplit<DistanceType, MatType>::GetProjVector(
|
||||
const HRectBound<DistanceType>& bound,
|
||||
const MatType& data,
|
||||
const arma::Col<size_t>& /* points */,
|
||||
AxisParallelProjVector& projVector,
|
||||
@@ -50,25 +50,25 @@ bool SpaceSplit<MetricType, MatType>::GetProjVector(
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename MetricType, typename MatType>
|
||||
template<typename DistanceType, typename MatType>
|
||||
template<typename BoundType>
|
||||
bool SpaceSplit<MetricType, MatType>::GetProjVector(
|
||||
bool SpaceSplit<DistanceType, MatType>::GetProjVector(
|
||||
const BoundType& /* bound */,
|
||||
const MatType& data,
|
||||
const arma::Col<size_t>& points,
|
||||
ProjVector& projVector,
|
||||
double& midValue)
|
||||
{
|
||||
MetricType metric;
|
||||
DistanceType distance;
|
||||
|
||||
// Efficiently estimate the farthest pair of points in the given set.
|
||||
size_t fst = points[rand() % points.n_elem];
|
||||
size_t snd = points[0];
|
||||
double max = metric.Evaluate(data.col(fst), data.col(snd));
|
||||
double max = distance.Evaluate(data.col(fst), data.col(snd));
|
||||
|
||||
for (size_t i = 1; i < points.n_elem; ++i)
|
||||
{
|
||||
double dist = metric.Evaluate(data.col(fst), data.col(points[i]));
|
||||
double dist = distance.Evaluate(data.col(fst), data.col(points[i]));
|
||||
if (dist > max)
|
||||
{
|
||||
max = dist;
|
||||
@@ -80,7 +80,7 @@ bool SpaceSplit<MetricType, MatType>::GetProjVector(
|
||||
|
||||
for (size_t i = 0; i < points.n_elem; ++i)
|
||||
{
|
||||
double dist = metric.Evaluate(data.col(fst), data.col(points[i]));
|
||||
double dist = distance.Evaluate(data.col(fst), data.col(points[i]));
|
||||
if (dist > max)
|
||||
{
|
||||
max = dist;
|
||||
|
||||
@@ -23,15 +23,15 @@ struct IsSpillTree
|
||||
};
|
||||
|
||||
// Specialization for SpillTree.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType>
|
||||
template<typename HyperplaneDistanceType>
|
||||
class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
struct IsSpillTree<SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>>
|
||||
struct IsSpillTree<SpillTree<DistanceType, StatisticType, MatType,
|
||||
HyperplaneType, SplitType>>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType, bool Defeatist>
|
||||
class SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillDualTreeTraverser
|
||||
class SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::SpillDualTreeTraverser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType, bool Defeatist>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillDualTreeTraverser<RuleType, Defeatist>::SpillDualTreeTraverser(
|
||||
RuleType& rule) :
|
||||
rule(rule),
|
||||
@@ -37,18 +37,19 @@ SpillDualTreeTraverser<RuleType, Defeatist>::SpillDualTreeTraverser(
|
||||
numBaseCases(0)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType, bool Defeatist>
|
||||
void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
void
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillDualTreeTraverser<RuleType, Defeatist>::Traverse(
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
queryNode,
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
referenceNode,
|
||||
const bool bruteForce)
|
||||
{
|
||||
|
||||
@@ -23,15 +23,15 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType, bool Defeatist>
|
||||
class SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillSingleTreeTraverser
|
||||
class SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::SpillSingleTreeTraverser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -20,31 +20,32 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType, bool Defeatist>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillSingleTreeTraverser<RuleType, Defeatist>::SpillSingleTreeTraverser(
|
||||
RuleType& rule) :
|
||||
rule(rule),
|
||||
numPrunes(0)
|
||||
{ /* Nothing to do. */ }
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename RuleType, bool Defeatist>
|
||||
void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
void
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillSingleTreeTraverser<RuleType, Defeatist>::Traverse(
|
||||
const size_t queryIndex,
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
referenceNode,
|
||||
const bool bruteForce)
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace mlpack {
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @tparam MetricType The metric used for tree-building.
|
||||
* @tparam DistanceType The distance metric used for tree-building.
|
||||
* @tparam StatisticType Extra data contained in the node. See statistic.hpp
|
||||
* for the necessary skeleton interface.
|
||||
* @tparam MatType The dataset class.
|
||||
@@ -62,12 +62,12 @@ namespace mlpack {
|
||||
* particular node into two parts. Its definition decides the way this split
|
||||
* is done.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType = EmptyStatistic,
|
||||
typename MatType = arma::mat,
|
||||
template<typename HyperplaneMetricType>
|
||||
template<typename HyperplaneDistanceType>
|
||||
class HyperplaneType = AxisOrthogonalHyperplane,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType = MidpointSpaceSplit>
|
||||
class SpillTree
|
||||
{
|
||||
@@ -77,7 +77,7 @@ class SpillTree
|
||||
//! The type of element held in MatType.
|
||||
typedef typename MatType::elem_type ElemType;
|
||||
//! The bound type.
|
||||
typedef typename HyperplaneType<MetricType>::BoundType BoundType;
|
||||
typedef typename HyperplaneType<DistanceType>::BoundType BoundType;
|
||||
|
||||
private:
|
||||
//! The left child node.
|
||||
@@ -95,7 +95,7 @@ class SpillTree
|
||||
//! Flag to distinguish overlapping nodes from non-overlapping nodes.
|
||||
bool overlappingNode;
|
||||
//! Splitting hyperplane represented by this node.
|
||||
HyperplaneType<MetricType> hyperplane;
|
||||
HyperplaneType<DistanceType> hyperplane;
|
||||
//! The bound object for this node.
|
||||
BoundType bound;
|
||||
//! Any extra data contained in the node.
|
||||
@@ -274,10 +274,14 @@ class SpillTree
|
||||
bool Overlap() const { return overlappingNode; }
|
||||
|
||||
//! Get the Hyperplane instance.
|
||||
const HyperplaneType<MetricType>& Hyperplane() const { return hyperplane; }
|
||||
const HyperplaneType<DistanceType>& Hyperplane() const { return hyperplane; }
|
||||
|
||||
//! Get the metric that the tree uses.
|
||||
MetricType Metric() const { return MetricType(); }
|
||||
//! Get the distance metric that the tree uses.
|
||||
[[deprecated("Will be removed in mlpack 5.0.0; use Distance()")]]
|
||||
DistanceType Metric() const { return DistanceType(); }
|
||||
|
||||
//! Get the distance metric that the tree uses.
|
||||
DistanceType Distance() const { return DistanceType(); }
|
||||
|
||||
//! Return the number of children in this node.
|
||||
size_t NumChildren() const;
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree(
|
||||
const MatType& data,
|
||||
const double tau,
|
||||
@@ -55,13 +55,13 @@ SpillTree(
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree(
|
||||
MatType&& data,
|
||||
const double tau,
|
||||
@@ -92,13 +92,13 @@ SpillTree(
|
||||
stat = StatisticType(*this);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree(
|
||||
SpillTree* parent,
|
||||
arma::Col<size_t>& points,
|
||||
@@ -127,13 +127,13 @@ SpillTree(
|
||||
* Create a hybrid spill tree by copying the other tree. Be careful! This can
|
||||
* take a long time and use a lot of memory.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree(const SpillTree& other) :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -194,14 +194,14 @@ SpillTree(const SpillTree& other) :
|
||||
/**
|
||||
* Copy assignment operator: copy the given other tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
operator=(const SpillTree& other)
|
||||
{
|
||||
if (this == &other)
|
||||
@@ -276,13 +276,13 @@ operator=(const SpillTree& other)
|
||||
/**
|
||||
* Move constructor.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree(SpillTree&& other) :
|
||||
left(other.left),
|
||||
right(other.right),
|
||||
@@ -321,14 +321,14 @@ SpillTree(SpillTree&& other) :
|
||||
/**
|
||||
* Move assignment operator: take ownership of the given tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
operator=(SpillTree&& other)
|
||||
{
|
||||
if (this == &other)
|
||||
@@ -381,14 +381,14 @@ operator=(SpillTree&& other)
|
||||
/**
|
||||
* Initialize the tree from an archive.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename Archive>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree(
|
||||
Archive& ar,
|
||||
const typename std::enable_if_t<cereal::is_loading<Archive>()>*) :
|
||||
@@ -404,13 +404,13 @@ SpillTree(
|
||||
* destructors in turn. This will invalidate any pointers or references to any
|
||||
* nodes which are children of this one.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
~SpillTree()
|
||||
{
|
||||
delete left;
|
||||
@@ -422,13 +422,13 @@ SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
delete dataset;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline bool SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline bool SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::IsLeaf() const
|
||||
{
|
||||
return !left;
|
||||
@@ -437,13 +437,13 @@ inline bool SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
/**
|
||||
* Returns the number of children in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::NumChildren() const
|
||||
{
|
||||
if (left && right)
|
||||
@@ -460,14 +460,14 @@ inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
* returned is not necessarily the nearest). If this is a leaf node, it will
|
||||
* return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename VecType>
|
||||
size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::GetNearestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
@@ -486,14 +486,14 @@ size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
* returned is not necessarily the furthest). If this is a leaf node, it will
|
||||
* return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename VecType>
|
||||
size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::GetFurthestChild(
|
||||
const VecType& point,
|
||||
typename std::enable_if_t<IsVector<VecType>::value>*)
|
||||
@@ -512,13 +512,13 @@ size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
* returned is not necessarily the nearest). If it can't decide it will
|
||||
* return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::GetNearestChild(const SpillTree& queryNode)
|
||||
{
|
||||
if (IsLeaf() || !left || !right)
|
||||
@@ -538,13 +538,13 @@ size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
* returned is not necessarily the furthest). If this is a leaf node, it will
|
||||
* return NumChildren() (invalid index).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::GetFurthestChild(const SpillTree& queryNode)
|
||||
{
|
||||
if (IsLeaf() || !left || !right)
|
||||
@@ -562,15 +562,15 @@ size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
* Return a bound on the furthest point in the node from the center. This
|
||||
* returns 0 unless the node is a leaf.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline typename SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline typename SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::ElemType
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
FurthestPointDistance() const
|
||||
{
|
||||
if (!IsLeaf())
|
||||
@@ -587,30 +587,30 @@ SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
* furthest descendant distance may be less than what this method returns (but
|
||||
* it will never be greater than this).
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline typename SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline typename SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::ElemType
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
FurthestDescendantDistance() const
|
||||
{
|
||||
return furthestDescendantDistance;
|
||||
}
|
||||
|
||||
//! Return the minimum distance from the center to any bound edge.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline typename SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline typename SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::ElemType
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
MinimumBoundDistance() const
|
||||
{
|
||||
return bound.MinWidth() / 2.0;
|
||||
@@ -619,14 +619,14 @@ SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
/**
|
||||
* Return the specified child.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
inline SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>&
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
Child(const size_t child) const
|
||||
{
|
||||
if (child == 0)
|
||||
@@ -638,13 +638,13 @@ SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
/**
|
||||
* Return the number of points contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::NumPoints() const
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -655,13 +655,13 @@ inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
/**
|
||||
* Return the number of descendants contained in the node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::NumDescendants() const
|
||||
{
|
||||
return count;
|
||||
@@ -670,13 +670,13 @@ inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
/**
|
||||
* Return the index of a particular descendant contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::Descendant(const size_t index) const
|
||||
{
|
||||
if (IsLeaf() || overlappingNode)
|
||||
@@ -694,13 +694,13 @@ inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
/**
|
||||
* Return the index of a particular point contained in this node.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
inline size_t SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>::Point(const size_t index) const
|
||||
{
|
||||
if (IsLeaf())
|
||||
@@ -709,13 +709,13 @@ inline size_t SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
return (size_t() - 1);
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
void SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SplitNode(arma::Col<size_t>& points,
|
||||
const size_t maxLeafSize,
|
||||
const double tau,
|
||||
@@ -736,7 +736,7 @@ void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
return; // We can't split this.
|
||||
}
|
||||
|
||||
const bool split = SplitType<MetricType, MatType>::SplitSpace(bound,
|
||||
const bool split = SplitType<DistanceType, MatType>::SplitSpace(bound,
|
||||
*dataset, points, hyperplane);
|
||||
// The node may not be always split. For instance, if all the points are the
|
||||
// same, we can't split them.
|
||||
@@ -775,21 +775,21 @@ void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
left->Center(leftCenter);
|
||||
right->Center(rightCenter);
|
||||
|
||||
const ElemType leftParentDistance = MetricType::Evaluate(center, leftCenter);
|
||||
const ElemType rightParentDistance = MetricType::Evaluate(center,
|
||||
const ElemType leftParentDistance = DistanceType::Evaluate(center, leftCenter);
|
||||
const ElemType rightParentDistance = DistanceType::Evaluate(center,
|
||||
rightCenter);
|
||||
|
||||
left->ParentDistance() = leftParentDistance;
|
||||
right->ParentDistance() = rightParentDistance;
|
||||
}
|
||||
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
bool SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
bool SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SplitPoints(const double tau,
|
||||
const double rho,
|
||||
const arma::Col<size_t>& points,
|
||||
@@ -869,13 +869,13 @@ bool SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
}
|
||||
|
||||
// Default constructor (private), for cereal.
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
SpillTree() :
|
||||
left(NULL),
|
||||
right(NULL),
|
||||
@@ -895,14 +895,14 @@ SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
/**
|
||||
* Serialize the tree.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
template<typename Archive>
|
||||
void SpillTree<MetricType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
void SpillTree<DistanceType, StatisticType, MatType, HyperplaneType, SplitType>::
|
||||
serialize(Archive& ar, const uint32_t /* version */)
|
||||
{
|
||||
// If we're loading, and we have children, they need to be deleted.
|
||||
|
||||
@@ -23,13 +23,13 @@ namespace mlpack {
|
||||
* tree-independent (but still optimized) tree-based algorithms. See
|
||||
* mlpack/core/tree/tree_traits.hpp for more information.
|
||||
*/
|
||||
template<typename MetricType,
|
||||
template<typename DistanceType,
|
||||
typename StatisticType,
|
||||
typename MatType,
|
||||
template<typename HyperplaneMetricType> class HyperplaneType,
|
||||
template<typename SplitMetricType, typename SplitMatType>
|
||||
template<typename HyperplaneDistanceType> class HyperplaneType,
|
||||
template<typename SplitDistanceType, typename SplitMatType>
|
||||
class SplitType>
|
||||
class TreeTraits<SpillTree<MetricType, StatisticType, MatType, HyperplaneType,
|
||||
class TreeTraits<SpillTree<DistanceType, StatisticType, MatType, HyperplaneType,
|
||||
SplitType>>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -53,8 +53,8 @@ namespace mlpack {
|
||||
*
|
||||
* @see @ref trees, SpillTree, MeanSPTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using SPTree = SpillTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using SPTree = SpillTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
AxisOrthogonalHyperplane,
|
||||
@@ -71,8 +71,8 @@ using SPTree = SpillTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, SpillTree, SPTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using MeanSPTree = SpillTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using MeanSPTree = SpillTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
AxisOrthogonalHyperplane,
|
||||
@@ -91,8 +91,8 @@ using MeanSPTree = SpillTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, SpillTree, SPTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using NonOrtSPTree = SpillTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using NonOrtSPTree = SpillTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
Hyperplane,
|
||||
@@ -110,8 +110,8 @@ using NonOrtSPTree = SpillTree<MetricType,
|
||||
*
|
||||
* @see @ref trees, SpillTree, MeanSPTree, NonOrtSPTree
|
||||
*/
|
||||
template<typename MetricType, typename StatisticType, typename MatType>
|
||||
using NonOrtMeanSPTree = SpillTree<MetricType,
|
||||
template<typename DistanceType, typename StatisticType, typename MatType>
|
||||
using NonOrtMeanSPTree = SpillTree<DistanceType,
|
||||
StatisticType,
|
||||
MatType,
|
||||
Hyperplane,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user