problem with find_within_range
Jason Remillard
remillard.jason at gmail.com
Tue Nov 17 20:00:26 UTC 2009
Hi,
I am using 0.7.0 with visual studio 2005. I usually don't do a "use
namespace std" until I am in my C++ files. This patch adds in the
std:: namespace, and fixes a warning about the compiler not knowing if
it should call the float, double, or long of sqrt. I included it
because I hope that it is not related to the problem I am having with
find_within_range.
The included test program makes a set or random 3D points, sets up the
kdtree on them, then picks a random search point with a random range.
It then calculates the points that should be returned by
find_within_range, and compares them to what actually comes back. I am
seeing both extra points and missing points. Bug, or I am doing
something wrong?
Thanks, Jason.
#include <kdtree++/kdtree.hpp>
#include <vector>
#include <map>
#include <stdio.h>
using namespace std;
struct kdtreeNode
{
typedef double value_type;
double xyz[3];
size_t index;
value_type operator[](size_t n) const
{
return xyz[n];
}
double distance( const kdtreeNode &node)
{
double x = xyz[0] - node.xyz[0];
double y = xyz[1] - node.xyz[1];
double z = xyz[2] - node.xyz[2];
return sqrt( x*x+y*y+z*z);
}
};
int main(int argc,char *argv[])
{
vector<kdtreeNode> pts;
typedef KDTree::KDTree<3,kdtreeNode> treeType;
treeType tree;
// make random 3d points
for ( size_t n = 0; n < 10000; ++n)
{
kdtreeNode node;
node.xyz[0] = double(rand())/RAND_MAX;
node.xyz[1] = double(rand())/RAND_MAX;
node.xyz[2] = double(rand())/RAND_MAX;
node.index = n;
tree.insert( node);
pts.push_back( node);
}
for (size_t r = 0; r < 1000; ++r)
{
kdtreeNode refNode;
refNode.xyz[0] = double(rand())/RAND_MAX;
refNode.xyz[1] = double(rand())/RAND_MAX;
refNode.xyz[2] = double(rand())/RAND_MAX;
double limit = double(rand())/RAND_MAX;
// find the correct return list by checking every single point
set<size_t> correctCloseList;
for ( size_t i= 0; i < pts.size(); ++i)
{
double dist = refNode.distance( pts[i]);
if ( dist < limit)
correctCloseList.insert( i );
}
// now do the same with the kdtree.
vector<kdtreeNode> howClose;
tree.find_within_range(refNode,limit,back_insert_iterator<vector<kdtreeNode>
>(howClose));
// make sure no extra points are returned, and the return has no
missing points.
for ( size_t i = 0; i < howClose.size(); ++i)
{
set<size_t>::iterator hit = correctCloseList.find( howClose[i].index);
if ( hit != correctCloseList.end())
{
correctCloseList.erase(hit);
}
else
{
// point that is too far away - fail!
assert(false);
printf("fail, extra points.\n");
}
}
// fail, not all of the close enough points returned.
assert( correctCloseList.size() == 0);
if ( correctCloseList.size() > 0)
{
printf("fail, missing points.\n");
}
}
}
-------------- next part --------------
Index: kdtree++/kdtree.hpp
===================================================================
--- kdtree++/kdtree.hpp (revision 792)
+++ kdtree++/kdtree.hpp (working copy)
@@ -512,7 +512,7 @@
std::pair<size_type, typename _Acc::result_type> >
best = _S_node_nearest (__K, 0, __val,
_M_get_root(), &_M_header, _M_get_root(),
- sqrt(_S_accumulate_node_distance
+ std::sqrt(_S_accumulate_node_distance
(__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)),
_M_cmp, _M_acc, _M_dist,
always_true<value_type>());
@@ -531,8 +531,8 @@
bool root_is_candidate = false;
const _Node<_Val>* node = _M_get_root();
{ // scope to ensure we don't use 'root_dist' anywhere else
- distance_type root_dist = sqrt(_S_accumulate_node_distance
- (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
+ distance_type root_dist = std::sqrt(double(_S_accumulate_node_distance
+ (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)));
if (root_dist <= __max)
{
root_is_candidate = true;
@@ -564,8 +564,8 @@
if (__p(_M_get_root()->_M_value))
{
{ // scope to ensure we don't use root_dist anywhere else
- distance_type root_dist = sqrt(_S_accumulate_node_distance
- (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val));
+ distance_type root_dist = std::sqrt(double(_S_accumulate_node_distance
+ (__K, _M_dist, _M_acc, _M_get_root()->_M_value, __val)));
if (root_dist <= __max)
{
root_is_candidate = true;
Index: kdtree++/node.hpp
===================================================================
--- kdtree++/node.hpp (revision 792)
+++ kdtree++/node.hpp (working copy)
@@ -213,7 +213,7 @@
typename _Dist::distance_type d = 0;
for (size_t i=0; i != __k; ++i)
d += _S_node_distance(i, __dist, __acc, __val, static_cast<const _Node<_Val>* >(cur)->_M_value);
- d = sqrt(d);
+ d = std::sqrt(double(d));
if (d <= __max)
// ("bad candidate notes")
// Changed: removed this test: || ( d == __max && cur < __best ))
@@ -245,7 +245,7 @@
near_node = probe->_M_left;
if (near_node
// only visit node's children if node's plane intersect hypersphere
- && (sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value)) <= __max))
+ && (std::sqrt(double(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value))) <= __max))
{
probe = near_node;
++probe_dim;
@@ -271,7 +271,7 @@
typename _Dist::distance_type d = 0;
for (size_t i=0; i < __k; ++i)
d += _S_node_distance(i, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value);
- d = sqrt(d);
+ d = std::sqrt(double(d));
if (d <= __max) // CHANGED, see the above notes ("bad candidate notes")
{
__best = static_cast<const _Node<_Val>* >(probe);
@@ -287,7 +287,7 @@
}
else if (far_node &&
// only visit node's children if node's plane intersect hypersphere
- sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value)) <= __max)
+ std::sqrt(double(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value))) <= __max)
{
probe = far_node;
++probe_dim;
@@ -302,7 +302,7 @@
{
if (pprobe == near_node && far_node
// only visit node's children if node's plane intersect hypersphere
- && sqrt(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value)) <= __max)
+ && std::sqrt(double(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(probe)->_M_value))) <= __max)
{
pprobe = probe;
probe = far_node;
@@ -330,7 +330,7 @@
near_node = cur->_M_left;
if (near_node
// only visit node's children if node's plane intersect hypersphere
- && (sqrt(_S_node_distance(cur_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(cur)->_M_value)) <= __max))
+ && (std::sqrt(double(_S_node_distance(cur_dim % __k, __dist, __acc, __val, static_cast<const _Node<_Val>* >(cur)->_M_value))) <= __max))
{
probe = near_node;
++probe_dim;
More information about the libkdtree-devel
mailing list