#ifndef KNN_NODE_IMPL_H_ #define KNN_NODE_IMPL_H_ #define TEMPLATE__ \ template #define KNN_NODE__ \ KnnNode TEMPLATE__ KNN_NODE__::KnnNode() { left_.SetNULL(); right_.SetNULL(); points_.SetNULL(); node_id_ = numeric_limits::max(); min_dist_so_far_=numeric_limits::max(); } TEMPLATE__ void KNN_NODE__::Init(const BoundingBox_t &box, const NodeCachedStatistics_t &statistics, index_t node_id, index_t num_of_points) { box_.Alias(box); statistics_.Alias(statistics); node_id_ = node_id; num_of_points_ = num_of_points; } TEMPLATE__ void KNN_NODE__::Init(const typename KNN_NODE__::BoundingBox_t &box, const typename KNN_NODE__::NodeCachedStatistics_t &statistics, index_t node_id, index_t start, index_t num_of_points, int32 dimension, BinaryDataset *dataset) { box_.Alias(box); statistics_.Alias(statistics); node_id_ = node_id; num_of_points_ = num_of_points; points_.Reset(Allocator_t::template malloc (num_of_points_*dimension)); index_.Reset(Allocator_t::template malloc(num_of_points_)); points_.Lock(); index_.Lock(); for(index_t i=start; iAt(i,j); } index_[i-start]=dataset->get_id(i); } points_.Unlock(); index_.Unlock(); } TEMPLATE__ KNN_NODE__::~KnnNode() { } TEMPLATE__ void *KNN_NODE__::operator new(size_t size) { typename Allocator_t::template Ptr temp; temp.Reset(Allocator_t::malloc(size)); return (void *)temp.get(); } TEMPLATE__ void KNN_NODE__::operator delete(void *p) { } TEMPLATE__ template pair KNN_NODE__::ClosestChild(POINTTYPE point, int32 dimension, ComputationsCounter &comp) { left_.Lock(); right_.Lock(); return box_.ClosestChild(left_, right_, point, dimension, comp); left_.Unlock(); right_.Unlock(); } TEMPLATE__ inline pair, pair > KNN_NODE__::ClosestNode(typename KNN_NODE__::NodePtr_t ptr1, typename KNN_NODE__::NodePtr_t ptr2, int32 dimension, ComputationsCounter &comp) { ptr1.Lock(); ptr2.Lock(); Precision_t dist1 = BoundingBox_t::Distance(box_, ptr1->get_box(), dimension, comp); Precision_t dist2 = BoundingBox_t::Distance(box_, ptr2->get_box(), dimension, comp); ptr1.Unlock(); ptr2.Unlock(); if (dist1 inline void KNN_NODE__::FindNearest(POINTTYPE query_point, vector > &nearest, index_t knns, int32 dimension, typename KNN_NODE__::PointIdDiscriminator_t &discriminator, ComputationsCounter &comp) { for(index_t i=0; i >::iterator it; it=nearest.begin()+knns; std::sort(nearest.begin(), nearest.end(), PairComparator()); if (likely(nearest.size()>(uint32)knns)) { nearest.erase(it, nearest.end()); } else { pair dummy; dummy.first=numeric_limits::max(); index_t extra_size=(index_t)(knns-nearest.size()); for(index_t i=0; i &comp) { points_.Lock(); index_.Lock(); query_node->points_.Lock(); query_node->index_.Lock(); query_node->kneighbors_.Lock(); query_node->distances_.Lock(); Precision_t max_local_distance = 0; for(index_t i=0; inum_of_points_; i++) { Precision_t distance; // for k nearest neighbors // get the current maximum distance for the specific point distance = query_node->distances_[i*knns+knns-1]; // We should check whether this speeds up or slows down // the performance comp.UpdateComparisons(); Precision_t *temp_point=query_node->points_.get_p()+i*dimension; if (this->box_.CrossesBoundaries(temp_point, dimension, distance, comp)) { // for k nearest neighbors vector > temp(knns); for(int32 j=0; jdistances_[i*knns+j]; temp[j].second=query_node->kneighbors_[i*knns+j]; } NullPoint_t point; point.Alias(query_node->points_.get_p()+i*dimension, query_node->index_[i]); FindNearest(point, temp, knns, dimension, discriminator, comp); DEBUG_ASSERT_MSG((index_t)temp.size()==knns, "During %i-nn seach, returned %u results",(int)knns, (unsigned int)temp.size()); for(int32 j=0; jkneighbors_[i*knns+j]=temp[j].second; query_node->distances_[i*knns+j]=temp[j].first; } // Estimate the maximum nearest neighbor distance comp.UpdateComparisons(); if (max_local_distance < temp.back().first) { max_local_distance = temp.back().first; } } if (max_local_distance < distance) { max_local_distance = distance; } } if (max_neighbor_distance>max_local_distance) { max_neighbor_distance=max_local_distance; } points_.Unlock(); index_.Unlock(); query_node->points_.Unlock(); query_node->index_.Unlock(); query_node->kneighbors_.Unlock(); query_node->distances_.Unlock(); } TEMPLATE__ void KNN_NODE__::OutputNeighbors(NNResult *out, index_t knns) { kneighbors_.Lock(); distances_.Lock(); index_.Lock(); for(index_t i=0; i