Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ethen8181
GitHub Repository: ethen8181/machine-learning
Path: blob/master/python/cython/pairwise3.pyx
2574 views
1
# cython: boundscheck = False
2
# cython: wraparound = False
3
4
cimport cython
5
import numpy as np
6
from libc.math cimport sqrt
7
from cython.parallel import parallel, prange
8
9
# up till now we're still utilizing only a single thread
10
# we can use multiple threads and tap into all available CPU cores
11
# using the parallel functionality;
12
# to do this we need to release the GIL (this helps python's memory management,
13
# but it is also this functionality that does not allow python to use all cores)
14
# to call a "GIL-less" function, we place nogil after it;
15
# note that we can't interact with python objects inside
16
cdef inline double euclidean_distance(double[:, :] X, int i, int j, int N) nogil:
17
18
# declare C types for as many of our variables as possible
19
# using cdef:
20
cdef:
21
int k
22
double tmp, d = 0.0
23
24
for k in range(N):
25
tmp = X[i, k] - X[j, k]
26
d += tmp * tmp
27
28
return sqrt(d)
29
30
31
def pairwise3(double[:, :] X):
32
33
cdef:
34
int i, j
35
double dist
36
int n_samples = X.shape[0], n_dim = X.shape[1]
37
double[:, :] D = np.zeros((n_samples, n_samples), dtype = np.float64)
38
39
# parallelize this over the outermost loop, using the prange function
40
with nogil, parallel():
41
for i in prange(n_samples):
42
for j in range(i + 1, n_samples):
43
dist = euclidean_distance(X, i, j, n_dim)
44
D[i, j] = dist
45
D[j, i] = dist
46
return D
47
48