From steve at net-nativesuk.me.uk Tue Nov 3 07:47:01 2009 From: steve at net-nativesuk.me.uk (Steve Evans) Date: Tue, 03 Nov 2009 07:47:01 -0000 Subject: Recruitment fees are history Message-ID: An HTML attachment was scrubbed... URL: From jsantam.hm at hotmail.com Mon Nov 16 17:10:20 2009 From: jsantam.hm at hotmail.com (jsl n) Date: Mon, 16 Nov 2009 18:10:20 +0100 Subject: How to searching for in kdtree when dynamic elements are considered Message-ID: Hi, I'm using kdtree for searching for the closest point between two images. The kdtree stores the points of one (fixed) of the two images and the second one is iteratively transformed (rotated, translated, etc). The closest point is computed for each moved point each iteration. This is the procedure, but, what happen if the fixed image (the one that the kdtree stores) is also transformed each iteration? should I build a new kdtree each iteration? I need to know if there is an efficient solution for this dynamic situations where all the image points (of the fixed image) are transformed in the same way. Thanks in advance. _________________________________________________________________ Deja que Sietes te ense?e todo los secretos de Windows http://www.sietesunpueblodeexpertos.com/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From paulharris at computer.org Mon Nov 16 23:37:09 2009 From: paulharris at computer.org (Paul Harris) Date: Tue, 17 Nov 2009 07:37:09 +0800 Subject: How to searching for in kdtree when dynamic elements are considered In-Reply-To: References: Message-ID: <3fa3884f0911161537gcc72420pcc1610d31fb1ac87@mail.gmail.com> Hi Jsl, I'm not sure exactly what you are talking about, but if all you are doing is transformations, then what I would do is *when* you are querying the tree, transform the query location into the coordinate system of the tree. eg, you build the tree with the plain image ABC, let the tree coordinate system be X,Y then you want to find a point close to x,y then you search for X,Y=x,y if you then transform image ABC by adding 10 to y... so therefore X=x Y=y-10 where X,Y are the tree coordinates, and x,y are the transformed coordinates. Then if you want to find a point (21,56), then you transform into tree coords : (21,46) and then search. remember, X=x, Y=y-10 so X=21, Y=56-10 any rotation, translation etc can reversed. matrix multiplications make this simple and quick to do. that way you can avoid rebuilding the tree with each iteration, which would be expensive. cheers Paul 2009/11/17 jsl n > Hi, > > I'm using kdtree for searching for the closest point between two images. > The kdtree stores the points of one (fixed) of the two images and the > second > one is iteratively transformed (rotated, translated, etc). The closest > point is > computed for each moved point each iteration. > > This is the procedure, but, what happen if the fixed image (the one that > the > kdtree stores) is also transformed each iteration? should I build a new > kdtree > each iteration? I need to know if there is an efficient solution for this > dynamic > situations where all the image points (of the fixed image) are transformed > in > the same way. > > Thanks in advance. > > ------------------------------ > 49 habitantes, 49 expertos en Windows 7. As? es Sietes, ?Vis?talo! > > _______________________________________________ > libkdtree-devel mailing list > libkdtree-devel at lists.alioth.debian.org > http://lists.alioth.debian.org/mailman/listinfo/libkdtree-devel > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sylvain.bougerel.devel at gmail.com Tue Nov 17 03:05:27 2009 From: sylvain.bougerel.devel at gmail.com (Sylvain Bougerel) Date: Tue, 17 Nov 2009 11:05:27 +0800 Subject: How to searching for in kdtree when dynamic elements are considered In-Reply-To: References: Message-ID: On Tue, Nov 17, 2009 at 1:10 AM, jsl n wrote: > Hi, > > This is the procedure, but, what happen if the fixed image (the one that the > kdtree stores) is also transformed each iteration? should I build a new > kdtree > each iteration? I need to know if there is an efficient solution for this > dynamic > situations where all the image points (of the fixed image) are transformed > in > the same way. > > Thanks in advance. > Hi Jsl (?), (The following comments are agnostic with regard to the type of objects stored in the tree) Some transformations result in a violation of the invariant, others do not. Uniform translations or scallings of all point in the tree along a linear vector or with constant factor (be it in affine or euclidean space) will not break the invariant. So you can lock the kd-tree (if necessary), perform the translation or scalling of all points in the tree, unlock the kd-tree (if necessary), and continue your program. Uniform rotations, on the contrary, do not have this property (neither in affine nor in euclidean space), they *always* break the invariant (unless they are null rotation, of course) in the kd-tree. Therefore, upon a rotation, you have no choice but to rebuild your kd-tree entirely. Others transformation, such as perspectives transform or matrix transform may or may not break the invariant in the tree. Unless you are able to determine that a particular transformation is, in fact, a composition of more elementary translations or scallings, you will have to rebuild the tree every time you have such transform on your image. Cheers, Sylvain From sylvain.bougerel.devel at gmail.com Tue Nov 17 03:10:14 2009 From: sylvain.bougerel.devel at gmail.com (Sylvain Bougerel) Date: Tue, 17 Nov 2009 11:10:14 +0800 Subject: How to searching for in kdtree when dynamic elements are considered In-Reply-To: <3fa3884f0911161537gcc72420pcc1610d31fb1ac87@mail.gmail.com> References: <3fa3884f0911161537gcc72420pcc1610d31fb1ac87@mail.gmail.com> Message-ID: On Tue, Nov 17, 2009 at 7:37 AM, Paul Harris wrote: > Hi Jsl, > > any rotation, translation etc can reversed.? matrix multiplications make > this simple and quick to do. > > that way you can avoid rebuilding the tree with each iteration, which would > be expensive. > > cheers > Paul > Hi Jsl, You should follow Paul's proposition if it is possible. I was just stating a factual truth about kd-tree in general in my previous mail. Paul's implementation obviously performs better. Cheers, Sylvain From remillard.jason at gmail.com Tue Nov 17 20:00:26 2009 From: remillard.jason at gmail.com (Jason Remillard) Date: Tue, 17 Nov 2009 15:00:26 -0500 Subject: problem with find_within_range Message-ID: <903d4a620911171200i6c4ce6adu3f50b75bb1c9f76e@mail.gmail.com> 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 #include #include #include 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 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 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 howClose; tree.find_within_range(refNode,limit,back_insert_iterator >(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::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 > 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()); @@ -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* >(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* >(probe)->_M_value)) <= __max)) + && (std::sqrt(double(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast* >(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* >(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* >(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* >(probe)->_M_value)) <= __max) + std::sqrt(double(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast* >(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* >(probe)->_M_value)) <= __max) + && std::sqrt(double(_S_node_distance(probe_dim % __k, __dist, __acc, __val, static_cast* >(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* >(cur)->_M_value)) <= __max)) + && (std::sqrt(double(_S_node_distance(cur_dim % __k, __dist, __acc, __val, static_cast* >(cur)->_M_value))) <= __max)) { probe = near_node; ++probe_dim; From paulharris at computer.org Wed Nov 18 03:19:52 2009 From: paulharris at computer.org (Paul Harris) Date: Wed, 18 Nov 2009 11:19:52 +0800 Subject: problem with find_within_range In-Reply-To: <903d4a620911171200i6c4ce6adu3f50b75bb1c9f76e@mail.gmail.com> References: <903d4a620911171200i6c4ce6adu3f50b75bb1c9f76e@mail.gmail.com> Message-ID: <3fa3884f0911171919x32c0ad62o34aeb2ddf0d8c4f2@mail.gmail.com> Hi Jason, 2009/11/18 Jason Remillard > 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. > > Thank you for that, I had forgotten that if you #include it puts all the math functions (like sqrt) into the std namespace. I'll make the changes on the git HEAD. > 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, nd compares them to what actually comes back. I am > seeing both extra points and missing points. Bug, or I am doing > something wrong? > > I'm afraid that you are technically doing something wrong. Only find_nearest bothers to sqrt() the distances. find_within_range converts the 'limit' into a square region (or bounding box) with sides=limit and then searches and returns all points within that box. This is how it has always been - all of the _within_range() functions work this way. I don't think this is ideal, and it should certainly be more obvious. I myself had forgotten that it does this. I can't really change the way it works as people possibly rely on this behaviour. Personally I'd prefer it sqrt'd to find the distance, but the change is not as simple as just wacking in a sqrt somewhere. Plus people don't always want to use euclidean distances so its not really a step in the right direction. I've added your test (with corrections and comments) to git-head, and also added extra comments to kdtree.hpp, so people won't be caught out as easily when 0.7.2 comes out. There are a few things you could do: a) adjust what you expect from kdtree. see below, i've adjusted your test so that it runs without failing. b) use visit_within_range() to test the distance properly before adding it to the vector, or double-check the distances in the result vector. c) try out my git branch paulharris/region ... i've templated the Region that you can search on, and so you could implement a Region of your own that does the sqrt() test in the encloses() method. this could eventually be incorporated into the standard kdtree so that we can then call eg tree.find_within_range_accurate() or whatever. cheers, Paul > Thanks, Jason. > > #include > #include > #include > #include > #include > > 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]; > // this is not correct return sqrt( x*x+y*y+z*z); // this is what kdtree checks with find_within_range() // the "manhattan distance" from the search point. // effectively, distance is the maximum distance in any one dimension. return max(fabs(x),max(fabs(y),fabs(z))); } > }; > > int main(int argc,char *argv[]) > { > vector 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 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 howClose; > > tree.find_within_range(refNode,limit,back_insert_iterator > >(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::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"); > } > } > } > > _______________________________________________ > libkdtree-devel mailing list > libkdtree-devel at lists.alioth.debian.org > http://lists.alioth.debian.org/mailman/listinfo/libkdtree-devel > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From remillard.jason at gmail.com Wed Nov 18 14:01:53 2009 From: remillard.jason at gmail.com (Jason Remillard) Date: Wed, 18 Nov 2009 09:01:53 -0500 Subject: thread safety on query functions Message-ID: <903d4a620911180601t4f492341nc98cced609b8ab68@mail.gmail.com> Hi, Sorry if this has been asked before, but I was not able to figure out how to search over the list archives. I would like to build up a kdtree, then spawn multiple threads via openmp that will do parallel queries on the tree. The find, find_nearest, find_within_range, and visit_within_range are all declared as const. However, are they really const? - Does calling them modify the state of the tree in anyway? - Any cached data in the tree? - Any intermediate data stored in the nodes? If the search functions write to any tree data then concurrent calls will not work. Thanks Jason. From elegant_dice at yahoo.com Wed Nov 18 14:11:32 2009 From: elegant_dice at yahoo.com (Paul) Date: Wed, 18 Nov 2009 22:11:32 +0800 Subject: thread safety on query functions In-Reply-To: <903d4a620911180601t4f492341nc98cced609b8ab68@mail.gmail.com> References: <903d4a620911180601t4f492341nc98cced609b8ab68@mail.gmail.com> Message-ID: <3fa3884f0911180611n52cfe529t5a1b5fada49dd7f2@mail.gmail.com> 2009/11/18 Jason Remillard > Hi, > > Sorry if this has been asked before, but I was not able to figure out > how to search over the list archives. > > I would like to build up a kdtree, then spawn multiple threads via > openmp that will do parallel queries on the tree. The find, > find_nearest, find_within_range, and visit_within_range are all > declared as const. However, are they really const? > - Does calling them modify the state of the tree in anyway? > - Any cached data in the tree? > - Any intermediate data stored in the nodes? > > If the search functions write to any tree data then concurrent calls > will not work. > > All the const methods are const-correct, to my knowledge. This is important to me too. Plus, there is no need to write anything during a search as there is no caching or intermediate data. Note that your accessor and other classes you use with kdtree will also need to be thread-safe. Also note that if you use something like visit_within_range(), the visitor is *copied* around (like other STL algorithms), so make sure that your visitor is fast to copy (use pointers or pimpl pattern or letter-envelope pattern or whatever you want to call it). see ya Paul -------------- next part -------------- An HTML attachment was scrubbed... URL: