提交 fc58b0f9 编写于 作者: M Marius Muja

Nicer way of instantiating indexes based on runtime values

上级 f3fb4e76
......@@ -72,7 +72,7 @@ struct index_creator
nnIndex = new KDTreeCuda3dIndex<Distance>(dataset, params, distance);
break;
#endif
case FLANN_INDEX_KMEANS:
nnIndex = new KMeansIndex<Distance>(dataset, params, distance);
break;
......@@ -151,12 +151,133 @@ struct index_creator<FalseType,FalseType,Distance>
}
};
/**
* enable_if sfinae helper
*/
template<bool, typename T = void> struct enable_if{};
template<typename T> struct enable_if<true,T> { typedef T type; };
/**
* disable_if sfinae helper
*/
template<bool, typename T> struct disable_if{ typedef T type; };
template<typename T> struct disable_if<true,T> { };
/**
* Check if two type are the same
*/
template <typename T, typename U>
struct same_type
{
enum {value = false};
};
template<typename T>
struct same_type<T,T>
{
enum {value = true};
};
/**
* Checks if an index and a distance can be used together
*/
template<template <typename> class Index, typename Distance, typename ElementType>
struct valid_combination
{
#define HAS_MEMBER(member) \
template<typename T> \
struct member { \
typedef char No; \
typedef long Yes; \
template<typename C> static Yes test( typename C::member* ); \
template<typename C> static No test( ... ); \
enum { value = sizeof (test<T>(0))==sizeof(Yes) }; \
};
HAS_MEMBER(needs_kdtree_distance)
HAS_MEMBER(needs_vector_space_distance)
HAS_MEMBER(is_kdtree_distance)
HAS_MEMBER(is_vector_space_distance)
static const bool value = same_type<ElementType,typename Distance::ElementType>::value &&
(!needs_kdtree_distance<Index<Distance> >::value || is_kdtree_distance<Distance>::value) &&
(!needs_vector_space_distance<Index<Distance> >::value || is_vector_space_distance<Distance>::value);
};
/*********************************************************
* Create index
**********************************************************/
template <template<typename> class Index, typename Distance, typename T>
NNIndex<Distance>* create_index_(flann::Matrix<T> data, const flann::IndexParams& params, const Distance& distance,
typename enable_if<valid_combination<Index,Distance,T>::value,void>::type* = 0)
{
return new Index<Distance>(data, params);
}
template <template<typename> class Index, typename Distance, typename T>
NNIndex<Distance>* create_index_(flann::Matrix<T> data, const flann::IndexParams& params, const Distance& distance,
typename disable_if<valid_combination<Index,Distance,T>::value,void>::type* = 0)
{
return NULL;
}
template<typename Distance>
NNIndex<Distance>* create_index_by_type(const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance)
{
return index_creator<typename Distance::is_kdtree_distance,
typename Distance::is_vector_space_distance,
Distance>::create(dataset, params,distance);
typedef typename Distance::ElementType ElementType;
flann_algorithm_t index_type = get_param<flann_algorithm_t>(params, "algorithm");
NNIndex<Distance>* nnIndex;
switch (index_type) {
case FLANN_INDEX_LINEAR:
nnIndex = create_index_<LinearIndex,Distance,ElementType>(dataset, params, distance);
break;
case FLANN_INDEX_KDTREE_SINGLE:
nnIndex = create_index_<KDTreeSingleIndex,Distance,ElementType>(dataset, params, distance);
break;
case FLANN_INDEX_KDTREE:
nnIndex = create_index_<KDTreeIndex,Distance,ElementType>(dataset, params, distance);
break;
//! #define this symbol before including flann.h to enable GPU search algorithms. But you have
//! to link libflann_cuda then!
#ifdef FLANN_USE_CUDA
case FLANN_INDEX_KDTREE_CUDA:
nnIndex = create_index_<KDTreeCuda3dIndex,Distance,ElementType>(dataset, params, distance);
break;
#endif
case FLANN_INDEX_KMEANS:
nnIndex = create_index_<KMeansIndex,Distance,ElementType>(dataset, params, distance);
break;
case FLANN_INDEX_COMPOSITE:
nnIndex = create_index_<CompositeIndex,Distance,ElementType>(dataset, params, distance);
break;
case FLANN_INDEX_AUTOTUNED:
nnIndex = create_index_<AutotunedIndex,Distance,ElementType>(dataset, params, distance);
break;
case FLANN_INDEX_HIERARCHICAL:
nnIndex = create_index_<HierarchicalClusteringIndex,Distance,ElementType>(dataset, params, distance);
break;
case FLANN_INDEX_LSH:
nnIndex = create_index_<LshIndex,Distance,ElementType>(dataset, params, distance);
break;
default:
throw FLANNException("Unknown index type");
}
if (nnIndex==NULL) {
throw FLANNException("Invalid index/distance combination");
}
return nnIndex;
}
}
......
......@@ -73,6 +73,8 @@ public:
typedef typename Distance::ElementType ElementType;
typedef typename Distance::ResultType DistanceType;
typedef bool needs_kdtree_distance;
AutotunedIndex(const Matrix<ElementType>& inputData, const IndexParams& params = AutotunedIndexParams(), Distance d = Distance()) :
dataset_(inputData), distance_(d)
{
......
......@@ -97,8 +97,7 @@ class FalseType
template<class T>
struct L2_Simple
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -130,8 +129,7 @@ struct L2_Simple
template<class T>
struct L2
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -195,8 +193,7 @@ struct L2
template<class T>
struct L1
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -252,8 +249,7 @@ struct L1
template<class T>
struct MinkowskiDistance
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -316,8 +312,7 @@ struct MinkowskiDistance
template<class T>
struct MaxDistance
{
typedef FalseType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_vector_space_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -373,9 +368,6 @@ struct MaxDistance
*/
struct HammingLUT
{
typedef FalseType is_kdtree_distance;
typedef FalseType is_vector_space_distance;
typedef unsigned char ElementType;
typedef int ResultType;
......@@ -473,12 +465,8 @@ struct HammingLUT
* That code was taken from brief.cpp in OpenCV
*/
template<class T>
struct Hamming
struct HammingPopcnt
{
typedef FalseType is_kdtree_distance;
typedef FalseType is_vector_space_distance;
typedef T ElementType;
typedef int ResultType;
......@@ -535,11 +523,8 @@ struct Hamming
};
template<typename T>
struct Hamming2
struct Hamming
{
typedef FalseType is_kdtree_distance;
typedef FalseType is_vector_space_distance;
typedef T ElementType;
typedef unsigned int ResultType;
......@@ -594,8 +579,7 @@ struct Hamming2
template<class T>
struct HistIntersectionDistance
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -649,8 +633,7 @@ struct HistIntersectionDistance
template<class T>
struct HellingerDistance
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -697,8 +680,7 @@ struct HellingerDistance
template<class T>
struct ChiSquareDistance
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......@@ -751,8 +733,7 @@ struct ChiSquareDistance
template<class T>
struct KL_Divergence
{
typedef TrueType is_kdtree_distance;
typedef TrueType is_vector_space_distance;
typedef bool is_kdtree_distance;
typedef T ElementType;
typedef typename Accumulator<T>::Type ResultType;
......
......@@ -73,6 +73,7 @@ public:
typedef typename Distance::ElementType ElementType;
typedef typename Distance::ResultType DistanceType;
typedef bool needs_kdtree_distance;
/**
* KDTree constructor
......
......@@ -84,6 +84,7 @@ public:
typedef typename Distance::ElementType ElementType;
typedef typename Distance::ResultType DistanceType;
typedef bool needs_vector_space_distance;
typedef void (KMeansIndex::* centersAlgFunction)(int, int*, int, int*, int&);
......
......@@ -86,7 +86,7 @@ enum flann_algorithm_t
FLANN_INDEX_KDTREE_SINGLE = 4,
FLANN_INDEX_HIERARCHICAL = 5,
FLANN_INDEX_LSH = 6,
FLANN_INDEX_KDTREE_CUDA = 7,
FLANN_INDEX_KDTREE_CUDA = 7,
FLANN_INDEX_SAVED = 254,
FLANN_INDEX_AUTOTUNED = 255,
......@@ -137,6 +137,9 @@ enum flann_distance_t
FLANN_DIST_CS = 7,
FLANN_DIST_KULLBACK_LEIBLER = 8,
FLANN_DIST_KL = 8,
FLANN_DIST_HAMMING = 9,
FLANN_DIST_HAMMING_LUT = 10,
FLANN_DIST_HAMMING_POPCNT = 11,
// deprecated constants, should use the FLANN_DIST_* ones instead
EUCLIDEAN = 1,
......
......@@ -22,8 +22,9 @@ namespace cdiggins
namespace anyimpl
{
struct bad_any_cast
struct bad_any_cast : public std::runtime_error
{
bad_any_cast() : std::runtime_error("Cannot convert 'any' value") { }
};
struct empty_any
......@@ -146,7 +147,7 @@ base_any_policy* get_policy()
class any
{
typedef any any_t;
typedef any any_t; // workaround for the NVCC compiler under windows
private:
// fields
anyimpl::base_any_policy* policy;
......
......@@ -256,7 +256,7 @@ public:
{
// Check for duplicate indices
size_t j = i - 1;
while ((j >= 0) && (dist_index_[j].dist_ == dist)) {
while (dist_index_[j].dist_ == dist) {
if (dist_index_[j].index_ == index) {
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册