11
11
12
12
def tree_creation_and_query_types ():
13
13
print ("*** KdTree Creation And Basic Information ***" )
14
- # An input array must have a dimension of two and it must be contiguous. A
15
- # C contiguous array contains points in its rows and an F contiguous array
16
- # contains points in its columns.
14
+ # An input array must have a dimension of two and it must be
15
+ # contiguous. A C contiguous array contains points in its rows and
16
+ # an F contiguous array contains points in its columns.
17
17
p = np .array ([[2 , 1 ], [4 , 3 ], [8 , 7 ]], dtype = np .float32 )
18
- # Both the in and output distances are squared when using Metric.L2Squared.
18
+ # Both the in and output distances are squared when using
19
+ # Metric.L2Squared.
19
20
t = pt .KdTree (p , pt .Metric .L2Squared , 1 )
20
21
print (f"{ t } " )
21
22
print (f"Number of points used to build the tree: { t .npts } " )
@@ -37,9 +38,10 @@ def tree_creation_and_query_types():
37
38
print ()
38
39
39
40
print ("*** Approximate Nearest Neighbor Search ***" )
40
- # Searching for approximate nearest neighbors works the same way.
41
- # An approximate nearest neighbor can be at most a distance factor of 1+e
42
- # farther away from the true nearest neighbor.
41
+ # Approximate nearest neighbor searches require an extra parameter
42
+ # compared to exact nearest neighbor searches, namely, a distance
43
+ # factor. An approximate nearest neighbor can be at most a factor
44
+ # of 1+e farther away from the true nearest neighbor.
43
45
max_error = 0.75
44
46
# Apply the metric function to the ratio to get the squared ratio.
45
47
max_error_ratio = t .metric (1.0 + max_error )
@@ -48,14 +50,14 @@ def tree_creation_and_query_types():
48
50
# Note that we scale back the ann distance its original distance.
49
51
print ("The 2nd closest to each input point:" )
50
52
for knn in knns :
51
- print (
52
- f"Point index { knn [1 ][0 ]} with distance { knn [1 ][1 ] * max_error_ratio } " )
53
+ print ("Point index {0} with distance {1}" . format (
54
+ knn [1 ][0 ], knn [1 ][1 ] * max_error_ratio ) )
53
55
print ()
54
56
55
57
print ("*** Radius Search ***" )
56
- # A radius search doesn't return a numpy array but a custom vector of numpy
57
- # arrays. This is because the number of neighbors to each of input points
58
- # may vary for a radius search.
58
+ # A radius search doesn't return a numpy array but a custom vector
59
+ # of numpy arrays. This is because the number of neighbors to each
60
+ # of input points may vary for a radius search.
59
61
search_radius = t .metric (2.5 )
60
62
print (f"Result with radius: { search_radius } " )
61
63
rnns = t .search_radius (p , search_radius )
@@ -69,8 +71,9 @@ def tree_creation_and_query_types():
69
71
print ()
70
72
71
73
print ("*** Box Search ***" )
72
- # A box search returns the same data structure as a radius search. However,
73
- # instead of containing neighbors it simply contains indices.
74
+ # A box search returns the same data structure as a radius search.
75
+ # However, instead of containing neighbors it simply contains
76
+ # indices.
74
77
min = np .array ([[0 , 0 ], [2 , 2 ], [0 , 0 ], [6 , 6 ]], dtype = np .float32 )
75
78
max = np .array ([[3 , 3 ], [3 , 3 ], [9 , 9 ], [9 , 9 ]], dtype = np .float32 )
76
79
bnns = t .search_box (min , max )
@@ -96,11 +99,14 @@ def tree_creation_and_query_types():
96
99
def array_initialization ():
97
100
print ("*** Array Initialization ***" )
98
101
p = np .array ([[2 , 1 ], [4 , 3 ], [8 , 7 ]], dtype = np .float64 )
99
- # In and output distances are absolute distances when using Metric.L1 .
102
+ # Metric.L1: The sum of absolute differences .
100
103
t = pt .KdTree (p , pt .Metric .L1 , 10 )
104
+ # Metric.LInf: The max of absolute differences.
105
+ t = pt .KdTree (p , pt .Metric .LInf , 10 )
101
106
102
- # This type of forward initialization of arrays may be useful to streamline
103
- # loops that depend on them and where reusing memory is desired. E.g.: ICP.
107
+ # This type of forward initialization of arrays may be useful to
108
+ # streamline loops that depend on them and where reusing memory is
109
+ # desired. E.g.: ICP.
104
110
knns = np .empty ((0 ), dtype = t .dtype_neighbor )
105
111
print (knns .dtype )
106
112
rnns = pt .DArray (dtype = t .dtype_neighbor )
@@ -112,9 +118,9 @@ def array_initialization():
112
118
113
119
def performance_test_pico_tree ():
114
120
print ("*** Performance against scans.bin ***" )
115
- # The benchmark documentation, docs/benchmark.md section "Running a new
116
- # benchmark", explains how to generate a scans.bin file from an online
117
- # dataset.
121
+ # The benchmark documentation, docs/benchmark.md section "Running a
122
+ # new benchmark", explains how to generate a scans.bin file from an
123
+ # online dataset.
118
124
try :
119
125
p0 = np .fromfile (Path (__file__ ).parent / "scans0.bin" ,
120
126
np .float32 ).reshape ((- 1 , 3 ))
@@ -125,34 +131,36 @@ def performance_test_pico_tree():
125
131
return
126
132
127
133
cnt_build_time_before = perf_counter ()
128
- # Tree creation is only slightly slower in Python vs C++ using the bindings .
134
+ # Tree creation is only slightly slower in Python.
129
135
t = pt .KdTree (p0 , pt .Metric .L2Squared , 10 )
130
- #t = spKDTree(p0, leafsize=10)
131
- #t = skKDTree(p0, leaf_size=10)
132
- #t = pyKDTree(p0, leafsize=10)
136
+ # t = spKDTree(p0, leafsize=10)
137
+ # t = skKDTree(p0, leaf_size=10)
138
+ # t = pyKDTree(p0, leafsize=10)
133
139
cnt_build_time_after = perf_counter ()
134
- print (f"{ t } was built in { (cnt_build_time_after - cnt_build_time_before ) * 1000.0 } ms" )
135
- # Use the OMP_NUM_THREADS environment variable to influence the number of
136
- # threads used for querying: export OMP_NUM_THREADS=1
140
+ print ("{0} was built in {1}ms" .format (
141
+ t , (cnt_build_time_after - cnt_build_time_before ) * 1000.0 ))
142
+ # Use the OMP_NUM_THREADS environment variable to influence the
143
+ # number of threads used for querying: export OMP_NUM_THREADS=1
137
144
k = 1
138
145
cnt_query_time_before = perf_counter ()
139
- # Searching for nearest neighbors is a constant amount of time slower
140
- # using the bindings as compared to the C++ benchmark (regardless of k).
141
- # The following must be noted however: The Python benchmark simply calls
142
- # the knn function provided by the Python bindings. As such it does not
143
- # directly wrap the C++ benchmark. This means the performance difference is
144
- # not only due to the bindings overhead. The C++ implementation benchmark
145
- # may have been optimized more because is very simple. The bindings also
146
- # have various extra overhead: checks, numpy array memory creation, OpenMP,
147
- # etc.
148
- # TODO The actual overhead is probably very similar to that of the KdTree
149
- # creation, but it would be nice to measure the overhead w.r.t. the actual
150
- # query.
146
+ # Searching for nearest neighbors is a constant amount of time
147
+ # slower using the bindings as compared to the C++ benchmark
148
+ # (regardless of k). The following must be noted however: The
149
+ # Python benchmark simply calls the knn function provided by the
150
+ # Python bindings. As such it does not directly wrap the C++
151
+ # benchmark. This means the performance difference is not only due
152
+ # to the bindings overhead. The C++ implementation benchmark may
153
+ # have been optimized more because is very simple. The bindings
154
+ # also have various extra overhead: checks, numpy array memory
155
+ # creation, OpenMP, etc.
156
+ # TODO The actual overhead is probably very similar to that of the
157
+ # KdTree creation, but it would be nice to measure the overhead
158
+ # w.r.t. the actual query.
151
159
unused_knns = t .search_knn (p1 , k )
152
- #unused_dd, unused_ii = t.query(p1, k=k)
160
+ # unused_dd, unused_ii = t.query(p1, k=k)
153
161
cnt_query_time_after = perf_counter ()
154
- print (
155
- f" { len (p1 )} points queried in { (cnt_query_time_after - cnt_query_time_before ) * 1000.0 } ms" )
162
+ print ("{0} points queried in {1}ms" . format (
163
+ len (p1 ), (cnt_query_time_after - cnt_query_time_before ) * 1000.0 ) )
156
164
print ()
157
165
158
166
0 commit comments