Added more modularity in the way the KD tree is built

This commit is contained in:
Guilhem Lavaux 2012-05-20 09:21:00 -04:00
parent e8d1edf453
commit 5fa5a73104
4 changed files with 62 additions and 46 deletions

View File

@ -5,6 +5,7 @@
#include <fstream> #include <fstream>
#define __KD_TREE_NUMNODES #define __KD_TREE_NUMNODES
#include "mykdtree.hpp" #include "mykdtree.hpp"
#include "kdtree_splitters.hpp"
#define NTRY 100 #define NTRY 100
#define ND 3 #define ND 3
@ -12,7 +13,7 @@
using namespace std; using namespace std;
using namespace CosmoTool; using namespace CosmoTool;
typedef KDTree<ND,char> MyTree; typedef KDTree<ND,char,ComputePrecision,KD_homogeneous_cell_splitter<ND, char> > MyTree;
typedef KDCell<ND,char> MyCell; typedef KDCell<ND,char> MyCell;
MyCell *findNearest(MyTree::coords& xc, MyCell *cells, uint32_t Ncells) MyCell *findNearest(MyTree::coords& xc, MyCell *cells, uint32_t Ncells)

View File

@ -217,7 +217,7 @@ namespace CosmoTool {
kdc[i] = c[i]; kdc[i] = c[i];
// It may happen that we are unlucky and have to iterate to farther // 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 do
{ {
uint32_t i; uint32_t i;

View File

@ -60,6 +60,7 @@ namespace CosmoTool {
uint32_t numCells; uint32_t numCells;
}; };
template<int N, typename ValType, typename CType = ComputePrecision> template<int N, typename ValType, typename CType = ComputePrecision>
class RecursionMultipleInfo class RecursionMultipleInfo
{ {
@ -77,6 +78,12 @@ namespace CosmoTool {
}; };
template<int N, typename ValType, typename CType = ComputePrecision> template<int N, typename ValType, typename CType = ComputePrecision>
struct KD_default_cell_splitter
{
void operator()(KDCell<N,ValType,CType> **cells, uint32_t Ncells, uint32_t& split_index, int axis, typename KDDef<N,CType>::KDCoordinates minBound, typename KDDef<N,CType>::KDCoordinates maxBound);
};
template<int N, typename ValType, typename CType = ComputePrecision, typename CellSplitter = KD_default_cell_splitter<N,ValType,CType> >
class KDTree class KDTree
{ {
public: public:
@ -85,6 +92,8 @@ namespace CosmoTool {
typedef KDCell<N,ValType,CType> Cell; typedef KDCell<N,ValType,CType> Cell;
typedef KDTreeNode<N,ValType,CType> Node; typedef KDTreeNode<N,ValType,CType> Node;
CellSplitter splitter;
KDTree(Cell *cells, uint32_t Ncells); KDTree(Cell *cells, uint32_t Ncells);
~KDTree(); ~KDTree();

View File

@ -23,13 +23,13 @@ namespace CosmoTool {
int rank; int rank;
}; };
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
KDTree<N,ValType,CType>::~KDTree() KDTree<N,ValType,CType,CellSplitter>::~KDTree()
{ {
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
KDTree<N,ValType,CType>::KDTree(Cell *cells, uint32_t Ncells) KDTree<N,ValType,CType,CellSplitter>::KDTree(Cell *cells, uint32_t Ncells)
{ {
base_cell = cells; base_cell = cells;
@ -43,8 +43,8 @@ namespace CosmoTool {
optimize(); optimize();
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
void KDTree<N,ValType,CType>::optimize() void KDTree<N,ValType,CType,CellSplitter>::optimize()
{ {
coords absoluteMin, absoluteMax; coords absoluteMin, absoluteMax;
@ -76,9 +76,9 @@ namespace CosmoTool {
std::cout << " done." << std::endl; std::cout << " done." << std::endl;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
uint32_t KDTree<N,ValType,CType>::getIntersection(const coords& x, CoordType r, uint32_t KDTree<N,ValType,CType,CellSplitter>::getIntersection(const coords& x, CoordType r,
KDTree<N,ValType,CType>::Cell **cells, KDTree<N,ValType,CType,CellSplitter>::Cell **cells,
uint32_t numCells) uint32_t numCells)
throw (NotEnoughCells) throw (NotEnoughCells)
{ {
@ -96,8 +96,8 @@ namespace CosmoTool {
return info.currentRank; return info.currentRank;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
uint32_t KDTree<N,ValType,CType>::getIntersection(const coords& x, CoordType r, uint32_t KDTree<N,ValType,CType,CellSplitter>::getIntersection(const coords& x, CoordType r,
Cell **cells, Cell **cells,
CoordType *distances, CoordType *distances,
uint32_t numCells) uint32_t numCells)
@ -117,8 +117,8 @@ namespace CosmoTool {
return info.currentRank; return info.currentRank;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
uint32_t KDTree<N,ValType,CType>::countCells(const coords& x, CoordType r) uint32_t KDTree<N,ValType,CType,CellSplitter>::countCells(const coords& x, CoordType r)
{ {
RecursionInfoCells<N,ValType> info; RecursionInfoCells<N,ValType> info;
@ -134,9 +134,9 @@ namespace CosmoTool {
return info.currentRank; return info.currentRank;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
template<bool justCount> template<bool justCount>
void KDTree<N,ValType,CType>::recursiveIntersectionCells(RecursionInfoCells<N,ValType,CType>& info, void KDTree<N,ValType,CType,CellSplitter>::recursiveIntersectionCells(RecursionInfoCells<N,ValType,CType>& info,
Node *node, Node *node,
int level) int level)
throw (NotEnoughCells) throw (NotEnoughCells)
@ -208,7 +208,16 @@ namespace CosmoTool {
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType>
KDTreeNode<N,ValType,CType> *KDTree<N,ValType,CType>::buildTree(Cell **cell0, void KD_default_cell_splitter<N,ValType,CType>::operator()(KDCell<N,ValType,CType> **cells, uint32_t Ncells, uint32_t& split_index, int axis, typename KDDef<N,CType>::KDCoordinates minBound, typename KDDef<N,CType>::KDCoordinates maxBound)
{
CellCompare<N,ValType,CType> compare(axis);
std::sort(cells, cells+Ncells, compare);
split_index = Ncells/2;
}
template<int N, typename ValType, typename CType, typename CellSplitter>
KDTreeNode<N,ValType,CType> *KDTree<N,ValType,CType,CellSplitter>::buildTree(Cell **cell0,
uint32_t Ncells, uint32_t Ncells,
uint32_t depth, uint32_t depth,
coords minBound, coords minBound,
@ -219,14 +228,11 @@ namespace CosmoTool {
int axis = depth % N; int axis = depth % N;
Node *node = &nodes[lastNode++]; Node *node = &nodes[lastNode++];
uint32_t mid = Ncells/2; uint32_t mid;
coords tmpBound; coords tmpBound;
// Isolate the environment // Isolate the environment
{ splitter(cell0, Ncells, mid, axis, minBound, maxBound);
CellCompare<N,ValType,CType> compare(axis);
std::sort(cell0, cell0+Ncells, compare);
}
node->value = *(cell0+mid); node->value = *(cell0+mid);
memcpy(&node->minBound[0], &minBound[0], sizeof(coords)); memcpy(&node->minBound[0], &minBound[0], sizeof(coords));
@ -252,8 +258,8 @@ namespace CosmoTool {
return node; return node;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
uint32_t KDTree<N,ValType,CType>::countActives() const uint32_t KDTree<N,ValType,CType,CellSplitter>::countActives() const
{ {
uint32_t numActive = 0; uint32_t numActive = 0;
for (uint32_t i = 0; i < lastNode; i++) for (uint32_t i = 0; i < lastNode; i++)
@ -264,9 +270,9 @@ namespace CosmoTool {
return numActive; return numActive;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
typename KDDef<N,CType>::CoordType typename KDDef<N,CType>::CoordType
KDTree<N,ValType,CType>::computeDistance(const Cell *cell, const coords& x) const KDTree<N,ValType,CType,CellSplitter>::computeDistance(const Cell *cell, const coords& x) const
{ {
CoordType d2 = 0; CoordType d2 = 0;
@ -278,9 +284,9 @@ namespace CosmoTool {
return d2; return d2;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
void void
KDTree<N,ValType,CType>::recursiveNearest( KDTree<N,ValType,CType,CellSplitter>::recursiveNearest(
Node *node, Node *node,
int level, int level,
const coords& x, const coords& x,
@ -352,9 +358,9 @@ namespace CosmoTool {
} }
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
KDCell<N,ValType,CType> * KDCell<N,ValType,CType> *
KDTree<N,ValType,CType>::getNearestNeighbour(const coords& x) KDTree<N,ValType,CType,CellSplitter>::getNearestNeighbour(const coords& x)
{ {
CoordType R2 = INFINITY; CoordType R2 = INFINITY;
Cell *best = 0; Cell *best = 0;
@ -364,9 +370,9 @@ namespace CosmoTool {
return best; return best;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
void void
KDTree<N,ValType,CType>::recursiveMultipleNearest(RecursionMultipleInfo<N,ValType,CType>& info, Node *node, KDTree<N,ValType,CType,CellSplitter>::recursiveMultipleNearest(RecursionMultipleInfo<N,ValType,CType>& info, Node *node,
int level) int level)
{ {
CoordType d2 = 0; CoordType d2 = 0;
@ -421,8 +427,8 @@ namespace CosmoTool {
} }
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
void KDTree<N,ValType,CType>::getNearestNeighbours(const coords& x, uint32_t N2, void KDTree<N,ValType,CType,CellSplitter>::getNearestNeighbours(const coords& x, uint32_t N2,
Cell **cells) Cell **cells)
{ {
RecursionMultipleInfo<N,ValType> info(x, cells, N2); RecursionMultipleInfo<N,ValType> info(x, cells, N2);
@ -435,8 +441,8 @@ namespace CosmoTool {
// std::cout << "Traversed = " << info.traversed << std::endl; // std::cout << "Traversed = " << info.traversed << std::endl;
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
void KDTree<N,ValType,CType>::getNearestNeighbours(const coords& x, uint32_t N2, void KDTree<N,ValType,CType,CellSplitter>::getNearestNeighbours(const coords& x, uint32_t N2,
Cell **cells, Cell **cells,
CoordType *distances) CoordType *distances)
{ {
@ -470,8 +476,8 @@ namespace CosmoTool {
long rootId; long rootId;
}; };
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
void KDTree<N,ValType,CType>::saveTree(std::ostream& o) const void KDTree<N,ValType,CType,CellSplitter>::saveTree(std::ostream& o) const
{ {
KDTreeHeader h; KDTreeHeader h;
@ -505,8 +511,8 @@ namespace CosmoTool {
} }
} }
template<int N, typename ValType, typename CType> template<int N, typename ValType, typename CType, typename CellSplitter>
KDTree<N,ValType,CType>::KDTree(std::istream& in, Cell *cells, uint32_t Ncells) KDTree<N,ValType,CType,CellSplitter>::KDTree(std::istream& in, Cell *cells, uint32_t Ncells)
throw (InvalidOnDiskKDTree) throw (InvalidOnDiskKDTree)
{ {
KDTreeHeader h; KDTreeHeader h;