More type parametrization

This commit is contained in:
Guilhem Lavaux 2009-02-03 19:00:46 -06:00
parent 44f9f29bf6
commit 4bd956e41f
2 changed files with 108 additions and 110 deletions

View File

@ -7,20 +7,19 @@
namespace CosmoTool { namespace CosmoTool {
template<int N> template<int N, typename CType = ComputePrecision>
struct KDDef struct KDDef
{ {
typedef float CoordType; typedef CType CoordType;
typedef float KDCoordinates[N]; typedef float KDCoordinates[N];
static const int NumCubes = 1 << (N);
}; };
template<int N, typename ValType> template<int N, typename ValType, typename CType = ComputePrecision>
struct KDCell struct KDCell
{ {
bool active; bool active;
ValType val; ValType val;
typename KDDef<N>::KDCoordinates coord; typename KDDef<N,CType>::KDCoordinates coord;
}; };
class NotEnoughCells: public Exception class NotEnoughCells: public Exception
@ -30,114 +29,113 @@ namespace CosmoTool {
~NotEnoughCells() throw () {} ~NotEnoughCells() throw () {}
}; };
template<int N, typename ValType> template<int N, typename ValType, typename CType = ComputePrecision>
struct KDTreeNode struct KDTreeNode
{ {
KDCell<N,ValType> *value; KDCell<N,ValType,CType> *value;
KDTreeNode<N,ValType> *children[2]; KDTreeNode<N,ValType,CType> *children[2];
typename KDDef<N>::KDCoordinates minBound, maxBound; typename KDDef<N,CType>::KDCoordinates minBound, maxBound;
}; };
template<int N, typename ValType> template<int N, typename ValType, typename CType = ComputePrecision>
class RecursionInfoCells class RecursionInfoCells
{ {
public: public:
typename KDDef<N>::KDCoordinates x; typename KDDef<N,CType>::KDCoordinates x;
typename KDDef<N>::CoordType r, r2; typename KDDef<N,CType>::CoordType r, r2;
KDCell<N, ValType> **cells; KDCell<N, ValType,CType> **cells;
typename KDDef<N>::CoordType *distances; typename KDDef<N,CType>::CoordType *distances;
uint32_t currentRank; uint32_t currentRank;
uint32_t numCells; uint32_t numCells;
}; };
template<int N, typename ValType> template<int N, typename ValType, typename CType = ComputePrecision>
class RecursionMultipleInfo class RecursionMultipleInfo
{ {
public: public:
const typename KDDef<N>::KDCoordinates& x; const typename KDDef<N,CType>::KDCoordinates& x;
BoundedQueue< KDCell<N,ValType> *, typename KDDef<N>::CoordType> queue; BoundedQueue< KDCell<N,ValType,CType> *, typename KDDef<N,CType>::CoordType> queue;
int traversed; int traversed;
RecursionMultipleInfo(const typename KDDef<N>::KDCoordinates& rx, RecursionMultipleInfo(const typename KDDef<N,CType>::KDCoordinates& rx,
KDCell<N,ValType> **cells, KDCell<N,ValType,CType> **cells,
uint32_t numCells) uint32_t numCells)
: x(rx), queue(cells, numCells, INFINITY),traversed(0) : x(rx), queue(cells, numCells, INFINITY),traversed(0)
{ {
} }
}; };
template<int N, typename ValType> template<int N, typename ValType, typename CType = ComputePrecision>
class KDTree class KDTree
{ {
public: public:
static const int NumCubes = KDDef<N>::NumCubes; typedef typename KDDef<N,CType>::CoordType CoordType;
public:
typedef typename KDDef<N>::CoordType CoordType;
typedef typename KDDef<N>::KDCoordinates coords; typedef typename KDDef<N>::KDCoordinates coords;
typedef KDCell<N,ValType,CType> Cell;
typedef KDTreeNode<N,ValType,CType> Node;
KDTree(KDCell<N,ValType> *cells, uint32_t Ncells); KDTree(Cell *cells, uint32_t Ncells);
~KDTree(); ~KDTree();
uint32_t getIntersection(const coords& x, CoordType r, uint32_t getIntersection(const coords& x, CoordType r,
KDCell<N, ValType> **cells, Cell **cells,
uint32_t numCells) uint32_t numCells)
throw (NotEnoughCells); throw (NotEnoughCells);
uint32_t getIntersection(const coords& x, CoordType r, uint32_t getIntersection(const coords& x, CoordType r,
KDCell<N, ValType> **cells, Cell **cells,
CoordType *distances, CoordType *distances,
uint32_t numCells) uint32_t numCells)
throw (NotEnoughCells); throw (NotEnoughCells);
KDCell<N, ValType> *getNearestNeighbour(const coords& x); Cell *getNearestNeighbour(const coords& x);
void getNearestNeighbours(const coords& x, uint32_t N, void getNearestNeighbours(const coords& x, uint32_t N,
KDCell<N, ValType> **cells); Cell **cells);
void getNearestNeighbours(const coords& x, uint32_t N, void getNearestNeighbours(const coords& x, uint32_t N,
KDCell<N, ValType> **cells, Cell **cells,
CoordType *distances); CoordType *distances);
KDTreeNode<N,ValType> *getRoot() { return root; } Node *getRoot() { return root; }
void optimize(); void optimize();
KDTreeNode<N,ValType> *getAllNodes() { return nodes; } Node *getAllNodes() { return nodes; }
uint32_t getNumNodes() const { return lastNode; } uint32_t getNumNodes() const { return lastNode; }
uint32_t countActives() const; uint32_t countActives() const;
protected: protected:
KDTreeNode<N, ValType> *nodes; Node *nodes;
uint32_t numNodes; uint32_t numNodes;
uint32_t lastNode; uint32_t lastNode;
KDTreeNode<N, ValType> *root; Node *root;
KDCell<N, ValType> **sortingHelper; Cell **sortingHelper;
KDTreeNode<N, ValType> *buildTree(KDCell<N,ValType> **cell0, Node *buildTree(Cell **cell0,
uint32_t N, uint32_t N,
uint32_t depth, uint32_t depth,
coords minBound, coords minBound,
coords maxBound); coords maxBound);
void recursiveIntersectionCells(RecursionInfoCells<N,ValType>& info, void recursiveIntersectionCells(RecursionInfoCells<N,ValType, CType>& info,
KDTreeNode<N,ValType> *node, Node *node,
int level) int level)
throw (NotEnoughCells); throw (NotEnoughCells);
CoordType computeDistance(KDCell<N,ValType> *cell, const coords& x); CoordType computeDistance(Cell *cell, const coords& x);
void recursiveNearest(KDTreeNode<N, ValType> *node, void recursiveNearest(Node *node,
int level, int level,
const coords& x, const coords& x,
CoordType& R2, CoordType& R2,
KDCell<N,ValType>*& cell); Cell*& cell);
void recursiveMultipleNearest(RecursionMultipleInfo<N,ValType>& info, KDTreeNode<N,ValType> *node, void recursiveMultipleNearest(RecursionMultipleInfo<N,ValType,CType>& info, Node *node,
int level); int level);
}; };
template<int N, class T> template<int N, typename T, typename CType>
uint32_t gatherActiveCells(KDCell<N,T> **cells, uint32_t numCells); uint32_t gatherActiveCells(KDCell<N,T,CType> **cells, uint32_t numCells);
}; };

