Spatial C++ Library
Generic Multi-Dimensional Containers and Spatial Operations
Fractional Time Complexity

Functions with fractional time complexity in dimension $d$ noted $O(n^{1\,-\,1/d})\,$ will run and return their output in an amount of time that depends primarily on the number of dimensions used in the container.

Proper balancing of the tree and choice of dimension for the search will also affect the running time of the function, but it has less influence as the number of elements in the container increases.

Function of this time complexity will amortize overtime, however they will not amortize as fast as logarithmic time complexity function. And therefore, for the benefit of amortization to show, it is often necessary that for a given dimension $d$ and number of elements $n$ in the tree, the number of elements in the tree be far superior the exponent of the dimension:

\[n > 2^{d\,+\,1}\]

This class of time complexity is very common on many of the function of the containers based on a k-d tree. This is due to the invarient of the k-d tree that acts on a single dimension at every depth of the k-d tree. Thus, if a point is being searched for in a particular dimension, and the space has 3 dimensions to work with, then prunning (i.e. eleminating part of tree from the search) only happens once every 3 steps down. By comparison, in a regular binary search tree, prunning occurs at every step down.

To give an idea of how prunning will work with such kind of time complexity, the table below shows the number of node that will be prunned for a various ranks and for various number of elements, if the tree is perfectly balanced. The value below are only representative, to give an idea of the evolution of the running time for a function of such complexity. The number of nodes visited versus nodes prunned by an algorithm is generally one of the most reliable indicator of the running time of a function in a tree.

Number of elements in the container Number of dimension = 1: $O(\log n)\,$ Number of dimension = 2: $O(n^{1\,-\,1/d})\,$ Number of dimension = 3: $O(n^{1\,-\,1/d})\,$ Number of dimension = 4: $O(n^{1\,-\,1/d})\,$
nodes visitednode prunned nodes visitednode prunned nodes visitednode prunned nodes visitednode prunned
16 412 88 88 97
64 658 1747 2737 3133
256 8248 35221 76180 103153
1024 101014 67957 203821 322702
409612 4084140 3956525 3571970 3126
1638414 16370281 161031339 150452852 13532
65536 1665520 53764999 339462142 826557271
262144 18262126 1126261018 8576253568 23729238415
104857620 1048556 22521046324 216431026933 67744980832
4194304 224194282 43004190004 545794139725 1927294001575
16777216 2416777192 901116768205 13757616639640 54711316230103
67108864 2667108838 1802267090842 34673266762132 155101865557846
268435456 28268435428 34406268401050 873793267561663 4393263264042193

As can be seen from the table above, for a single dimension, the number of node prunned by an algorithm running in logarithmic amortized time becomes larger than the number of node visited even when just a few nodes are in the tree. For space of 4 dimensions, we need to insert around 200 points in order to count more node prunned than nodes visited.

In practices, because tree does not have a very good locality of reference, iterating through very large trees is further slown down by the number of cache misses. If your application depends heavily on a function that runs in fractional time complexity in a high number dimensions (i.e. above 10 for example), and you do not plan to have a very large number of elements in your tree (i.e. less 10,000 for example), containers in this library may not be the most optimized solution for you, and you may need to look at other advanced solutions. In some cases, a std::vector<> may even provide better raw performance.

Member spatial::details::decrement_mapping (NodePtr node, dimension_type dim, Rank rank, dimension_type map, KeyCompare key_comp)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::decrement_ordered (ordered_iterator< Container > &iter)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::increment_mapping (NodePtr node, dimension_type dim, Rank rank, dimension_type map, KeyCompare key_comp)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::increment_ordered (ordered_iterator< Container > &iter)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::Kdtree< Rank, Key, Value, Compare, Alloc >::find (const key_type &key)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Parameters
keythe value to be searched for.
Returns
An iterator to that value or an iterator to the element past the end of the container.
Member spatial::details::lower_bound_mapping (NodePtr node, dimension_type dim, Rank rank, dimension_type map, KeyCompare key_comp, const KeyType &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::lower_bound_ordered (ordered_iterator< Container > &iter, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::maximum_mapping (NodePtr node, dimension_type dim, Rank rank, dimension_type map, KeyCompare key_comp)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::maximum_ordered (ordered_iterator< Container > &iter)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::minimum_mapping (NodePtr node, dimension_type dim, Rank rank, dimension_type map, KeyCompare key_comp)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::minimum_ordered (ordered_iterator< Container > &iter)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::upper_bound_mapping (NodePtr node, dimension_type dim, Rank rank, dimension_type map, KeyCompare key_comp, const KeyType &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::details::upper_bound_ordered (ordered_iterator< Container > &iter, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::mapping_begin (Container &container, dimension_type mapping_dim)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::mapping_lower_bound (Container &container, dimension_type mapping_dim, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::mapping_range (const Container &container, dimension_type mapping_dim)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::mapping_range (Container &container, dimension_type mapping_dim)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::mapping_upper_bound (Container &container, dimension_type mapping_dim, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_begin (const Container &container)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_begin (Container &container)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_lower_bound (const Container &container, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_lower_bound (Container &container, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_range (const Container &container)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_range (Container &container)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
Member spatial::ordered_upper_bound (Container &container, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
See also
ordered_iterator
Member spatial::ordered_upper_bound (const Container &container, const typename container_traits< Container >::key_type &bound)
This function has average fractional time complexity: $O(n^{1\,-\,1/d})\,$
See also
ordered_iterator