Notebook created by Martín Villanueva - martin.villanueva@usm.cl
- DI UTFSM - May2017.
In [5]:
%matplotlib inline
import numpy as np
import numexpr as ne
import numba
import math
import random
import matplotlib.pyplot as plt
import scipy as sp
import sys
%load_ext Cython
Cython is both a Superset of Python and a Python Library that lets you combine C and Python in various ways. There are two main use-cases:
In order to get it properly working, you need Cython and a C compiler:
conda install cython
We will introduce the basic Cython usage by impementing the Eratosthenes Sieve Algorithm, which is an algorithm to find all prime numbers smaller than a given number.
In [1]:
def primes_python(n):
primes = [False, False] + [True] * (n - 2)
i= 2
while i < n:
# We do not deal with composite numbers.
if not primes[i]:
i += 1
continue
k= i+i
# We mark multiples of i as composite numbers.
while k < n:
primes[k] = False
k += i
i += 1
# We return all numbers marked with True.
return [i for i in range(2, n) if primes[i]]
In [2]:
primes_python(20)
Out[2]:
[2, 3, 5, 7, 11, 13, 17, 19]
Let's evaluate the performance for the first version:
In [3]:
tp = %timeit -o primes_python(10000)
100 loops, best of 3: 4.57 ms per loop
And now we write our first Cython version, by just adding %%cython
magic in the first line of the cell:
In [6]:
%%cython
def primes_cython1(n):
primes = [False, False] + [True] * (n - 2)
i= 2
while i < n:
# We do not deal with composite numbers.
if not primes[i]:
i += 1
continue
k= i+i
# We mark multiples of i as composite numbers.
while k < n:
primes[k] = False
k += i
i += 1
# We return all numbers marked with True.
return [i for i in range(2, n) if primes[i]]
In [7]:
tc1 = %timeit -o primes_cython1(10000)
100 loops, best of 3: 2.67 ms per loop
We achieve x2 speed improvement doing (practically) nothing!.
When we add %%cython
at the beginning of the cell, the code gets compiled by Cython into a C extension. Then, this extension is loaded, and the compiled function is readily available in the interactive namespace.
Lets help the compiler by explicitly defining the type of the variables with the cdef
macro/keyword:
In [8]:
%%cython
def primes_cython2(int n):
# Note the type declarations below
cdef list primes = [False, False] + [True] * (n - 2)
cdef int i = 2
cdef int k = 0
# The rest of the functions is unchanged
while i < n:
# We do not deal with composite numbers.
if not primes[i]:
i += 1
continue
k= i+i
# We mark multiples of i as composite numbers.
while k < n:
primes[k] = False
k += i
i += 1
# We return all numbers marked with True.
return [i for i in range(2, n) if primes[i]]
In [9]:
tc2 = %timeit -o primes_cython2(10000)
1000 loops, best of 3: 320 µs per loop
In [10]:
print("Cython version 1 speedup: {0}".format(tp.best/tc1.best))
print("Cython version 2 speedup: {0}".format(tp.best/tc2.best))
Cython version 1 speedup: 1.7089263650919428
Cython version 2 speedup: 14.255755129764186
Then: In general, Cython will be the most efficient when it can compile data structures and operations directly to C by making as few CPython API calls as possible. Specifying the types of the variables often leads to greater speed improvements.
Just for curiosity let's see the performance Numba's JIT achieves:
In [11]:
@numba.jit(nopython=True)
def primes_numba(n):
primes = [False, False] + [True] * (n - 2)
i= 2
while i < n:
# We do not deal with composite numbers.
if not primes[i]:
i += 1
continue
k= i+i
# We mark multiples of i as composite numbers.
while k < n:
primes[k] = False
k += i
i += 1
# We return all numbers marked with True.
res = []
for i in range(2,n):
if primes[i]: res.append(i)
return res
In [12]:
tn = %timeit -o primes_numba(10000)
The slowest run took 2398.70 times longer than the fastest. This could mean that an intermediate result is being cached.
1 loop, best of 3: 143 µs per loop
Numba wins this time! but: This is not the final form of Cython...
We can inspect the C code generated by Cython with the -a
argument. Let's inspect the code used above.
The non-optimized lines will be shown in a gradient of yellow (white lines are faster, yellow lines are slower), telling you which lines are the least efficiently compiled to C. By clicking on a line, you can see the generated C code corresponding to that line.
In [13]:
%%cython -a
def primes_cython1(n):
primes = [False, False] + [True] * (n - 2)
i= 2
while i < n:
# We do not deal with composite numbers.
if not primes[i]:
i += 1
continue
k= i+i
# We mark multiples of i as composite numbers.
while k < n:
primes[k] = False
k += i
i += 1
# We return all numbers marked with True.
return [i for i in range(2, n) if primes[i]]
Out[13]:
Cython: _cython_magic_7ce427e7ceb040e959d167c66d2f6928.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: def primes_cython1(n):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_1primes_cython1(PyObject *__pyx_self, PyObject *__pyx_v_n); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_1primes_cython1 = {"primes_cython1", (PyCFunction)__pyx_pw_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_1primes_cython1, METH_O, 0};
static PyObject *__pyx_pw_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_1primes_cython1(PyObject *__pyx_self, PyObject *__pyx_v_n) {
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("primes_cython1 (wrapper)", 0);
__pyx_r = __pyx_pf_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_primes_cython1(__pyx_self, ((PyObject *)__pyx_v_n));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_primes_cython1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_n) {
PyObject *__pyx_v_primes = NULL;
PyObject *__pyx_v_i = NULL;
PyObject *__pyx_v_k = NULL;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("primes_cython1", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_AddTraceback("_cython_magic_7ce427e7ceb040e959d167c66d2f6928.primes_cython1", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XDECREF(__pyx_v_primes);
__Pyx_XDECREF(__pyx_v_i);
__Pyx_XDECREF(__pyx_v_k);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple_ = PyTuple_Pack(4, __pyx_n_s_n, __pyx_n_s_primes, __pyx_n_s_i, __pyx_n_s_k); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple_);
__Pyx_GIVEREF(__pyx_tuple_);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_7ce427e7ceb040e959d167c66d2f6928_1primes_cython1, NULL, __pyx_n_s_cython_magic_7ce427e7ceb040e959); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_primes_cython1, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+02: primes = [False, False] + [True] * (n - 2)
__pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_INCREF(Py_False);
__Pyx_GIVEREF(Py_False);
PyList_SET_ITEM(__pyx_t_1, 0, Py_False);
__Pyx_INCREF(Py_False);
__Pyx_GIVEREF(Py_False);
PyList_SET_ITEM(__pyx_t_1, 1, Py_False);
__pyx_t_2 = __Pyx_PyInt_SubtractObjC(__pyx_v_n, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_INCREF(Py_True);
__Pyx_GIVEREF(Py_True);
PyList_SET_ITEM(__pyx_t_3, 0, Py_True);
{ PyObject* __pyx_temp = PyNumber_InPlaceMultiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_temp)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_temp);
__Pyx_DECREF(__pyx_t_3);
__pyx_t_3 = __pyx_temp;
}
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = PyNumber_Add(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 2, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_v_primes = ((PyObject*)__pyx_t_2);
__pyx_t_2 = 0;
+03: i= 2
__Pyx_INCREF(__pyx_int_2);
__pyx_v_i = __pyx_int_2;
+04: while i < n:
while (1) {
__pyx_t_2 = PyObject_RichCompare(__pyx_v_i, __pyx_v_n, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
__pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
if (!__pyx_t_4) break;
05: # We do not deal with composite numbers.
+06: if not primes[i]:
__pyx_t_2 = PyObject_GetItem(__pyx_v_primes, __pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_5 = ((!__pyx_t_4) != 0);
if (__pyx_t_5) {
/* … */
}
+07: i += 1
__pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF_SET(__pyx_v_i, __pyx_t_2);
__pyx_t_2 = 0;
+08: continue
goto __pyx_L3_continue;
+09: k= i+i
__pyx_t_2 = PyNumber_Add(__pyx_v_i, __pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_XDECREF_SET(__pyx_v_k, __pyx_t_2);
__pyx_t_2 = 0;
10: # We mark multiples of i as composite numbers.
+11: while k < n:
while (1) {
__pyx_t_2 = PyObject_RichCompare(__pyx_v_k, __pyx_v_n, Py_LT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error)
__pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
if (!__pyx_t_5) break;
+12: primes[k] = False
if (unlikely(PyObject_SetItem(__pyx_v_primes, __pyx_v_k, Py_False) < 0)) __PYX_ERR(0, 12, __pyx_L1_error)
+13: k += i
__pyx_t_2 = PyNumber_InPlaceAdd(__pyx_v_k, __pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 13, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF_SET(__pyx_v_k, __pyx_t_2);
__pyx_t_2 = 0;
}
+14: i += 1
__pyx_t_2 = __Pyx_PyInt_AddObjC(__pyx_v_i, __pyx_int_1, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF_SET(__pyx_v_i, __pyx_t_2);
__pyx_t_2 = 0;
__pyx_L3_continue:;
}
15: # We return all numbers marked with True.
+16: return [i for i in range(2, n) if primes[i]]
__Pyx_XDECREF(__pyx_r);
{ /* enter inner scope */
PyObject *__pyx_7genexpr__pyx_v_i = NULL;
__pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_INCREF(__pyx_int_2);
__Pyx_GIVEREF(__pyx_int_2);
PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_int_2);
__Pyx_INCREF(__pyx_v_n);
__Pyx_GIVEREF(__pyx_v_n);
PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_n);
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
__pyx_t_3 = __pyx_t_1; __Pyx_INCREF(__pyx_t_3); __pyx_t_6 = 0;
__pyx_t_7 = NULL;
} else {
__pyx_t_6 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_7 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 16, __pyx_L10_error)
}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
for (;;) {
if (likely(!__pyx_t_7)) {
if (likely(PyList_CheckExact(__pyx_t_3))) {
if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_3)) break;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
__pyx_t_1 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_6); __Pyx_INCREF(__pyx_t_1); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 16, __pyx_L10_error)
#else
__pyx_t_1 = PySequence_ITEM(__pyx_t_3, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_1);
#endif
} else {
if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
__pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_6); __Pyx_INCREF(__pyx_t_1); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 16, __pyx_L10_error)
#else
__pyx_t_1 = PySequence_ITEM(__pyx_t_3, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_1);
#endif
}
} else {
__pyx_t_1 = __pyx_t_7(__pyx_t_3);
if (unlikely(!__pyx_t_1)) {
PyObject* exc_type = PyErr_Occurred();
if (exc_type) {
if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
else __PYX_ERR(0, 16, __pyx_L10_error)
}
break;
}
__Pyx_GOTREF(__pyx_t_1);
}
__Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_i, __pyx_t_1);
__pyx_t_1 = 0;
__pyx_t_1 = PyObject_GetItem(__pyx_v_primes, __pyx_7genexpr__pyx_v_i); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 16, __pyx_L10_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
if (__pyx_t_5) {
if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_7genexpr__pyx_v_i))) __PYX_ERR(0, 16, __pyx_L10_error)
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_XDECREF(__pyx_7genexpr__pyx_v_i);
goto __pyx_L14_exit_scope;
__pyx_L10_error:;
__Pyx_XDECREF(__pyx_7genexpr__pyx_v_i);
goto __pyx_L1_error;
__pyx_L14_exit_scope:;
} /* exit inner scope */
__pyx_r = __pyx_t_2;
__pyx_t_2 = 0;
goto __pyx_L0;
In [14]:
%%cython -a
def primes_cython2(int n):
# Note the type declarations below
cdef list primes = [False, False] + [True] * (n - 2)
cdef int i = 2
cdef int k = 0
# The rest of the functions is unchanged
while i < n:
# We do not deal with composite numbers.
if not primes[i]:
i += 1
continue
k= i+i
# We mark multiples of i as composite numbers.
while k < n:
primes[k] = False
k += i
i += 1
# We return all numbers marked with True.
return [i for i in range(2, n) if primes[i]]
Out[14]:
Cython: _cython_magic_7faed0e5d5b89d29eea1f4d95c47da28.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: def primes_cython2(int n):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_1primes_cython2(PyObject *__pyx_self, PyObject *__pyx_arg_n); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_1primes_cython2 = {"primes_cython2", (PyCFunction)__pyx_pw_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_1primes_cython2, METH_O, 0};
static PyObject *__pyx_pw_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_1primes_cython2(PyObject *__pyx_self, PyObject *__pyx_arg_n) {
int __pyx_v_n;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("primes_cython2 (wrapper)", 0);
assert(__pyx_arg_n); {
__pyx_v_n = __Pyx_PyInt_As_int(__pyx_arg_n); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28.primes_cython2", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_primes_cython2(__pyx_self, ((int)__pyx_v_n));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_primes_cython2(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_n) {
PyObject *__pyx_v_primes = 0;
int __pyx_v_i;
int __pyx_v_k;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("primes_cython2", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_AddTraceback("_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28.primes_cython2", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XDECREF(__pyx_v_primes);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple_ = PyTuple_Pack(5, __pyx_n_s_n, __pyx_n_s_n, __pyx_n_s_primes, __pyx_n_s_i, __pyx_n_s_k); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple_);
__Pyx_GIVEREF(__pyx_tuple_);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_7faed0e5d5b89d29eea1f4d95c47da28_1primes_cython2, NULL, __pyx_n_s_cython_magic_7faed0e5d5b89d29ee); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_primes_cython2, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: # Note the type declarations below
+03: cdef list primes = [False, False] + [True] * (n - 2)
__pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_INCREF(Py_False);
__Pyx_GIVEREF(Py_False);
PyList_SET_ITEM(__pyx_t_1, 0, Py_False);
__Pyx_INCREF(Py_False);
__Pyx_GIVEREF(Py_False);
PyList_SET_ITEM(__pyx_t_1, 1, Py_False);
__pyx_t_2 = PyList_New(1 * (((__pyx_v_n - 2)<0) ? 0:(__pyx_v_n - 2))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 3, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
{ Py_ssize_t __pyx_temp;
for (__pyx_temp=0; __pyx_temp < (__pyx_v_n - 2); __pyx_temp++) {
__Pyx_INCREF(Py_True);
__Pyx_GIVEREF(Py_True);
PyList_SET_ITEM(__pyx_t_2, __pyx_temp, Py_True);
}
}
__pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_v_primes = ((PyObject*)__pyx_t_3);
__pyx_t_3 = 0;
+04: cdef int i = 2
__pyx_v_i = 2;
+05: cdef int k = 0
__pyx_v_k = 0;
06: # The rest of the functions is unchanged
+07: while i < n:
while (1) {
__pyx_t_4 = ((__pyx_v_i < __pyx_v_n) != 0);
if (!__pyx_t_4) break;
08: # We do not deal with composite numbers.
+09: if not primes[i]:
__pyx_t_3 = __Pyx_GetItemInt_List(__pyx_v_primes, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_5 = ((!__pyx_t_4) != 0);
if (__pyx_t_5) {
/* … */
}
+10: i += 1
__pyx_v_i = (__pyx_v_i + 1);
+11: continue
goto __pyx_L3_continue;
+12: k= i+i
__pyx_v_k = (__pyx_v_i + __pyx_v_i);
13: # We mark multiples of i as composite numbers.
+14: while k < n:
while (1) {
__pyx_t_5 = ((__pyx_v_k < __pyx_v_n) != 0);
if (!__pyx_t_5) break;
+15: primes[k] = False
if (unlikely(__Pyx_SetItemInt(__pyx_v_primes, __pyx_v_k, Py_False, int, 1, __Pyx_PyInt_From_int, 1, 1, 1) < 0)) __PYX_ERR(0, 15, __pyx_L1_error)
+16: k += i
__pyx_v_k = (__pyx_v_k + __pyx_v_i);
}
+17: i += 1
__pyx_v_i = (__pyx_v_i + 1);
__pyx_L3_continue:;
}
18: # We return all numbers marked with True.
+19: return [i for i in range(2, n) if primes[i]]
__Pyx_XDECREF(__pyx_r);
{ /* enter inner scope */
int __pyx_7genexpr__pyx_v_i;
__pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_6 = __pyx_v_n;
for (__pyx_t_7 = 2; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) {
__pyx_7genexpr__pyx_v_i = __pyx_t_7;
__pyx_t_2 = __Pyx_GetItemInt_List(__pyx_v_primes, __pyx_7genexpr__pyx_v_i, int, 1, __Pyx_PyInt_From_int, 1, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
if (__pyx_t_5) {
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_7genexpr__pyx_v_i); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
if (unlikely(__Pyx_ListComp_Append(__pyx_t_3, (PyObject*)__pyx_t_2))) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
} /* exit inner scope */
__pyx_r = __pyx_t_3;
__pyx_t_3 = 0;
goto __pyx_L0;
If you want to use Cython outside the notebook (the way it was thought...), you have to do the work of the magic:
.pyx
file.cython filename.pyx
generating the filename.c
file.gcc -shared -fPIC -fwrapv -O3 -fno-strict-aliasing -I/home/mavillan/anaconda3/include/python3.6m -o primes.so primes.c
In [17]:
# Matrices to use
A = np.random.random((1000,3))
B = np.random.random((500,3))
In [59]:
def dist(a, b):
return np.sqrt(np.sum((a-b)**2))
def distance_matrix_python(A, B):
m = A.shape[0]
n = B.shape[0]
D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i],B[j])
return D
In [60]:
%timeit distance_matrix_python(A,B)
1 loop, best of 3: 1min 50s per loop
In [62]:
%%cython -a
import numpy as np
def dist(a, b):
return np.sqrt(np.sum((a-b)**2))
def distance_matrix_cython0(A, B):
m = A.shape[0]
n = B.shape[0]
D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i],B[j])
return D
Out[62]:
Cython: _cython_magic_9adc1e9d908de5b5586c08f087884ecd.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02:
+03: def dist(a, b):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_1dist = {"dist", (PyCFunction)__pyx_pw_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_1dist, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
PyObject *__pyx_v_a = 0;
PyObject *__pyx_v_b = 0;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, 1); __PYX_ERR(0, 3, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dist") < 0)) __PYX_ERR(0, 3, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_a = values[0];
__pyx_v_b = values[1];
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_9adc1e9d908de5b5586c08f087884ecd.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_dist(__pyx_self, __pyx_v_a, __pyx_v_b);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_dist(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__Pyx_XDECREF(__pyx_t_6);
__Pyx_XDECREF(__pyx_t_7);
__Pyx_AddTraceback("_cython_magic_9adc1e9d908de5b5586c08f087884ecd.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple_ = PyTuple_Pack(2, __pyx_n_s_a, __pyx_n_s_b); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 3, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple_);
__Pyx_GIVEREF(__pyx_tuple_);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_1dist, NULL, __pyx_n_s_cython_magic_9adc1e9d908de5b558); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_dist, __pyx_t_1) < 0) __PYX_ERR(0, 3, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_dist, 3, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) __PYX_ERR(0, 3, __pyx_L1_error)
+04: return np.sqrt(np.sum((a-b)**2))
__Pyx_XDECREF(__pyx_r);
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_4 = PyNumber_Subtract(__pyx_v_a, __pyx_v_b); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_6 = PyNumber_Power(__pyx_t_4, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_5, function);
}
}
if (!__pyx_t_4) {
__pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__Pyx_GOTREF(__pyx_t_2);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_5)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_6};
__pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_6};
__pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
} else
#endif
{
__pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_6);
PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_6);
__pyx_t_6 = 0;
__pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
}
}
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__pyx_t_5 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_5)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_5);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_5) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_2};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_2};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else
#endif
{
__pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_2);
__pyx_t_2 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
05:
+06: def distance_matrix_cython0(A, B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_3distance_matrix_cython0(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_3distance_matrix_cython0 = {"distance_matrix_cython0", (PyCFunction)__pyx_pw_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_3distance_matrix_cython0, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_3distance_matrix_cython0(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
PyObject *__pyx_v_A = 0;
PyObject *__pyx_v_B = 0;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython0 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython0", 1, 2, 2, 1); __PYX_ERR(0, 6, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython0") < 0)) __PYX_ERR(0, 6, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = values[0];
__pyx_v_B = values[1];
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython0", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 6, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_9adc1e9d908de5b5586c08f087884ecd.distance_matrix_cython0", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_2distance_matrix_cython0(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_2distance_matrix_cython0(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_A, PyObject *__pyx_v_B) {
PyObject *__pyx_v_m = NULL;
PyObject *__pyx_v_n = NULL;
PyObject *__pyx_v_D = NULL;
PyObject *__pyx_v_i = NULL;
PyObject *__pyx_v_j = NULL;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython0", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__Pyx_XDECREF(__pyx_t_10);
__Pyx_XDECREF(__pyx_t_11);
__Pyx_XDECREF(__pyx_t_13);
__Pyx_AddTraceback("_cython_magic_9adc1e9d908de5b5586c08f087884ecd.distance_matrix_cython0", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XDECREF(__pyx_v_m);
__Pyx_XDECREF(__pyx_v_n);
__Pyx_XDECREF(__pyx_v_D);
__Pyx_XDECREF(__pyx_v_i);
__Pyx_XDECREF(__pyx_v_j);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__3 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_D, __pyx_n_s_i, __pyx_n_s_j); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__3);
__Pyx_GIVEREF(__pyx_tuple__3);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_9adc1e9d908de5b5586c08f087884ecd_3distance_matrix_cython0, NULL, __pyx_n_s_cython_magic_9adc1e9d908de5b558); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython0, __pyx_t_1) < 0) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+07: m = A.shape[0]
__pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_A, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_m = __pyx_t_2;
__pyx_t_2 = 0;
+08: n = B.shape[0]
__pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_B, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_v_n = __pyx_t_1;
__pyx_t_1 = 0;
+09: D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_INCREF(__pyx_v_m);
__Pyx_GIVEREF(__pyx_v_m);
PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_m);
__Pyx_INCREF(__pyx_v_n);
__Pyx_GIVEREF(__pyx_v_n);
PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_n);
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_2};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_2};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else
#endif
{
__pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2);
__pyx_t_2 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_v_D = __pyx_t_1;
__pyx_t_1 = 0;
+10: for i in range(m):
__pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_INCREF(__pyx_v_m);
__Pyx_GIVEREF(__pyx_v_m);
PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_m);
__pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
__pyx_t_1 = __pyx_t_3; __Pyx_INCREF(__pyx_t_1); __pyx_t_6 = 0;
__pyx_t_7 = NULL;
} else {
__pyx_t_6 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_t_7 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 10, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
for (;;) {
if (likely(!__pyx_t_7)) {
if (likely(PyList_CheckExact(__pyx_t_1))) {
if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_1)) break;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
__pyx_t_3 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 10, __pyx_L1_error)
#else
__pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
#endif
} else {
if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
__pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) __PYX_ERR(0, 10, __pyx_L1_error)
#else
__pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
#endif
}
} else {
__pyx_t_3 = __pyx_t_7(__pyx_t_1);
if (unlikely(!__pyx_t_3)) {
PyObject* exc_type = PyErr_Occurred();
if (exc_type) {
if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
else __PYX_ERR(0, 10, __pyx_L1_error)
}
break;
}
__Pyx_GOTREF(__pyx_t_3);
}
__Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_3);
__pyx_t_3 = 0;
/* … */
}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+11: for j in range(n):
__pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_INCREF(__pyx_v_n);
__Pyx_GIVEREF(__pyx_v_n);
PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_n);
__pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
__pyx_t_3 = __pyx_t_5; __Pyx_INCREF(__pyx_t_3); __pyx_t_8 = 0;
__pyx_t_9 = NULL;
} else {
__pyx_t_8 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 11, __pyx_L1_error)
}
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
for (;;) {
if (likely(!__pyx_t_9)) {
if (likely(PyList_CheckExact(__pyx_t_3))) {
if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_3)) break;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
__pyx_t_5 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 11, __pyx_L1_error)
#else
__pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
#endif
} else {
if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
__pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 11, __pyx_L1_error)
#else
__pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
#endif
}
} else {
__pyx_t_5 = __pyx_t_9(__pyx_t_3);
if (unlikely(!__pyx_t_5)) {
PyObject* exc_type = PyErr_Occurred();
if (exc_type) {
if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
else __PYX_ERR(0, 11, __pyx_L1_error)
}
break;
}
__Pyx_GOTREF(__pyx_t_5);
}
__Pyx_XDECREF_SET(__pyx_v_j, __pyx_t_5);
__pyx_t_5 = 0;
/* … */
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+12: D[i,j] = dist(A[i],B[j])
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_dist); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = PyObject_GetItem(__pyx_v_A, __pyx_v_i); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_10 = PyObject_GetItem(__pyx_v_B, __pyx_v_j); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_10);
__pyx_t_11 = NULL;
__pyx_t_12 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
__pyx_t_11 = PyMethod_GET_SELF(__pyx_t_2);
if (likely(__pyx_t_11)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
__Pyx_INCREF(__pyx_t_11);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_2, function);
__pyx_t_12 = 1;
}
}
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_2)) {
PyObject *__pyx_temp[3] = {__pyx_t_11, __pyx_t_4, __pyx_t_10};
__pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
PyObject *__pyx_temp[3] = {__pyx_t_11, __pyx_t_4, __pyx_t_10};
__pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
} else
#endif
{
__pyx_t_13 = PyTuple_New(2+__pyx_t_12); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
if (__pyx_t_11) {
__Pyx_GIVEREF(__pyx_t_11); PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_11); __pyx_t_11 = NULL;
}
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_12, __pyx_t_4);
__Pyx_GIVEREF(__pyx_t_10);
PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_12, __pyx_t_10);
__pyx_t_4 = 0;
__pyx_t_10 = 0;
__pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_13, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
}
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_INCREF(__pyx_v_i);
__Pyx_GIVEREF(__pyx_v_i);
PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_i);
__Pyx_INCREF(__pyx_v_j);
__Pyx_GIVEREF(__pyx_v_j);
PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_j);
if (unlikely(PyObject_SetItem(__pyx_v_D, __pyx_t_2, __pyx_t_5) < 0)) __PYX_ERR(0, 12, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+13: return D
__Pyx_XDECREF(__pyx_r);
__Pyx_INCREF(__pyx_v_D);
__pyx_r = __pyx_v_D;
goto __pyx_L0;
In [63]:
%timeit distance_matrix_cython0(A,B)
1 loop, best of 3: 1min 51s per loop
Now let's improve this naive Cython implementation by statically defining the types of the variables:
In [15]:
%%cython -a
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
def dist(cnp.ndarray[float64_t, ndim=1] a, cnp.ndarray[float64_t, ndim=1] b):
return np.sqrt(np.sum((a-b)**2))
def distance_matrix_cython1(cnp.ndarray[float64_t, ndim=2] A, cnp.ndarray[float64_t, ndim=2] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
cnp.ndarray[float64_t, ndim=2] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i], B[j])
return D
Out[15]:
Cython: _cython_magic_ed6bc794487e0d219dae0b68e7bdb406.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: cimport numpy as cnp
03:
04: ctypedef cnp.float64_t float64_t
05:
+06: def dist(cnp.ndarray[float64_t, ndim=1] a, cnp.ndarray[float64_t, ndim=1] b):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_1dist = {"dist", (PyCFunction)__pyx_pw_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_1dist, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
PyArrayObject *__pyx_v_a = 0;
PyArrayObject *__pyx_v_b = 0;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, 1); __PYX_ERR(0, 6, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dist") < 0)) __PYX_ERR(0, 6, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_a = ((PyArrayObject *)values[0]);
__pyx_v_b = ((PyArrayObject *)values[1]);
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 6, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_ed6bc794487e0d219dae0b68e7bdb406.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_a), __pyx_ptype_5numpy_ndarray, 1, "a", 0))) __PYX_ERR(0, 6, __pyx_L1_error)
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_b), __pyx_ptype_5numpy_ndarray, 1, "b", 0))) __PYX_ERR(0, 6, __pyx_L1_error)
__pyx_r = __pyx_pf_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_dist(__pyx_self, __pyx_v_a, __pyx_v_b);
/* function exit code */
goto __pyx_L0;
__pyx_L1_error:;
__pyx_r = NULL;
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_dist(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_a, PyArrayObject *__pyx_v_b) {
__Pyx_LocalBuf_ND __pyx_pybuffernd_a;
__Pyx_Buffer __pyx_pybuffer_a;
__Pyx_LocalBuf_ND __pyx_pybuffernd_b;
__Pyx_Buffer __pyx_pybuffer_b;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
__pyx_pybuffer_a.pybuffer.buf = NULL;
__pyx_pybuffer_a.refcount = 0;
__pyx_pybuffernd_a.data = NULL;
__pyx_pybuffernd_a.rcbuffer = &__pyx_pybuffer_a;
__pyx_pybuffer_b.pybuffer.buf = NULL;
__pyx_pybuffer_b.refcount = 0;
__pyx_pybuffernd_b.data = NULL;
__pyx_pybuffernd_b.rcbuffer = &__pyx_pybuffer_b;
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_a.rcbuffer->pybuffer, (PyObject*)__pyx_v_a, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 6, __pyx_L1_error)
}
__pyx_pybuffernd_a.diminfo[0].strides = __pyx_pybuffernd_a.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_a.diminfo[0].shape = __pyx_pybuffernd_a.rcbuffer->pybuffer.shape[0];
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_b.rcbuffer->pybuffer, (PyObject*)__pyx_v_b, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 6, __pyx_L1_error)
}
__pyx_pybuffernd_b.diminfo[0].strides = __pyx_pybuffernd_b.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_b.diminfo[0].shape = __pyx_pybuffernd_b.rcbuffer->pybuffer.shape[0];
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__Pyx_XDECREF(__pyx_t_6);
__Pyx_XDECREF(__pyx_t_7);
{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_b.rcbuffer->pybuffer);
__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
__Pyx_AddTraceback("_cython_magic_ed6bc794487e0d219dae0b68e7bdb406.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
goto __pyx_L2;
__pyx_L0:;
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_b.rcbuffer->pybuffer);
__pyx_L2:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__10 = PyTuple_Pack(2, __pyx_n_s_a, __pyx_n_s_b); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__10);
__Pyx_GIVEREF(__pyx_tuple__10);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_1dist, NULL, __pyx_n_s_cython_magic_ed6bc794487e0d219d); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_dist, __pyx_t_1) < 0) __PYX_ERR(0, 6, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_dist, 6, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 6, __pyx_L1_error)
+07: return np.sqrt(np.sum((a-b)**2))
__Pyx_XDECREF(__pyx_r);
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_sqrt); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sum); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_4 = PyNumber_Subtract(((PyObject *)__pyx_v_a), ((PyObject *)__pyx_v_b)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_6 = PyNumber_Power(__pyx_t_4, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_5, function);
}
}
if (!__pyx_t_4) {
__pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__Pyx_GOTREF(__pyx_t_2);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_5)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_6};
__pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_6};
__pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
} else
#endif
{
__pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_6);
PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_6);
__pyx_t_6 = 0;
__pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
}
}
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__pyx_t_5 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_5)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_5);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_5) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_2};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_2};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
} else
#endif
{
__pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_7);
__Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __pyx_t_5 = NULL;
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_2);
__pyx_t_2 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
08:
+09: def distance_matrix_cython1(cnp.ndarray[float64_t, ndim=2] A, cnp.ndarray[float64_t, ndim=2] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_3distance_matrix_cython1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_3distance_matrix_cython1 = {"distance_matrix_cython1", (PyCFunction)__pyx_pw_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_3distance_matrix_cython1, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_3distance_matrix_cython1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
PyArrayObject *__pyx_v_A = 0;
PyArrayObject *__pyx_v_B = 0;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython1 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython1", 1, 2, 2, 1); __PYX_ERR(0, 9, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython1") < 0)) __PYX_ERR(0, 9, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = ((PyArrayObject *)values[0]);
__pyx_v_B = ((PyArrayObject *)values[1]);
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython1", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 9, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_ed6bc794487e0d219dae0b68e7bdb406.distance_matrix_cython1", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_A), __pyx_ptype_5numpy_ndarray, 1, "A", 0))) __PYX_ERR(0, 9, __pyx_L1_error)
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_B), __pyx_ptype_5numpy_ndarray, 1, "B", 0))) __PYX_ERR(0, 9, __pyx_L1_error)
__pyx_r = __pyx_pf_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_2distance_matrix_cython1(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
goto __pyx_L0;
__pyx_L1_error:;
__pyx_r = NULL;
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_2distance_matrix_cython1(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_A, PyArrayObject *__pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
PyArrayObject *__pyx_v_D = 0;
__Pyx_LocalBuf_ND __pyx_pybuffernd_A;
__Pyx_Buffer __pyx_pybuffer_A;
__Pyx_LocalBuf_ND __pyx_pybuffernd_B;
__Pyx_Buffer __pyx_pybuffer_B;
__Pyx_LocalBuf_ND __pyx_pybuffernd_D;
__Pyx_Buffer __pyx_pybuffer_D;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython1", 0);
__pyx_pybuffer_D.pybuffer.buf = NULL;
__pyx_pybuffer_D.refcount = 0;
__pyx_pybuffernd_D.data = NULL;
__pyx_pybuffernd_D.rcbuffer = &__pyx_pybuffer_D;
__pyx_pybuffer_A.pybuffer.buf = NULL;
__pyx_pybuffer_A.refcount = 0;
__pyx_pybuffernd_A.data = NULL;
__pyx_pybuffernd_A.rcbuffer = &__pyx_pybuffer_A;
__pyx_pybuffer_B.pybuffer.buf = NULL;
__pyx_pybuffer_B.refcount = 0;
__pyx_pybuffernd_B.data = NULL;
__pyx_pybuffernd_B.rcbuffer = &__pyx_pybuffer_B;
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_A.rcbuffer->pybuffer, (PyObject*)__pyx_v_A, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error)
}
__pyx_pybuffernd_A.diminfo[0].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_A.diminfo[0].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_A.diminfo[1].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_A.diminfo[1].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[1];
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_B.rcbuffer->pybuffer, (PyObject*)__pyx_v_B, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 9, __pyx_L1_error)
}
__pyx_pybuffernd_B.diminfo[0].strides = __pyx_pybuffernd_B.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_B.diminfo[0].shape = __pyx_pybuffernd_B.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_B.diminfo[1].strides = __pyx_pybuffernd_B.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_B.diminfo[1].shape = __pyx_pybuffernd_B.rcbuffer->pybuffer.shape[1];
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__Pyx_XDECREF(__pyx_t_12);
{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_B.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
__Pyx_AddTraceback("_cython_magic_ed6bc794487e0d219dae0b68e7bdb406.distance_matrix_cython1", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
goto __pyx_L2;
__pyx_L0:;
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_B.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
__pyx_L2:;
__Pyx_XDECREF((PyObject *)__pyx_v_D);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__12 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__12);
__Pyx_GIVEREF(__pyx_tuple__12);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_3distance_matrix_cython1, NULL, __pyx_n_s_cython_magic_ed6bc794487e0d219d); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython1, __pyx_t_1) < 0) __PYX_ERR(0, 9, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
10: cdef:
+11: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A->dimensions[0]);
+12: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B->dimensions[0]);
13: int i,j
+14: cnp.ndarray[float64_t, ndim=2] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 14, __pyx_L1_error)
__pyx_t_6 = ((PyArrayObject *)__pyx_t_1);
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_D.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
__pyx_v_D = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_D.rcbuffer->pybuffer.buf = NULL;
__PYX_ERR(0, 14, __pyx_L1_error)
} else {__pyx_pybuffernd_D.diminfo[0].strides = __pyx_pybuffernd_D.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_D.diminfo[0].shape = __pyx_pybuffernd_D.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_D.diminfo[1].strides = __pyx_pybuffernd_D.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_D.diminfo[1].shape = __pyx_pybuffernd_D.rcbuffer->pybuffer.shape[1];
}
}
__pyx_t_6 = 0;
__pyx_v_D = ((PyArrayObject *)__pyx_t_1);
__pyx_t_1 = 0;
+15: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+16: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+17: D[i,j] = dist(A[i], B[j])
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_dist); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_A), __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_5 = __Pyx_GetItemInt(((PyObject *)__pyx_v_B), __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__pyx_t_4 = NULL;
__pyx_t_11 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
__pyx_t_11 = 1;
}
}
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_12 = PyTuple_New(2+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
if (__pyx_t_4) {
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4); __pyx_t_4 = NULL;
}
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_11, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_5);
__pyx_t_2 = 0;
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_13 == ((npy_float64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_t_14 = __pyx_v_i;
__pyx_t_15 = __pyx_v_j;
__pyx_t_11 = -1;
if (__pyx_t_14 < 0) {
__pyx_t_14 += __pyx_pybuffernd_D.diminfo[0].shape;
if (unlikely(__pyx_t_14 < 0)) __pyx_t_11 = 0;
} else if (unlikely(__pyx_t_14 >= __pyx_pybuffernd_D.diminfo[0].shape)) __pyx_t_11 = 0;
if (__pyx_t_15 < 0) {
__pyx_t_15 += __pyx_pybuffernd_D.diminfo[1].shape;
if (unlikely(__pyx_t_15 < 0)) __pyx_t_11 = 1;
} else if (unlikely(__pyx_t_15 >= __pyx_pybuffernd_D.diminfo[1].shape)) __pyx_t_11 = 1;
if (unlikely(__pyx_t_11 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_11);
__PYX_ERR(0, 17, __pyx_L1_error)
}
*__Pyx_BufPtrStrided2d(__pyx_t_46_cython_magic_ed6bc794487e0d219dae0b68e7bdb406_float64_t *, __pyx_pybuffernd_D.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_D.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_D.diminfo[1].strides) = __pyx_t_13;
}
}
+18: return D
__Pyx_XDECREF(__pyx_r);
__Pyx_INCREF(((PyObject *)__pyx_v_D));
__pyx_r = ((PyObject *)__pyx_v_D);
goto __pyx_L0;
In [18]:
%timeit -n 10 distance_matrix_cython1(A,B)
10 loops, best of 3: 4.96 s per loop
In [121]:
%%cython -a
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
from libc.math cimport sqrt
def dist(cnp.ndarray[float64_t, ndim=1] a, cnp.ndarray[float64_t, ndim=1] b):
cdef:
int i = 0
int n = a.shape[0]
float ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return sqrt(ret)
def distance_matrix_cython2(cnp.ndarray[float64_t, ndim=2] A, cnp.ndarray[float64_t, ndim=2] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
cnp.ndarray[float64_t, ndim=2] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i], B[j])
return D
Out[121]:
Cython: _cython_magic_3ab6171dbfe4bc4aec552e931e888117.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: cimport numpy as cnp
03:
04: ctypedef cnp.float64_t float64_t
05: from libc.math cimport sqrt
06:
+07: def dist(cnp.ndarray[float64_t, ndim=1] a, cnp.ndarray[float64_t, ndim=1] b):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_1dist = {"dist", (PyCFunction)__pyx_pw_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_1dist, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
PyArrayObject *__pyx_v_a = 0;
PyArrayObject *__pyx_v_b = 0;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, 1); __PYX_ERR(0, 7, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dist") < 0)) __PYX_ERR(0, 7, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_a = ((PyArrayObject *)values[0]);
__pyx_v_b = ((PyArrayObject *)values[1]);
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 7, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_3ab6171dbfe4bc4aec552e931e888117.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_a), __pyx_ptype_5numpy_ndarray, 1, "a", 0))) __PYX_ERR(0, 7, __pyx_L1_error)
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_b), __pyx_ptype_5numpy_ndarray, 1, "b", 0))) __PYX_ERR(0, 7, __pyx_L1_error)
__pyx_r = __pyx_pf_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_dist(__pyx_self, __pyx_v_a, __pyx_v_b);
/* function exit code */
goto __pyx_L0;
__pyx_L1_error:;
__pyx_r = NULL;
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_dist(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_a, PyArrayObject *__pyx_v_b) {
int __pyx_v_i;
int __pyx_v_n;
float __pyx_v_ret;
__Pyx_LocalBuf_ND __pyx_pybuffernd_a;
__Pyx_Buffer __pyx_pybuffer_a;
__Pyx_LocalBuf_ND __pyx_pybuffernd_b;
__Pyx_Buffer __pyx_pybuffer_b;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
__pyx_pybuffer_a.pybuffer.buf = NULL;
__pyx_pybuffer_a.refcount = 0;
__pyx_pybuffernd_a.data = NULL;
__pyx_pybuffernd_a.rcbuffer = &__pyx_pybuffer_a;
__pyx_pybuffer_b.pybuffer.buf = NULL;
__pyx_pybuffer_b.refcount = 0;
__pyx_pybuffernd_b.data = NULL;
__pyx_pybuffernd_b.rcbuffer = &__pyx_pybuffer_b;
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_a.rcbuffer->pybuffer, (PyObject*)__pyx_v_a, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 7, __pyx_L1_error)
}
__pyx_pybuffernd_a.diminfo[0].strides = __pyx_pybuffernd_a.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_a.diminfo[0].shape = __pyx_pybuffernd_a.rcbuffer->pybuffer.shape[0];
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_b.rcbuffer->pybuffer, (PyObject*)__pyx_v_b, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0, __pyx_stack) == -1)) __PYX_ERR(0, 7, __pyx_L1_error)
}
__pyx_pybuffernd_b.diminfo[0].strides = __pyx_pybuffernd_b.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_b.diminfo[0].shape = __pyx_pybuffernd_b.rcbuffer->pybuffer.shape[0];
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_6);
{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_b.rcbuffer->pybuffer);
__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
__Pyx_AddTraceback("_cython_magic_3ab6171dbfe4bc4aec552e931e888117.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
goto __pyx_L2;
__pyx_L0:;
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_a.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_b.rcbuffer->pybuffer);
__pyx_L2:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__10 = PyTuple_Pack(5, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__10)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__10);
__Pyx_GIVEREF(__pyx_tuple__10);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_1dist, NULL, __pyx_n_s_cython_magic_3ab6171dbfe4bc4aec); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_dist, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__11 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__10, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_dist, 7, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__11)) __PYX_ERR(0, 7, __pyx_L1_error)
08: cdef:
+09: int i = 0
__pyx_v_i = 0;
+10: int n = a.shape[0]
__pyx_v_n = (__pyx_v_a->dimensions[0]);
+11: float ret = 0
__pyx_v_ret = 0.0;
+12: for i in range(n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+13: ret += (a[i]-b[i])**2
__pyx_t_3 = __pyx_v_i;
__pyx_t_4 = -1;
if (__pyx_t_3 < 0) {
__pyx_t_3 += __pyx_pybuffernd_a.diminfo[0].shape;
if (unlikely(__pyx_t_3 < 0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_3 >= __pyx_pybuffernd_a.diminfo[0].shape)) __pyx_t_4 = 0;
if (unlikely(__pyx_t_4 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_4);
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_t_5 = __pyx_v_i;
__pyx_t_4 = -1;
if (__pyx_t_5 < 0) {
__pyx_t_5 += __pyx_pybuffernd_b.diminfo[0].shape;
if (unlikely(__pyx_t_5 < 0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_5 >= __pyx_pybuffernd_b.diminfo[0].shape)) __pyx_t_4 = 0;
if (unlikely(__pyx_t_4 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_4);
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_v_ret = (__pyx_v_ret + pow(((*__Pyx_BufPtrStrided1d(__pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t *, __pyx_pybuffernd_a.rcbuffer->pybuffer.buf, __pyx_t_3, __pyx_pybuffernd_a.diminfo[0].strides)) - (*__Pyx_BufPtrStrided1d(__pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t *, __pyx_pybuffernd_b.rcbuffer->pybuffer.buf, __pyx_t_5, __pyx_pybuffernd_b.diminfo[0].strides))), 2.0));
}
+14: return sqrt(ret)
__Pyx_XDECREF(__pyx_r);
__pyx_t_6 = PyFloat_FromDouble(sqrt(__pyx_v_ret)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__pyx_r = __pyx_t_6;
__pyx_t_6 = 0;
goto __pyx_L0;
15:
16:
+17: def distance_matrix_cython2(cnp.ndarray[float64_t, ndim=2] A, cnp.ndarray[float64_t, ndim=2] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_3distance_matrix_cython2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_3distance_matrix_cython2 = {"distance_matrix_cython2", (PyCFunction)__pyx_pw_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_3distance_matrix_cython2, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_3distance_matrix_cython2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
PyArrayObject *__pyx_v_A = 0;
PyArrayObject *__pyx_v_B = 0;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython2 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython2", 1, 2, 2, 1); __PYX_ERR(0, 17, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython2") < 0)) __PYX_ERR(0, 17, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = ((PyArrayObject *)values[0]);
__pyx_v_B = ((PyArrayObject *)values[1]);
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython2", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 17, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_3ab6171dbfe4bc4aec552e931e888117.distance_matrix_cython2", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_A), __pyx_ptype_5numpy_ndarray, 1, "A", 0))) __PYX_ERR(0, 17, __pyx_L1_error)
if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_B), __pyx_ptype_5numpy_ndarray, 1, "B", 0))) __PYX_ERR(0, 17, __pyx_L1_error)
__pyx_r = __pyx_pf_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_2distance_matrix_cython2(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
goto __pyx_L0;
__pyx_L1_error:;
__pyx_r = NULL;
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_2distance_matrix_cython2(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_A, PyArrayObject *__pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
PyArrayObject *__pyx_v_D = 0;
__Pyx_LocalBuf_ND __pyx_pybuffernd_A;
__Pyx_Buffer __pyx_pybuffer_A;
__Pyx_LocalBuf_ND __pyx_pybuffernd_B;
__Pyx_Buffer __pyx_pybuffer_B;
__Pyx_LocalBuf_ND __pyx_pybuffernd_D;
__Pyx_Buffer __pyx_pybuffer_D;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython2", 0);
__pyx_pybuffer_D.pybuffer.buf = NULL;
__pyx_pybuffer_D.refcount = 0;
__pyx_pybuffernd_D.data = NULL;
__pyx_pybuffernd_D.rcbuffer = &__pyx_pybuffer_D;
__pyx_pybuffer_A.pybuffer.buf = NULL;
__pyx_pybuffer_A.refcount = 0;
__pyx_pybuffernd_A.data = NULL;
__pyx_pybuffernd_A.rcbuffer = &__pyx_pybuffer_A;
__pyx_pybuffer_B.pybuffer.buf = NULL;
__pyx_pybuffer_B.refcount = 0;
__pyx_pybuffernd_B.data = NULL;
__pyx_pybuffernd_B.rcbuffer = &__pyx_pybuffer_B;
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_A.rcbuffer->pybuffer, (PyObject*)__pyx_v_A, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 17, __pyx_L1_error)
}
__pyx_pybuffernd_A.diminfo[0].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_A.diminfo[0].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_A.diminfo[1].strides = __pyx_pybuffernd_A.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_A.diminfo[1].shape = __pyx_pybuffernd_A.rcbuffer->pybuffer.shape[1];
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_B.rcbuffer->pybuffer, (PyObject*)__pyx_v_B, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0, __pyx_stack) == -1)) __PYX_ERR(0, 17, __pyx_L1_error)
}
__pyx_pybuffernd_B.diminfo[0].strides = __pyx_pybuffernd_B.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_B.diminfo[0].shape = __pyx_pybuffernd_B.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_B.diminfo[1].strides = __pyx_pybuffernd_B.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_B.diminfo[1].shape = __pyx_pybuffernd_B.rcbuffer->pybuffer.shape[1];
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__Pyx_XDECREF(__pyx_t_12);
{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
__Pyx_PyThreadState_declare
__Pyx_PyThreadState_assign
__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_B.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
__Pyx_AddTraceback("_cython_magic_3ab6171dbfe4bc4aec552e931e888117.distance_matrix_cython2", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
goto __pyx_L2;
__pyx_L0:;
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_A.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_B.rcbuffer->pybuffer);
__Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_D.rcbuffer->pybuffer);
__pyx_L2:;
__Pyx_XDECREF((PyObject *)__pyx_v_D);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__12 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__12)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__12);
__Pyx_GIVEREF(__pyx_tuple__12);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_3distance_matrix_cython2, NULL, __pyx_n_s_cython_magic_3ab6171dbfe4bc4aec); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython2, __pyx_t_1) < 0) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
18: cdef:
+19: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A->dimensions[0]);
+20: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B->dimensions[0]);
21: int i,j
+22: cnp.ndarray[float64_t, ndim=2] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_ptype_5numpy_ndarray))))) __PYX_ERR(0, 22, __pyx_L1_error)
__pyx_t_6 = ((PyArrayObject *)__pyx_t_1);
{
__Pyx_BufFmt_StackElem __pyx_stack[1];
if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_D.rcbuffer->pybuffer, (PyObject*)__pyx_t_6, &__Pyx_TypeInfo_nn___pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0, __pyx_stack) == -1)) {
__pyx_v_D = ((PyArrayObject *)Py_None); __Pyx_INCREF(Py_None); __pyx_pybuffernd_D.rcbuffer->pybuffer.buf = NULL;
__PYX_ERR(0, 22, __pyx_L1_error)
} else {__pyx_pybuffernd_D.diminfo[0].strides = __pyx_pybuffernd_D.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_D.diminfo[0].shape = __pyx_pybuffernd_D.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_D.diminfo[1].strides = __pyx_pybuffernd_D.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_D.diminfo[1].shape = __pyx_pybuffernd_D.rcbuffer->pybuffer.shape[1];
}
}
__pyx_t_6 = 0;
__pyx_v_D = ((PyArrayObject *)__pyx_t_1);
__pyx_t_1 = 0;
+23: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+24: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+25: D[i,j] = dist(A[i], B[j])
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_dist); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_2 = __Pyx_GetItemInt(((PyObject *)__pyx_v_A), __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_5 = __Pyx_GetItemInt(((PyObject *)__pyx_v_B), __pyx_v_j, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__pyx_t_4 = NULL;
__pyx_t_11 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
__pyx_t_11 = 1;
}
}
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_11, 2+__pyx_t_11); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_12 = PyTuple_New(2+__pyx_t_11); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_12);
if (__pyx_t_4) {
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_4); __pyx_t_4 = NULL;
}
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_12, 0+__pyx_t_11, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_12, 1+__pyx_t_11, __pyx_t_5);
__pyx_t_2 = 0;
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_12, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_13 == ((npy_float64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_t_14 = __pyx_v_i;
__pyx_t_15 = __pyx_v_j;
__pyx_t_11 = -1;
if (__pyx_t_14 < 0) {
__pyx_t_14 += __pyx_pybuffernd_D.diminfo[0].shape;
if (unlikely(__pyx_t_14 < 0)) __pyx_t_11 = 0;
} else if (unlikely(__pyx_t_14 >= __pyx_pybuffernd_D.diminfo[0].shape)) __pyx_t_11 = 0;
if (__pyx_t_15 < 0) {
__pyx_t_15 += __pyx_pybuffernd_D.diminfo[1].shape;
if (unlikely(__pyx_t_15 < 0)) __pyx_t_11 = 1;
} else if (unlikely(__pyx_t_15 >= __pyx_pybuffernd_D.diminfo[1].shape)) __pyx_t_11 = 1;
if (unlikely(__pyx_t_11 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_11);
__PYX_ERR(0, 25, __pyx_L1_error)
}
*__Pyx_BufPtrStrided2d(__pyx_t_46_cython_magic_3ab6171dbfe4bc4aec552e931e888117_float64_t *, __pyx_pybuffernd_D.rcbuffer->pybuffer.buf, __pyx_t_14, __pyx_pybuffernd_D.diminfo[0].strides, __pyx_t_15, __pyx_pybuffernd_D.diminfo[1].strides) = __pyx_t_13;
}
}
+26: return D
__Pyx_XDECREF(__pyx_r);
__Pyx_INCREF(((PyObject *)__pyx_v_D));
__pyx_r = ((PyObject *)__pyx_v_D);
goto __pyx_L0;
In [122]:
%timeit -n 10 distance_matrix_cython2(A,B)
10 loops, best of 3: 1.17 s per loop
Typed memoryviews allow efficient access to memory buffers, such as those underlying NumPy arrays, without incurring any Python overhead. Memoryviews are similar to the current NumPy array buffer support (np.ndarray[np.float64_t, ndim=2]), but they have more features and cleaner syntax.
They can handle a wider variety of sources of array data. For example, they can handle C arrays and the Cython array type (Cython arrays).
Syntaxis: dtype[:,::1]
where ::1
indicates the axis where elements are contiguous.
In [19]:
%%cython -a
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
from libc.math cimport sqrt
def dist(float64_t[::1] a, float64_t[::1] b):
cdef:
int i = 0
int n = a.shape[0]
float ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return sqrt(ret)
def distance_matrix_cython3(float64_t[:,::1] A, float64_t[:,::1] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
float64_t[:,::1] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i], B[j])
return D
Out[19]:
Cython: _cython_magic_0b434337ca1aa0c18339dae232dd3e72.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: cimport numpy as cnp
03:
04: ctypedef cnp.float64_t float64_t
05: from libc.math cimport sqrt
06:
+07: def dist(float64_t[::1] a, float64_t[::1] b):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_1dist = {"dist", (PyCFunction)__pyx_pw_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_1dist, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_a = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_b = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, 1); __PYX_ERR(0, 7, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dist") < 0)) __PYX_ERR(0, 7, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_a = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t(values[0]); if (unlikely(!__pyx_v_a.memview)) __PYX_ERR(0, 7, __pyx_L3_error)
__pyx_v_b = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t(values[1]); if (unlikely(!__pyx_v_b.memview)) __PYX_ERR(0, 7, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 7, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_0b434337ca1aa0c18339dae232dd3e72.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_dist(__pyx_self, __pyx_v_a, __pyx_v_b);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_dist(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b) {
int __pyx_v_i;
int __pyx_v_n;
float __pyx_v_ret;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_6);
__Pyx_AddTraceback("_cython_magic_0b434337ca1aa0c18339dae232dd3e72.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_a, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_b, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__23 = PyTuple_Pack(5, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__23);
__Pyx_GIVEREF(__pyx_tuple__23);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_1dist, NULL, __pyx_n_s_cython_magic_0b434337ca1aa0c183); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_dist, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_dist, 7, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 7, __pyx_L1_error)
08: cdef:
+09: int i = 0
__pyx_v_i = 0;
+10: int n = a.shape[0]
__pyx_v_n = (__pyx_v_a.shape[0]);
+11: float ret = 0
__pyx_v_ret = 0.0;
+12: for i in range(n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+13: ret += (a[i]-b[i])**2
__pyx_t_3 = __pyx_v_i;
__pyx_t_4 = -1;
if (__pyx_t_3 < 0) {
__pyx_t_3 += __pyx_v_a.shape[0];
if (unlikely(__pyx_t_3 < 0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_3 >= __pyx_v_a.shape[0])) __pyx_t_4 = 0;
if (unlikely(__pyx_t_4 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_4);
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_t_5 = __pyx_v_i;
__pyx_t_4 = -1;
if (__pyx_t_5 < 0) {
__pyx_t_5 += __pyx_v_b.shape[0];
if (unlikely(__pyx_t_5 < 0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_5 >= __pyx_v_b.shape[0])) __pyx_t_4 = 0;
if (unlikely(__pyx_t_4 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_4);
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_v_ret = (__pyx_v_ret + pow(((*((__pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t *) __pyx_v_a.data) + __pyx_t_3)) ))) - (*((__pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t *) __pyx_v_b.data) + __pyx_t_5)) )))), 2.0));
}
+14: return sqrt(ret)
__Pyx_XDECREF(__pyx_r);
__pyx_t_6 = PyFloat_FromDouble(sqrt(__pyx_v_ret)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__pyx_r = __pyx_t_6;
__pyx_t_6 = 0;
goto __pyx_L0;
15:
16:
+17: def distance_matrix_cython3(float64_t[:,::1] A, float64_t[:,::1] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_3distance_matrix_cython3(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_3distance_matrix_cython3 = {"distance_matrix_cython3", (PyCFunction)__pyx_pw_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_3distance_matrix_cython3, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_3distance_matrix_cython3(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_A = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_B = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython3 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython3", 1, 2, 2, 1); __PYX_ERR(0, 17, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython3") < 0)) __PYX_ERR(0, 17, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t(values[0]); if (unlikely(!__pyx_v_A.memview)) __PYX_ERR(0, 17, __pyx_L3_error)
__pyx_v_B = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t(values[1]); if (unlikely(!__pyx_v_B.memview)) __PYX_ERR(0, 17, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython3", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 17, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_0b434337ca1aa0c18339dae232dd3e72.distance_matrix_cython3", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_2distance_matrix_cython3(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_2distance_matrix_cython3(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_A, __Pyx_memviewslice __pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
__Pyx_memviewslice __pyx_v_D = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython3", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__Pyx_XDECREF(__pyx_t_13);
__Pyx_AddTraceback("_cython_magic_0b434337ca1aa0c18339dae232dd3e72.distance_matrix_cython3", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_D, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_A, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_B, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__25 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__25);
__Pyx_GIVEREF(__pyx_tuple__25);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_3distance_matrix_cython3, NULL, __pyx_n_s_cython_magic_0b434337ca1aa0c183); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython3, __pyx_t_1) < 0) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_distance_matrix_cython3, 17, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 17, __pyx_L1_error)
18: cdef:
+19: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A.shape[0]);
+20: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B.shape[0]);
21: int i,j
+22: float64_t[:,::1] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t(__pyx_t_1);
if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_D = __pyx_t_6;
__pyx_t_6.memview = NULL;
__pyx_t_6.data = NULL;
+23: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+24: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+25: D[i,j] = dist(A[i], B[j])
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_dist); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_11.data = __pyx_v_A.data;
__pyx_t_11.memview = __pyx_v_A.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_i;
Py_ssize_t __pyx_tmp_shape = __pyx_v_A.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_A.strides[0];
if (1 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (1 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 25, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_A.shape[1];
__pyx_t_11.strides[0] = __pyx_v_A.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_2 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__pyx_t_11.data = __pyx_v_B.data;
__pyx_t_11.memview = __pyx_v_B.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_j;
Py_ssize_t __pyx_tmp_shape = __pyx_v_B.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_B.strides[0];
if (1 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (1 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 25, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_B.shape[1];
__pyx_t_11.strides[0] = __pyx_v_B.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_5 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t, 0);; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__pyx_t_4 = NULL;
__pyx_t_12 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
__pyx_t_12 = 1;
}
}
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_13 = PyTuple_New(2+__pyx_t_12); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
if (__pyx_t_4) {
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_4); __pyx_t_4 = NULL;
}
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_12, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_12, __pyx_t_5);
__pyx_t_2 = 0;
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_13, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_14 == ((npy_float64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_t_15 = __pyx_v_i;
__pyx_t_16 = __pyx_v_j;
__pyx_t_12 = -1;
if (__pyx_t_15 < 0) {
__pyx_t_15 += __pyx_v_D.shape[0];
if (unlikely(__pyx_t_15 < 0)) __pyx_t_12 = 0;
} else if (unlikely(__pyx_t_15 >= __pyx_v_D.shape[0])) __pyx_t_12 = 0;
if (__pyx_t_16 < 0) {
__pyx_t_16 += __pyx_v_D.shape[1];
if (unlikely(__pyx_t_16 < 0)) __pyx_t_12 = 1;
} else if (unlikely(__pyx_t_16 >= __pyx_v_D.shape[1])) __pyx_t_12 = 1;
if (unlikely(__pyx_t_12 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_12);
__PYX_ERR(0, 25, __pyx_L1_error)
}
*((__pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t *) ( /* dim=0 */ (__pyx_v_D.data + __pyx_t_15 * __pyx_v_D.strides[0]) )) + __pyx_t_16)) )) = __pyx_t_14;
}
}
+26: return D
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_D, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_0b434337ca1aa0c18339dae232dd3e72_float64_t, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
In [20]:
%timeit -n 10 distance_matrix_cython3(A,B)
10 loops, best of 3: 370 ms per loop
In [21]:
%%cython -a -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
from libc.math cimport sqrt
def dist(float64_t[::1] a, float64_t[::1] b):
cdef:
int i = 0
int n = a.shape[0]
float ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return sqrt(ret)
def distance_matrix_cython4(float64_t[:,::1] A, float64_t[:,::1] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
float64_t[:,::1] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i], B[j])
return D
Out[21]:
Cython: _cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: cimport numpy as cnp
03:
04: ctypedef cnp.float64_t float64_t
05: from libc.math cimport sqrt
06:
+07: def dist(float64_t[::1] a, float64_t[::1] b):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_1dist = {"dist", (PyCFunction)__pyx_pw_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_1dist, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_a = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_b = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, 1); __PYX_ERR(0, 7, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dist") < 0)) __PYX_ERR(0, 7, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_a = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t(values[0]); if (unlikely(!__pyx_v_a.memview)) __PYX_ERR(0, 7, __pyx_L3_error)
__pyx_v_b = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t(values[1]); if (unlikely(!__pyx_v_b.memview)) __PYX_ERR(0, 7, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 7, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_dist(__pyx_self, __pyx_v_a, __pyx_v_b);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_dist(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b) {
int __pyx_v_i;
int __pyx_v_n;
float __pyx_v_ret;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_6);
__Pyx_AddTraceback("_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_a, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_b, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__23 = PyTuple_Pack(5, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__23);
__Pyx_GIVEREF(__pyx_tuple__23);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_1dist, NULL, __pyx_n_s_cython_magic_f8ce0c70262cdf15fd); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_dist, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_dist, 7, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 7, __pyx_L1_error)
08: cdef:
+09: int i = 0
__pyx_v_i = 0;
+10: int n = a.shape[0]
__pyx_v_n = (__pyx_v_a.shape[0]);
+11: float ret = 0
__pyx_v_ret = 0.0;
+12: for i in range(n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+13: ret += (a[i]-b[i])**2
__pyx_t_3 = __pyx_v_i;
__pyx_t_4 = -1;
if (__pyx_t_3 < 0) {
__pyx_t_3 += __pyx_v_a.shape[0];
if (unlikely(__pyx_t_3 < 0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_3 >= __pyx_v_a.shape[0])) __pyx_t_4 = 0;
if (unlikely(__pyx_t_4 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_4);
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_t_5 = __pyx_v_i;
__pyx_t_4 = -1;
if (__pyx_t_5 < 0) {
__pyx_t_5 += __pyx_v_b.shape[0];
if (unlikely(__pyx_t_5 < 0)) __pyx_t_4 = 0;
} else if (unlikely(__pyx_t_5 >= __pyx_v_b.shape[0])) __pyx_t_4 = 0;
if (unlikely(__pyx_t_4 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_4);
__PYX_ERR(0, 13, __pyx_L1_error)
}
__pyx_v_ret = (__pyx_v_ret + pow(((*((__pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t *) __pyx_v_a.data) + __pyx_t_3)) ))) - (*((__pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t *) __pyx_v_b.data) + __pyx_t_5)) )))), 2.0));
}
+14: return sqrt(ret)
__Pyx_XDECREF(__pyx_r);
__pyx_t_6 = PyFloat_FromDouble(sqrt(__pyx_v_ret)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 14, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_6);
__pyx_r = __pyx_t_6;
__pyx_t_6 = 0;
goto __pyx_L0;
15:
16:
+17: def distance_matrix_cython4(float64_t[:,::1] A, float64_t[:,::1] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_3distance_matrix_cython4(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_3distance_matrix_cython4 = {"distance_matrix_cython4", (PyCFunction)__pyx_pw_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_3distance_matrix_cython4, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_3distance_matrix_cython4(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_A = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_B = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython4 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython4", 1, 2, 2, 1); __PYX_ERR(0, 17, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython4") < 0)) __PYX_ERR(0, 17, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t(values[0]); if (unlikely(!__pyx_v_A.memview)) __PYX_ERR(0, 17, __pyx_L3_error)
__pyx_v_B = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t(values[1]); if (unlikely(!__pyx_v_B.memview)) __PYX_ERR(0, 17, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython4", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 17, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e.distance_matrix_cython4", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_2distance_matrix_cython4(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_2distance_matrix_cython4(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_A, __Pyx_memviewslice __pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
__Pyx_memviewslice __pyx_v_D = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython4", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__Pyx_XDECREF(__pyx_t_13);
__Pyx_AddTraceback("_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e.distance_matrix_cython4", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_D, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_A, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_B, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__25 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__25);
__Pyx_GIVEREF(__pyx_tuple__25);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_3distance_matrix_cython4, NULL, __pyx_n_s_cython_magic_f8ce0c70262cdf15fd); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython4, __pyx_t_1) < 0) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_distance_matrix_cython4, 17, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 17, __pyx_L1_error)
18: cdef:
+19: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A.shape[0]);
+20: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B.shape[0]);
21: int i,j
+22: float64_t[:,::1] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t(__pyx_t_1);
if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 22, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_D = __pyx_t_6;
__pyx_t_6.memview = NULL;
__pyx_t_6.data = NULL;
+23: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+24: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+25: D[i,j] = dist(A[i], B[j])
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_dist); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_11.data = __pyx_v_A.data;
__pyx_t_11.memview = __pyx_v_A.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_i;
Py_ssize_t __pyx_tmp_shape = __pyx_v_A.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_A.strides[0];
if (1 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (1 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 25, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_A.shape[1];
__pyx_t_11.strides[0] = __pyx_v_A.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_2 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__pyx_t_11.data = __pyx_v_B.data;
__pyx_t_11.memview = __pyx_v_B.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_j;
Py_ssize_t __pyx_tmp_shape = __pyx_v_B.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_B.strides[0];
if (1 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (1 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 25, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_B.shape[1];
__pyx_t_11.strides[0] = __pyx_v_B.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_5 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t, 0);; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__pyx_t_4 = NULL;
__pyx_t_12 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
__pyx_t_12 = 1;
}
}
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_13 = PyTuple_New(2+__pyx_t_12); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
if (__pyx_t_4) {
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_4); __pyx_t_4 = NULL;
}
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_12, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_12, __pyx_t_5);
__pyx_t_2 = 0;
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_13, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_14 == ((npy_float64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_t_15 = __pyx_v_i;
__pyx_t_16 = __pyx_v_j;
__pyx_t_12 = -1;
if (__pyx_t_15 < 0) {
__pyx_t_15 += __pyx_v_D.shape[0];
if (unlikely(__pyx_t_15 < 0)) __pyx_t_12 = 0;
} else if (unlikely(__pyx_t_15 >= __pyx_v_D.shape[0])) __pyx_t_12 = 0;
if (__pyx_t_16 < 0) {
__pyx_t_16 += __pyx_v_D.shape[1];
if (unlikely(__pyx_t_16 < 0)) __pyx_t_12 = 1;
} else if (unlikely(__pyx_t_16 >= __pyx_v_D.shape[1])) __pyx_t_12 = 1;
if (unlikely(__pyx_t_12 != -1)) {
__Pyx_RaiseBufferIndexError(__pyx_t_12);
__PYX_ERR(0, 25, __pyx_L1_error)
}
*((__pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t *) ( /* dim=0 */ (__pyx_v_D.data + __pyx_t_15 * __pyx_v_D.strides[0]) )) + __pyx_t_16)) )) = __pyx_t_14;
}
}
+26: return D
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_D, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_f8ce0c70262cdf15fd0d44d07af61b5e_float64_t, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
In [22]:
%timeit -n 10 distance_matrix_cython4(A,B)
10 loops, best of 3: 368 ms per loop
Compiler directives are instructions which affect the behavior of Cython code.
cdivision
(True / False)
boundscheck
(True / False)
nonecheck
(True / False)
wraparound
(True / False)
initializedcheck
(True / False)
For all the compilation directives see here.
In [23]:
%%cython -a -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
#!python
#cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
from libc.math cimport sqrt
def dist(float64_t[::1] a, float64_t[::1] b):
cdef:
int i = 0
int n = a.shape[0]
float ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return sqrt(ret)
def distance_matrix_cython5(float64_t[:,::1] A, float64_t[:,::1] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
float64_t[:,::1] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i,:], B[j,:])
return D
Out[23]:
Cython: _cython_magic_9c0c3b17c4f6bac0815df807cbf0eead.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: #!python
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: #cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
03:
+04: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
05: cimport numpy as cnp
06:
07: ctypedef cnp.float64_t float64_t
08: from libc.math cimport sqrt
09:
+10: def dist(float64_t[::1] a, float64_t[::1] b):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_1dist = {"dist", (PyCFunction)__pyx_pw_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_1dist, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_1dist(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_a = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_b = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, 1); __PYX_ERR(0, 10, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "dist") < 0)) __PYX_ERR(0, 10, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_a = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t(values[0]); if (unlikely(!__pyx_v_a.memview)) __PYX_ERR(0, 10, __pyx_L3_error)
__pyx_v_b = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t(values[1]); if (unlikely(!__pyx_v_b.memview)) __PYX_ERR(0, 10, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("dist", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 10, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_dist(__pyx_self, __pyx_v_a, __pyx_v_b);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_dist(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b) {
int __pyx_v_i;
int __pyx_v_n;
float __pyx_v_ret;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_5);
__Pyx_AddTraceback("_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead.dist", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_a, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_b, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__23 = PyTuple_Pack(5, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_i, __pyx_n_s_n, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__23);
__Pyx_GIVEREF(__pyx_tuple__23);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_1dist, NULL, __pyx_n_s_cython_magic_9c0c3b17c4f6bac081); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_dist, __pyx_t_1) < 0) __PYX_ERR(0, 10, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_dist, 10, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 10, __pyx_L1_error)
11: cdef:
+12: int i = 0
__pyx_v_i = 0;
+13: int n = a.shape[0]
__pyx_v_n = (__pyx_v_a.shape[0]);
+14: float ret = 0
__pyx_v_ret = 0.0;
+15: for i in range(n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+16: ret += (a[i]-b[i])**2
__pyx_t_3 = __pyx_v_i;
__pyx_t_4 = __pyx_v_i;
__pyx_v_ret = (__pyx_v_ret + pow(((*((__pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t *) __pyx_v_a.data) + __pyx_t_3)) ))) - (*((__pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t *) __pyx_v_b.data) + __pyx_t_4)) )))), 2.0));
}
+17: return sqrt(ret)
__Pyx_XDECREF(__pyx_r);
__pyx_t_5 = PyFloat_FromDouble(sqrt(__pyx_v_ret)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 17, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__pyx_r = __pyx_t_5;
__pyx_t_5 = 0;
goto __pyx_L0;
18:
19:
+20: def distance_matrix_cython5(float64_t[:,::1] A, float64_t[:,::1] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_3distance_matrix_cython5(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_3distance_matrix_cython5 = {"distance_matrix_cython5", (PyCFunction)__pyx_pw_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_3distance_matrix_cython5, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_3distance_matrix_cython5(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_A = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_B = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython5 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython5", 1, 2, 2, 1); __PYX_ERR(0, 20, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython5") < 0)) __PYX_ERR(0, 20, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t(values[0]); if (unlikely(!__pyx_v_A.memview)) __PYX_ERR(0, 20, __pyx_L3_error)
__pyx_v_B = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t(values[1]); if (unlikely(!__pyx_v_B.memview)) __PYX_ERR(0, 20, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython5", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 20, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead.distance_matrix_cython5", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_2distance_matrix_cython5(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_2distance_matrix_cython5(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_A, __Pyx_memviewslice __pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
__Pyx_memviewslice __pyx_v_D = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython5", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__Pyx_XDECREF(__pyx_t_13);
__Pyx_AddTraceback("_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead.distance_matrix_cython5", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_D, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_A, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_B, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__25 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 20, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__25);
__Pyx_GIVEREF(__pyx_tuple__25);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_3distance_matrix_cython5, NULL, __pyx_n_s_cython_magic_9c0c3b17c4f6bac081); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 20, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython5, __pyx_t_1) < 0) __PYX_ERR(0, 20, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_distance_matrix_cython5, 20, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 20, __pyx_L1_error)
21: cdef:
+22: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A.shape[0]);
+23: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B.shape[0]);
24: int i,j
+25: float64_t[:,::1] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t(__pyx_t_1);
if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_D = __pyx_t_6;
__pyx_t_6.memview = NULL;
__pyx_t_6.data = NULL;
+26: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+27: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+28: D[i,j] = dist(A[i,:], B[j,:])
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_dist); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_11.data = __pyx_v_A.data;
__pyx_t_11.memview = __pyx_v_A.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_i;
Py_ssize_t __pyx_tmp_shape = __pyx_v_A.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_A.strides[0];
if (0 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 28, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_A.shape[1];
__pyx_t_11.strides[0] = __pyx_v_A.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_2 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t, 0);; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__pyx_t_11.data = __pyx_v_B.data;
__pyx_t_11.memview = __pyx_v_B.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_j;
Py_ssize_t __pyx_tmp_shape = __pyx_v_B.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_B.strides[0];
if (0 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 28, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_B.shape[1];
__pyx_t_11.strides[0] = __pyx_v_B.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_5 = __pyx_memoryview_fromslice(__pyx_t_11, 1, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t, 0);; if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__pyx_t_4 = NULL;
__pyx_t_12 = 0;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
__pyx_t_12 = 1;
}
}
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[3] = {__pyx_t_4, __pyx_t_2, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 2+__pyx_t_12); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_13 = PyTuple_New(2+__pyx_t_12); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_13);
if (__pyx_t_4) {
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_4); __pyx_t_4 = NULL;
}
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_12, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_12, __pyx_t_5);
__pyx_t_2 = 0;
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_13, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_t_1); if (unlikely((__pyx_t_14 == ((npy_float64)-1)) && PyErr_Occurred())) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_t_15 = __pyx_v_i;
__pyx_t_16 = __pyx_v_j;
*((__pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t *) ( /* dim=0 */ (__pyx_v_D.data + __pyx_t_15 * __pyx_v_D.strides[0]) )) + __pyx_t_16)) )) = __pyx_t_14;
}
}
+29: return D
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_D, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_9c0c3b17c4f6bac0815df807cbf0eead_float64_t, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
In [24]:
%timeit -n 10 distance_matrix_cython5(A,B)
10 loops, best of 3: 365 ms per loop
With the cdef
keywork we can realy define C function, as we shown below. In such functions all variable types should be defined and should have a return type, and can't be called directly in Python, i.e, only can be called by functions defined in the same module.
There is a midpoint between def
and cdef
which automatically creates a Python function with the same name, so the function can be called directly.
In [25]:
%%cython -a -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
#!python
#cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
from libc.math cimport sqrt
cdef float64_t dist(float64_t[::1] a, float64_t[::1] b):
cdef:
int i = 0
int n = a.shape[0]
float ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return sqrt(ret)
def distance_matrix_cython6(float64_t[:,::1] A, float64_t[:,::1] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
float64_t[:,::1] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i,:], B[j,:])
return D
Out[25]:
Cython: _cython_magic_55f47f37023751be50bd87c6d8f78ec3.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: #!python
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: #cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
03:
+04: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
05: cimport numpy as cnp
06:
07: ctypedef cnp.float64_t float64_t
08: from libc.math cimport sqrt
09:
+10: cdef float64_t dist(float64_t[::1] a, float64_t[::1] b):
static __pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t __pyx_f_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_dist(__Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b) {
int __pyx_v_i;
int __pyx_v_n;
float __pyx_v_ret;
__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
/* … */
/* function exit code */
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
11: cdef:
+12: int i = 0
__pyx_v_i = 0;
+13: int n = a.shape[0]
__pyx_v_n = (__pyx_v_a.shape[0]);
+14: float ret = 0
__pyx_v_ret = 0.0;
+15: for i in range(n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+16: ret += (a[i]-b[i])**2
__pyx_t_3 = __pyx_v_i;
__pyx_t_4 = __pyx_v_i;
__pyx_v_ret = (__pyx_v_ret + pow(((*((__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t *) __pyx_v_a.data) + __pyx_t_3)) ))) - (*((__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t *) __pyx_v_b.data) + __pyx_t_4)) )))), 2.0));
}
+17: return sqrt(ret)
__pyx_r = sqrt(__pyx_v_ret);
goto __pyx_L0;
18:
19:
+20: def distance_matrix_cython6(float64_t[:,::1] A, float64_t[:,::1] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_1distance_matrix_cython6(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_1distance_matrix_cython6 = {"distance_matrix_cython6", (PyCFunction)__pyx_pw_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_1distance_matrix_cython6, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_1distance_matrix_cython6(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_A = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_B = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython6 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython6", 1, 2, 2, 1); __PYX_ERR(0, 20, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython6") < 0)) __PYX_ERR(0, 20, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t(values[0]); if (unlikely(!__pyx_v_A.memview)) __PYX_ERR(0, 20, __pyx_L3_error)
__pyx_v_B = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t(values[1]); if (unlikely(!__pyx_v_B.memview)) __PYX_ERR(0, 20, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython6", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 20, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_55f47f37023751be50bd87c6d8f78ec3.distance_matrix_cython6", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_distance_matrix_cython6(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_distance_matrix_cython6(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_A, __Pyx_memviewslice __pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
__Pyx_memviewslice __pyx_v_D = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython6", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
__Pyx_AddTraceback("_cython_magic_55f47f37023751be50bd87c6d8f78ec3.distance_matrix_cython6", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_D, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_A, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_B, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__23 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 20, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__23);
__Pyx_GIVEREF(__pyx_tuple__23);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_1distance_matrix_cython6, NULL, __pyx_n_s_cython_magic_55f47f37023751be50); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 20, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython6, __pyx_t_1) < 0) __PYX_ERR(0, 20, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_distance_matrix_cython6, 20, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 20, __pyx_L1_error)
21: cdef:
+22: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A.shape[0]);
+23: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B.shape[0]);
24: int i,j
+25: float64_t[:,::1] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t(__pyx_t_1);
if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 25, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_D = __pyx_t_6;
__pyx_t_6.memview = NULL;
__pyx_t_6.data = NULL;
+26: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+27: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+28: D[i,j] = dist(A[i,:], B[j,:])
__pyx_t_11.data = __pyx_v_A.data;
__pyx_t_11.memview = __pyx_v_A.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_i;
Py_ssize_t __pyx_tmp_shape = __pyx_v_A.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_A.strides[0];
if (0 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 28, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_A.shape[1];
__pyx_t_11.strides[0] = __pyx_v_A.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_12.data = __pyx_v_B.data;
__pyx_t_12.memview = __pyx_v_B.memview;
__PYX_INC_MEMVIEW(&__pyx_t_12, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_j;
Py_ssize_t __pyx_tmp_shape = __pyx_v_B.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_B.strides[0];
if (0 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 28, __pyx_L1_error)
}
__pyx_t_12.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_12.shape[0] = __pyx_v_B.shape[1];
__pyx_t_12.strides[0] = __pyx_v_B.strides[1];
__pyx_t_12.suboffsets[0] = -1;
__pyx_t_13 = __pyx_v_i;
__pyx_t_14 = __pyx_v_j;
*((__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t *) ( /* dim=0 */ (__pyx_v_D.data + __pyx_t_13 * __pyx_v_D.strides[0]) )) + __pyx_t_14)) )) = __pyx_f_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_dist(__pyx_t_11, __pyx_t_12);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
__pyx_t_12.memview = NULL;
__pyx_t_12.data = NULL;
}
}
+29: return D
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_D, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_55f47f37023751be50bd87c6d8f78ec3_float64_t, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
In [26]:
%timeit -n 10 distance_matrix_cython6(A,B)
10 loops, best of 3: 17.7 ms per loop
In [29]:
%%cython -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
#!python
#cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
cdef float64_t test1(float64_t a, float64_t b):
return a+b
In [31]:
test1(1.,1.)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-31-f4ee9cdb0154> in <module>()
----> 1 test1(1.,1.)
NameError: name 'test1' is not defined
In [32]:
%%cython -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
#!python
#cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
cpdef float64_t test2(float64_t a, float64_t b):
return a+b
In [33]:
test2(1,1)
Out[33]:
2.0
In computing, inline expansion, or inlining, is a manual or compiler optimization that replaces a function call site with the body of the called function.
As a rule of thumb: Some inlining will improve speed at very minor cost of space, but excess inlining will hurt speed, due to inlined code consuming too much of the instruction cache, and also cost significant space.
In [34]:
%%cython -a -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
#!python
#cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
import numpy as np
cimport numpy as cnp
ctypedef cnp.float64_t float64_t
from libc.math cimport sqrt
cdef inline float64_t dist(float64_t[::1] a, float64_t[::1] b):
cdef:
int i = 0
int n = a.shape[0]
float ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return sqrt(ret)
def distance_matrix_cython7(float64_t[:,::1] A, float64_t[:,::1] B):
cdef:
int m = A.shape[0]
int n = B.shape[0]
int i,j
float64_t[:,::1] D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i,:], B[j,:])
return D
Out[34]:
Cython: _cython_magic_4f7592de4881141d314a4e9ccb0eb6e6.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
+01: #!python
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: #cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
03:
+04: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
05: cimport numpy as cnp
06:
07: ctypedef cnp.float64_t float64_t
08: from libc.math cimport sqrt
09:
+10: cdef inline float64_t dist(float64_t[::1] a, float64_t[::1] b):
static CYTHON_INLINE __pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t __pyx_f_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_dist(__Pyx_memviewslice __pyx_v_a, __Pyx_memviewslice __pyx_v_b) {
int __pyx_v_i;
int __pyx_v_n;
float __pyx_v_ret;
__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("dist", 0);
/* … */
/* function exit code */
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
11: cdef:
+12: int i = 0
__pyx_v_i = 0;
+13: int n = a.shape[0]
__pyx_v_n = (__pyx_v_a.shape[0]);
+14: float ret = 0
__pyx_v_ret = 0.0;
+15: for i in range(n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+16: ret += (a[i]-b[i])**2
__pyx_t_3 = __pyx_v_i;
__pyx_t_4 = __pyx_v_i;
__pyx_v_ret = (__pyx_v_ret + pow(((*((__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t *) __pyx_v_a.data) + __pyx_t_3)) ))) - (*((__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t *) ( /* dim=0 */ ((char *) (((__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t *) __pyx_v_b.data) + __pyx_t_4)) )))), 2.0));
}
+17: return sqrt(ret)
__pyx_r = sqrt(__pyx_v_ret);
goto __pyx_L0;
18:
+19: def distance_matrix_cython7(float64_t[:,::1] A, float64_t[:,::1] B):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_1distance_matrix_cython7(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_1distance_matrix_cython7 = {"distance_matrix_cython7", (PyCFunction)__pyx_pw_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_1distance_matrix_cython7, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_1distance_matrix_cython7(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_A = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_B = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython7 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_A,&__pyx_n_s_B,0};
PyObject* values[2] = {0,0};
if (unlikely(__pyx_kwds)) {
Py_ssize_t kw_args;
const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
switch (pos_args) {
case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
case 0: break;
default: goto __pyx_L5_argtuple_error;
}
kw_args = PyDict_Size(__pyx_kwds);
switch (pos_args) {
case 0:
if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_A)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_B)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython7", 1, 2, 2, 1); __PYX_ERR(0, 19, __pyx_L3_error)
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "distance_matrix_cython7") < 0)) __PYX_ERR(0, 19, __pyx_L3_error)
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
}
__pyx_v_A = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t(values[0]); if (unlikely(!__pyx_v_A.memview)) __PYX_ERR(0, 19, __pyx_L3_error)
__pyx_v_B = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t(values[1]); if (unlikely(!__pyx_v_B.memview)) __PYX_ERR(0, 19, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("distance_matrix_cython7", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 19, __pyx_L3_error)
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6.distance_matrix_cython7", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_distance_matrix_cython7(__pyx_self, __pyx_v_A, __pyx_v_B);
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_distance_matrix_cython7(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_A, __Pyx_memviewslice __pyx_v_B) {
int __pyx_v_m;
int __pyx_v_n;
int __pyx_v_i;
int __pyx_v_j;
__Pyx_memviewslice __pyx_v_D = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("distance_matrix_cython7", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_XDECREF(__pyx_t_5);
__PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
__Pyx_AddTraceback("_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6.distance_matrix_cython7", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_D, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_A, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_B, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__23 = PyTuple_Pack(7, __pyx_n_s_A, __pyx_n_s_B, __pyx_n_s_m, __pyx_n_s_n, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_D); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_GOTREF(__pyx_tuple__23);
__Pyx_GIVEREF(__pyx_tuple__23);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_1distance_matrix_cython7, NULL, __pyx_n_s_cython_magic_4f7592de4881141d31); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_distance_matrix_cython7, __pyx_t_1) < 0) __PYX_ERR(0, 19, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(2, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_martin_ipython_cython__cy, __pyx_n_s_distance_matrix_cython7, 19, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 19, __pyx_L1_error)
20: cdef:
+21: int m = A.shape[0]
__pyx_v_m = (__pyx_v_A.shape[0]);
+22: int n = B.shape[0]
__pyx_v_n = (__pyx_v_B.shape[0]);
23: int i,j
+24: float64_t[:,::1] D = np.empty((m,n))
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __Pyx_PyInt_From_int(__pyx_v_m); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_n); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_5);
__Pyx_GIVEREF(__pyx_t_2);
PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_4);
__pyx_t_2 = 0;
__pyx_t_4 = 0;
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (!__pyx_t_4) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
#if CYTHON_FAST_PYCALL
if (PyFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
#if CYTHON_FAST_PYCCALL
if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_5};
__pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
} else
#endif
{
__pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_2);
__Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __pyx_t_4 = NULL;
__Pyx_GIVEREF(__pyx_t_5);
PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
__pyx_t_5 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
}
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t(__pyx_t_1);
if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 24, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_D = __pyx_t_6;
__pyx_t_6.memview = NULL;
__pyx_t_6.data = NULL;
+25: for i in range(m):
__pyx_t_7 = __pyx_v_m;
for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+26: for j in range(n):
__pyx_t_9 = __pyx_v_n;
for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
__pyx_v_j = __pyx_t_10;
+27: D[i,j] = dist(A[i,:], B[j,:])
__pyx_t_11.data = __pyx_v_A.data;
__pyx_t_11.memview = __pyx_v_A.memview;
__PYX_INC_MEMVIEW(&__pyx_t_11, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_i;
Py_ssize_t __pyx_tmp_shape = __pyx_v_A.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_A.strides[0];
if (0 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 27, __pyx_L1_error)
}
__pyx_t_11.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_11.shape[0] = __pyx_v_A.shape[1];
__pyx_t_11.strides[0] = __pyx_v_A.strides[1];
__pyx_t_11.suboffsets[0] = -1;
__pyx_t_12.data = __pyx_v_B.data;
__pyx_t_12.memview = __pyx_v_B.memview;
__PYX_INC_MEMVIEW(&__pyx_t_12, 0);
{
Py_ssize_t __pyx_tmp_idx = __pyx_v_j;
Py_ssize_t __pyx_tmp_shape = __pyx_v_B.shape[0];
Py_ssize_t __pyx_tmp_stride = __pyx_v_B.strides[0];
if (0 && (__pyx_tmp_idx < 0))
__pyx_tmp_idx += __pyx_tmp_shape;
if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 0)");
__PYX_ERR(0, 27, __pyx_L1_error)
}
__pyx_t_12.data += __pyx_tmp_idx * __pyx_tmp_stride;
}
__pyx_t_12.shape[0] = __pyx_v_B.shape[1];
__pyx_t_12.strides[0] = __pyx_v_B.strides[1];
__pyx_t_12.suboffsets[0] = -1;
__pyx_t_13 = __pyx_v_i;
__pyx_t_14 = __pyx_v_j;
*((__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t *) ( /* dim=0 */ (__pyx_v_D.data + __pyx_t_13 * __pyx_v_D.strides[0]) )) + __pyx_t_14)) )) = __pyx_f_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_dist(__pyx_t_11, __pyx_t_12);
__PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
__pyx_t_11.memview = NULL;
__pyx_t_11.data = NULL;
__PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
__pyx_t_12.memview = NULL;
__pyx_t_12.data = NULL;
}
}
+28: return D
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_D, 2, (PyObject *(*)(char *)) __pyx_memview_get_nn___pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t, (int (*)(char *, PyObject *)) __pyx_memview_set_nn___pyx_t_46_cython_magic_4f7592de4881141d314a4e9ccb0eb6e6_float64_t, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
In [35]:
%timeit -n 10 distance_matrix_cython7(A,B)
10 loops, best of 3: 17.7 ms per loop
In [36]:
@numba.jit(nopython=True)
def dist(a, b):
n = a.shape[0]
ret = 0
for i in range(n):
ret += (a[i]-b[i])**2
return math.sqrt(ret)
@numba.jit(nopython=True)
def distance_matrix_numba(A, B):
m = A.shape[0]
n = B.shape[0]
D = np.empty((m,n))
for i in range(m):
for j in range(n):
D[i,j] = dist(A[i,:], B[j,:])
return D
In [37]:
%timeit -n 10 distance_matrix_numba(A,B)
10 loops, best of 3: 38.7 ms per loop
We have seen that with Cython we can implement our algorithms achieving C performance. Moreover it is very versatile and we can do some other advanced thing with it:
To support object-oriented programming, Cython supports writing normal Python classes exactly as in Python.
In [38]:
%%cython -a -c=-fPIC -c=-fwrapv -c=-O3 -c=-fno-strict-aliasing
#!python
#cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
cdef class A(object):
def d(self): return 0
cdef int c(self): return 0
cpdef int p(self): return 0
def test_def(self, long num):
while num > 0:
self.d()
num -= 1
def test_cdef(self, long num):
while num > 0:
self.c()
num -= 1
def test_cpdef(self, long num):
while num > 0:
self.p()
num -= 1
Out[38]:
Cython: _cython_magic_0022a03a89d67550b61649805488f623.pyx
Generated by Cython 0.25.2
Yellow lines hint at Python interaction.
Click on a line that starts with a "+
" to see the C code that Cython generated for it.
01: #!python
02: #cython: cdivision=True, boundscheck=False, nonecheck=False, wraparound=False, initializedcheck=False
03:
+04: cdef class A(object):
struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A {
PyObject_HEAD
struct __pyx_vtabstruct_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_vtab;
};
struct __pyx_vtabstruct_46_cython_magic_0022a03a89d67550b61649805488f623_A {
int (*c)(struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *);
int (*p)(struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *, int __pyx_skip_dispatch);
};
static struct __pyx_vtabstruct_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_vtabptr_46_cython_magic_0022a03a89d67550b61649805488f623_A;
+05: def d(self): return 0
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_1d(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_1d(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("d (wrapper)", 0);
__pyx_r = __pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_d(((struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_d(CYTHON_UNUSED struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("d", 0);
__Pyx_XDECREF(__pyx_r);
__Pyx_INCREF(__pyx_int_0);
__pyx_r = __pyx_int_0;
goto __pyx_L0;
/* function exit code */
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+06: cdef int c(self): return 0
static int __pyx_f_46_cython_magic_0022a03a89d67550b61649805488f623_1A_c(CYTHON_UNUSED struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self) {
int __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("c", 0);
__pyx_r = 0;
goto __pyx_L0;
/* function exit code */
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+07: cpdef int p(self): return 0
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_3p(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static int __pyx_f_46_cython_magic_0022a03a89d67550b61649805488f623_1A_p(CYTHON_UNUSED struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self, int __pyx_skip_dispatch) {
int __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("p", 0);
/* Check if called by wrapper */
if (unlikely(__pyx_skip_dispatch)) ;
/* Check if overridden in Python */
else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
__pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_p); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_3p)) {
__Pyx_INCREF(__pyx_t_1);
__pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (__pyx_t_4) {
__pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
} else {
__pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
}
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_r = __pyx_t_5;
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
goto __pyx_L0;
}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
}
__pyx_r = 0;
goto __pyx_L0;
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_WriteUnraisable("_cython_magic_0022a03a89d67550b61649805488f623.A.p", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
__pyx_r = 0;
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_3p(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_3p(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("p (wrapper)", 0);
__pyx_r = __pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_2p(((struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_2p(struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("p", 0);
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __Pyx_PyInt_From_int(__pyx_f_46_cython_magic_0022a03a89d67550b61649805488f623_1A_p(__pyx_v_self, 1)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_AddTraceback("_cython_magic_0022a03a89d67550b61649805488f623.A.p", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
08:
+09: def test_def(self, long num):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_5test_def(PyObject *__pyx_v_self, PyObject *__pyx_arg_num); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_5test_def(PyObject *__pyx_v_self, PyObject *__pyx_arg_num) {
long __pyx_v_num;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("test_def (wrapper)", 0);
assert(__pyx_arg_num); {
__pyx_v_num = __Pyx_PyInt_As_long(__pyx_arg_num); if (unlikely((__pyx_v_num == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 9, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_0022a03a89d67550b61649805488f623.A.test_def", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_4test_def(((struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self), ((long)__pyx_v_num));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_4test_def(struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self, long __pyx_v_num) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("test_def", 0);
/* … */
/* function exit code */
__pyx_r = Py_None; __Pyx_INCREF(Py_None);
goto __pyx_L0;
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_2);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_XDECREF(__pyx_t_4);
__Pyx_AddTraceback("_cython_magic_0022a03a89d67550b61649805488f623.A.test_def", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+10: while num > 0:
while (1) {
__pyx_t_1 = ((__pyx_v_num > 0) != 0);
if (!__pyx_t_1) break;
+11: self.d()
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_d); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_4 = NULL;
if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_3, function);
}
}
if (__pyx_t_4) {
__pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error)
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
} else {
__pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 11, __pyx_L1_error)
}
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+12: num -= 1
__pyx_v_num = (__pyx_v_num - 1);
}
13:
+14: def test_cdef(self, long num):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_7test_cdef(PyObject *__pyx_v_self, PyObject *__pyx_arg_num); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_7test_cdef(PyObject *__pyx_v_self, PyObject *__pyx_arg_num) {
long __pyx_v_num;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("test_cdef (wrapper)", 0);
assert(__pyx_arg_num); {
__pyx_v_num = __Pyx_PyInt_As_long(__pyx_arg_num); if (unlikely((__pyx_v_num == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 14, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_0022a03a89d67550b61649805488f623.A.test_cdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_6test_cdef(((struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self), ((long)__pyx_v_num));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_6test_cdef(struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self, long __pyx_v_num) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("test_cdef", 0);
/* … */
/* function exit code */
__pyx_r = Py_None; __Pyx_INCREF(Py_None);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+15: while num > 0:
while (1) {
__pyx_t_1 = ((__pyx_v_num > 0) != 0);
if (!__pyx_t_1) break;
+16: self.c()
((struct __pyx_vtabstruct_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self->__pyx_vtab)->c(__pyx_v_self);
+17: num -= 1
__pyx_v_num = (__pyx_v_num - 1);
}
18:
+19: def test_cpdef(self, long num):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_9test_cpdef(PyObject *__pyx_v_self, PyObject *__pyx_arg_num); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_0022a03a89d67550b61649805488f623_1A_9test_cpdef(PyObject *__pyx_v_self, PyObject *__pyx_arg_num) {
long __pyx_v_num;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("test_cpdef (wrapper)", 0);
assert(__pyx_arg_num); {
__pyx_v_num = __Pyx_PyInt_As_long(__pyx_arg_num); if (unlikely((__pyx_v_num == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 19, __pyx_L3_error)
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_0022a03a89d67550b61649805488f623.A.test_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_8test_cpdef(((struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self), ((long)__pyx_v_num));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_0022a03a89d67550b61649805488f623_1A_8test_cpdef(struct __pyx_obj_46_cython_magic_0022a03a89d67550b61649805488f623_A *__pyx_v_self, long __pyx_v_num) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("test_cpdef", 0);
/* … */
/* function exit code */
__pyx_r = Py_None; __Pyx_INCREF(Py_None);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+20: while num > 0:
while (1) {
__pyx_t_1 = ((__pyx_v_num > 0) != 0);
if (!__pyx_t_1) break;
+21: self.p()
((struct __pyx_vtabstruct_46_cython_magic_0022a03a89d67550b61649805488f623_A *)__pyx_v_self->__pyx_vtab)->p(__pyx_v_self, 0);
+22: num -= 1
__pyx_v_num = (__pyx_v_num - 1);
}
In [39]:
%%timeit n = 1000000
a1 = A()
a1.test_def(n)
10 loops, best of 3: 40.2 ms per loop
In [40]:
%%timeit n = 1000000
a1 = A()
a1.test_cdef(n)
100 loops, best of 3: 2.01 ms per loop
In [41]:
%%timeit n = 1000000
a1 = A()
a1.test_cpdef(n)
100 loops, best of 3: 3.11 ms per loop
Wrapper libraries (or library wrappers) consist of a thin layer of code which translates a library's existing interface into a compatible interface. Cython allows us to do this with C libraries... In fact many important project use Cython to do that:
Content source: mavillan/SciProg
Similar notebooks: