Proto
Proto_Morton.H
1 #ifndef _PROTO_MORTON_H_
2 #define _PROTO_MORTON_H_
3 #include <array>
4 #include <cstdint>
5 #include <algorithm>
6 #include "Proto_Point.H"
7 using namespace std;
8 #if DIM==2
9 #define LOGSIZE 16 // 21 // DIM*LOGSIZE must be less than the size (in bits) of (uint64_t).
10 #define MORTONSIZE 65536 // 2097152 // = 2^LOGSIZE.
11 #endif
12 #if DIM==3
13 #define LOGSIZE 10 // DIM*LOGSIZE must be less than the size (in bits) of (uint64_t).
14 #define MORTONSIZE 1024 // = 2^LOGSIZE.
15 #endif
16 #if DIM==4
17 #define LOGSIZE 16 // DIM*LOGSIZE must be less than the size (in bits) of (uint64_t).
18 #define MORTONSIZE 65536 // = 2^LOGSIZE.
19 #endif
20 #if DIM==5
21 #define LOGSIZE 12 // DIM*LOGSIZE must be less than the size (in bits) of (uint64_t).
22 #define MORTONSIZE 4096 // = 2^LOGSIZE.
23 #endif
24 #if DIM==6
25 #define LOGSIZE 10 // DIM*LOGSIZE must be less than the size (in bits) of (uint64_t).
26 #define MORTONSIZE 1024 // = 2^LOGSIZE.
27 #endif
28 /*
29 Class for computing Morton Index of a DIM-tuple corresponding to the
30 bits of each element of the tuple.
31 */
32 namespace Proto
33 {
34  class Morton
35  {
36  public:
37 #if DIM > 1
38 #if DIM < 7
39  array<vector<uint64_t>,DIM> m_morton1D;
40 #endif
41 #endif
42  Morton()
43  {
44  PR_TIMERS("Morton define");
45  PR_assert(DIM < 7);
46  for (int d = 0; d < DIM; d++)
47  {
48  m_morton1D[d]=vector<uint64_t>(MORTONSIZE);
49  }
50 #if DIM > 1
51  uint64_t mask0 = 1;
52  for (uint64_t i = 0; i <MORTONSIZE; i++)
53  {
54  for (uint64_t d = 0; d < DIM;d++)
55  {
56  m_morton1D[d][i] = 0;
57  }
58  for (uint64_t logi = 0; logi < LOGSIZE; logi++)
59  {
60  for (uint64_t d = 0;d < DIM; d++)
61  {
62  m_morton1D[d][i] +=
63  ((i >> logi) & mask0) << (DIM*logi + d);
64  }
65  }
66  }
67  };
68 #endif
69 };
70 // Function that computes the Morton index corresponding to the input Point.
71 
72  inline uint64_t mortonIndex(const Point& a_pt,const Morton& m_morton)
73  {
74  uint64_t retval = 0;
75  // PR_assert((a_pt%(Point::Ones()*MORTONSIZE)) == a_pt);
76  // We are enforcing the condition that the Morton index can be computed.
77 #if DIM > 1
78  for (int d = 0; d < DIM; d++)
79  {
80  retval +=m_morton.m_morton1D[d][a_pt[d]];
81  // retval += s_morton1D[d][a_pt[d]%MORTONSIZE]; Used for many-to-one Morton index.
82  }
83 #else
84  retval = a_pt[0];
85 #endif
86  return retval;
87  }
88  //static uint64_t operator()(const Point& a_pt) const {return index(a_pt);}
89  inline bool compareSecond(pair<Point,uint64_t> a_a,pair<Point,uint64_t> a_b)
90  {return a_a.second < a_b.second;}
91  inline void mortonSort(vector<Point>& a_pts, const Morton& m_morton)
92  {
93  vector<pair<Point,uint64_t> > sorter;
94  for (int k = 0; k < a_pts.size();++k)
95  {
96  sorter.push_back(pair<Point,uint64_t>
97  (a_pts[k],mortonIndex(a_pts[k],m_morton)));
98  }
99 
100  std::sort(sorter.begin(),sorter.end(),compareSecond);
101  for (int k = 0; k < sorter.size();++k)
102  {
103  a_pts[k] = sorter[k].first;
104  }
105  }
106 }// end Proto namespace.
107 #endif
Definition: Proto_Box.H:11