| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #ifndef FLANN_ALL_INDICES_H_ |
| | #define FLANN_ALL_INDICES_H_ |
| |
|
| | #include "FLANN/general.h" |
| |
|
| | #include "FLANN/algorithms/nn_index.h" |
| | #include "FLANN/algorithms/kdtree_index.h" |
| | #include "FLANN/algorithms/kdtree_single_index.h" |
| | #include "FLANN/algorithms/kmeans_index.h" |
| | #include "FLANN/algorithms/composite_index.h" |
| | #include "FLANN/algorithms/linear_index.h" |
| | #include "FLANN/algorithms/hierarchical_clustering_index.h" |
| | #include "FLANN/algorithms/lsh_index.h" |
| | #include "FLANN/algorithms/autotuned_index.h" |
| | #ifdef FLANN_USE_CUDA |
| | #include "FLANN/algorithms/kdtree_cuda_3d_index.h" |
| | #endif |
| |
|
| |
|
| | namespace flann |
| | { |
| |
|
| | |
| | |
| | |
| | template<bool, typename T = void> struct enable_if{}; |
| | template<typename T> struct enable_if<true,T> { typedef T type; }; |
| |
|
| | |
| | |
| | |
| | template<bool, typename T> struct disable_if{ typedef T type; }; |
| | template<typename T> struct disable_if<true,T> { }; |
| |
|
| | |
| | |
| | |
| | template <typename T, typename U> |
| | struct same_type |
| | { |
| | enum {value = false}; |
| | }; |
| |
|
| | template<typename T> |
| | struct same_type<T,T> |
| | { |
| | enum {value = true}; |
| | }; |
| |
|
| | #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) |
| |
|
| | struct DummyDistance |
| | { |
| | typedef float ElementType; |
| | typedef float ResultType; |
| |
|
| | template <typename Iterator1, typename Iterator2> |
| | ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType = -1) const |
| | { |
| | return ResultType(0); |
| | } |
| |
|
| | template <typename U, typename V> |
| | inline ResultType accum_dist(const U& a, const V& b, int) const |
| | { |
| | return ResultType(0); |
| | } |
| | }; |
| |
|
| | |
| | |
| | |
| | template<template <typename> class Index, typename Distance, typename ElemType> |
| | struct valid_combination |
| | { |
| | static const bool value = same_type<ElemType,typename Distance::ElementType>::value && |
| | (!needs_kdtree_distance<Index<DummyDistance> >::value || is_kdtree_distance<Distance>::value) && |
| | (!needs_vector_space_distance<Index<DummyDistance> >::value || is_kdtree_distance<Distance>::value || is_vector_space_distance<Distance>::value); |
| |
|
| | }; |
| |
|
| |
|
| | |
| | |
| | |
| | template <template<typename> class Index, typename Distance, typename T> |
| | inline 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, distance); |
| | } |
| |
|
| | template <template<typename> class Index, typename Distance, typename T> |
| | inline 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> |
| | inline NNIndex<Distance>* |
| | create_index_by_type(const flann_algorithm_t index_type, |
| | const Matrix<typename Distance::ElementType>& dataset, const IndexParams& params, const Distance& distance) |
| | { |
| | typedef typename Distance::ElementType ElementType; |
| |
|
| | 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; |
| | |
| | |
| | #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("Unsupported index/distance combination"); |
| | } |
| | return nnIndex; |
| | } |
| |
|
| | } |
| |
|
| | #endif |
| |
|