Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
utils.h
Go to the documentation of this file.
1
29#pragma once
30
31#include <cstddef>
32#include <type_traits>
33
34namespace ogdf {
35namespace energybased {
36namespace dtree {
37
38template<typename IntType, int Dim>
39inline typename std::enable_if<Dim != 1 && Dim != 2, bool>::type mortonComparerEqual(
40 const IntType a[Dim], const IntType b[Dim]) {
41 // loop over the dimension
42 for (int d = Dim - 1; d >= 0; d--) {
43 // if the block is different
44 if (a[d] != b[d]) {
45 return false;
46 }
47 }
48 return true;
49}
50
51// special tuned version for unsigned int and dim = 1
52template<typename IntType, int Dim>
53inline typename std::enable_if<Dim == 1, bool>::type mortonComparerEqual(const IntType a[Dim],
54 const IntType b[Dim]) {
55 return a[0] == b[0];
56}
57
58// special tuned version for unsigned int and dim = 2
59template<typename IntType, int Dim>
60inline typename std::enable_if<Dim == 2, bool>::type mortonComparerEqual(const IntType a[Dim],
61 const IntType b[Dim]) {
62 return a[0] == b[0] && a[1] == b[1];
63}
64
65template<typename IntType, int Dim>
66inline typename std::enable_if<Dim != 1 && Dim != 2, bool>::type mortonComparerLess(
67 const IntType a[Dim], const IntType b[Dim]) {
68 // loop over the dimension
69 for (int d = Dim - 1; d >= 0; d--) {
70 // if the block is different
71 if (a[d] != b[d]) {
72 return a[d] < b[d];
73 }
74 }
75 return false;
76}
77
78// special tuned version for unsigned int and dim = 1
79template<typename IntType, int Dim>
80inline typename std::enable_if<Dim == 1, bool>::type mortonComparerLess(const unsigned int a[Dim],
81 const unsigned int b[Dim]) {
82 return a[0] < b[0];
83}
84
85// special tuned version for unsigned int and dim = 2
86template<typename IntType, int Dim>
87inline typename std::enable_if<Dim == 2, bool>::type mortonComparerLess(const unsigned int a[Dim],
88 const unsigned int b[Dim]) {
89 return (a[1] == b[1]) ? a[0] < b[0] : a[1] < b[1];
90}
91
92template<typename IntType, int Dim>
93inline typename std::enable_if<Dim != 1 && Dim != 2, void>::type interleaveBits(
94 const IntType coords[Dim], IntType mnr[Dim]) {
95 // number of bits of the grid coord type
96 const int BitLength = sizeof(IntType) << 3;
97
98 // loop over the dimension
99 for (int d = 0; d < Dim; d++) {
100 // reset the mnr
101 mnr[d] = 0x0;
102 }
103
104 // counter for the res bit
105 int k = 0;
106
107 // now loop over all bits
108 for (int i = 0; i < BitLength; ++i) {
109 // loop over the dimension
110 for (int d = 0; d < Dim; d++) {
111 // set the k-th bit in the correct block at the k % position
112 mnr[k / BitLength] |= ((coords[d] >> i) & 0x1) << (k % BitLength);
113
114 // stupid increment
115 k++;
116 }
117 };
118}
119
120template<typename IntType, int Dim>
121inline typename std::enable_if<Dim == 1, void>::type interleaveBits(const unsigned int coords[Dim],
122 unsigned int mnr[Dim]) {
123 mnr[0] = coords[0];
124}
125
126template<typename IntType, int Dim>
127inline typename std::enable_if<Dim == 2, void>::type interleaveBits(const unsigned int coords[Dim],
128 unsigned int mnr[Dim]) {
129 // half the bit length = #bytes * 4
130 const size_t HalfBitLength = sizeof(unsigned int) << 2;
131
132 // reset the mnr
133 mnr[0] = 0x0;
134 mnr[1] = 0x0;
135
136 // this variable is used to generate an alternating pattern for the
137 // lower half bits of both coords (the higher half will be shifted out later)
138 unsigned int x_lo[2] = {coords[0], coords[1]};
139
140 // this one is used for the higher half, thus, we shift them to right
141 unsigned int x_hi[2] = {coords[0] >> HalfBitLength, coords[1] >> HalfBitLength};
142
143 // a mask full of 1's
144 unsigned int mask = ~0x0;
145
146 for (unsigned int i = (HalfBitLength); i > 0; i = i >> 1) {
147 // increase frequency
148 // generates step by step: ..., 11110000, 11001100, 10101010
149 mask = mask ^ (mask << i);
150
151 // create an alternating 0x0x0x0x0x pattern for the lower bits
152 x_lo[0] = (x_lo[0] | (x_lo[0] << i)) & mask;
153 x_lo[1] = (x_lo[1] | (x_lo[1] << i)) & mask;
154 // and for the higher bits too
155 x_hi[0] = (x_hi[0] | (x_hi[0] << i)) & mask;
156 x_hi[1] = (x_hi[1] | (x_hi[1] << i)) & mask;
157 };
158
159 // save the lower bits alternating in the first block
160 mnr[0] = x_lo[0] | (x_lo[1] << 1);
161
162 // the higher go into the second block
163 mnr[1] = x_hi[0] | (x_hi[1] << 1);
164}
165
166template<typename IntType>
167inline int mostSignificantBit(IntType x) {
168 // number of bits of the int type
169 const size_t BitLength = sizeof(IntType) << 3;
170
171 // the index 0... BitLength - 1 of the msb
172 int result = 0;
173
174 // binary search on the bits of x
175 for (unsigned int i = (BitLength >> 1); i > 0; i = i >> 1) {
176 // check if anything left of i - 1 is set
177 if (x >> i) {
178 // it is msb must be in that half
179 x = x >> i;
180
181 // msb > i
182 result += i;
183 }
184 }
185
186 // return the result
187 return result;
188}
189
190template<typename IntType, int Dim>
191inline typename std::enable_if<Dim != 1, int>::type lowestCommonAncestorLevel(const IntType a[Dim],
192 const IntType b[Dim]) {
193 // number of bits of the grid coord type
194 const size_t BitLength = sizeof(IntType) << 3;
195
196 // loop over the dimension
197 for (int d = Dim - 1; d >= 0; d--) {
198 // if the block is different
199 if (a[d] != b[d]) {
200 int msb = (mostSignificantBit<IntType>(a[d] ^ b[d]) + (d * BitLength));
201
202 // the lowest common ancestor level is msb / num coords
203 return msb / Dim;
204 }
205 }
206
207 return 0;
208}
209
210template<typename IntType, int Dim>
211inline typename std::enable_if<Dim == 1, int>::type lowestCommonAncestorLevel(
212 const unsigned int a[Dim], const unsigned int b[Dim]) {
213 return mostSignificantBit<unsigned int>(a[0] ^ b[0]);
214}
215
216}
217}
218}
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
std::enable_if< Dim!=1, int >::type lowestCommonAncestorLevel(const IntType a[Dim], const IntType b[Dim])
Definition utils.h:191
std::enable_if< Dim!=1 &&Dim!=2, void >::type interleaveBits(const IntType coords[Dim], IntType mnr[Dim])
Definition utils.h:93
std::enable_if< Dim!=1 &&Dim!=2, bool >::type mortonComparerLess(const IntType a[Dim], const IntType b[Dim])
Definition utils.h:66
std::enable_if< Dim!=1 &&Dim!=2, bool >::type mortonComparerEqual(const IntType a[Dim], const IntType b[Dim])
Definition utils.h:39
int mostSignificantBit(IntType x)
Definition utils.h:167
The namespace for all OGDF objects.