View File

@ -5,7 +5,7 @@
namespace CosmoTool { namespace CosmoTool {
template<int N, typename ValType> template<int N, typename ValType, typename CType>
class CellCompare class CellCompare
{ {
public: public:
@ -14,7 +14,7 @@ namespace CosmoTool {
rank = k; rank = k;
} }
bool operator()(const KDCell<N,ValType> *a, const KDCell<N,ValType> *b) const bool operator()(const KDCell<N,ValType,CType> *a, const KDCell<N,ValType,CType> *b) const
{ {
return (a->coord[rank] < b->coord[rank]); return (a->coord[rank] < b->coord[rank]);
} }
@ -22,27 +22,27 @@ namespace CosmoTool {
int rank; int rank;
}; };
template<int N, typename ValType> template<int N, typename ValType, typename CType>
KDTree<N,ValType>::~KDTree() KDTree<N,ValType,CType>::~KDTree()
{ {
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
KDTree<N,ValType>::KDTree(KDCell<N,ValType> *cells, uint32_t Ncells) KDTree<N,ValType,CType>::KDTree(Cell *cells, uint32_t Ncells)
{ {
numNodes = Ncells; numNodes = Ncells;
nodes = new KDTreeNode<N,ValType>[numNodes]; nodes = new Node[numNodes];
sortingHelper = new KDCell<N,ValType> *[Ncells]; sortingHelper = new Cell *[Ncells];
for (uint32_t i = 0; i < Ncells; i++) for (uint32_t i = 0; i < Ncells; i++)
sortingHelper[i] = &cells[i]; sortingHelper[i] = &cells[i];
optimize(); optimize();
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
void KDTree<N,ValType>::optimize() void KDTree<N,ValType,CType>::optimize()
{ {
coords absoluteMin, absoluteMax; coords absoluteMin, absoluteMax;
@ -62,13 +62,13 @@ namespace CosmoTool {
std::cout << " done." << std::endl; std::cout << " done." << std::endl;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
uint32_t KDTree<N,ValType>::getIntersection(const coords& x, CoordType r, uint32_t KDTree<N,ValType,CType>::getIntersection(const coords& x, CoordType r,
KDCell<N, ValType> **cells, KDTree<N,ValType,CType>::Cell **cells,
uint32_t numCells) uint32_t numCells)
throw (NotEnoughCells) throw (NotEnoughCells)
{ {
RecursionInfoCells<N,ValType> info; RecursionInfoCells<N,ValType,CType> info;
memcpy(info.x, x, sizeof(x)); memcpy(info.x, x, sizeof(x));
info.r = r; info.r = r;
@ -82,11 +82,11 @@ namespace CosmoTool {
return info.currentRank; return info.currentRank;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
uint32_t KDTree<N,ValType>::getIntersection(const coords& x, CoordType r, uint32_t KDTree<N,ValType,CType>::getIntersection(const coords& x, CoordType r,
KDCell<N, ValType> **cells, Cell **cells,
CoordType *distances, CoordType *distances,
uint32_t numCells) uint32_t numCells)
throw (NotEnoughCells) throw (NotEnoughCells)
{ {
RecursionInfoCells<N,ValType> info; RecursionInfoCells<N,ValType> info;
@ -103,10 +103,10 @@ namespace CosmoTool {
return info.currentRank; return info.currentRank;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
void KDTree<N,ValType>::recursiveIntersectionCells(RecursionInfoCells<N,ValType>& info, void KDTree<N,ValType,CType>::recursiveIntersectionCells(RecursionInfoCells<N,ValType,CType>& info,
KDTreeNode<N,ValType> *node, Node *node,
int level) int level)
throw (NotEnoughCells) throw (NotEnoughCells)
{ {
int axis = level % N; int axis = level % N;
@ -147,9 +147,9 @@ namespace CosmoTool {
} }
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
uint32_t gatherActiveCells(KDCell<N,ValType> **cells, uint32_t gatherActiveCells(KDCell<N,ValType,CType> **cells,
uint32_t Ncells) uint32_t Ncells)
{ {
uint32_t swapId = Ncells-1; uint32_t swapId = Ncells-1;
uint32_t i = 0; uint32_t i = 0;
@ -172,24 +172,24 @@ namespace CosmoTool {
return swapId+1; return swapId+1;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
KDTreeNode<N, ValType> *KDTree<N,ValType>::buildTree(KDCell<N,ValType> **cell0, KDTreeNode<N,ValType,CType> *KDTree<N,ValType,CType>::buildTree(Cell **cell0,
uint32_t Ncells, uint32_t Ncells,
uint32_t depth, uint32_t depth,
coords minBound, coords minBound,
coords maxBound) coords maxBound)
{ {
if (Ncells == 0) if (Ncells == 0)
return 0; return 0;
int axis = depth % N; int axis = depth % N;
KDTreeNode<N,ValType> *node = &nodes[lastNode++]; Node *node = &nodes[lastNode++];
uint32_t mid = Ncells/2; uint32_t mid = Ncells/2;
coords tmpBound; coords tmpBound;
// Isolate the environment // Isolate the environment
{ {
CellCompare<N,ValType> compare(axis); CellCompare<N,ValType,CType> compare(axis);
std::sort(cell0, cell0+Ncells, compare); std::sort(cell0, cell0+Ncells, compare);
} }
@ -211,8 +211,8 @@ namespace CosmoTool {
return node; return node;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
uint32_t KDTree<N,ValType>::countActives() const uint32_t KDTree<N,ValType,CType>::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++)
@ -223,9 +223,9 @@ namespace CosmoTool {
return numActive; return numActive;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
typename KDDef<N>::CoordType typename KDDef<N,CType>::CoordType
KDTree<N,ValType>::computeDistance(KDCell<N, ValType> *cell, const coords& x) KDTree<N,ValType,CType>::computeDistance(Cell *cell, const coords& x)
{ {
CoordType d2 = 0; CoordType d2 = 0;
@ -237,18 +237,18 @@ namespace CosmoTool {
return d2; return d2;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
void void
KDTree<N,ValType>::recursiveNearest( KDTree<N,ValType,CType>::recursiveNearest(
KDTreeNode<N,ValType> *node, Node *node,
int level, int level,
const coords& x, const coords& x,
CoordType& R2, CoordType& R2,
KDCell<N,ValType> *& best) Cell *& best)
{ {
CoordType d2 = 0; CoordType d2 = 0;
int axis = level % N; int axis = level % N;
KDTreeNode<N,ValType> *other, *go; Node *other, *go;
if (x[axis] < node->value->coord[axis]) if (x[axis] < node->value->coord[axis])
{ {
@ -311,26 +311,26 @@ namespace CosmoTool {
} }
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
KDCell<N, ValType> * KDCell<N,ValType,CType> *
KDTree<N,ValType>::getNearestNeighbour(const coords& x) KDTree<N,ValType,CType>::getNearestNeighbour(const coords& x)
{ {
CoordType R2 = INFINITY; CoordType R2 = INFINITY;
KDCell<N,ValType> *best = 0; Cell *best = 0;
recursiveNearest(root, 0, x, R2, best); recursiveNearest(root, 0, x, R2, best);
return best; return best;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
void void
KDTree<N,ValType>::recursiveMultipleNearest(RecursionMultipleInfo<N,ValType>& info, KDTreeNode<N,ValType> *node, KDTree<N,ValType,CType>::recursiveMultipleNearest(RecursionMultipleInfo<N,ValType,CType>& info, Node *node,
int level) int level)
{ {
CoordType d2 = 0; CoordType d2 = 0;
int axis = level % N; int axis = level % N;
KDTreeNode<N,ValType> *other, *go; Node *other, *go;
if (info.x[axis] < node->value->coord[axis]) if (info.x[axis] < node->value->coord[axis])
{ {
@ -380,9 +380,9 @@ namespace CosmoTool {
} }
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
void KDTree<N,ValType>::getNearestNeighbours(const coords& x, uint32_t N2, void KDTree<N,ValType,CType>::getNearestNeighbours(const coords& x, uint32_t N2,
KDCell<N, ValType> **cells) Cell **cells)
{ {
RecursionMultipleInfo<N,ValType> info(x, cells, N2); RecursionMultipleInfo<N,ValType> info(x, cells, N2);
@ -391,13 +391,13 @@ namespace CosmoTool {
recursiveMultipleNearest(info, root, 0); recursiveMultipleNearest(info, root, 0);
std::cout << "Traversed = " << info.traversed << std::endl; // std::cout << "Traversed = " << info.traversed << std::endl;
} }
template<int N, typename ValType> template<int N, typename ValType, typename CType>
void KDTree<N,ValType>::getNearestNeighbours(const coords& x, uint32_t N2, void KDTree<N,ValType,CType>::getNearestNeighbours(const coords& x, uint32_t N2,
KDCell<N, ValType> **cells, Cell **cells,
CoordType *distances) CoordType *distances)
{ {
RecursionMultipleInfo<N,ValType> info(x, cells, N2); RecursionMultipleInfo<N,ValType> info(x, cells, N2);
@ -405,9 +405,9 @@ namespace CosmoTool {
cells[i] = 0; cells[i] = 0;
recursiveMultipleNearest(info, root, 0); recursiveMultipleNearest(info, root, 0);
memcpy(distances, info.getPriorities(), sizeof(CoordType)*N2); memcpy(distances, info.queue.getPriorities(), sizeof(CoordType)*N2);
std::cout << "Traversed = " << info.traversed << std::endl; // std::cout << "Traversed = " << info.traversed << std::endl;
} }
}; };