diff --git a/sample/testkd2.cpp b/sample/testkd2.cpp index 0226ba0..2b79408 100644 --- a/sample/testkd2.cpp +++ b/sample/testkd2.cpp @@ -5,6 +5,7 @@ #include #define __KD_TREE_NUMNODES #include "mykdtree.hpp" +#include "kdtree_splitters.hpp" #define NTRY 100 #define ND 3 @@ -12,7 +13,7 @@ using namespace std; using namespace CosmoTool; -typedef KDTree MyTree; +typedef KDTree > MyTree; typedef KDCell MyCell; MyCell *findNearest(MyTree::coords& xc, MyCell *cells, uint32_t Ncells) diff --git a/src/dinterpolate.tcc b/src/dinterpolate.tcc index ecd04ae..58e7dfb 100644 --- a/src/dinterpolate.tcc +++ b/src/dinterpolate.tcc @@ -217,7 +217,7 @@ namespace CosmoTool { kdc[i] = c[i]; // It may happen that we are unlucky and have to iterate to farther - // neighbors. It should happen, especially on the boundaries. + // neighbors. It is bound to happen, especially on the boundaries. do { uint32_t i; diff --git a/src/mykdtree.hpp b/src/mykdtree.hpp index d661376..c2087b5 100644 --- a/src/mykdtree.hpp +++ b/src/mykdtree.hpp @@ -59,6 +59,7 @@ namespace CosmoTool { uint32_t currentRank; uint32_t numCells; }; + template class RecursionMultipleInfo @@ -76,7 +77,13 @@ namespace CosmoTool { } }; - template + template + struct KD_default_cell_splitter + { + void operator()(KDCell **cells, uint32_t Ncells, uint32_t& split_index, int axis, typename KDDef::KDCoordinates minBound, typename KDDef::KDCoordinates maxBound); + }; + + template > class KDTree { public: @@ -84,6 +91,8 @@ namespace CosmoTool { typedef typename KDDef::KDCoordinates coords; typedef KDCell Cell; typedef KDTreeNode Node; + + CellSplitter splitter; KDTree(Cell *cells, uint32_t Ncells); ~KDTree(); diff --git a/src/mykdtree.tcc b/src/mykdtree.tcc index 9899d60..6f5eebf 100644 --- a/src/mykdtree.tcc +++ b/src/mykdtree.tcc @@ -23,13 +23,13 @@ namespace CosmoTool { int rank; }; - template - KDTree::~KDTree() + template + KDTree::~KDTree() { } - template - KDTree::KDTree(Cell *cells, uint32_t Ncells) + template + KDTree::KDTree(Cell *cells, uint32_t Ncells) { base_cell = cells; @@ -43,8 +43,8 @@ namespace CosmoTool { optimize(); } - template - void KDTree::optimize() + template + void KDTree::optimize() { coords absoluteMin, absoluteMax; @@ -76,9 +76,9 @@ namespace CosmoTool { std::cout << " done." << std::endl; } - template - uint32_t KDTree::getIntersection(const coords& x, CoordType r, - KDTree::Cell **cells, + template + uint32_t KDTree::getIntersection(const coords& x, CoordType r, + KDTree::Cell **cells, uint32_t numCells) throw (NotEnoughCells) { @@ -96,8 +96,8 @@ namespace CosmoTool { return info.currentRank; } - template - uint32_t KDTree::getIntersection(const coords& x, CoordType r, + template + uint32_t KDTree::getIntersection(const coords& x, CoordType r, Cell **cells, CoordType *distances, uint32_t numCells) @@ -117,8 +117,8 @@ namespace CosmoTool { return info.currentRank; } - template - uint32_t KDTree::countCells(const coords& x, CoordType r) + template + uint32_t KDTree::countCells(const coords& x, CoordType r) { RecursionInfoCells info; @@ -134,9 +134,9 @@ namespace CosmoTool { return info.currentRank; } - template + template template - void KDTree::recursiveIntersectionCells(RecursionInfoCells& info, + void KDTree::recursiveIntersectionCells(RecursionInfoCells& info, Node *node, int level) throw (NotEnoughCells) @@ -208,25 +208,31 @@ namespace CosmoTool { } template - KDTreeNode *KDTree::buildTree(Cell **cell0, - uint32_t Ncells, - uint32_t depth, - coords minBound, - coords maxBound) + void KD_default_cell_splitter::operator()(KDCell **cells, uint32_t Ncells, uint32_t& split_index, int axis, typename KDDef::KDCoordinates minBound, typename KDDef::KDCoordinates maxBound) + { + CellCompare compare(axis); + std::sort(cells, cells+Ncells, compare); + split_index = Ncells/2; + } + + + template + KDTreeNode *KDTree::buildTree(Cell **cell0, + uint32_t Ncells, + uint32_t depth, + coords minBound, + coords maxBound) { if (Ncells == 0) return 0; int axis = depth % N; Node *node = &nodes[lastNode++]; - uint32_t mid = Ncells/2; + uint32_t mid; coords tmpBound; // Isolate the environment - { - CellCompare compare(axis); - std::sort(cell0, cell0+Ncells, compare); - } + splitter(cell0, Ncells, mid, axis, minBound, maxBound); node->value = *(cell0+mid); memcpy(&node->minBound[0], &minBound[0], sizeof(coords)); @@ -252,8 +258,8 @@ namespace CosmoTool { return node; } - template - uint32_t KDTree::countActives() const + template + uint32_t KDTree::countActives() const { uint32_t numActive = 0; for (uint32_t i = 0; i < lastNode; i++) @@ -264,9 +270,9 @@ namespace CosmoTool { return numActive; } - template + template typename KDDef::CoordType - KDTree::computeDistance(const Cell *cell, const coords& x) const + KDTree::computeDistance(const Cell *cell, const coords& x) const { CoordType d2 = 0; @@ -278,9 +284,9 @@ namespace CosmoTool { return d2; } - template + template void - KDTree::recursiveNearest( + KDTree::recursiveNearest( Node *node, int level, const coords& x, @@ -352,9 +358,9 @@ namespace CosmoTool { } } - template + template KDCell * - KDTree::getNearestNeighbour(const coords& x) + KDTree::getNearestNeighbour(const coords& x) { CoordType R2 = INFINITY; Cell *best = 0; @@ -364,9 +370,9 @@ namespace CosmoTool { return best; } - template + template void - KDTree::recursiveMultipleNearest(RecursionMultipleInfo& info, Node *node, + KDTree::recursiveMultipleNearest(RecursionMultipleInfo& info, Node *node, int level) { CoordType d2 = 0; @@ -421,8 +427,8 @@ namespace CosmoTool { } } - template - void KDTree::getNearestNeighbours(const coords& x, uint32_t N2, + template + void KDTree::getNearestNeighbours(const coords& x, uint32_t N2, Cell **cells) { RecursionMultipleInfo info(x, cells, N2); @@ -435,8 +441,8 @@ namespace CosmoTool { // std::cout << "Traversed = " << info.traversed << std::endl; } - template - void KDTree::getNearestNeighbours(const coords& x, uint32_t N2, + template + void KDTree::getNearestNeighbours(const coords& x, uint32_t N2, Cell **cells, CoordType *distances) { @@ -470,8 +476,8 @@ namespace CosmoTool { long rootId; }; - template - void KDTree::saveTree(std::ostream& o) const + template + void KDTree::saveTree(std::ostream& o) const { KDTreeHeader h; @@ -505,8 +511,8 @@ namespace CosmoTool { } } - template - KDTree::KDTree(std::istream& in, Cell *cells, uint32_t Ncells) + template + KDTree::KDTree(std::istream& in, Cell *cells, uint32_t Ncells) throw (InvalidOnDiskKDTree) { KDTreeHeader h;