33 #ifndef DTK_NANOFLANN_HPP_ 34 #define DTK_NANOFLANN_HPP_ 43 #include <Teuchos_Array.hpp> 46 #if !defined( NOMINMAX ) && ( defined( _WIN32 ) || defined( _WIN32_ ) || \ 47 defined( WIN32 ) || defined( _WIN64 ) ) 66 #define NANOFLANN_VERSION 0x117 70 template <
typename DistanceType,
typename IndexType = size_t,
71 typename CountType =
size_t>
80 inline KNNResultSet( CountType capacity_ )
81 : capacity( capacity_ )
86 inline void init( IndexType *indices_, DistanceType *dists_ )
91 dists[capacity - 1] = ( std::numeric_limits<DistanceType>::max )();
94 inline CountType size()
const {
return count; }
96 inline bool full()
const {
return count == capacity; }
98 inline void addPoint( DistanceType dist, IndexType index )
101 for ( i = count; i > 0; --i )
103 #ifdef NANOFLANN_FIRST_MATCH // If defined and two poins have the same distance, 106 if ( ( dists[i - 1] > dist ) ||
107 ( ( dist == dists[i - 1] ) && ( indices[i - 1] > index ) ) )
110 if ( dists[i - 1] > dist )
115 dists[i] = dists[i - 1];
116 indices[i] = indices[i - 1];
127 if ( count < capacity )
131 inline DistanceType worstDist()
const {
return dists[capacity - 1]; }
137 template <
typename DistanceType,
typename IndexType =
size_t>
141 const DistanceType radius;
143 Teuchos::Array<std::pair<IndexType, DistanceType>> &m_indices_dists;
146 DistanceType radius_,
147 Teuchos::Array<std::pair<IndexType, DistanceType>> &indices_dists )
149 , m_indices_dists( indices_dists )
156 inline void init() { clear(); }
157 inline void clear() { m_indices_dists.clear(); }
159 inline size_t size()
const {
return m_indices_dists.size(); }
161 inline bool full()
const {
return true; }
163 inline void addPoint( DistanceType dist, IndexType index )
166 m_indices_dists.push_back( std::make_pair( index, dist ) );
169 inline DistanceType worstDist()
const {
return radius; }
184 if ( m_indices_dists.empty() )
185 throw std::runtime_error(
"Cannot invoke " 186 "RadiusResultSet::worst_item() on an " 187 "empty list of results." );
188 typedef typename Teuchos::Array<
189 std::pair<IndexType, DistanceType>>::const_iterator DistIt;
191 std::max_element( m_indices_dists.begin(), m_indices_dists.end() );
200 template <
typename PairType>
201 inline bool operator()(
const PairType &p1,
const PairType &p2 )
const 203 return p1.second < p2.second;
211 template <
typename T>
212 void save_value( FILE *stream,
const T &value,
size_t count = 1 )
214 fwrite( &value,
sizeof( value ), count, stream );
217 template <
typename T>
218 void save_value( FILE *stream,
const Teuchos::Array<T> &value )
220 size_t size = value.size();
221 fwrite( &size,
sizeof(
size_t ), 1, stream );
222 fwrite( &value[0],
sizeof( T ), size, stream );
225 template <
typename T>
226 void load_value( FILE *stream, T &value,
size_t count = 1 )
228 size_t read_cnt = fread( &value,
sizeof( value ), count, stream );
229 if ( read_cnt != count )
231 throw std::runtime_error(
"Cannot read from file" );
235 template <
typename T>
236 void load_value( FILE *stream, Teuchos::Array<T> &value )
239 size_t read_cnt = fread( &size,
sizeof(
size_t ), 1, stream );
242 throw std::runtime_error(
"Cannot read from file" );
244 value.resize( size );
245 read_cnt = fread( &value[0],
sizeof( T ), size, stream );
246 if ( read_cnt != size )
248 throw std::runtime_error(
"Cannot read from file" );
256 template <
typename T>
259 return ( x < 0 ) ? -x : x;
262 inline int abs<int>(
int x )
267 inline float abs<float>(
float x )
272 inline double abs<double>(
double x )
277 inline long double abs<long double>(
long double x )
289 template <
class T,
class DataSource,
typename _DistanceType = T>
292 typedef T ElementType;
293 typedef _DistanceType DistanceType;
295 const DataSource &data_source;
298 : data_source( _data_source )
302 inline DistanceType operator()(
const T *a,
const size_t b_idx,
size_t size,
303 DistanceType worst_dist = -1 )
const 305 DistanceType result = DistanceType();
306 const T *last = a + size;
307 const T *lastgroup = last - 3;
311 while ( a < lastgroup )
313 const DistanceType diff0 = nanoflann::abs(
314 a[0] - data_source.kdtree_get_pt( b_idx, d++ ) );
315 const DistanceType diff1 = nanoflann::abs(
316 a[1] - data_source.kdtree_get_pt( b_idx, d++ ) );
317 const DistanceType diff2 = nanoflann::abs(
318 a[2] - data_source.kdtree_get_pt( b_idx, d++ ) );
319 const DistanceType diff3 = nanoflann::abs(
320 a[3] - data_source.kdtree_get_pt( b_idx, d++ ) );
321 result += diff0 + diff1 + diff2 + diff3;
323 if ( ( worst_dist > 0 ) && ( result > worst_dist ) )
332 result += nanoflann::abs( *a++ -
333 data_source.kdtree_get_pt( b_idx, d++ ) );
338 template <
typename U,
typename V>
339 inline DistanceType accum_dist(
const U a,
const V b,
int )
const 341 return nanoflann::abs( a - b );
352 template <
class T,
class DataSource,
typename _DistanceType = T>
355 typedef T ElementType;
356 typedef _DistanceType DistanceType;
358 const DataSource &data_source;
361 : data_source( _data_source )
365 inline DistanceType operator()(
const T *a,
const size_t b_idx,
size_t size,
366 DistanceType worst_dist = -1 )
const 368 DistanceType result = DistanceType();
369 const T *last = a + size;
370 const T *lastgroup = last - 3;
374 while ( a < lastgroup )
376 const DistanceType diff0 =
377 a[0] - data_source.kdtree_get_pt( b_idx, d++ );
378 const DistanceType diff1 =
379 a[1] - data_source.kdtree_get_pt( b_idx, d++ );
380 const DistanceType diff2 =
381 a[2] - data_source.kdtree_get_pt( b_idx, d++ );
382 const DistanceType diff3 =
383 a[3] - data_source.kdtree_get_pt( b_idx, d++ );
385 diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
387 if ( ( worst_dist > 0 ) && ( result > worst_dist ) )
396 const DistanceType diff0 =
397 *a++ - data_source.kdtree_get_pt( b_idx, d++ );
398 result += diff0 * diff0;
403 template <
typename U,
typename V>
404 inline DistanceType accum_dist(
const U a,
const V b,
int )
const 406 return ( a - b ) * ( a - b );
417 template <
class T,
class DataSource,
typename _DistanceType = T>
420 typedef T ElementType;
421 typedef _DistanceType DistanceType;
423 const DataSource &data_source;
426 : data_source( _data_source )
430 inline DistanceType operator()(
const T *a,
const size_t b_idx,
433 return data_source.kdtree_distance( a, b_idx, size );
436 template <
typename U,
typename V>
437 inline DistanceType accum_dist(
const U a,
const V b,
int )
const 439 return ( a - b ) * ( a - b );
446 template <
class T,
class DataSource>
455 template <
class T,
class DataSource>
464 template <
class T,
class DataSource>
482 : leaf_max_size( _leaf_max_size )
487 size_t leaf_max_size;
497 bool sorted_ =
true )
498 : checks( checks_IGNORED_ )
522 template <
typename T>
525 T *mem = (T *)::malloc(
sizeof( T ) * count );
545 const size_t BLOCKSIZE = 8192;
547 class PooledAllocator
575 PooledAllocator(
const size_t blocksize_ = BLOCKSIZE )
576 : blocksize( blocksize_ )
584 ~PooledAllocator() { free_all(); }
589 while ( base != NULL )
591 void *prev = *( (
void **)base );
602 void *malloc(
const size_t req_size )
609 const size_t size = ( req_size + ( WORDSIZE - 1 ) ) & ~( WORDSIZE - 1 );
615 if ( size > remaining )
618 wastedMemory += remaining;
621 const size_t blocksize =
622 ( size +
sizeof(
void * ) + ( WORDSIZE - 1 ) > BLOCKSIZE )
623 ? size +
sizeof(
void * ) + ( WORDSIZE - 1 )
627 void *m = ::malloc( blocksize );
630 fprintf( stderr,
"Failed to allocate memory.\n" );
635 ( (
void **)m )[0] = base;
642 remaining = blocksize -
sizeof(
void * ) - shift;
643 loc = ( (
char *)m +
sizeof(
void * ) + shift );
646 loc = (
char *)loc + size;
661 template <
typename T>
662 T *
allocate(
const size_t count = 1 )
664 T *mem = (T *)this->malloc(
sizeof( T ) * count );
701 template <
typename T, std::
size_t N>
709 typedef T value_type;
711 typedef const T *const_iterator;
712 typedef T &reference;
713 typedef const T &const_reference;
714 typedef std::size_t size_type;
715 typedef std::ptrdiff_t difference_type;
718 inline iterator begin() {
return elems; }
719 inline const_iterator begin()
const {
return elems; }
720 inline iterator end() {
return elems + N; }
721 inline const_iterator end()
const {
return elems + N; }
724 #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && \ 725 !defined( BOOST_MSVC_STD_ITERATOR ) && \ 726 !defined( BOOST_NO_STD_ITERATOR_TRAITS ) 727 typedef std::reverse_iterator<iterator> reverse_iterator;
728 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
729 #elif defined( _MSC_VER ) && ( _MSC_VER == 1300 ) && \ 730 defined( BOOST_DINKUMWARE_STDLIB ) && ( BOOST_DINKUMWARE_STDLIB == 310 ) 732 typedef std::reverse_iterator<std::_Ptrit<
733 value_type, difference_type, iterator, reference, iterator, reference>>
735 typedef std::reverse_iterator<
736 std::_Ptrit<value_type, difference_type, const_iterator,
737 const_reference, iterator, reference>>
738 const_reverse_iterator;
741 typedef std::reverse_iterator<iterator, T> reverse_iterator;
742 typedef std::reverse_iterator<const_iterator, T> const_reverse_iterator;
745 reverse_iterator rbegin() {
return reverse_iterator( end() ); }
746 const_reverse_iterator rbegin()
const 748 return const_reverse_iterator( end() );
750 reverse_iterator rend() {
return reverse_iterator( begin() ); }
751 const_reverse_iterator rend()
const 753 return const_reverse_iterator( begin() );
756 inline reference operator[]( size_type i ) {
return elems[i]; }
757 inline const_reference operator[]( size_type i )
const {
return elems[i]; }
759 reference at( size_type i )
764 const_reference at( size_type i )
const 770 reference front() {
return elems[0]; }
771 const_reference front()
const {
return elems[0]; }
772 reference back() {
return elems[N - 1]; }
773 const_reference back()
const {
return elems[N - 1]; }
775 static inline size_type size() {
return N; }
776 static bool empty() {
return false; }
777 static size_type max_size() {
return N; }
784 inline void resize(
const size_t nElements )
786 if ( nElements != N )
787 throw std::logic_error(
"Try to change the size of a CArray." );
792 std::swap_ranges( begin(), end(), y.begin() );
795 const T *data()
const {
return elems; }
797 T *data() {
return elems; }
799 template <
typename T2>
802 std::copy( rhs.begin(), rhs.end(), begin() );
806 inline void assign(
const T &value )
808 for (
size_t i = 0; i < N; i++ )
812 void assign(
const size_t n,
const T &value )
815 for (
size_t i = 0; i < N; i++ )
821 static void rangecheck( size_type i )
825 throw std::out_of_range(
"CArray<>: index out of range" );
834 template <
int DIM,
typename T>
840 template <
typename T>
843 typedef Teuchos::Array<T> container_t;
889 template <
typename Distance,
class DatasetAdaptor,
int DIM = -1,
890 typename IndexType =
size_t>
894 typedef typename Distance::ElementType ElementType;
895 typedef typename Distance::DistanceType DistanceType;
901 Teuchos::Array<IndexType>
vind;
903 size_t m_leaf_max_size;
925 IndexType left, right;
936 DistanceType divlow, divhigh;
942 Node *child1, *child2;
944 typedef Node *NodePtr;
948 ElementType low, high;
965 template <
typename T,
typename DistanceType>
979 inline bool operator<( const BranchStruct<T, DistanceType> &rhs )
const 981 return mindist < rhs.mindist;
1015 const DatasetAdaptor &inputData,
1018 : dataset( inputData )
1019 , index_params( params )
1021 , distance( inputData )
1023 m_size = dataset.kdtree_get_point_count();
1024 dim = dimensionality;
1029 if ( params.dim > 0 )
1032 m_leaf_max_size = params.leaf_max_size;
1057 computeBoundingBox( root_bbox );
1059 root_node = divideTree( 0, m_size, root_bbox );
1065 size_t size()
const {
return m_size; }
1070 size_t veclen()
const {
return static_cast<size_t>( DIM > 0 ? DIM : dim ); }
1078 return pool.usedMemory + pool.wastedMemory +
1079 dataset.kdtree_get_point_count() *
1080 sizeof( IndexType );
1099 template <
typename RESULTSET>
1105 throw std::runtime_error(
"[nanoflann] findNeighbors() called " 1106 "before building the index." );
1107 float epsError = 1 + searchParams.
eps;
1111 dists.assign( ( DIM > 0 ? DIM : dim ), 0 );
1112 DistanceType distsq = computeInitialDistances( vec, dists );
1113 searchLevel( result, vec, root_node, distsq, dists,
1127 const size_t num_closest, IndexType *out_indices,
1128 DistanceType *out_distances_sq,
1129 const int nChecks_IGNORED = 10 )
const 1131 nanoflann::KNNResultSet<DistanceType, IndexType> resultSet(
1133 resultSet.init( out_indices, out_distances_sq );
1134 this->findNeighbors( resultSet, query_point,
1156 const ElementType *query_point,
const DistanceType radius,
1157 Teuchos::Array<std::pair<IndexType, DistanceType>> &IndicesDists,
1162 this->findNeighbors( resultSet, query_point, searchParams );
1164 if ( searchParams.
sorted )
1165 std::sort( IndicesDists.begin(), IndicesDists.end(),
1168 return resultSet.size();
1179 m_size = dataset.kdtree_get_point_count();
1180 if ( Teuchos::as<std::size_t>( vind.size() ) !=
1181 Teuchos::as<std::size_t>( m_size ) )
1182 vind.resize( m_size );
1183 for (
size_t i = 0; i < m_size; i++ )
1188 inline ElementType dataset_get(
size_t idx,
int component )
const 1190 return dataset.kdtree_get_pt( idx, component );
1193 void save_tree( FILE *stream, NodePtr tree )
1195 save_value( stream, *tree );
1196 if ( tree->child1 != NULL )
1198 save_tree( stream, tree->child1 );
1200 if ( tree->child2 != NULL )
1202 save_tree( stream, tree->child2 );
1206 void load_tree( FILE *stream, NodePtr &tree )
1208 tree = pool.allocate<Node>();
1209 load_value( stream, *tree );
1210 if ( tree->child1 != NULL )
1212 load_tree( stream, tree->child1 );
1214 if ( tree->child2 != NULL )
1216 load_tree( stream, tree->child2 );
1222 bbox.resize( ( DIM > 0 ? DIM : dim ) );
1223 if ( dataset.kdtree_get_bbox( bbox ) )
1229 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1231 bbox[i].low = bbox[i].high = dataset_get( 0, i );
1233 const size_t N = dataset.kdtree_get_point_count();
1234 for (
size_t k = 1; k < N; ++k )
1236 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1238 if ( dataset_get( k, i ) < bbox[i].low )
1239 bbox[i].low = dataset_get( k, i );
1240 if ( dataset_get( k, i ) > bbox[i].high )
1241 bbox[i].high = dataset_get( k, i );
1256 NodePtr divideTree(
const IndexType left,
const IndexType right,
1259 NodePtr node = pool.allocate<Node>();
1262 if ( ( right - left ) <= m_leaf_max_size )
1264 node->child1 = node->child2 = NULL;
1265 node->lr.left = left;
1266 node->lr.right = right;
1269 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1271 bbox[i].low = dataset_get( vind[left], i );
1272 bbox[i].high = dataset_get( vind[left], i );
1274 for ( IndexType k = left + 1; k < right; ++k )
1276 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1278 if ( bbox[i].low > dataset_get( vind[k], i ) )
1279 bbox[i].low = dataset_get( vind[k], i );
1280 if ( bbox[i].high < dataset_get( vind[k], i ) )
1281 bbox[i].high = dataset_get( vind[k], i );
1289 DistanceType cutval;
1290 middleSplit_( &vind[0] + left, right - left, idx, cutfeat, cutval,
1293 node->sub.divfeat = cutfeat;
1296 left_bbox[cutfeat].high = cutval;
1297 node->child1 = divideTree( left, left + idx, left_bbox );
1300 right_bbox[cutfeat].low = cutval;
1301 node->child2 = divideTree( left + idx, right, right_bbox );
1303 node->sub.divlow = left_bbox[cutfeat].high;
1304 node->sub.divhigh = right_bbox[cutfeat].low;
1306 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1308 bbox[i].low = std::min( left_bbox[i].low, right_bbox[i].low );
1310 std::max( left_bbox[i].high, right_bbox[i].high );
1317 void computeMinMax( IndexType *ind, IndexType count,
int element,
1318 ElementType &min_elem, ElementType &max_elem )
1320 min_elem = dataset_get( ind[0], element );
1321 max_elem = dataset_get( ind[0], element );
1322 for ( IndexType i = 1; i < count; ++i )
1324 ElementType val = dataset_get( ind[i], element );
1325 if ( val < min_elem )
1327 if ( val > max_elem )
1332 void middleSplit( IndexType *ind, IndexType count, IndexType &index,
1333 int &cutfeat, DistanceType &cutval,
1337 ElementType max_span = bbox[0].high - bbox[0].low;
1339 cutval = ( bbox[0].high + bbox[0].low ) / 2;
1340 for (
int i = 1; i < ( DIM > 0 ? DIM : dim ); ++i )
1342 ElementType span = bbox[i].low - bbox[i].low;
1343 if ( span > max_span )
1347 cutval = ( bbox[i].high + bbox[i].low ) / 2;
1352 ElementType min_elem, max_elem;
1353 computeMinMax( ind, count, cutfeat, min_elem, max_elem );
1354 cutval = ( min_elem + max_elem ) / 2;
1355 max_span = max_elem - min_elem;
1359 for (
size_t i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1363 ElementType span = bbox[i].high - bbox[i].low;
1364 if ( span > max_span )
1366 computeMinMax( ind, count, i, min_elem, max_elem );
1367 span = max_elem - min_elem;
1368 if ( span > max_span )
1372 cutval = ( min_elem + max_elem ) / 2;
1376 IndexType lim1, lim2;
1377 planeSplit( ind, count, cutfeat, cutval, lim1, lim2 );
1379 if ( lim1 > count / 2 )
1381 else if ( lim2 < count / 2 )
1387 void middleSplit_( IndexType *ind, IndexType count, IndexType &index,
1388 int &cutfeat, DistanceType &cutval,
1391 const DistanceType epsilon =
static_cast<DistanceType
>( 0.00001 );
1392 ElementType max_span = bbox[0].high - bbox[0].low;
1393 for (
int i = 1; i < ( DIM > 0 ? DIM : dim ); ++i )
1395 ElementType span = bbox[i].high - bbox[i].low;
1396 if ( span > max_span )
1401 ElementType max_spread = -1;
1403 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1405 ElementType span = bbox[i].high - bbox[i].low;
1406 if ( span > ( 1 - epsilon ) * max_span )
1408 ElementType min_elem, max_elem;
1409 computeMinMax( ind, count, cutfeat, min_elem, max_elem );
1410 ElementType spread = max_elem - min_elem;
1412 if ( spread > max_spread )
1415 max_spread = spread;
1420 DistanceType split_val = ( bbox[cutfeat].low + bbox[cutfeat].high ) / 2;
1421 ElementType min_elem, max_elem;
1422 computeMinMax( ind, count, cutfeat, min_elem, max_elem );
1424 if ( split_val < min_elem )
1426 else if ( split_val > max_elem )
1431 IndexType lim1, lim2;
1432 planeSplit( ind, count, cutfeat, cutval, lim1, lim2 );
1434 if ( lim1 > count / 2 )
1436 else if ( lim2 < count / 2 )
1452 void planeSplit( IndexType *ind,
const IndexType count,
int cutfeat,
1453 DistanceType cutval, IndexType &lim1, IndexType &lim2 )
1457 IndexType right = count - 1;
1460 while ( left <= right &&
1461 dataset_get( ind[left], cutfeat ) < cutval )
1463 while ( right && left <= right &&
1464 dataset_get( ind[right], cutfeat ) >= cutval )
1466 if ( left > right || !right )
1468 std::swap( ind[left], ind[right] );
1479 while ( left <= right &&
1480 dataset_get( ind[left], cutfeat ) <= cutval )
1482 while ( right && left <= right &&
1483 dataset_get( ind[right], cutfeat ) > cutval )
1485 if ( left > right || !right )
1487 std::swap( ind[left], ind[right] );
1494 DistanceType computeInitialDistances(
const ElementType *vec,
1498 DistanceType distsq = 0.0;
1500 for (
int i = 0; i < ( DIM > 0 ? DIM : dim ); ++i )
1502 if ( vec[i] < root_bbox[i].low )
1504 dists[i] = distance.accum_dist( vec[i], root_bbox[i].low, i );
1507 if ( vec[i] > root_bbox[i].high )
1509 dists[i] = distance.accum_dist( vec[i], root_bbox[i].high, i );
1521 template <
class RESULTSET>
1522 void searchLevel( RESULTSET &result_set,
const ElementType *vec,
1523 const NodePtr node, DistanceType mindistsq,
1527 if ( ( node->child1 == NULL ) && ( node->child2 == NULL ) )
1531 DistanceType worst_dist = result_set.worstDist();
1532 for ( IndexType i = node->lr.left; i < node->lr.right; ++i )
1534 const IndexType index = vind[i];
1536 distance( vec, index, ( DIM > 0 ? DIM : dim ) );
1537 if ( dist < worst_dist )
1539 result_set.addPoint( dist, vind[i] );
1546 int idx = node->sub.divfeat;
1547 ElementType val = vec[idx];
1548 DistanceType diff1 = val - node->sub.divlow;
1549 DistanceType diff2 = val - node->sub.divhigh;
1553 DistanceType cut_dist;
1554 if ( ( diff1 + diff2 ) < 0 )
1556 bestChild = node->child1;
1557 otherChild = node->child2;
1558 cut_dist = distance.accum_dist( val, node->sub.divhigh, idx );
1562 bestChild = node->child2;
1563 otherChild = node->child1;
1564 cut_dist = distance.accum_dist( val, node->sub.divlow, idx );
1568 searchLevel( result_set, vec, bestChild, mindistsq, dists, epsError );
1570 DistanceType dst = dists[idx];
1571 mindistsq = mindistsq + cut_dist - dst;
1572 dists[idx] = cut_dist;
1573 if ( mindistsq * epsError <= result_set.worstDist() )
1575 searchLevel( result_set, vec, otherChild, mindistsq, dists,
1590 save_value( stream, m_size );
1591 save_value( stream, dim );
1592 save_value( stream, root_bbox );
1593 save_value( stream, m_leaf_max_size );
1594 save_value( stream, vind );
1595 save_tree( stream, root_node );
1606 load_value( stream, m_size );
1607 load_value( stream, dim );
1608 load_value( stream, root_bbox );
1609 load_value( stream, m_leaf_max_size );
1610 load_value( stream, vind );
1611 load_tree( stream, root_node );
1641 typename IndexType =
size_t>
1646 typedef typename MatrixType::Scalar num_t;
1648 typename Distance::template traits<num_t, self_t>::distance_t metric_t;
1656 const int leaf_max_size = 10 )
1657 : m_data_matrix( mat )
1659 const size_t dims = mat.cols();
1660 if ( DIM > 0 && static_cast<int>( dims ) != DIM )
1661 throw std::runtime_error(
"Data set dimensionality does not match " 1662 "the 'DIM' template argument" );
1663 index =
new index_t(
1671 const MatrixType &m_data_matrix;
1680 inline void query(
const num_t *query_point,
const size_t num_closest,
1681 IndexType *out_indices, num_t *out_distances_sq,
1682 const int nChecks_IGNORED = 10 )
const 1684 nanoflann::KNNResultSet<typename MatrixType::Scalar, IndexType>
1685 resultSet( num_closest );
1686 resultSet.init( out_indices, out_distances_sq );
1694 const self_t &derived()
const {
return *
this; }
1695 self_t &derived() {
return *
this; }
1698 inline size_t kdtree_get_point_count()
const 1700 return m_data_matrix.rows();
1705 inline num_t kdtree_distance(
const num_t *p1,
const size_t idx_p2,
1709 for (
size_t i = 0; i < size; i++ )
1711 const num_t d = p1[i] - m_data_matrix.coeff( idx_p2, i );
1718 inline num_t kdtree_get_pt(
const size_t idx,
int dim )
const 1720 return m_data_matrix.coeff( idx, dim );
1729 template <
class BBOX>
1730 bool kdtree_get_bbox( BBOX &bb )
const
SearchParams(int checks_IGNORED_=32, float eps_=0, bool sorted_=true)
void resize(const size_t nElements)
size_t radiusSearch(const ElementType *query_point, const DistanceType radius, Teuchos::Array< std::pair< IndexType, DistanceType >> &IndicesDists, const SearchParams &searchParams) const
KDTreeEigenMatrixAdaptor(const int dimensionality, const MatrixType &mat, const int leaf_max_size=10)
Constructor: takes a const ref to the matrix object with the data points.
void findNeighbors(RESULTSET &result, const ElementType *vec, const SearchParams &searchParams) const
int dim
Dimensionality of each data point.
float eps
search for eps-approximate neighbours (default: 0)
array_or_vector_selector< DIM, Interval >::container_t BoundingBox
void knnSearch(const ElementType *query_point, const size_t num_closest, IndexType *out_indices, DistanceType *out_distances_sq, const int nChecks_IGNORED=10) const
T * allocate(size_t count=1)
Teuchos::Array< IndexType > vind
const DatasetAdaptor & dataset
The source of our data.
std::pair< IndexType, DistanceType > worst_item() const
size_t usedMemory() const
~KDTreeSingleIndexAdaptor()
bool operator()(const PairType &p1, const PairType &p2) const
void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int nChecks_IGNORED=10) const
KDTreeSingleIndexAdaptor(const int dimensionality, const DatasetAdaptor &inputData, const KDTreeSingleIndexAdaptorParams ¶ms=KDTreeSingleIndexAdaptorParams())
array_or_vector_selector< DIM, DistanceType >::container_t distance_vector_t
void saveIndex(FILE *stream)
void set_radius_and_clear(const DistanceType r)
void loadIndex(FILE *stream)