4#include "../myAssert.h"
5#include "../indices/index.h"
6#include "MultiDepthHashCellStructure.h"
11class Static_CellOneD {
14 inline static double coordinate(indexInteger index);
17 inline static indexInteger nextRight(indexInteger index,
int level);
19 inline static indexInteger nextLeft(indexInteger index,
int level);
24 inline static int depth(indexInteger index);
26 inline static indexInteger father(
const indexInteger index);
28 inline static indexInteger leftSon(
const indexInteger index);
30 inline static indexInteger rightSon(
const indexInteger index);
32 inline static indexInteger nextLeft(indexInteger index);
33 inline static indexInteger nextRight(indexInteger index);
41 inline static int internDepth(indexInteger index);
45class CellOneD :
private Static_CellOneD {
51 inline CellOneD(indexInteger ind) : index(ind) {};
63 inline CellOneD nextLeft();
66 inline CellOneD nextRight();
74 inline CellOneD nextRightLevel(
int level);
77 inline double coordinate();
79 indexInteger getInteger()
const {
return index; }
89#if __cplusplus >= 202002L
90inline int Static_CellOneD::depth(indexInteger index) {
91 return std::bit_width(index>>1);
104inline int Static_CellOneD::depth(indexInteger index) {
105 static_assert(
sizeof(indexInteger) == 4,
106 "__builtin_clz only works for ints or compile with cpp20 support");
107 if(index==0)
return 0;
108 return __builtin_clz(index) ^ 31;
112inline int CellOneD::depth() {
113 return Static_CellOneD::depth(index);
117double Static_CellOneD::coordinate(indexInteger index) {
130 if(index==0)
return 0;
131 int d = depth(index);
134 double h = 1.0/double(POW2(d));
136 indexInteger n= subtractFirstBit(index);
138 return double(2*n+1)*h;
142double CellOneD::coordinate() {
143 return Static_CellOneD::coordinate(index);
146#if __cplusplus >= 202002L
147indexInteger Static_CellOneD::nextRight(indexInteger index) {
149 if(index==~(1<<(
sizeof(index)*8-1)))
return 0;
150 return index >> (std::countr_one(index)+1);
154indexInteger Static_CellOneD::nextRight(indexInteger index) {
156 static_assert(
sizeof(indexInteger) == 4,
157 "__builtin_ctz only works for ints or compile with cpp20 support");
158 unsigned inverted = ~index;
159 unsigned firstRight = __builtin_ctz(inverted);
160 return index >> (firstRight + 1 );
164CellOneD CellOneD::nextRight() {
165 return CellOneD(Static_CellOneD::nextRight(index));
168#if __cplusplus >= 202002L
169indexInteger Static_IndexOneD::nextLeft(indexInteger index) {
170 if(index==(1<<(
sizeof(index)*8-1)))
172 return index >> (std::countr_zero(index)+1);
176indexInteger Static_CellOneD::nextLeft(indexInteger index) {
177 static_assert(
sizeof(indexInteger) == 4,
178 "__builtin_ctz only works for ints or compile with cpp20 support");
179 unsigned firstRight = __builtin_ctz(index);
180 return index >> (firstRight + 1 );
184CellOneD CellOneD::nextLeft() {
185 return CellOneD(Static_CellOneD::nextLeft(index));
188inline int Static_CellOneD::internDepth(indexInteger index) {
189 if(index==0)
return -1;
190 return (
sizeof(index)<<3) - __builtin_clz(index) - 1;
200indexInteger Static_CellOneD::nextRight(indexInteger index,
int level) {
201 int myDepth = internDepth(index);
203 level = level - myDepth;
206 if(level==0)
return nextRight(index);
207 index = (index << 1) + 1;
208 for(
int i=1;i<level;++i) {
214indexInteger Static_CellOneD::nextLeft(indexInteger index,
int level) {
215 int myDepth = depth(index);
217 level = level - myDepth;
220 if(level==0)
return nextLeft(index);
222 for(
int i=1;i<level;++i) {
223 index = (index << 1) + 1;
229CellOneD CellOneD::nextRightLevel(
int level) {
230 indexInteger indexRight = Static_CellOneD::nextRight(index,level);
231 return CellOneD(Static_CellOneD::nextRight(indexRight,level));
235class CellDimension :
private Static_CellOneD {
237 inline CellDimension();
240 inline indexInteger getIndex(
int d)
const;
242 inline int getDepth(
int d)
const;
244 inline bool operator==(
const CellDimension I)
const;
246 inline double coordinate(
int d)
const;
248 inline CellDimension nextLeftLevel(
int d,
int level);
250 inline CellDimension nextRightLevel(
int d,
int level);
252 inline void replace(
int d, indexInteger newIndex);
253 inline void replace(
int d, CellOneD indRep);
255 inline void PrintCoordinates(){
256 for(
int d=0; d<DimensionSparseGrid; d++){
257 cout << coordinate(d) <<
" " ;
261 inline double getLeftBoundary(
int d){
262 return nextLeftLevel(d, getDepth(d)).coordinate(d);
265 inline double getRightBoundary(
int d){
266 return nextRightLevel(d, getDepth(d)).coordinate(d);
273 inline CellDimension(
const indexInteger index_org[DimensionSparseGrid]);
275 indexInteger index[DimensionSparseGrid];
279CellDimension::CellDimension(){
281 for (
int i = 0; i < DimensionSparseGrid; ++i) {
288double CellDimension::coordinate(
int d)
const {
289 return Static_CellOneD::coordinate(index[d]);
293indexInteger CellDimension::getIndex(
int d)
const {
298int CellDimension::getDepth(
int d)
const {
300 return Static_CellOneD::depth(index[d]);
304inline bool CellDimension::operator==(
const CellDimension I)
const {
305 for(
int d=0;d<DimensionSparseGrid;++d) {
306 if(index[d] != I.index[d])
return false;
312CellDimension CellDimension::nextLeftLevel(
int d,
int level){
315 CellDimension back(index);
317 back.replace(d, Static_CellOneD::nextLeft(index[d],level));
322CellDimension CellDimension::nextRightLevel(
int d,
int level){
325 CellDimension back(index);
327 back.replace(d, Static_CellOneD::nextRight(index[d],level));
334inline void CellDimension::replace(
int d, indexInteger newIndex) {
339void CellDimension::replace(
int d, CellOneD indRep) {
340 index[d] = indRep.getInteger();
344CellDimension::CellDimension(
const indexInteger index_org[DimensionSparseGrid]) {
345 for (
int i = 0; i < DimensionSparseGrid; ++i) {
346 index[i] = index_org[i];