Commit 7516a324 authored by Julien Jerphanion's avatar Julien Jerphanion

[WIP] KDTree implementation

parent 85f51247
# distutils: language = c++ # distutils: language = c++
from cython.view cimport array as cvarray
import numpy as np
from libcythonplus.list cimport cyplist from libcythonplus.list cimport cyplist
from runtime.runtime cimport BatchMailBox, NullResult, Scheduler from runtime.runtime cimport BatchMailBox, NullResult, Scheduler
from libc.stdio cimport ( from libc.stdio cimport (
fprintf, fopen, fclose, fread, fprintf, fopen, fclose, fread,
fwrite, FILE, stdout, printf, ferror fwrite, FILE, stdout, printf, ferror
) )
from libc.stdlib cimport malloc, free
from stdlib.stat cimport Stat, dev_t from stdlib.stat cimport Stat, dev_t
from stdlib.fmt cimport sprintf from stdlib.fmt cimport sprintf
from stdlib.string cimport string from stdlib.string cimport string
...@@ -19,57 +24,85 @@ cdef lock Scheduler scheduler ...@@ -19,57 +24,85 @@ cdef lock Scheduler scheduler
cdef cypclass Node activable: cdef cypclass Node activable:
"""A KDTree Node""" """A KDTree Node"""
cyplist[int] point double[:] point
active Node left_child active Node left
active Node right_child active Node right
__init__(self): __init__(self):
self._active_result_class = NullResult self._active_result_class = NullResult
self._active_queue_class = consume BatchMailBox(scheduler) self._active_queue_class = consume BatchMailBox(scheduler)
self.left_child = NULL self.left = NULL
self.right_child = NULL self.right = NULL
void build_node(self, lock cyplist[cyplist[int]] points, int depth): void build_node(
self,
double * points,
int n,
int depth,
int dims,
int dim_for_split
):
cdef int i
if (depth < 0): if (depth < 0):
return return
printf("Depth %d\n", depth) printf("Depth %d\n", depth)
self.left_child = activate(consume Node()) printf("Dim %d\n", dim_for_split)
self.right_child = activate(consume Node()) for i in range(n):
printf("X[%d, %d] = %f\n",
i, dim_for_split,
points[i*dims+dim_for_split])
self.left_child.build_node(NULL, consume points, depth - 1) printf("\n")
self.right_child.build_node(NULL, consume points, depth - 1) # TODO: find a way to partitions indices here
self.left = activate(consume Node())
self.right = activate(consume Node())
cdef int start(string path) nogil: self.left.build_node(NULL, points, depth - 1, n, dims, (dim_for_split +
global scheduler 1)
scheduler = Scheduler() % dims)
self.right.build_node(NULL, points, depth - 1, n, dims, (dim_for_split
points = cyplist[cyplist[int]]() + 1
%
dims))
# TODO: integrate here
# [7, 2],
# [5, 4],
# [9, 6],
# [4, 7],
# [8, 1],
# [2, 3]
cdef int start() nogil:
global scheduler
scheduler = Scheduler()
cdef int i
cdef int n = 12
cdef int d = 2
# TODO: use memory view for convenience
# cdef double p[12][2]
# cdef double [:, ::1] points_views = p
# Use Golden Spiral for the layout
cdef double golden_ratio = (1 + 5**0.5)/2
cdef double * points = <double *> malloc(n * d * sizeof(double))
for i in range(n):
points[i * d] = (i / golden_ratio) % 1
points[i *d +1] = i / n
printf("Before\n")
node = consume Node() node = consume Node()
if node is NULL: if node is NULL:
return -1 return -1
root = activate(consume node) root = activate(consume node)
root.build_node(NULL, consume points, 4) root.build_node(NULL, points, n, 5, d, 0)
scheduler.finish() scheduler.finish()
del scheduler del scheduler
free(points)
return 0 return 0
cdef public int main() nogil: cdef public int main() nogil:
return start(<char*>'.') return start()
def python_main(): def python_main():
start(<char*>'.') start()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment