33#include <NDEVR/Buffer.h>
34#include <NDEVR/BinaryHeap.h>
43 template<
class t_container_type>
46 uint04* middle = indices.
begin(start + ((end - start) / 2));
47 std::nth_element(indices.
begin(start), middle, indices.
begin(end), [&elements, dimension](
uint04 i,
uint04 j)
49 return elements[i].center()[dimension] < elements[j].center()[dimension];
51 return start + ((end - start) / 2);
55 template<
class t_node_type,
class t_container_type>
73 sint04 child = nLeft++, parent = (child - 1) / 2;
76 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
79 left.
insert(points[indices[val]][dimension], val);
82 if (left.
size() == max_heap)
85 for (; nRight != max_heap; nRight++)
91 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
94 child = points[indices[left[2]]][dimension] > points[indices[left[1]]][dimension] ? 2 : 1;
95 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
101 child = parent * 2 + 1;
102 while (child < max_heap)
104 if (child < half_heap
105 && points[indices[left[child + 1]]][dimension] > points[indices[left[child]]][dimension])
107 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
109 left[parent] = left[child];
111 child = parent * 2 + 1;
125 sint04 child = nRight++, parent = (child - 1) / 2;
126 while (parent && points[indices[val]][dimension] < points[indices[right[parent]]][dimension])
128 right[child] = right[parent];
130 parent = (parent - 1) / 2;
135 if (nRight == max_heap)
138 for (; nLeft != max_heap; nLeft++)
144 if (points[indices[val]][dimension] > points[indices[
median]][dimension])
146 child = points[indices[right[2]]][dimension] < points[indices[right[1]]][dimension] ? 2 : 1;
147 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
153 child = parent * 2 + 1;
154 while (child < max_heap)
156 if (child < half_heap
157 && points[indices[right[child + 1]]][dimension] < points[indices[right[child]]][dimension])
159 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
161 right[parent] = right[child];
163 child = parent * 2 + 1;
177 template<u
int01 t_bucket_size,
class t_buffer_type,
class t_container_type>
180 const uint04 half_heap = t_bucket_size / 2;
181 const uint04 max_heap = t_bucket_size / 2 + 1;
182 uint04 left[t_bucket_size / 2 + 1];
183 uint04 right[t_bucket_size / 2 + 1];
197 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
200 sint04 child = nLeft++, parent = (child - 1) / 2;
201 while (parent && points[indices[val]][dimension] > points[indices[left[parent]]][dimension])
203 left[child] = left[parent];
205 parent = (parent - 1) / 2;
210 if (nLeft == max_heap)
213 for (; nRight != max_heap; nRight++)
219 if (points[indices[val]][dimension] < points[indices[
median]][dimension])
221 child = points[indices[left[2]]][dimension] > points[indices[left[1]]][dimension] ? 2 : 1;
222 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
228 child = parent * 2 + 1;
229 while (child < max_heap)
231 if (child < half_heap
232 && points[indices[left[child + 1]]][dimension] > points[indices[left[child]]][dimension])
234 if (points[indices[val]][dimension] >= points[indices[left[child]]][dimension])
236 left[parent] = left[child];
238 child = parent * 2 + 1;
252 sint04 child = nRight++, parent = (child - 1) / 2;
253 while (parent && points[indices[val]][dimension] < points[indices[right[parent]]][dimension])
255 right[child] = right[parent];
257 parent = (parent - 1) / 2;
262 if (nRight == max_heap)
265 for (; nLeft != max_heap; nLeft++)
271 if (points[indices[val]][dimension] > points[indices[
median]][dimension])
273 child = points[indices[right[2]]][dimension] < points[indices[right[1]]][dimension] ? 2 : 1;
274 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
280 child = parent * 2 + 1;
281 while (child < max_heap)
283 if (child < half_heap
284 && points[indices[right[child + 1]]][dimension] < points[indices[right[child]]][dimension])
286 if (points[indices[val]][dimension] <= points[indices[right[child]]][dimension])
288 right[parent] = right[child];
290 child = parent * 2 + 1;
306 template<
class t_buffer_type>
309 uint04 skip = (end - start) / 64;
317 return indices[start];
320 if (skip > 64) number_value = 64;
321 else if (skip > 32) number_value = 32;
322 else if (skip > 16) number_value = 16;
323 else if (skip > 8) number_value = 8;
325 uint04 median_locations[64];
327 for (
uint04 i = 0; i < number_value; i++)
330 median_locations[i] = (indices[median_loc]);
331 median_values[i] = median_loc;
333 switch (number_value)
335 case 64:
return median_values[
StaticHeapMedian<63>(elements, median_locations, 0, 1, dimension)];
336 case 32:
return median_values[
StaticHeapMedian<31>(elements, median_locations, 0, 1, dimension)];
337 case 16:
return median_values[
StaticHeapMedian<15>(elements, median_locations, 0, 1, dimension)];
338 case 8:
return median_values[
StaticHeapMedian<7>(elements, median_locations, 0, 1, dimension)];
339 default:
lib_assert(
false,
"Unknown number_value in roughHeapMedian");
348 template<
class t_type,
class t_node_type>
351 const t_type value = points[indices[value_index]][dimension];
353 std::swap(indices[--end], indices[value_index]);
355 for (
uint04 idx = start; idx < end; idx++)
357 if (points[indices[idx]][dimension] <= value)
359 std::swap(indices[idx], indices[store]);
363 std::swap(indices[end], indices[store]);
371 template<
class t_type,
class t_node_type>
374 const uint04 median_loc =
ApxMedian(points, indices, start, end, dimension);
382 template<
class t_type,
class t_buffer_type,
class t_bounds_type>
385 const t_type value = points[indices[value_index]].center()[dimension];
386 bounds_right.addToBounds(points[indices[value_index]]);
388 std::swap(indices[--end], indices[value_index]);
390 for (
uint04 idx = start; idx < end; idx++)
392 auto element = points[indices[idx]];
393 if (element.center()[dimension] == value)
395 if ((store - start) <= (idx - start) / 2)
397 bounds_left.addToBounds(element);
398 std::swap(indices[idx], indices[store]);
403 bounds_right.addToBounds(element);
406 else if (element.center()[dimension] < value)
408 bounds_left.addToBounds(element);
409 std::swap(indices[idx], indices[store]);
414 bounds_right.addToBounds(element);
417 std::swap(indices[end], indices[store]);
#define lib_assert(expression, message)
Definition LibAssert.h:61
A heap data structure that takes the form of a binary tree which is a common way of implementing prio...
Definition BinaryHeap.hpp:42
void insert(t_comp_type comparison, t_value_type value)
Definition BinaryHeap.hpp:47
uint04 size() const
Definition BinaryHeap.hpp:74
The equivelent of std::vector but with a bit more control. The basic array unit of the library.
Definition Buffer.hpp:56
decltype(auto) begin()
Definition Buffer.hpp:402
int32_t sint04
-Defines an alias representing a 4 byte, signed integer. -Can represent exact integer values -2147483...
Definition BaseValues.hpp:64
uint04 ApxNthElement(const Buffer< t_node_type > &points, Buffer< uint04 > &indices, uint04 start, uint04 end, uint01 dimension)
Returns the aproximate Nth element, or value that is close to the Nth Element, significantly faster t...
Definition Median.hpp:372
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:80
uint04 SortAboutValue(uint04 value_index, const Buffer< t_node_type > &points, Buffer< uint04 > &indices, uint04 start, uint04 end, uint01 dimension)
Sorts all incoming indices within the given range such that the resulting index matrix will have valu...
Definition Median.hpp:349
uint04 ApxMedian(const t_buffer_type &elements, const Buffer< uint04 > &indices, uint04 start, uint04 end, uint01 dimension)
Returns the aproximate median, or value that is close to the median, significantly faster than it wou...
Definition Median.hpp:307
uint04 StaticHeapMedian(const t_buffer_type &points, const t_container_type &indices, uint04 start, uint04 step, uint01 dimension)
Return the median value in a Buffer of points based on a given dimension.
Definition Median.hpp:178
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:56
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
Definition BaseValues.hpp:96
constexpr t_to cast(const Angle< t_from > &value)
Definition Angle.h:375
uint04 median(const t_container_type &elements, Buffer< uint04 > &indices, const uint04 start, const uint04 end, uint01 dimension)
Definition Median.hpp:44
Defines for a given type (such as sint04, fltp08, UUID, etc) a maximum, minimum, and reserved 'invali...
Definition BaseValues.hpp:233