Merge pull request #684 from MarcosPividori/approx-knn
Approximate Neighbor Search for Dual tree algorithms.
This commit is contained in:
@@ -72,6 +72,12 @@ PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0);
|
||||
PARAM_FLAG("naive", "If true, O(n^2) naive mode is used for computation.", "N");
|
||||
PARAM_FLAG("single_mode", "If true, single-tree search is used (as opposed to "
|
||||
"dual-tree search).", "s");
|
||||
PARAM_DOUBLE("epsilon", "If specified, will do approximate furthest neighbor "
|
||||
"search with given relative error. Must be in the range [0,1).", "e", 0);
|
||||
PARAM_DOUBLE("percentage", "If specified, will do approximate furthest neighbor"
|
||||
" search. Must be in the range (0,1] (decimal form). Resultant neighbors "
|
||||
"will be at least (p*100) % of the distance as the true furthest neighbor.",
|
||||
"p", 1);
|
||||
|
||||
// Convenience typedef.
|
||||
typedef NSModel<FurthestNeighborSort> KFNModel;
|
||||
@@ -138,6 +144,24 @@ int main(int argc, char *argv[])
|
||||
Log::Fatal << "Invalid leaf size: " << lsInt << ". Must be greater than 0."
|
||||
<< endl;
|
||||
|
||||
// Sanity check on epsilon.
|
||||
double epsilon = CLI::GetParam<double>("epsilon");
|
||||
if (epsilon < 0 || epsilon >= 1)
|
||||
Log::Fatal << "Invalid epsilon: " << epsilon << ". Must be in the range "
|
||||
<< "[0,1)." << endl;
|
||||
|
||||
// Sanity check on percentage.
|
||||
const double percentage = CLI::GetParam<double>("percentage");
|
||||
if (percentage <= 0 || percentage > 1)
|
||||
Log::Fatal << "Invalid percentage: " << percentage << ". Must be in the "
|
||||
<< "range (0,1] (decimal form)." << endl;
|
||||
|
||||
if (CLI::HasParam("percentage") && CLI::HasParam("epsilon"))
|
||||
Log::Fatal << "Cannot provide both epsilon and percentage." << endl;
|
||||
|
||||
if (CLI::HasParam("percentage"))
|
||||
epsilon = 1 - percentage;
|
||||
|
||||
// We either have to load the reference data, or we have to load the model.
|
||||
NSModel<FurthestNeighborSort> kfn;
|
||||
const bool naive = CLI::HasParam("naive");
|
||||
@@ -175,7 +199,8 @@ int main(int argc, char *argv[])
|
||||
Log::Info << "Loaded reference data from '" << referenceFile << "' ("
|
||||
<< referenceSet.n_rows << "x" << referenceSet.n_cols << ")." << endl;
|
||||
|
||||
kfn.BuildModel(std::move(referenceSet), size_t(lsInt), naive, singleMode);
|
||||
kfn.BuildModel(std::move(referenceSet), size_t(lsInt), naive, singleMode,
|
||||
epsilon);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -191,6 +216,7 @@ int main(int argc, char *argv[])
|
||||
kfn.SingleMode() = CLI::HasParam("single_mode");
|
||||
kfn.Naive() = CLI::HasParam("naive");
|
||||
kfn.LeafSize() = size_t(lsInt);
|
||||
kfn.Epsilon() = epsilon;
|
||||
}
|
||||
|
||||
// Perform search, if desired.
|
||||
|
||||
@@ -74,6 +74,8 @@ PARAM_INT("seed", "Random seed (if 0, std::time(NULL) is used).", "s", 0);
|
||||
PARAM_FLAG("naive", "If true, O(n^2) naive mode is used for computation.", "N");
|
||||
PARAM_FLAG("single_mode", "If true, single-tree search is used (as opposed to "
|
||||
"dual-tree search).", "S");
|
||||
PARAM_DOUBLE("epsilon", "If specified, will do approximate nearest neighbor "
|
||||
"search with given relative error.", "e", 0);
|
||||
|
||||
// Convenience typedef.
|
||||
typedef NSModel<NearestNeighborSort> KNNModel;
|
||||
@@ -137,10 +139,14 @@ int main(int argc, char *argv[])
|
||||
// Sanity check on leaf size.
|
||||
const int lsInt = CLI::GetParam<int>("leaf_size");
|
||||
if (lsInt < 1)
|
||||
{
|
||||
Log::Fatal << "Invalid leaf size: " << lsInt << ". Must be greater "
|
||||
"than 0." << endl;
|
||||
}
|
||||
|
||||
// Sanity check on epsilon.
|
||||
const double epsilon = CLI::GetParam<double>("epsilon");
|
||||
if (epsilon < 0)
|
||||
Log::Fatal << "Invalid epsilon: " << epsilon << ". Must be non-negative. "
|
||||
<< endl;
|
||||
|
||||
// We either have to load the reference data, or we have to load the model.
|
||||
NSModel<NearestNeighborSort> knn;
|
||||
@@ -180,7 +186,8 @@ int main(int argc, char *argv[])
|
||||
<< referenceSet.n_rows << " x " << referenceSet.n_cols << ")."
|
||||
<< endl;
|
||||
|
||||
knn.BuildModel(std::move(referenceSet), size_t(lsInt), naive, singleMode);
|
||||
knn.BuildModel(std::move(referenceSet), size_t(lsInt), naive, singleMode,
|
||||
epsilon);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -196,6 +203,7 @@ int main(int argc, char *argv[])
|
||||
knn.SingleMode() = CLI::HasParam("single_mode");
|
||||
knn.Naive() = CLI::HasParam("naive");
|
||||
knn.LeafSize() = size_t(lsInt);
|
||||
knn.Epsilon() = epsilon;
|
||||
}
|
||||
|
||||
// Perform search, if desired.
|
||||
|
||||
@@ -84,11 +84,13 @@ class NeighborSearch
|
||||
* dual-tree search). This overrides singleMode (if it is set to true).
|
||||
* @param singleMode If true, single-tree search will be used (as opposed to
|
||||
* dual-tree search).
|
||||
* @param epsilon Relative approximate error (non-negative).
|
||||
* @param metric An optional instance of the MetricType class.
|
||||
*/
|
||||
NeighborSearch(const MatType& referenceSet,
|
||||
const bool naive = false,
|
||||
const bool singleMode = false,
|
||||
const double epsilon = 0,
|
||||
const MetricType metric = MetricType());
|
||||
|
||||
/**
|
||||
@@ -108,11 +110,13 @@ class NeighborSearch
|
||||
* dual-tree search). This overrides singleMode (if it is set to true).
|
||||
* @param singleMode If true, single-tree search will be used (as opposed to
|
||||
* dual-tree search).
|
||||
* @param epsilon Relative approximate error (non-negative).
|
||||
* @param metric An optional instance of the MetricType class.
|
||||
*/
|
||||
NeighborSearch(MatType&& referenceSet,
|
||||
const bool naive = false,
|
||||
const bool singleMode = false,
|
||||
const double epsilon = 0,
|
||||
const MetricType metric = MetricType());
|
||||
|
||||
/**
|
||||
@@ -138,10 +142,12 @@ class NeighborSearch
|
||||
* @param referenceSet Set of reference points corresponding to referenceTree.
|
||||
* @param singleMode Whether single-tree computation should be used (as
|
||||
* opposed to dual-tree computation).
|
||||
* @param epsilon Relative approximate error (non-negative).
|
||||
* @param metric Instantiated distance metric.
|
||||
*/
|
||||
NeighborSearch(Tree* referenceTree,
|
||||
const bool singleMode = false,
|
||||
const double epsilon = 0,
|
||||
const MetricType metric = MetricType());
|
||||
|
||||
/**
|
||||
@@ -152,10 +158,12 @@ class NeighborSearch
|
||||
* @param naive Whether to use naive search.
|
||||
* @param singleMode Whether single-tree computation should be used (as
|
||||
* opposed to dual-tree computation).
|
||||
* @param epsilon Relative approximate error (non-negative).
|
||||
* @param metric Instantiated metric.
|
||||
*/
|
||||
NeighborSearch(const bool naive = false,
|
||||
const bool singleMode = false,
|
||||
const double epsilon = 0,
|
||||
const MetricType metric = MetricType());
|
||||
|
||||
|
||||
@@ -270,6 +278,11 @@ class NeighborSearch
|
||||
//! Modify whether or not search is done in single-tree mode.
|
||||
bool& SingleMode() { return singleMode; }
|
||||
|
||||
//! Access the relative error to be considered in approximate search.
|
||||
double Epsilon() const { return epsilon; }
|
||||
//! Modify the relative error to be considered in approximate search.
|
||||
double& Epsilon() { return epsilon; }
|
||||
|
||||
//! Access the reference dataset.
|
||||
const MatType& ReferenceSet() const { return *referenceSet; }
|
||||
|
||||
@@ -294,6 +307,8 @@ class NeighborSearch
|
||||
bool naive;
|
||||
//! Indicates if single-tree search is being used (as opposed to dual-tree).
|
||||
bool singleMode;
|
||||
//! Indicates the relative error to be considered in approximate search.
|
||||
double epsilon;
|
||||
|
||||
//! Instantiation of metric.
|
||||
MetricType metric;
|
||||
|
||||
@@ -75,6 +75,7 @@ NeighborSearch<SortPolicy, MetricType, MatType, TreeType, TraversalType>::
|
||||
NeighborSearch(const MatType& referenceSetIn,
|
||||
const bool naive,
|
||||
const bool singleMode,
|
||||
const double epsilon,
|
||||
const MetricType metric) :
|
||||
referenceTree(naive ? NULL :
|
||||
BuildTree<MatType, Tree>(referenceSetIn, oldFromNewReferences)),
|
||||
@@ -83,12 +84,14 @@ NeighborSearch(const MatType& referenceSetIn,
|
||||
setOwner(false),
|
||||
naive(naive),
|
||||
singleMode(!naive && singleMode), // No single mode if naive.
|
||||
epsilon(epsilon),
|
||||
metric(metric),
|
||||
baseCases(0),
|
||||
scores(0),
|
||||
treeNeedsReset(false)
|
||||
{
|
||||
// Nothing to do.
|
||||
if (epsilon < 0)
|
||||
throw std::invalid_argument("epsilon must be non-negative");
|
||||
}
|
||||
|
||||
// Construct the object.
|
||||
@@ -103,6 +106,7 @@ NeighborSearch<SortPolicy, MetricType, MatType, TreeType, TraversalType>::
|
||||
NeighborSearch(MatType&& referenceSetIn,
|
||||
const bool naive,
|
||||
const bool singleMode,
|
||||
const double epsilon,
|
||||
const MetricType metric) :
|
||||
referenceTree(naive ? NULL :
|
||||
BuildTree<MatType, Tree>(std::move(referenceSetIn),
|
||||
@@ -113,12 +117,14 @@ NeighborSearch(MatType&& referenceSetIn,
|
||||
setOwner(naive),
|
||||
naive(naive),
|
||||
singleMode(!naive && singleMode),
|
||||
epsilon(epsilon),
|
||||
metric(metric),
|
||||
baseCases(0),
|
||||
scores(0),
|
||||
treeNeedsReset(false)
|
||||
{
|
||||
// Nothing to do.
|
||||
if (epsilon < 0)
|
||||
throw std::invalid_argument("epsilon must be non-negative");
|
||||
}
|
||||
|
||||
// Construct the object.
|
||||
@@ -132,6 +138,7 @@ template<typename SortPolicy,
|
||||
NeighborSearch<SortPolicy, MetricType, MatType, TreeType, TraversalType>::
|
||||
NeighborSearch(Tree* referenceTree,
|
||||
const bool singleMode,
|
||||
const double epsilon,
|
||||
const MetricType metric) :
|
||||
referenceTree(referenceTree),
|
||||
referenceSet(&referenceTree->Dataset()),
|
||||
@@ -139,12 +146,14 @@ NeighborSearch(Tree* referenceTree,
|
||||
setOwner(false),
|
||||
naive(false),
|
||||
singleMode(singleMode),
|
||||
epsilon(epsilon),
|
||||
metric(metric),
|
||||
baseCases(0),
|
||||
scores(0),
|
||||
treeNeedsReset(false)
|
||||
{
|
||||
// Nothing else to initialize.
|
||||
if (epsilon < 0)
|
||||
throw std::invalid_argument("epsilon must be non-negative");
|
||||
}
|
||||
|
||||
// Construct the object without a reference dataset.
|
||||
@@ -158,6 +167,7 @@ template<typename SortPolicy,
|
||||
NeighborSearch<SortPolicy, MetricType, MatType, TreeType, TraversalType>::
|
||||
NeighborSearch(const bool naive,
|
||||
const bool singleMode,
|
||||
const double epsilon,
|
||||
const MetricType metric) :
|
||||
referenceTree(NULL),
|
||||
referenceSet(new MatType()), // Empty matrix.
|
||||
@@ -165,11 +175,14 @@ NeighborSearch<SortPolicy, MetricType, MatType, TreeType, TraversalType>::
|
||||
setOwner(true),
|
||||
naive(naive),
|
||||
singleMode(singleMode),
|
||||
epsilon(epsilon),
|
||||
metric(metric),
|
||||
baseCases(0),
|
||||
scores(0),
|
||||
treeNeedsReset(false)
|
||||
{
|
||||
if (epsilon < 0)
|
||||
throw std::invalid_argument("epsilon must be non-negative");
|
||||
// Build the tree on the empty dataset, if necessary.
|
||||
if (!naive)
|
||||
{
|
||||
@@ -364,7 +377,8 @@ Search(const MatType& querySet,
|
||||
if (naive)
|
||||
{
|
||||
// Create the helper object for the tree traversal.
|
||||
RuleType rules(*referenceSet, querySet, *neighborPtr, *distancePtr, metric);
|
||||
RuleType rules(*referenceSet, querySet, *neighborPtr, *distancePtr, metric,
|
||||
epsilon);
|
||||
|
||||
// The naive brute-force traversal.
|
||||
for (size_t i = 0; i < querySet.n_cols; ++i)
|
||||
@@ -376,7 +390,8 @@ Search(const MatType& querySet,
|
||||
else if (singleMode)
|
||||
{
|
||||
// Create the helper object for the tree traversal.
|
||||
RuleType rules(*referenceSet, querySet, *neighborPtr, *distancePtr, metric);
|
||||
RuleType rules(*referenceSet, querySet, *neighborPtr, *distancePtr, metric,
|
||||
epsilon);
|
||||
|
||||
// Create the traverser.
|
||||
typename Tree::template SingleTreeTraverser<RuleType> traverser(rules);
|
||||
@@ -402,7 +417,7 @@ Search(const MatType& querySet,
|
||||
|
||||
// Create the helper object for the tree traversal.
|
||||
RuleType rules(*referenceSet, queryTree->Dataset(), *neighborPtr,
|
||||
*distancePtr, metric);
|
||||
*distancePtr, metric, epsilon);
|
||||
|
||||
// Create the traverser.
|
||||
TraversalType<RuleType> traverser(rules);
|
||||
@@ -527,7 +542,8 @@ Search(Tree* queryTree,
|
||||
|
||||
// Create the helper object for the traversal.
|
||||
typedef NeighborSearchRules<SortPolicy, MetricType, Tree> RuleType;
|
||||
RuleType rules(*referenceSet, querySet, *neighborPtr, distances, metric);
|
||||
RuleType rules(*referenceSet, querySet, *neighborPtr, distances, metric,
|
||||
epsilon);
|
||||
|
||||
// Create the traverser.
|
||||
TraversalType<RuleType> traverser(rules);
|
||||
@@ -598,7 +614,7 @@ Search(const size_t k,
|
||||
// Create the helper object for the traversal.
|
||||
typedef NeighborSearchRules<SortPolicy, MetricType, Tree> RuleType;
|
||||
RuleType rules(*referenceSet, *referenceSet, *neighborPtr, *distancePtr,
|
||||
metric, true /* don't return the same point as nearest neighbor */);
|
||||
metric, epsilon, true /* don't return the same point as nearest neighbor */);
|
||||
|
||||
if (naive)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@ class NeighborSearchRules
|
||||
arma::Mat<size_t>& neighbors,
|
||||
arma::mat& distances,
|
||||
MetricType& metric,
|
||||
const double epsilon = 0,
|
||||
const bool sameSet = false);
|
||||
/**
|
||||
* Get the distance from the query point to the reference point.
|
||||
@@ -120,6 +121,9 @@ class NeighborSearchRules
|
||||
//! Denotes whether or not the reference and query sets are the same.
|
||||
bool sameSet;
|
||||
|
||||
//! Relative error to be considered in approximate search.
|
||||
const double epsilon;
|
||||
|
||||
//! The last query point BaseCase() was called with.
|
||||
size_t lastQueryIndex;
|
||||
//! The last reference point BaseCase() was called with.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file nearest_neighbor_rules_impl.hpp
|
||||
* @file neighbor_search_rules_impl.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of NearestNeighborRules.
|
||||
* Implementation of NeighborSearchRules.
|
||||
*/
|
||||
#ifndef MLPACK_METHODS_NEIGHBOR_SEARCH_NEAREST_NEIGHBOR_RULES_IMPL_HPP
|
||||
#define MLPACK_METHODS_NEIGHBOR_SEARCH_NEAREST_NEIGHBOR_RULES_IMPL_HPP
|
||||
@@ -20,6 +20,7 @@ NeighborSearchRules<SortPolicy, MetricType, TreeType>::NeighborSearchRules(
|
||||
arma::Mat<size_t>& neighbors,
|
||||
arma::mat& distances,
|
||||
MetricType& metric,
|
||||
const double epsilon,
|
||||
const bool sameSet) :
|
||||
referenceSet(referenceSet),
|
||||
querySet(querySet),
|
||||
@@ -27,6 +28,7 @@ NeighborSearchRules<SortPolicy, MetricType, TreeType>::NeighborSearchRules(
|
||||
distances(distances),
|
||||
metric(metric),
|
||||
sameSet(sameSet),
|
||||
epsilon(epsilon),
|
||||
lastQueryIndex(querySet.n_cols),
|
||||
lastReferenceIndex(referenceSet.n_cols),
|
||||
baseCases(0),
|
||||
@@ -112,7 +114,8 @@ inline double NeighborSearchRules<SortPolicy, MetricType, TreeType>::Score(
|
||||
}
|
||||
|
||||
// Compare against the best k'th distance for this query point so far.
|
||||
const double bestDistance = distances(distances.n_rows - 1, queryIndex);
|
||||
double bestDistance = distances(distances.n_rows - 1, queryIndex);
|
||||
bestDistance = SortPolicy::Relax(bestDistance, epsilon);
|
||||
|
||||
return (SortPolicy::IsBetter(distance, bestDistance)) ? distance : DBL_MAX;
|
||||
}
|
||||
@@ -128,7 +131,8 @@ inline double NeighborSearchRules<SortPolicy, MetricType, TreeType>::Rescore(
|
||||
return oldScore;
|
||||
|
||||
// Just check the score again against the distances.
|
||||
const double bestDistance = distances(distances.n_rows - 1, queryIndex);
|
||||
double bestDistance = distances(distances.n_rows - 1, queryIndex);
|
||||
bestDistance = SortPolicy::Relax(bestDistance, epsilon);
|
||||
|
||||
return (SortPolicy::IsBetter(oldScore, bestDistance)) ? oldScore : DBL_MAX;
|
||||
}
|
||||
@@ -419,6 +423,8 @@ inline double NeighborSearchRules<SortPolicy, MetricType, TreeType>::
|
||||
queryNode.Stat().SecondBound() = bestDistance;
|
||||
queryNode.Stat().AuxBound() = auxDistance;
|
||||
|
||||
worstDistance = SortPolicy::Relax(worstDistance, epsilon);
|
||||
|
||||
if (SortPolicy::IsBetter(worstDistance, bestDistance))
|
||||
return worstDistance;
|
||||
else
|
||||
|
||||
@@ -69,7 +69,11 @@ class MonoSearchVisitor : public boost::static_visitor<void>
|
||||
|
||||
MonoSearchVisitor(const size_t k,
|
||||
arma::Mat<size_t>& neighbors,
|
||||
arma::mat& distances);
|
||||
arma::mat& distances) :
|
||||
k(k),
|
||||
neighbors(neighbors),
|
||||
distances(distances)
|
||||
{};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -177,6 +181,16 @@ class NaiveVisitor : public boost::static_visitor<bool&>
|
||||
bool& operator()(NSType *ns) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* EpsilonVisitor exposes the Epsilon method of the given NSType.
|
||||
*/
|
||||
class EpsilonVisitor : public boost::static_visitor<double&>
|
||||
{
|
||||
public:
|
||||
template<typename NSType>
|
||||
double& operator()(NSType *ns) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* ReferenceSetVisitor exposes the referenceSet of the given NSType.
|
||||
*/
|
||||
@@ -266,6 +280,10 @@ class NSModel
|
||||
bool Naive() const;
|
||||
bool& Naive();
|
||||
|
||||
//! Expose Epsilon.
|
||||
double Epsilon() const;
|
||||
double& Epsilon();
|
||||
|
||||
//! Expose leafSize.
|
||||
size_t LeafSize() const { return leafSize; }
|
||||
size_t& LeafSize() { return leafSize; }
|
||||
@@ -282,7 +300,8 @@ class NSModel
|
||||
void BuildModel(arma::mat&& referenceSet,
|
||||
const size_t leafSize,
|
||||
const bool naive,
|
||||
const bool singleMode);
|
||||
const bool singleMode,
|
||||
const double epsilon = 0);
|
||||
|
||||
//! Perform neighbor search. The query set will be reordered.
|
||||
void Search(arma::mat&& querySet,
|
||||
|
||||
@@ -18,15 +18,6 @@
|
||||
namespace mlpack {
|
||||
namespace neighbor {
|
||||
|
||||
//! Save parameters for monochromatic neighbor search.
|
||||
MonoSearchVisitor::MonoSearchVisitor(const size_t k,
|
||||
arma::Mat<size_t>& neighbors,
|
||||
arma::mat& distances) :
|
||||
k(k),
|
||||
neighbors(neighbors),
|
||||
distances(distances)
|
||||
{}
|
||||
|
||||
//! Monochromatic neighbor search on the given NSType instance.
|
||||
template<typename NSType>
|
||||
void MonoSearchVisitor::operator()(NSType *ns) const
|
||||
@@ -185,6 +176,15 @@ bool& NaiveVisitor::operator()(NSType* ns) const
|
||||
throw std::runtime_error("no neighbor search model initialized");
|
||||
}
|
||||
|
||||
//! Expose the Epsilon method of the given NSType.
|
||||
template<typename NSType>
|
||||
double& EpsilonVisitor::operator()(NSType* ns) const
|
||||
{
|
||||
if (ns)
|
||||
return ns->Epsilon();
|
||||
throw std::runtime_error("no neighbor search model initialized");
|
||||
}
|
||||
|
||||
//! Expose the referenceSet of the given NSType.
|
||||
template<typename NSType>
|
||||
const arma::mat& ReferenceSetVisitor::operator()(NSType* ns) const
|
||||
@@ -293,12 +293,25 @@ bool& NSModel<SortPolicy>::Naive()
|
||||
return boost::apply_visitor(NaiveVisitor(), nSearch);
|
||||
}
|
||||
|
||||
template<typename SortPolicy>
|
||||
double NSModel<SortPolicy>::Epsilon() const
|
||||
{
|
||||
return boost::apply_visitor(EpsilonVisitor(), nSearch);
|
||||
}
|
||||
|
||||
template<typename SortPolicy>
|
||||
double& NSModel<SortPolicy>::Epsilon()
|
||||
{
|
||||
return boost::apply_visitor(EpsilonVisitor(), nSearch);
|
||||
}
|
||||
|
||||
//! Build the reference tree.
|
||||
template<typename SortPolicy>
|
||||
void NSModel<SortPolicy>::BuildModel(arma::mat&& referenceSet,
|
||||
const size_t leafSize,
|
||||
const bool naive,
|
||||
const bool singleMode)
|
||||
const bool singleMode,
|
||||
const double epsilon)
|
||||
{
|
||||
// Initialize random basis if necessary.
|
||||
if (randomBasis)
|
||||
@@ -348,23 +361,26 @@ void NSModel<SortPolicy>::BuildModel(arma::mat&& referenceSet,
|
||||
switch (treeType)
|
||||
{
|
||||
case KD_TREE:
|
||||
nSearch = new NSType<SortPolicy, tree::KDTree>(naive, singleMode);
|
||||
nSearch = new NSType<SortPolicy, tree::KDTree>(naive, singleMode,
|
||||
epsilon);
|
||||
break;
|
||||
case COVER_TREE:
|
||||
nSearch = new NSType<SortPolicy, tree::StandardCoverTree>(naive,
|
||||
singleMode);
|
||||
singleMode, epsilon);
|
||||
break;
|
||||
case R_TREE:
|
||||
nSearch = new NSType<SortPolicy, tree::RTree>(naive, singleMode);
|
||||
nSearch = new NSType<SortPolicy, tree::RTree>(naive, singleMode, epsilon);
|
||||
break;
|
||||
case R_STAR_TREE:
|
||||
nSearch = new NSType<SortPolicy, tree::RStarTree>(naive, singleMode);
|
||||
nSearch = new NSType<SortPolicy, tree::RStarTree>(naive, singleMode,
|
||||
epsilon);
|
||||
break;
|
||||
case BALL_TREE:
|
||||
nSearch = new NSType<SortPolicy, tree::BallTree>(naive, singleMode);
|
||||
nSearch = new NSType<SortPolicy, tree::BallTree>(naive, singleMode,
|
||||
epsilon);
|
||||
break;
|
||||
case X_TREE:
|
||||
nSearch = new NSType<SortPolicy, tree::XTree>(naive, singleMode);
|
||||
nSearch = new NSType<SortPolicy, tree::XTree>(naive, singleMode, epsilon);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -389,13 +405,16 @@ void NSModel<SortPolicy>::Search(arma::mat&& querySet,
|
||||
if (randomBasis)
|
||||
querySet = q * querySet;
|
||||
|
||||
Log::Info << "Searching for " << k << " nearest neighbors with ";
|
||||
Log::Info << "Searching for " << k << " neighbors with ";
|
||||
if (!Naive() && !SingleMode())
|
||||
Log::Info << "dual-tree " << TreeName() << " search..." << std::endl;
|
||||
else if (!Naive())
|
||||
Log::Info << "single-tree " << TreeName() << " search..." << std::endl;
|
||||
else
|
||||
Log::Info << "brute-force (naive) search..." << std::endl;
|
||||
if (Epsilon() != 0 && !Naive())
|
||||
Log::Info << "Maximum of " << Epsilon() * 100 << "% relative error."
|
||||
<< std::endl;
|
||||
|
||||
BiSearchVisitor<SortPolicy> search(querySet, k, neighbors, distances,
|
||||
leafSize);
|
||||
@@ -408,13 +427,16 @@ void NSModel<SortPolicy>::Search(const size_t k,
|
||||
arma::Mat<size_t>& neighbors,
|
||||
arma::mat& distances)
|
||||
{
|
||||
Log::Info << "Searching for " << k << " nearest neighbors with ";
|
||||
Log::Info << "Searching for " << k << " neighbors with ";
|
||||
if (!Naive() && !SingleMode())
|
||||
Log::Info << "dual-tree " << TreeName() << " search..." << std::endl;
|
||||
else if (!Naive())
|
||||
Log::Info << "single-tree " << TreeName() << " search..." << std::endl;
|
||||
else
|
||||
Log::Info << "brute-force (naive) search..." << std::endl;
|
||||
if (Epsilon() != 0 && !Naive())
|
||||
Log::Info << "Maximum of " << Epsilon() * 100 << "% relative error."
|
||||
<< std::endl;
|
||||
|
||||
MonoSearchVisitor search(k, neighbors, distances);
|
||||
boost::apply_visitor(search, nSearch);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/***
|
||||
* @file nearest_neighbor_sort.cpp
|
||||
* @file furthest_neighbor_sort.cpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Implementation of the simple FurthestNeighborSort policy class.
|
||||
@@ -12,7 +12,7 @@ size_t FurthestNeighborSort::SortDistance(const arma::vec& list,
|
||||
const arma::Col<size_t>& indices,
|
||||
double newDistance)
|
||||
{
|
||||
// The first element in the list is the nearest neighbor. We only want to
|
||||
// The first element in the list is the furthest neighbor. We only want to
|
||||
// insert if the new distance is greater than the last element in the list.
|
||||
if (newDistance < list[list.n_elem - 1])
|
||||
return (size_t() - 1); // Do not insert.
|
||||
|
||||
@@ -145,6 +145,23 @@ class FurthestNeighborSort
|
||||
*/
|
||||
static inline double CombineWorst(const double a, const double b)
|
||||
{ return std::max(a - b, 0.0); }
|
||||
|
||||
/**
|
||||
* Return the given value relaxed.
|
||||
*
|
||||
* @param value Value to relax.
|
||||
* @param epsilon Relative error (non-negative).
|
||||
*
|
||||
* @return double Value relaxed.
|
||||
*/
|
||||
static inline double Relax(const double value, const double epsilon)
|
||||
{
|
||||
if (value == 0)
|
||||
return 0;
|
||||
if (value == DBL_MAX || epsilon >= 1)
|
||||
return DBL_MAX;
|
||||
return (1 / (1 - epsilon)) * value;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace neighbor
|
||||
|
||||
@@ -150,6 +150,21 @@ class NearestNeighborSort
|
||||
return DBL_MAX;
|
||||
return a + b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given value relaxed.
|
||||
*
|
||||
* @param value Value to relax.
|
||||
* @param epsilon Relative error (non-negative).
|
||||
*
|
||||
* @return double Value relaxed.
|
||||
*/
|
||||
static inline double Relax(const double value, const double epsilon)
|
||||
{
|
||||
if (value == DBL_MAX)
|
||||
return DBL_MAX;
|
||||
return (1 / (1 + epsilon)) * value;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace neighbor
|
||||
|
||||
@@ -28,9 +28,11 @@ add_executable(mlpack_test
|
||||
kernel_pca_test.cpp
|
||||
kernel_traits_test.cpp
|
||||
kfn_test.cpp
|
||||
akfn_test.cpp
|
||||
kmeans_test.cpp
|
||||
knn_test.cpp
|
||||
krann_search_test.cpp
|
||||
aknn_test.cpp
|
||||
lars_test.cpp
|
||||
lbfgs_test.cpp
|
||||
lin_alg_test.cpp
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <mlpack/methods/ann/layer/hard_tanh_layer.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mlpack/methods/logistic_regression/logistic_regression.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace arma;
|
||||
using namespace mlpack::optimization;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/adaboost/adaboost.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
using namespace arma;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <mlpack/methods/logistic_regression/logistic_regression.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace arma;
|
||||
using namespace mlpack::optimization;
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* @file akfn_test.cpp
|
||||
*
|
||||
* Tests for KFN (k-furthest-neighbors) with different values of epsilon.
|
||||
*/
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::neighbor;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::metric;
|
||||
using namespace mlpack::bound;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(AKFNTest);
|
||||
|
||||
/**
|
||||
* Test the dual-tree furthest-neighbors method with different values for
|
||||
* epsilon. This uses both a query and reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(AproxVsExact1)
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
if (!data::Load("test_data_3_1000.csv", dataset))
|
||||
BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
for (size_t c = 0; c < 4; c++)
|
||||
{
|
||||
KFN* akfn;
|
||||
double epsilon;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0: // Use the dual-tree method with e=0.02.
|
||||
epsilon = 0.02;
|
||||
break;
|
||||
case 1: // Use the dual-tree method with e=0.05.
|
||||
epsilon = 0.05;
|
||||
break;
|
||||
case 2: // Use the dual-tree method with e=0.10.
|
||||
epsilon = 0.10;
|
||||
break;
|
||||
case 3: // Use the dual-tree method with e=0.20.
|
||||
epsilon = 0.20;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now perform the actual calculation.
|
||||
akfn = new KFN(dataset, false, false, epsilon);
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
akfn->Search(dataset, 15, neighborsAprox, distancesAprox);
|
||||
|
||||
for (size_t i = 0; i < neighborsAprox.n_elem; i++)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox(i), distancesExact(i), epsilon);
|
||||
|
||||
// Clean the memory.
|
||||
delete akfn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the dual-tree furthest-neighbors method with the exact method. This
|
||||
* uses only a reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(AproxVsExact2)
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
if (!data::Load("test_data_3_1000.csv", dataset))
|
||||
BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(15, neighborsExact, distancesExact);
|
||||
|
||||
KFN akfn(dataset, false, false, 0.05);
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
akfn.Search(15, neighborsAprox, distancesAprox);
|
||||
|
||||
for (size_t i = 0; i < neighborsAprox.n_elem; i++)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the single-tree furthest-neighbors method with the exact method. This
|
||||
* uses only a reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SingleTreeVsExact)
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
if (!data::Load("test_data_3_1000.csv", dataset))
|
||||
BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(15, neighborsExact, distancesExact);
|
||||
|
||||
KFN akfn(dataset, false, true, 0.05);
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
akfn.Search(15, neighborsAprox, distancesAprox);
|
||||
|
||||
for (size_t i = 0; i < neighborsAprox.n_elem; i++)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the cover tree single-tree furthest-neighbors method against the exact
|
||||
* method. This uses only a random reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SingleCoverTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
dataset.randu(75, 1000); // 75 dimensional, 1000 points.
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
StandardCoverTree<EuclideanDistance, NeighborSearchStat<FurthestNeighborSort>,
|
||||
arma::mat> tree(dataset);
|
||||
|
||||
NeighborSearch<FurthestNeighborSort, LMetric<2>, arma::mat, StandardCoverTree>
|
||||
coverTreeSearch(&tree, true, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsCoverTree;
|
||||
arma::mat distancesCoverTree;
|
||||
coverTreeSearch.Search(dataset, 15, neighborsCoverTree, distancesCoverTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsCoverTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesCoverTree[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the cover tree dual-tree furthest neighbors method against the exact
|
||||
* method.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DualCoverTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
data::Load("test_data_3_1000.csv", dataset);
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
StandardCoverTree<EuclideanDistance, NeighborSearchStat<FurthestNeighborSort>,
|
||||
arma::mat> referenceTree(dataset);
|
||||
|
||||
NeighborSearch<FurthestNeighborSort, LMetric<2>, arma::mat, StandardCoverTree>
|
||||
coverTreeSearch(&referenceTree, false, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsCoverTree;
|
||||
arma::mat distancesCoverTree;
|
||||
coverTreeSearch.Search(dataset, 15, neighborsCoverTree, distancesCoverTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsCoverTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesCoverTree[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the ball tree single-tree furthest-neighbors method against the exact
|
||||
* method. This uses only a random reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SingleBallTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
dataset.randu(75, 1000); // 75 dimensional, 1000 points.
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
NeighborSearch<FurthestNeighborSort, EuclideanDistance, arma::mat, BallTree>
|
||||
ballTreeSearch(dataset, false, true, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsBallTree;
|
||||
arma::mat distancesBallTree;
|
||||
ballTreeSearch.Search(dataset, 15, neighborsBallTree, distancesBallTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsBallTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesBallTree(i), distancesExact(i), 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the ball tree dual-tree furthest neighbors method against the exact
|
||||
* method.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DualBallTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
data::Load("test_data_3_1000.csv", dataset);
|
||||
|
||||
KFN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(15, neighborsExact, distancesExact);
|
||||
|
||||
NeighborSearch<FurthestNeighborSort, EuclideanDistance, arma::mat, BallTree>
|
||||
ballTreeSearch(dataset, false, false, 0.05);
|
||||
arma::Mat<size_t> neighborsBallTree;
|
||||
arma::mat distancesBallTree;
|
||||
ballTreeSearch.Search(15, neighborsBallTree, distancesBallTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsBallTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesBallTree(i), distancesExact(i), 0.05);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* @file aknn_test.cpp
|
||||
*
|
||||
* Test file for KNN class with different values of epsilon.
|
||||
*/
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
#include <mlpack/methods/neighbor_search/unmap.hpp>
|
||||
#include <mlpack/methods/neighbor_search/ns_model.hpp>
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
#include <mlpack/core/tree/example_tree.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::neighbor;
|
||||
using namespace mlpack::tree;
|
||||
using namespace mlpack::metric;
|
||||
using namespace mlpack::bound;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(AKNNTest);
|
||||
|
||||
/**
|
||||
* Test the dual-tree nearest-neighbors method with different values for
|
||||
* epsilon. This uses both a query and reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(AproxVsExact1)
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
if (!data::Load("test_data_3_1000.csv", dataset))
|
||||
BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
for (size_t c = 0; c < 4; c++)
|
||||
{
|
||||
KNN* aknn;
|
||||
double epsilon;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0: // Use the dual-tree method with e=0.02.
|
||||
epsilon = 0.02;
|
||||
break;
|
||||
case 1: // Use the dual-tree method with e=0.05.
|
||||
epsilon = 0.05;
|
||||
break;
|
||||
case 2: // Use the dual-tree method with e=0.10.
|
||||
epsilon = 0.10;
|
||||
break;
|
||||
case 3: // Use the dual-tree method with e=0.20.
|
||||
epsilon = 0.20;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now perform the actual calculation.
|
||||
aknn = new KNN(dataset, false, false, epsilon);
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
aknn->Search(dataset, 15, neighborsAprox, distancesAprox);
|
||||
|
||||
for (size_t i = 0; i < neighborsAprox.n_elem; i++)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox(i), distancesExact(i), epsilon);
|
||||
|
||||
// Clean the memory.
|
||||
delete aknn;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the dual-tree nearest-neighbors method with the exact method. This uses
|
||||
* only a reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(AproxVsExact2)
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
if (!data::Load("test_data_3_1000.csv", dataset))
|
||||
BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(15, neighborsExact, distancesExact);
|
||||
|
||||
KNN aknn(dataset, false, false, 0.05);
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
aknn.Search(15, neighborsAprox, distancesAprox);
|
||||
|
||||
for (size_t i = 0; i < neighborsAprox.n_elem; i++)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox(i), distancesExact(i), 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the single-tree nearest-neighbors method with the exact method. This
|
||||
* uses only a reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SingleTreeAproxVsExact)
|
||||
{
|
||||
arma::mat dataset;
|
||||
|
||||
if (!data::Load("test_data_3_1000.csv", dataset))
|
||||
BOOST_FAIL("Cannot load test dataset test_data_3_1000.csv!");
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(15, neighborsExact, distancesExact);
|
||||
|
||||
KNN aknn(dataset, false, true, 0.05);
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
aknn.Search(15, neighborsAprox, distancesAprox);
|
||||
|
||||
for (size_t i = 0; i < neighborsAprox.n_elem; i++)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the cover tree single-tree nearest-neighbors method against the exact
|
||||
* method. This uses only a random reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SingleCoverTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
dataset.randu(75, 1000); // 75 dimensional, 1000 points.
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
StandardCoverTree<EuclideanDistance, NeighborSearchStat<NearestNeighborSort>,
|
||||
arma::mat> tree(dataset);
|
||||
|
||||
NeighborSearch<NearestNeighborSort, LMetric<2>, arma::mat, StandardCoverTree>
|
||||
coverTreeSearch(&tree, true, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsCoverTree;
|
||||
arma::mat distancesCoverTree;
|
||||
coverTreeSearch.Search(dataset, 15, neighborsCoverTree, distancesCoverTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsCoverTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesCoverTree[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the cover tree dual-tree nearest neighbors method against the exact
|
||||
* method.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DualCoverTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
data::Load("test_data_3_1000.csv", dataset);
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
StandardCoverTree<EuclideanDistance, NeighborSearchStat<NearestNeighborSort>,
|
||||
arma::mat> referenceTree(dataset);
|
||||
|
||||
NeighborSearch<NearestNeighborSort, EuclideanDistance, arma::mat,
|
||||
StandardCoverTree> coverTreeSearch(&referenceTree, false, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsCoverTree;
|
||||
arma::mat distancesCoverTree;
|
||||
coverTreeSearch.Search(&referenceTree, 15, neighborsCoverTree,
|
||||
distancesCoverTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsCoverTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesCoverTree[i], distancesExact[i], 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the ball tree single-tree nearest-neighbors method against the exact
|
||||
* method. This uses only a random reference dataset.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SingleBallTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
dataset.randu(50, 300); // 50 dimensional, 300 points.
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(dataset, 15, neighborsExact, distancesExact);
|
||||
|
||||
NeighborSearch<NearestNeighborSort, EuclideanDistance, arma::mat, BallTree>
|
||||
ballTreeSearch(dataset, false, true, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsBallTree;
|
||||
arma::mat distancesBallTree;
|
||||
ballTreeSearch.Search(dataset, 15, neighborsBallTree, distancesBallTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsBallTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesBallTree(i), distancesExact(i), 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the ball tree dual-tree nearest neighbors method against the exact
|
||||
* method.
|
||||
*
|
||||
* Errors are produced if the results are not according to relative error.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(DualBallTreeTest)
|
||||
{
|
||||
arma::mat dataset;
|
||||
data::Load("test_data_3_1000.csv", dataset);
|
||||
|
||||
KNN exact(dataset);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(15, neighborsExact, distancesExact);
|
||||
|
||||
NeighborSearch<NearestNeighborSort, EuclideanDistance, arma::mat, BallTree>
|
||||
ballTreeSearch(dataset, false, false, 0.05);
|
||||
arma::Mat<size_t> neighborsBallTree;
|
||||
arma::mat distancesBallTree;
|
||||
ballTreeSearch.Search(15, neighborsBallTree, distancesBallTree);
|
||||
|
||||
for (size_t i = 0; i < neighborsBallTree.n_elem; ++i)
|
||||
REQUIRE_RELATIVE_ERR(distancesBallTree(i), distancesExact(i), 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure sparse nearest neighbors works with kd trees.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SparseKNNKDTreeTest)
|
||||
{
|
||||
// The dimensionality of these datasets must be high so that the probability
|
||||
// of a completely empty point is very low. In this case, with dimensionality
|
||||
// 70, the probability of all 70 dimensions being zero is 0.8^70 = 1.65e-7 in
|
||||
// the reference set and 0.9^70 = 6.27e-4 in the query set.
|
||||
arma::sp_mat queryDataset;
|
||||
queryDataset.sprandu(70, 200, 0.2);
|
||||
arma::sp_mat referenceDataset;
|
||||
referenceDataset.sprandu(70, 500, 0.1);
|
||||
arma::mat denseQuery(queryDataset);
|
||||
arma::mat denseReference(referenceDataset);
|
||||
|
||||
typedef NeighborSearch<NearestNeighborSort, EuclideanDistance, arma::sp_mat,
|
||||
KDTree> SparseKNN;
|
||||
|
||||
SparseKNN aknn(referenceDataset, false, false, 0.05);
|
||||
arma::mat distancesSparse;
|
||||
arma::Mat<size_t> neighborsSparse;
|
||||
aknn.Search(queryDataset, 10, neighborsSparse, distancesSparse);
|
||||
|
||||
KNN exact(denseReference);
|
||||
arma::mat distancesExact;
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
exact.Search(denseQuery, 10, neighborsExact, distancesExact);
|
||||
|
||||
for (size_t i = 0; i < neighborsExact.n_cols; ++i)
|
||||
for (size_t j = 0; j < neighborsExact.n_rows; ++j)
|
||||
REQUIRE_RELATIVE_ERR(distancesSparse(j, i), distancesExact(j, i), 0.05);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that we can build an NSModel<NearestNeighborSearch> and get correct
|
||||
* results.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(KNNModelTest)
|
||||
{
|
||||
typedef NSModel<NearestNeighborSort> KNNModel;
|
||||
|
||||
arma::mat queryData = arma::randu<arma::mat>(10, 50);
|
||||
arma::mat referenceData = arma::randu<arma::mat>(10, 200);
|
||||
|
||||
// Build all the possible models.
|
||||
KNNModel models[12];
|
||||
models[0] = KNNModel(KNNModel::TreeTypes::KD_TREE, true);
|
||||
models[1] = KNNModel(KNNModel::TreeTypes::KD_TREE, false);
|
||||
models[2] = KNNModel(KNNModel::TreeTypes::COVER_TREE, true);
|
||||
models[3] = KNNModel(KNNModel::TreeTypes::COVER_TREE, false);
|
||||
models[4] = KNNModel(KNNModel::TreeTypes::R_TREE, true);
|
||||
models[5] = KNNModel(KNNModel::TreeTypes::R_TREE, false);
|
||||
models[6] = KNNModel(KNNModel::TreeTypes::R_STAR_TREE, true);
|
||||
models[7] = KNNModel(KNNModel::TreeTypes::R_STAR_TREE, false);
|
||||
models[8] = KNNModel(KNNModel::TreeTypes::X_TREE, true);
|
||||
models[9] = KNNModel(KNNModel::TreeTypes::X_TREE, false);
|
||||
models[10] = KNNModel(KNNModel::TreeTypes::BALL_TREE, true);
|
||||
models[11] = KNNModel(KNNModel::TreeTypes::BALL_TREE, false);
|
||||
|
||||
for (size_t j = 0; j < 3; ++j)
|
||||
{
|
||||
// Get a baseline.
|
||||
KNN aknn(referenceData);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
aknn.Search(queryData, 3, neighborsExact, distancesExact);
|
||||
|
||||
for (size_t i = 0; i < 12; ++i)
|
||||
{
|
||||
// We only have std::move() constructors so make a copy of our data.
|
||||
arma::mat referenceCopy(referenceData);
|
||||
arma::mat queryCopy(queryData);
|
||||
if (j == 0)
|
||||
models[i].BuildModel(std::move(referenceCopy), 20, false, false, 0.05);
|
||||
if (j == 1)
|
||||
models[i].BuildModel(std::move(referenceCopy), 20, false, true, 0.05);
|
||||
if (j == 2)
|
||||
models[i].BuildModel(std::move(referenceCopy), 20, true, false);
|
||||
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
|
||||
models[i].Search(std::move(queryCopy), 3, neighborsAprox, distancesAprox);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(neighborsAprox.n_rows, neighborsExact.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(neighborsAprox.n_cols, neighborsExact.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(neighborsAprox.n_elem, neighborsExact.n_elem);
|
||||
BOOST_REQUIRE_EQUAL(distancesAprox.n_rows, distancesExact.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(distancesAprox.n_cols, distancesExact.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(distancesAprox.n_elem, distancesExact.n_elem);
|
||||
for (size_t k = 0; k < distancesAprox.n_elem; ++k)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox[k], distancesExact[k], 0.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that we can build an NSModel<NearestNeighborSearch> and get correct
|
||||
* results, in the case where the reference set is the same as the query set.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(KNNModelMonochromaticTest)
|
||||
{
|
||||
typedef NSModel<NearestNeighborSort> KNNModel;
|
||||
|
||||
arma::mat referenceData = arma::randu<arma::mat>(10, 200);
|
||||
|
||||
// Build all the possible models.
|
||||
KNNModel models[12];
|
||||
models[0] = KNNModel(KNNModel::TreeTypes::KD_TREE, true);
|
||||
models[1] = KNNModel(KNNModel::TreeTypes::KD_TREE, false);
|
||||
models[2] = KNNModel(KNNModel::TreeTypes::COVER_TREE, true);
|
||||
models[3] = KNNModel(KNNModel::TreeTypes::COVER_TREE, false);
|
||||
models[4] = KNNModel(KNNModel::TreeTypes::R_TREE, true);
|
||||
models[5] = KNNModel(KNNModel::TreeTypes::R_TREE, false);
|
||||
models[6] = KNNModel(KNNModel::TreeTypes::R_STAR_TREE, true);
|
||||
models[7] = KNNModel(KNNModel::TreeTypes::R_STAR_TREE, false);
|
||||
models[8] = KNNModel(KNNModel::TreeTypes::X_TREE, true);
|
||||
models[9] = KNNModel(KNNModel::TreeTypes::X_TREE, false);
|
||||
models[10] = KNNModel(KNNModel::TreeTypes::BALL_TREE, true);
|
||||
models[11] = KNNModel(KNNModel::TreeTypes::BALL_TREE, false);
|
||||
|
||||
for (size_t j = 0; j < 2; ++j)
|
||||
{
|
||||
// Get a baseline.
|
||||
KNN exact(referenceData);
|
||||
arma::Mat<size_t> neighborsExact;
|
||||
arma::mat distancesExact;
|
||||
exact.Search(3, neighborsExact, distancesExact);
|
||||
|
||||
for (size_t i = 0; i < 12; ++i)
|
||||
{
|
||||
// We only have a std::move() constructor... so copy the data.
|
||||
arma::mat referenceCopy(referenceData);
|
||||
if (j == 0)
|
||||
models[i].BuildModel(std::move(referenceCopy), 20, false, false, 0.05);
|
||||
if (j == 1)
|
||||
models[i].BuildModel(std::move(referenceCopy), 20, false, true, 0.05);
|
||||
|
||||
arma::Mat<size_t> neighborsAprox;
|
||||
arma::mat distancesAprox;
|
||||
|
||||
models[i].Search(3, neighborsAprox, distancesAprox);
|
||||
|
||||
BOOST_REQUIRE_EQUAL(neighborsAprox.n_rows, neighborsExact.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(neighborsAprox.n_cols, neighborsExact.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(neighborsAprox.n_elem, neighborsExact.n_elem);
|
||||
BOOST_REQUIRE_EQUAL(distancesAprox.n_rows, distancesExact.n_rows);
|
||||
BOOST_REQUIRE_EQUAL(distancesAprox.n_cols, distancesExact.n_cols);
|
||||
BOOST_REQUIRE_EQUAL(distancesAprox.n_elem, distancesExact.n_elem);
|
||||
for (size_t k = 0; k < distancesAprox.n_elem; ++k)
|
||||
REQUIRE_RELATIVE_ERR(distancesAprox[k], distancesExact[k], 0.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END();
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace arma;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <mlpack/methods/cf/svd_wrapper.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ArmadilloSVDTest);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/core/optimizers/aug_lagrangian/aug_lagrangian.hpp>
|
||||
#include <mlpack/core/optimizers/aug_lagrangian/aug_lagrangian_test_functions.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::optimization;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace arma;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(CFTest);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#define DEFAULT_INT 42
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
#define BASH_RED "\033[0;31m"
|
||||
#define BASH_GREEN "\033[0;32m"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <mlpack/methods/ann/convolution_rules/svd_convolution.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <mlpack/methods/ann/cnn.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/core/tree/cosine_tree/cosine_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(CosineTreeTest);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/decision_stump/decision_stump.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::decision_stump;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
// This trick does not work on Windows. We will have to comment out the tests
|
||||
// that depend on it.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::distribution;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/methods/emst/dtb.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/methods/fastmks/fastmks_model.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <mlpack/core/optimizers/rmsprop/rmsprop.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <mlpack/methods/gmm/eigenvalue_ratio_constraint.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::gmm;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/gmm/gmm.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::hmm;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mlpack/methods/hoeffding_trees/binary_numeric_split.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
#include <stack>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(ind2subTest);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <mlpack/methods/ann/init_rules/zero_init.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/methods/kernel_pca/kernel_pca.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(KernelPCATest);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <mlpack/core/metrics/mahalanobis_distance.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kernel;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kernel;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::neighbor;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kmeans;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
#include <mlpack/core/tree/example_tree.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::neighbor;
|
||||
@@ -888,7 +888,9 @@ BOOST_AUTO_TEST_CASE(DualBallTreeTest)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure sparse nearest neighbors works with kd trees.
|
||||
/**
|
||||
* Make sure sparse nearest neighbors works with kd trees.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(SparseKNNKDTreeTest)
|
||||
{
|
||||
// The dimensionality of these datasets must be high so that the probability
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
#include <mlpack/methods/rann/ra_search.hpp>
|
||||
#include <mlpack/methods/rann/ra_model.hpp>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/methods/lars/lars.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::regression;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <mlpack/methods/ann/layer/multiclass_classification_layer.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/core/optimizers/lbfgs/test_functions.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack::optimization;
|
||||
using namespace mlpack::optimization::test;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/core/math/lin_alg.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace arma;
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/methods/linear_regression/linear_regression.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::regression;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::data;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/methods/local_coordinate_coding/lcc.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
using namespace arma;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/core/optimizers/sgd/sgd.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::regression;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/core/optimizers/sdp/lrsdp.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::optimization;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
#include <mlpack/methods/lsh/lsh_search.hpp>
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/methods/ann/layer/lstm_layer.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/core/math/random.hpp>
|
||||
#include <mlpack/core/math/range.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace math;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/matrix_completion/matrix_completion.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::matrix_completion;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/methods/sparse_autoencoder/maximal_inputs.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/mean_shift/mean_shift.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::meanshift;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/metrics/lmetric.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack::metric;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <mlpack/methods/logistic_regression/logistic_regression.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace arma;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#endif
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
/**
|
||||
* Provide a global fixture for each test.
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/methods/naive_bayes/naive_bayes_classifier.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace naive_bayes;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <mlpack/core/optimizers/lbfgs/lbfgs.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::metric;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mlpack/methods/ann/init_rules/random_init.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mlpack/methods/amf/update_rules/nmf_mult_dist.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(NMFTest);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
#include <mlpack/methods/nystroem_method/ordered_selection.hpp>
|
||||
#include <mlpack/methods/nystroem_method/random_selection.hpp>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/pca/pca.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(PCATest);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/perceptron/perceptron.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace arma;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <mlpack/methods/ann/performance_functions/sse_function.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/methods/ann/pooling_rules/mean_pooling.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/methods/quic_svd/quic_svd.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(QUICSVDTest);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/methods/radical/radical.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(RadicalTest);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/core/tree/cover_tree.hpp>
|
||||
#include <mlpack/methods/range_search/rs_model.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::range;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::neighbor;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <mlpack/methods/ann/init_rules/nguyen_widrow_init.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::ann;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/regularized_svd/regularized_svd.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::svd;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <mlpack/methods/ann/layer/base_layer.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace arma;
|
||||
using namespace mlpack;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <mlpack/core/metrics/mahalanobis_distance.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace arma;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::optimization;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
#include <mlpack/core/dists/regression_distribution.hpp>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/core/optimizers/sgd/test_function.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace arma;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/softmax_regression/softmax_regression.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::regression;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <mlpack/methods/neighbor_search/sort_policies/furthest_neighbor_sort.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::neighbor;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/methods/sparse_autoencoder/sparse_autoencoder.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::nn;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <mlpack/methods/sparse_coding/sparse_coding.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
#include "serialization.hpp"
|
||||
|
||||
using namespace arma;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <mlpack/core/data/split_data.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace arma;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mlpack/methods/amf/termination_policies/simple_tolerance_termination.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(SVDBatchTest);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <mlpack/methods/amf/termination_policies/validation_RMSE_termination.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(SVDIncrementalTest);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <mlpack/methods/amf/update_rules/nmf_mult_div.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(TerminationPolicyTest);
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/**
|
||||
* @file old_boost_test_definitions.hpp
|
||||
* @file test_tools.hpp
|
||||
* @author Ryan Curtin
|
||||
*
|
||||
* Ancient Boost.Test versions don't act how we expect. This file includes the
|
||||
* things we need to fix that.
|
||||
* This file includes some useful macros for tests.
|
||||
*/
|
||||
#ifndef MLPACK_TESTS_OLD_BOOST_TEST_DEFINITIONS_HPP
|
||||
#define MLPACK_TESTS_OLD_BOOST_TEST_DEFINITIONS_HPP
|
||||
#ifndef MLPACK_TESTS_TEST_TOOLS_HPP
|
||||
#define MLPACK_TESTS_TEST_TOOLS_HPP
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
@@ -35,4 +34,9 @@
|
||||
|
||||
#endif
|
||||
|
||||
// Require the approximation L to be within a relative error of E respect to the
|
||||
// actual value R.
|
||||
#define REQUIRE_RELATIVE_ERR( L, R, E ) \
|
||||
BOOST_REQUIRE_LE( abs((R) - (L)), (E) * abs(R))
|
||||
|
||||
#endif
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <stack>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::math;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <mlpack/core/tree/rectangle_tree.hpp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::tree;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "old_boost_test_definitions.hpp"
|
||||
#include "test_tools.hpp"
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::emst;
|
||||
|
||||
Reference in New Issue
Block a user