33#include <NDEVR/Buffer.h>
34#include <NDEVR/BinaryHeap.h>
38 template<
class t_container_type>
41 uint04* middle = indices.
begin(start + ((end - start) / 2));
42 std::nth_element(indices.
begin(start), middle, indices.
begin(end), [&elements, dimension](
uint04 i,
uint04 j)
44 return elements[i].center()[dimension] < elements[j].center()[dimension];
46 return start + ((end - start) / 2);
50 template<
class t_node_type,
class t_container_type>
68 sint04 child = nLeft++, parent = (child - 1) / 2;
71 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
74 left.
insert(points[indices[val]][dimension], val);
77 if (left.
size() == max_heap)
80 for (; nRight != max_heap; nRight++)
86 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
89 child = points[indices[left[2]]][dimension] > points[indices[left[1]]][dimension] ? 2 : 1;
90 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
96 child = parent * 2 + 1;
97 while (child < max_heap)
100 && points[indices[left[child + 1]]][dimension] > points[indices[left[child]]][dimension])
102 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
104 left[parent] = left[child];
106 child = parent * 2 + 1;
120 sint04 child = nRight++, parent = (child - 1) / 2;
121 while (parent && points[indices[val]][dimension] < points[indices[right[parent]]][dimension])
123 right[child] = right[parent];
125 parent = (parent - 1) / 2;
130 if (nRight == max_heap)
133 for (; nLeft != max_heap; nLeft++)
139 if (points[indices[val]][dimension] > points[indices[
median]][dimension])
141 child = points[indices[right[2]]][dimension] < points[indices[right[1]]][dimension] ? 2 : 1;
142 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
148 child = parent * 2 + 1;
149 while (child < max_heap)
151 if (child < half_heap
152 && points[indices[right[child + 1]]][dimension] < points[indices[right[child]]][dimension])
154 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
156 right[parent] = right[child];
158 child = parent * 2 + 1;
171 template<u
int01 t_bucket_size,
class t_buffer_type,
class t_container_type>
174 const uint04 half_heap = t_bucket_size / 2;
175 const uint04 max_heap = t_bucket_size / 2 + 1;
176 uint04 left[t_bucket_size / 2 + 1];
177 uint04 right[t_bucket_size / 2 + 1];
191 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
194 sint04 child = nLeft++, parent = (child - 1) / 2;
195 while (parent && points[indices[val]][dimension] > points[indices[left[parent]]][dimension])
197 left[child] = left[parent];
199 parent = (parent - 1) / 2;
204 if (nLeft == max_heap)
207 for (; nRight != max_heap; nRight++)
213 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
215 child = points[indices[left[2]]][dimension] > points[indices[left[1]]][dimension] ? 2 : 1;
216 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
222 child = parent * 2 + 1;
223 while (child < max_heap)
225 if (child < half_heap
226 && points[indices[left[child + 1]]][dimension] > points[indices[left[child]]][dimension])
228 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
230 left[parent] = left[child];
232 child = parent * 2 + 1;
246 sint04 child = nRight++, parent = (child - 1) / 2;
247 while (parent && points[indices[val]][dimension] < points[indices[right[parent]]][dimension])
249 right[child] = right[parent];
251 parent = (parent - 1) / 2;
256 if (nRight == max_heap)
259 for (; nLeft != max_heap; nLeft++)
265 if (points[indices[val]][dimension] > points[indices[
median]][dimension])
267 child = points[indices[right[2]]][dimension] < points[indices[right[1]]][dimension] ? 2 : 1;
268 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
274 child = parent * 2 + 1;
275 while (child < max_heap)
277 if (child < half_heap
278 && points[indices[right[child + 1]]][dimension] < points[indices[right[child]]][dimension])
280 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
282 right[parent] = right[child];
284 child = parent * 2 + 1;
297 template<
class t_buffer_type>
300 uint04 skip = (end - start) / 64;
308 return indices[start];
311 if (skip > 64) number_value = 64;
312 else if (skip > 32) number_value = 32;
313 else if (skip > 16) number_value = 16;
314 else if (skip > 8) number_value = 8;
316 uint04 median_locations[64];
318 for (
uint04 i = 0; i < number_value; i++)
321 median_locations[i] = (indices[median_loc]);
322 median_values[i] = median_loc;
324 switch (number_value)
326 case 64:
return median_values[
staticHeapMedian<63>(elements, median_locations, 0, 1, dimension)];
327 case 32:
return median_values[
staticHeapMedian<31>(elements, median_locations, 0, 1, dimension)];
328 case 16:
return median_values[
staticHeapMedian<15>(elements, median_locations, 0, 1, dimension)];
329 case 8:
return median_values[
staticHeapMedian<7>(elements, median_locations, 0, 1, dimension)];
330 default:
lib_assert(
false,
"Unknown number_value in roughHeapMedian");
336 template<
class t_type,
class t_node_type>
339 const t_type value = points[indices[value_index]][dimension];
341 std::swap(indices[--end], indices[value_index]);
343 for (
uint04 idx = start; idx < end; idx++)
345 if (points[indices[idx]][dimension] <= value)
347 std::swap(indices[idx], indices[store]);
351 std::swap(indices[end], indices[store]);
354 template<
class t_type,
class t_node_type>
357 const uint04 median_loc =
apxMedian(points, indices, start, end, dimension);
360 template<
class t_type,
class t_buffer_type,
class t_bounds_type>
363 const t_type value = points[indices[value_index]].center()[dimension];
364 bounds_right.addToBounds(points[indices[value_index]]);
366 std::swap(indices[--end], indices[value_index]);
368 for (
uint04 idx = start; idx < end; idx++)
370 auto element = points[indices[idx]];
371 if (element.center()[dimension] == value)
373 if ((store - start) <= (idx - start) / 2)
375 bounds_left.addToBounds(element);
376 std::swap(indices[idx], indices[store]);
381 bounds_right.addToBounds(element);
384 else if (element.center()[dimension] < value)
386 bounds_left.addToBounds(element);
387 std::swap(indices[idx], indices[store]);
392 bounds_right.addToBounds(element);
395 std::swap(indices[end], indices[store]);
#define lib_assert(expression, message)
Asserts some logic in the code. Disabled in non debug mode by default. Can be re-enabled in release u...
Definition LibAssert.h:70
Definition BinaryHeap.hpp:39
void insert(t_comp_type comparison, t_value_type value)
Definition BinaryHeap.hpp:44
uint04 size() const
Definition BinaryHeap.hpp:71
The equivelent of std::vector but with a bit more control. The basic array unit of the library.
Definition Buffer.hpp:64
decltype(auto) begin()
Definition Buffer.hpp:504
int32_t sint04
-Defines an alias representing a 4 byte, signed integer. -Can represent exact integer values -2147483...
Definition BaseValues.hpp:76
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:98
uint04 apxNthElement(const Buffer< t_node_type > &points, Buffer< uint04 > &indices, uint04 start, uint04 end, uint01 dimension)
Definition Median.hpp:355
uint04 apxMedian(const t_buffer_type &elements, const Buffer< uint04 > &indices, uint04 start, uint04 end, uint01 dimension)
Definition Median.hpp:298
uint04 dynamicHeapMedian(uint04 size, const Buffer< t_node_type > &points, const t_container_type &indices, const uint04 start, const uint04 step, uint01 dimension)
Definition Median.hpp:51
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:120
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:514
uint04 staticHeapMedian(const t_buffer_type &points, const t_container_type &indices, uint04 start, uint04 step, uint01 dimension)
Definition Median.hpp:172
uint04 sortAboutValue(uint04 value_index, const Buffer< t_node_type > &points, Buffer< uint04 > &indices, uint04 start, uint04 end, uint01 dimension)
Definition Median.hpp:337
uint04 median(const t_container_type &elements, Buffer< uint04 > &indices, const uint04 start, const uint04 end, uint01 dimension)
Definition Median.hpp:39
Definition BaseValues.hpp:272