Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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.