131 PointND(
const Tfloat *xx_) { std::copy(xx_,xx_+ndim,
xx); }
159 typedef typename std::vector<NodeND>::iterator
iterator;
189 SortInPlace(data.begin(),data.end(),0);
195 data.emplace_back(pt, ii);
201 data.emplace_back(xx, ii);
207 PointS best_candidate;
208 best_candidate.sp=pt;
210 best_candidate.pos =0;
211 best_candidate.dist=Dist(data[0].pt, best_candidate.sp);
212 best_candidate.level=0;
213 PSearch(data.begin(), data.end(), 0, best_candidate);
214 return data[best_candidate.pos].ind;
225 PointS best_candidate;
226 best_candidate.sp=pt;
228 best_candidate.pos =0;
229 best_candidate.dist=Dist(data[0].pt, best_candidate.sp);
230 best_candidate.level=0;
231 PSearch(data.begin(), data.end(), 0, best_candidate);
233 clp=data[best_candidate.pos].pt;
234 return data[best_candidate.pos].ind;
248 PointS best_candidate;
249 best_candidate.sp=pt;
251 best_candidate.pos =0;
252 best_candidate.dist=Dist(data[0].pt, best_candidate.sp);
253 best_candidate.level=0;
254 PSearch(data.begin(), data.end(), 0, best_candidate);
256 ind=data[best_candidate.pos].ind;
257 dist=best_candidate.dist;
258 clp=data[best_candidate.pos].pt;
265 PointS best_candidate;
266 best_candidate.sp=pt;
268 best_candidate.pos =0;
269 best_candidate.dist=Dist(data[0].pt, best_candidate.sp);
271 for (
auto iti=data.begin()+1; iti!=data.end(); iti++)
273 dd=Dist(iti->pt, best_candidate.sp);
274 if (dd<best_candidate.dist)
276 best_candidate.pos=iti-data.begin();
277 best_candidate.dist=dd;
281 ind=data[best_candidate.pos].ind;
282 dist=best_candidate.dist;
288 std::vector<Tfloat> & dist)
302 std::vector<Tindex> &res,
303 std::vector<Tfloat> &dist)
306 for (
auto iti=data.begin(); iti!=data.end(); iti++)
308 dd=Dist(iti->pt, pt);
311 res.push_back(iti->ind);
319 std::vector<Tindex> &res)
322 for (
auto iti=data.begin(); iti!=data.end(); iti++)
324 dd=Dist(iti->pt, pt);
327 res.push_back(iti->ind);
342 CompN(std::uint8_t dd):
dim(dd) {}
345 bool operator() (
const PointND& p1,
const PointND& p2)
347 return p1.xx[
dim]<p2.xx[
dim];
351 bool operator() (
const NodeND& n1,
const NodeND& n2)
353 return n1.pt.xx[
dim]<n2.pt.xx[
dim];
361 Tfloat Dist(
const PointND &pt1,
const PointND &pt2)
const
363 for (
size_t i=0; i<ndim; i++)
365 tp.xx[i]=pt1.xx[i]-pt2.xx[i];
371 std::vector<NodeND> data;
375 Tfloat FindMedian(
typename std::vector<NodeND>::iterator itb,
376 typename std::vector<NodeND>::iterator ite,
380 std::nth_element(itb, itb+siz/2, ite, CompN(cdim));
381 return itb->pt.xx[cdim];
385 void SortInPlace(
typename std::vector<NodeND>::iterator itb,
386 typename std::vector<NodeND>::iterator ite,
389 std::uint8_t cdim=(std::uint8_t)(level%ndim);
393 std::nth_element(itb, itb+siz/2, ite, CompN(cdim));
395 SortInPlace(itb, itb+siz/2, level);
396 SortInPlace(itb+siz/2+1,ite, level);
411 void PSearch(
typename std::vector<NodeND>::const_iterator itb,
412 typename std::vector<NodeND>::const_iterator ite,
413 size_t level, PointS& bc)
const
415 std::uint8_t
dim=(std::uint8_t) (level%ndim);
417 typename std::vector<NodeND>::const_iterator mtb=itb+siz/2;
422 if ((bc.sp.xx[
dim]-bc.dist)>mtb->pt.xx[
dim])
424 PSearch(itb+siz/2+1, ite, level, bc);
426 else if ((bc.sp.xx[
dim]+bc.dist)<mtb->pt.xx[
dim])
428 PSearch(itb,itb+siz/2, level, bc);
432 if (bc.sp.xx[
dim]<mtb->pt.xx[
dim])
435 PSearch(itb,itb+siz/2, level, bc);
437 if (!((bc.sp.xx[
dim]+bc.dist)<mtb->pt.xx[
dim]))
439 PSearch(itb+siz/2+1, ite, level, bc);
442 Tfloat dd=Dist(mtb->pt, bc.sp);
445 bc.dist=dd; bc.pos=mtb-data.begin(); bc.level=level;
453 PSearch(itb+siz/2+1, ite, level, bc);
455 if (!((bc.sp.xx[
dim]-bc.dist)>mtb->pt.xx[
dim]))
457 PSearch(itb, itb+siz/2, level, bc);
460 Tfloat dd=Dist(mtb->pt, bc.sp);
463 bc.dist=dd; bc.pos=mtb-data.begin(); bc.level=level;
474 for (
auto it=itb; it!=ite; it++)
476 dd=Dist(it->pt, bc.sp);
479 bc.pos=it-data.begin();
488 void NNS(PointND& pt,
const int& npoints,
489 typename std::vector<NodeND>::iterator itb,
490 typename std::vector<NodeND>::iterator ite,
492 std::vector< std::tuple<Tfloat,Tindex> > & res)
const
494 std::uint8_t
dim=(std::uint8_t) (level%ndim);
496 typename std::vector<NodeND>::iterator mtb=itb+siz/2;
501 Tfloat R=std::get<0>(res[npoints-1]);
503 Tfloat dd=Dist(mtb->pt, pt);
506 res[npoints-1]=std::make_tuple(dd,mtb->ind);
507 std::nth_element(res.begin(), res.end()-1, res.end());
508 R=std::get<0>(res[npoints-1]);
510 if ((pt.xx[
dim]-R)>mtb->pt.xx[
dim])
512 NNS(pt, npoints, itb+siz/2+1, ite, level, res);
514 else if ((pt.xx[
dim]+R)<mtb->pt.xx[
dim])
516 NNS(pt, npoints, itb, itb+siz/2, level, res);
520 NNS(pt,npoints, itb+siz/2+1, ite, level, res);
521 NNS(pt,npoints, itb, itb+siz/2, level, res);
527 for (
auto it=itb; it!=ite; it++)
530 if (dd< std::get<0>(res[npoints-1]))
532 res[npoints-1]=std::make_tuple(dd,it->ind);
533 std::nth_element(res.begin(), res.end()-1, res.end());
541 typename std::vector<NodeND>::iterator itb,
542 typename std::vector<NodeND>::iterator ite,
544 std::vector<Tindex> & res)
const
546 std::uint8_t
dim=(std::uint8_t) (level%ndim);
548 typename std::vector<NodeND>::iterator mtb=itb+siz/2;
553 if ((pt.xx[
dim]-R)>mtb->pt.xx[
dim])
557 else if ((pt.xx[
dim]+R)<mtb->pt.xx[
dim])
567 Tfloat dd=Dist(mtb->pt, pt);
570 res.push_back(mtb->ind);
577 for (
auto it=itb; it!=ite; it++)
582 res.push_back(it->ind);
590 typename std::vector<NodeND>::iterator itb,
591 typename std::vector<NodeND>::iterator ite,
593 std::vector<Tindex> & res, std::vector<Tfloat> & dist)
const
595 std::uint8_t
dim=(std::uint8_t) (level%ndim);
597 typename std::vector<NodeND>::iterator mtb=itb+siz/2;
602 if ((pt.xx[
dim]-R)>mtb->pt.xx[
dim])
606 else if ((pt.xx[
dim]+R)<mtb->pt.xx[
dim])
616 Tfloat dd=Dist(mtb->pt, pt);
619 res.push_back(mtb->ind);
627 for (
auto it=itb; it!=ite; it++)
632 res.push_back(it->ind);