-
Notifications
You must be signed in to change notification settings - Fork 0
/
vptree.pyx
86 lines (71 loc) · 2.71 KB
/
vptree.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# distutils: language = c++
from libcpp cimport bool
from libcpp.vector cimport vector
cimport numpy as np
import numpy as np
cdef extern from "float.h":
double DBL_MAX
cdef extern from "limits.h":
int INT_MAX
cdef extern from "vptree.h":
cdef cppclass DataPoint:
DataPoint(int D, int ind, double *x)
cdef cppclass DataPointSparse:
DataPointSparse(int D, int ind, double *x)
cdef cppclass VpTree[T]:
VpTree()
void set_sparse()
void create(vector[T] *items)
void create(double *vals, int N, int D)
void search(double *val, int k, int D, double epsilon, vector[int] *indices, vector[double] *distances)
void view(double *vals, int N)
cdef class vptree(object):
cdef VpTree[DataPoint]* tree
cdef VpTree[DataPointSparse]* tree_sparse
cdef double[:, ::1] Y
cdef bool sparse
def __init__(self, sparse = False):
self.sparse = sparse
if sparse:
self.tree_sparse = new VpTree[DataPointSparse]()
self.tree_sparse.set_sparse()
else:
self.tree = new VpTree[DataPoint]()
def init(self, double[:, ::1] X):
cdef int N = X.shape[0]
cdef int D = X.shape[1]
cdef double [:] Dt
cdef vector[DataPoint] *DP
if self.sparse:
print 'failed'
else:
DP = new vector[DataPoint]()
for i in range(X.shape[0]):
Dt = np.ascontiguousarray(X[i], dtype=np.double)
DP.push_back(DataPoint(D, i, &Dt[0]))
self.tree.create(DP)
def init_sparse(self, np.ndarray X):
cdef double [:,:] D
cdef vector[DataPointSparse] *DP
if not self.sparse:
print 'failed'
else:
DP = new vector[DataPointSparse]()
for i in range(X.shape[0]):
D = np.ascontiguousarray(X[i], dtype=np.double)
DP.push_back(DataPointSparse(D.shape[0], i, &D[0,0]))
self.tree_sparse.create(DP)
def search(self, double[:] V, int k = INT_MAX, double epsilon = DBL_MAX):
cdef vector[int] res
cdef vector[double] dists
if k == INT_MAX and epsilon == DBL_MAX:
raise ValueError("either k or epsilon should be passed")
self.tree.search(&V[0], k, V.shape[0], epsilon, &res, &dists)
return (res, dists)
def search_sparse(self, double[:,::1] V, int k = INT_MAX, double epsilon = DBL_MAX):
cdef vector[int] res
cdef vector[double] dists
if k == INT_MAX and epsilon == DBL_MAX:
raise ValueError("either k or epsilon should be passed")
self.tree_sparse.search(&V[0,0], k, V.shape[0], epsilon, &res, &dists)
return (res, dists)