Outline:
We want to integrate the function $f(x) = x^4 - 3x$.
In [1]:
def f(x):
y = x**4 - 3*x
return y
def integrate_f(a, b, n):
dx = (b - a) / n
dx2 = dx / 2
s = f(a) * dx2
for i in range(1, n):
s += f(a + i * dx) * dx
s += f(b) * dx2
return s
Now, let's time this:
In [2]:
from scipy.integrate import quad
In [3]:
%timeit quad(f, -100,100)
The slowest run took 4.72 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 15.6 µs per loop
In [4]:
%timeit integrate_f(-100, 100, int(1e5))
10 loops, best of 3: 52.4 ms per loop
Not too bad, but this can add up. Let's see if Cython can do better:
In [5]:
%load_ext cython
In [4]:
%%cython
def f2(x):
y = x**4 - 3*x
return y
def integrate_f2(a, b, n):
dx = (b - a) / n
dx2 = dx / 2
s = f2(a) * dx2
for i in range(1, n):
s += f2(a + i * dx) * dx
s += f2(b) * dx2
return s
In [16]:
%timeit integrate_f2(-100, 100, int(1e5))
10 loops, best of 3: 37.6 ms per loop
That's a little bit faster, which is nice since all we did was to call Cython on the exact same code. But can we do better?
In [17]:
%%cython
def f3(double x):
y = x**4 - 3*x
return y
def integrate_f3(double a, double b, int n):
dx = (b - a) / n
dx2 = dx / 2
s = f3(a) * dx2
for i in range(1, n):
s += f3(a + i * dx) * dx
s += f3(b) * dx2
return s
In [18]:
%timeit integrate_f3(-100, 100, int(1e5))
10 loops, best of 3: 23.8 ms per loop
The final bit of "easy" Cython optimization is "declaring" the variables inside the function:
In [19]:
%%cython
def f4(double x):
y = x**4 - 3*x
return y
def integrate_f4(double a, double b, int n):
cdef:
double dx = (b - a) / n
double dx2 = dx / 2
double s = f4(a) * dx2
int i = 0
for i in range(1, n):
s += f4(a + i * dx) * dx
s += f4(b) * dx2
return s
In [21]:
%timeit integrate_f4(-100, 100, int(1e5))
100 loops, best of 3: 14.8 ms per loop
4X speedup with so little effort is pretty nice. What else can we do?
Cython has a nice "-a" flag (for annotation) that can provide clues about why your code is slow.
In [22]:
%%cython -a
def f4(double x):
y = x**4 - 3*x
return y
def integrate_f4(double a, double b, int n):
cdef:
double dx = (b - a) / n
double dx2 = dx / 2
double s = f4(a) * dx2
int i = 0
for i in range(1, n):
s += f4(a + i * dx) * dx
s += f4(b) * dx2
return s
Out[22]:
Cython: _cython_magic_d12f0b24eb436f44cb71d18b31147b95.pyx
Generated by Cython 0.22.1
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:
+02: def f4(double x):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_1f4(PyObject *__pyx_self, PyObject *__pyx_arg_x); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_1f4 = {"f4", (PyCFunction)__pyx_pw_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_1f4, METH_O, 0};
static PyObject *__pyx_pw_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_1f4(PyObject *__pyx_self, PyObject *__pyx_arg_x) {
double __pyx_v_x;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("f4 (wrapper)", 0);
assert(__pyx_arg_x); {
__pyx_v_x = __pyx_PyFloat_AsDouble(__pyx_arg_x); if (unlikely((__pyx_v_x == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_d12f0b24eb436f44cb71d18b31147b95.f4", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_f4(__pyx_self, ((double)__pyx_v_x));
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_f4(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_x) {
double __pyx_v_y;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("f4", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_AddTraceback("_cython_magic_d12f0b24eb436f44cb71d18b31147b95.f4", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple_ = PyTuple_Pack(3, __pyx_n_s_x, __pyx_n_s_x, __pyx_n_s_y); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple_);
__Pyx_GIVEREF(__pyx_tuple_);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_1f4, NULL, __pyx_n_s_cython_magic_d12f0b24eb436f44cb); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_f4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__2 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple_, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_student_cache_ipython_cyth, __pyx_n_s_f4, 2, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+03: y = x**4 - 3*x
__pyx_v_y = (pow(__pyx_v_x, 4.0) - (3.0 * __pyx_v_x));
+04: return y
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = PyFloat_FromDouble(__pyx_v_y); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 4; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
05:
+06: def integrate_f4(double a, double b, int n):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_3integrate_f4(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_3integrate_f4 = {"integrate_f4", (PyCFunction)__pyx_pw_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_3integrate_f4, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_3integrate_f4(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
double __pyx_v_a;
double __pyx_v_b;
int __pyx_v_n;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("integrate_f4 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_n,0};
PyObject* values[3] = {0,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 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
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("integrate_f4", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
case 2:
if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("integrate_f4", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "integrate_f4") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
}
__pyx_v_a = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_a == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_b = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_b == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_n = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("integrate_f4", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_d12f0b24eb436f44cb71d18b31147b95.integrate_f4", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_2integrate_f4(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_n);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_2integrate_f4(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_a, double __pyx_v_b, int __pyx_v_n) {
double __pyx_v_dx;
double __pyx_v_dx2;
double __pyx_v_s;
int __pyx_v_i;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("integrate_f4", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__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_9);
__Pyx_AddTraceback("_cython_magic_d12f0b24eb436f44cb71d18b31147b95.integrate_f4", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__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_n, __pyx_n_s_dx, __pyx_n_s_dx2, __pyx_n_s_s, __pyx_n_s_i); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple__3);
__Pyx_GIVEREF(__pyx_tuple__3);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_d12f0b24eb436f44cb71d18b31147b95_3integrate_f4, NULL, __pyx_n_s_cython_magic_d12f0b24eb436f44cb); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_integrate_f4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
07: cdef:
+08: double dx = (b - a) / n
__pyx_t_1 = (__pyx_v_b - __pyx_v_a);
if (unlikely(__pyx_v_n == 0)) {
#ifdef WITH_THREAD
PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
#endif
PyErr_SetString(PyExc_ZeroDivisionError, "float division");
#ifdef WITH_THREAD
PyGILState_Release(__pyx_gilstate_save);
#endif
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
}
__pyx_v_dx = (__pyx_t_1 / __pyx_v_n);
+09: double dx2 = dx / 2
__pyx_v_dx2 = (__pyx_v_dx / 2.0);
+10: double s = f4(a) * dx2
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_f4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_4 = PyFloat_FromDouble(__pyx_v_a); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && 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_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_2);
} else {
__pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4);
__pyx_t_4 = 0;
__pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_dx2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_6 = PyNumber_Multiply(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_t_6); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__pyx_v_s = __pyx_t_1;
+11: int i = 0
__pyx_v_i = 0;
+12: for i in range(1, n):
__pyx_t_7 = __pyx_v_n;
for (__pyx_t_8 = 1; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
+13: s += f4(a + i * dx) * dx
__pyx_t_6 = PyFloat_FromDouble(__pyx_v_s); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_f4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = PyFloat_FromDouble((__pyx_v_a + (__pyx_v_i * __pyx_v_dx))); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_4);
__pyx_t_5 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
__pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
if (likely(__pyx_t_5)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
__Pyx_INCREF(__pyx_t_5);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_2, function);
}
}
if (!__pyx_t_5) {
__pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__Pyx_GOTREF(__pyx_t_3);
} else {
__pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_9);
__Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_5); __pyx_t_5 = NULL;
__Pyx_GIVEREF(__pyx_t_4);
PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_4);
__pyx_t_4 = 0;
__pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
}
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = PyFloat_FromDouble(__pyx_v_dx); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_9 = PyNumber_Multiply(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_9);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = PyNumber_InPlaceAdd(__pyx_t_6, __pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
__pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_v_s = __pyx_t_1;
}
+14: s += f4(b) * dx2
__pyx_t_2 = PyFloat_FromDouble(__pyx_v_s); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_f4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_b); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_4 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
__pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6);
if (likely(__pyx_t_4)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
__Pyx_INCREF(__pyx_t_4);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_6, function);
}
}
if (!__pyx_t_4) {
__pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_GOTREF(__pyx_t_9);
} else {
__pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __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_3);
PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
__pyx_t_3 = 0;
__pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_5, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_9);
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
}
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__pyx_t_6 = PyFloat_FromDouble(__pyx_v_dx2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__pyx_t_5 = PyNumber_Multiply(__pyx_t_9, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__pyx_t_6 = PyNumber_InPlaceAdd(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__pyx_t_1 = __pyx_PyFloat_AsDouble(__pyx_t_6); if (unlikely((__pyx_t_1 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
__pyx_v_s = __pyx_t_1;
+15: return s
__Pyx_XDECREF(__pyx_r);
__pyx_t_6 = PyFloat_FromDouble(__pyx_v_s); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 15; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__pyx_r = __pyx_t_6;
__pyx_t_6 = 0;
goto __pyx_L0;
That's a lot of yellow still! How do we reduce this?
In [53]:
%%cython -a
#cython: cdivision=True
#import cython
cdef double f5(double x):
y = x**4 - 3*x
return y
def integrate_f6(double a, double b, int n):
cdef:
double dx = (b - a) / n
double dx2 = dx / 2
double s = f5(a) * dx2
int i = 0
for i in range(1, n):
s += f5(a + i * dx) * dx
s += f5(b) * dx2
return s
Out[53]:
Cython: _cython_magic_866acf3a78d320cf35b8a8e8296ecbb8.pyx
Generated by Cython 0.22.1
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: #cython: cdivision=True
02: #import cython
03:
+04: cdef double f5(double x):
static double __pyx_f_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_f5(double __pyx_v_x) {
double __pyx_v_y;
double __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("f5", 0);
/* … */
/* function exit code */
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+05: y = x**4 - 3*x
__pyx_v_y = (pow(__pyx_v_x, 4.0) - (3.0 * __pyx_v_x));
+06: return y
__pyx_r = __pyx_v_y;
goto __pyx_L0;
07:
+08: def integrate_f6(double a, double b, int n):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_1integrate_f6(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_1integrate_f6 = {"integrate_f6", (PyCFunction)__pyx_pw_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_1integrate_f6, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_1integrate_f6(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
double __pyx_v_a;
double __pyx_v_b;
int __pyx_v_n;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("integrate_f6 (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_n,0};
PyObject* values[3] = {0,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 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
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("integrate_f6", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
case 2:
if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("integrate_f6", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "integrate_f6") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
} else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
goto __pyx_L5_argtuple_error;
} else {
values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
}
__pyx_v_a = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_a == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_b = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_b == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_n = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_n == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("integrate_f6", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8.integrate_f6", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_integrate_f6(__pyx_self, __pyx_v_a, __pyx_v_b, __pyx_v_n);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_integrate_f6(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_a, double __pyx_v_b, int __pyx_v_n) {
double __pyx_v_dx;
double __pyx_v_dx2;
double __pyx_v_s;
int __pyx_v_i;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("integrate_f6", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_3);
__Pyx_AddTraceback("_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8.integrate_f6", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple_ = PyTuple_Pack(7, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_n, __pyx_n_s_dx, __pyx_n_s_dx2, __pyx_n_s_s, __pyx_n_s_i); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple_);
__Pyx_GIVEREF(__pyx_tuple_);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_1integrate_f6, NULL, __pyx_n_s_cython_magic_866acf3a78d320cf35); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_integrate_f6, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 8; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
09: cdef:
+10: double dx = (b - a) / n
__pyx_v_dx = ((__pyx_v_b - __pyx_v_a) / __pyx_v_n);
+11: double dx2 = dx / 2
__pyx_v_dx2 = (__pyx_v_dx / 2.0);
+12: double s = f5(a) * dx2
__pyx_v_s = (__pyx_f_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_f5(__pyx_v_a) * __pyx_v_dx2);
+13: int i = 0
__pyx_v_i = 0;
+14: for i in range(1, n):
__pyx_t_1 = __pyx_v_n;
for (__pyx_t_2 = 1; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+15: s += f5(a + i * dx) * dx
__pyx_v_s = (__pyx_v_s + (__pyx_f_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_f5((__pyx_v_a + (__pyx_v_i * __pyx_v_dx))) * __pyx_v_dx));
}
+16: s += f5(b) * dx2
__pyx_v_s = (__pyx_v_s + (__pyx_f_46_cython_magic_866acf3a78d320cf35b8a8e8296ecbb8_f5(__pyx_v_b) * __pyx_v_dx2));
+17: return s
__Pyx_XDECREF(__pyx_r);
__pyx_t_3 = PyFloat_FromDouble(__pyx_v_s); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__pyx_r = __pyx_t_3;
__pyx_t_3 = 0;
goto __pyx_L0;
In [54]:
%timeit integrate_f6(-100, 100, int(1e5))
100 loops, best of 3: 7.18 ms per loop
This is a very small subset of Python. Most scientific application deal not with single values, but with arrays of data.
In [55]:
import numpy as np
def mean3filter(arr):
arr_out = np.empty_like(arr)
for i in range(1, arr.shape[0] - 1):
arr_out[i] = np.sum(arr[i-1 : i+1]) / 3
arr_out[0] = (arr[0] + arr[1]) / 2
arr_out[-1] = (arr[-1] + arr[-2]) / 2
return arr_out
In [56]:
%timeit mean3filter(np.random.rand(1e5))
1 loops, best of 3: 628 ms per loop
In [57]:
%%cython
import cython
import numpy as np
@cython.boundscheck(False)
def mean3filter2(double[::1] arr):
cdef double[::1] arr_out = np.empty_like(arr)
cdef int i
for i in range(1, arr.shape[0]-1):
arr_out[i] = np.sum(arr[i-1 : i+1]) / 3
arr_out[0] = (arr[0] + arr[1]) / 2
arr_out[-1] = (arr[-1] + arr[-2]) / 2
return np.asarray(arr_out)
In [77]:
%timeit np.convolve(np.random.rand(1e5), np.array([1.,1.,1.]), 'same')
100 loops, best of 3: 3.11 ms per loop
In [58]:
%timeit mean3filter2(np.random.rand(1e5))
1 loops, best of 3: 1.17 s per loop
Rubbish! How do we fix this?
In [75]:
%%cython -a
import cython
import numpy as np
@cython.boundscheck(False)
def mean3filter2a(double[::1] arr):
# ::1 means that the array is contiguous
cdef double[::1] arr_out = np.empty_like(arr)
cdef int i
for i in range(1, arr.shape[0]-1):
#for j in range(3):
arr_out[i] = arr[i-1] + arr[i] + arr[i+1]
arr_out[i] *= 0.333333333333333333333333
#arr_out[i] = np.sum(arr[i-1 : i+1]) / 3
arr_out[0] = (arr[0] + arr[1]) / 2
arr_out[-1] = (arr[-1] + arr[-2]) / 2
return np.asarray(arr_out)
Out[75]:
Cython: _cython_magic_91ce2d70c0de6735a44d76fd658e8707.pyx
Generated by Cython 0.22.1
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 cython
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+02: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 2; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
03:
04: @cython.boundscheck(False)
+05: def mean3filter2a(double[::1] arr):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_1mean3filter2a(PyObject *__pyx_self, PyObject *__pyx_arg_arr); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_1mean3filter2a = {"mean3filter2a", (PyCFunction)__pyx_pw_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_1mean3filter2a, METH_O, 0};
static PyObject *__pyx_pw_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_1mean3filter2a(PyObject *__pyx_self, PyObject *__pyx_arg_arr) {
__Pyx_memviewslice __pyx_v_arr = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("mean3filter2a (wrapper)", 0);
assert(__pyx_arg_arr); {
__pyx_v_arr = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_arg_arr); if (unlikely(!__pyx_v_arr.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_91ce2d70c0de6735a44d76fd658e8707.mean3filter2a", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_mean3filter2a(__pyx_self, __pyx_v_arr);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_mean3filter2a(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_arr) {
__Pyx_memviewslice __pyx_v_arr_out = { 0, 0, { 0 }, { 0 }, { 0 } };
int __pyx_v_i;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("mean3filter2a", 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_AddTraceback("_cython_magic_91ce2d70c0de6735a44d76fd658e8707.mean3filter2a", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_arr, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_arr_out, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__13 = PyTuple_Pack(4, __pyx_n_s_arr, __pyx_n_s_arr, __pyx_n_s_arr_out, __pyx_n_s_i); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple__13);
__Pyx_GIVEREF(__pyx_tuple__13);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_91ce2d70c0de6735a44d76fd658e8707_1mean3filter2a, NULL, __pyx_n_s_cython_magic_91ce2d70c0de6735a4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_mean3filter2a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_student_cache_ipython_cyth, __pyx_n_s_mean3filter2a, 5, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 5; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
06: # ::1 means that the array is contiguous
+07: cdef double[::1] arr_out = np.empty_like(arr)
__pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_empty_like); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_arr, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__pyx_t_4 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && 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_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
__pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __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_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __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_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_1);
if (unlikely(!__pyx_t_6.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_v_arr_out = __pyx_t_6;
__pyx_t_6.memview = NULL;
__pyx_t_6.data = NULL;
08: cdef int i
+09: for i in range(1, arr.shape[0]-1):
__pyx_t_7 = ((__pyx_v_arr.shape[0]) - 1);
for (__pyx_t_8 = 1; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
__pyx_v_i = __pyx_t_8;
10: #for j in range(3):
+11: arr_out[i] = arr[i-1] + arr[i] + arr[i+1]
__pyx_t_9 = (__pyx_v_i - 1);
if (__pyx_t_9 < 0) __pyx_t_9 += __pyx_v_arr.shape[0];
__pyx_t_10 = __pyx_v_i;
if (__pyx_t_10 < 0) __pyx_t_10 += __pyx_v_arr.shape[0];
__pyx_t_11 = (__pyx_v_i + 1);
if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_arr.shape[0];
__pyx_t_12 = __pyx_v_i;
if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_arr_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr_out.data) + __pyx_t_12)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_9)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_10)) )))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_11)) ))));
+12: arr_out[i] *= 0.333333333333333333333333
__pyx_t_13 = __pyx_v_i;
if (__pyx_t_13 < 0) __pyx_t_13 += __pyx_v_arr_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr_out.data) + __pyx_t_13)) )) *= 0.333333333333333333333333;
}
13: #arr_out[i] = np.sum(arr[i-1 : i+1]) / 3
+14: arr_out[0] = (arr[0] + arr[1]) / 2
__pyx_t_7 = 0;
if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_arr.shape[0];
__pyx_t_14 = 1;
if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_v_arr.shape[0];
__pyx_t_15 = 0;
if (__pyx_t_15 < 0) __pyx_t_15 += __pyx_v_arr_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr_out.data) + __pyx_t_15)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_7)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_14)) )))) / 2.0);
+15: arr_out[-1] = (arr[-1] + arr[-2]) / 2
__pyx_t_16 = -1;
if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_v_arr.shape[0];
__pyx_t_17 = -2;
if (__pyx_t_17 < 0) __pyx_t_17 += __pyx_v_arr.shape[0];
__pyx_t_18 = -1;
if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_v_arr_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr_out.data) + __pyx_t_18)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_16)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_17)) )))) / 2.0);
+16: return np.asarray(arr_out)
__Pyx_XDECREF(__pyx_r);
__pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_5);
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_arr_out, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_2 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
__pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5);
if (likely(__pyx_t_2)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
__Pyx_INCREF(__pyx_t_2);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_5, function);
}
}
if (!__pyx_t_2) {
__pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_GOTREF(__pyx_t_1);
} else {
__pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_4);
__Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __pyx_t_2 = NULL;
__Pyx_GIVEREF(__pyx_t_3);
PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_3);
__pyx_t_3 = 0;
__pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 16; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
}
__Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
In [76]:
%timeit mean3filter2a(np.random.rand(1e5))
1000 loops, best of 3: 1.56 ms per loop
Warning:: Dragons afoot.
In [82]:
%%cython -a
import cython
from cython.parallel import prange
import numpy as np
@cython.boundscheck(False)
def mean3filter3a(double[::1] arr, double[::1] out):
cdef int i, j, k = arr.shape[0]-1
for i in range(1, k-1):
for j in range(i-1, i+1):
out[i] += arr[j]
out[i] /= 3
out[0] = (arr[0] + arr[1]) / 2
out[-1] = (arr[-1] + arr[-2]) / 2
return np.asarray(out)
Out[82]:
Cython: _cython_magic_25a90b065d2abbab3833deaf3d4785cf.pyx
Generated by Cython 0.22.1
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 cython
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: from cython.parallel import prange
+03: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
04:
05: @cython.boundscheck(False)
+06: def mean3filter3a(double[::1] arr, double[::1] out):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_1mean3filter3a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_1mean3filter3a = {"mean3filter3a", (PyCFunction)__pyx_pw_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_1mean3filter3a, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_1mean3filter3a(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_arr = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_out = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("mean3filter3a (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arr,&__pyx_n_s_out,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_arr)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_out)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("mean3filter3a", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mean3filter3a") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __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_arr = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[0]); if (unlikely(!__pyx_v_arr.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_out = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[1]); if (unlikely(!__pyx_v_out.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("mean3filter3a", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_25a90b065d2abbab3833deaf3d4785cf.mean3filter3a", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_mean3filter3a(__pyx_self, __pyx_v_arr, __pyx_v_out);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_mean3filter3a(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_arr, __Pyx_memviewslice __pyx_v_out) {
int __pyx_v_i;
int __pyx_v_j;
int __pyx_v_k;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("mean3filter3a", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_13);
__Pyx_XDECREF(__pyx_t_14);
__Pyx_XDECREF(__pyx_t_15);
__Pyx_XDECREF(__pyx_t_16);
__Pyx_XDECREF(__pyx_t_17);
__Pyx_AddTraceback("_cython_magic_25a90b065d2abbab3833deaf3d4785cf.mean3filter3a", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_arr, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_out, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__13 = PyTuple_Pack(5, __pyx_n_s_arr, __pyx_n_s_out, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple__13);
__Pyx_GIVEREF(__pyx_tuple__13);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_25a90b065d2abbab3833deaf3d4785cf_1mean3filter3a, NULL, __pyx_n_s_cython_magic_25a90b065d2abbab38); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_mean3filter3a, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_student_cache_ipython_cyth, __pyx_n_s_mean3filter3a, 6, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+07: cdef int i, j, k = arr.shape[0]-1
__pyx_v_k = ((__pyx_v_arr.shape[0]) - 1);
+08: for i in range(1, k-1):
__pyx_t_1 = (__pyx_v_k - 1);
for (__pyx_t_2 = 1; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+09: for j in range(i-1, i+1):
__pyx_t_3 = (__pyx_v_i + 1);
for (__pyx_t_4 = (__pyx_v_i - 1); __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
__pyx_v_j = __pyx_t_4;
+10: out[i] += arr[j]
__pyx_t_5 = __pyx_v_j;
if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_arr.shape[0];
__pyx_t_6 = __pyx_v_i;
if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_6)) )) += (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_5)) )));
}
+11: out[i] /= 3
__pyx_t_4 = __pyx_v_i;
if (__pyx_t_4 < 0) __pyx_t_4 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_4)) )) /= 3.0;
}
+12: out[0] = (arr[0] + arr[1]) / 2
__pyx_t_7 = 0;
if (__pyx_t_7 < 0) __pyx_t_7 += __pyx_v_arr.shape[0];
__pyx_t_8 = 1;
if (__pyx_t_8 < 0) __pyx_t_8 += __pyx_v_arr.shape[0];
__pyx_t_9 = 0;
if (__pyx_t_9 < 0) __pyx_t_9 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_9)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_7)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_8)) )))) / 2.0);
+13: out[-1] = (arr[-1] + arr[-2]) / 2
__pyx_t_10 = -1;
if (__pyx_t_10 < 0) __pyx_t_10 += __pyx_v_arr.shape[0];
__pyx_t_11 = -2;
if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_arr.shape[0];
__pyx_t_12 = -1;
if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_12)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_10)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_11)) )))) / 2.0);
+14: return np.asarray(out)
__Pyx_XDECREF(__pyx_r);
__pyx_t_14 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_14);
__pyx_t_15 = __Pyx_PyObject_GetAttrStr(__pyx_t_14, __pyx_n_s_asarray); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_15);
__Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
__pyx_t_14 = __pyx_memoryview_fromslice(__pyx_v_out, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_14);
__pyx_t_16 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_15))) {
__pyx_t_16 = PyMethod_GET_SELF(__pyx_t_15);
if (likely(__pyx_t_16)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_15);
__Pyx_INCREF(__pyx_t_16);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_15, function);
}
}
if (!__pyx_t_16) {
__pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_15, __pyx_t_14); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
__Pyx_GOTREF(__pyx_t_13);
} else {
__pyx_t_17 = PyTuple_New(1+1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_17);
__Pyx_GIVEREF(__pyx_t_16); PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_t_16); __pyx_t_16 = NULL;
__Pyx_GIVEREF(__pyx_t_14);
PyTuple_SET_ITEM(__pyx_t_17, 0+1, __pyx_t_14);
__pyx_t_14 = 0;
__pyx_t_13 = __Pyx_PyObject_Call(__pyx_t_15, __pyx_t_17, NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_13);
__Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
}
__Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
__pyx_r = __pyx_t_13;
__pyx_t_13 = 0;
goto __pyx_L0;
In [85]:
%%cython -a
import cython
from cython.parallel import prange
import numpy as np
@cython.boundscheck(False)
def mean3filter3(double[::1] arr, double[::1] out):
cdef int i, j, k = arr.shape[0]-1
with nogil:
for i in prange(1, k-1, schedule='static',
chunksize=(k-2) // 2, num_threads=4):
for j in range(i-1, i+1):
out[i] += arr[j]
out[i] /= 3
out[0] = (arr[0] + arr[1]) / 2
out[-1] = (arr[-1] + arr[-2]) / 2
return np.asarray(out)
Error compiling Cython file:
------------------------------------------------------------
...
import numpy as np
@cython.boundscheck(False)
def mean3filter3(double[::1] arr, double[::1] out):
cdef int i, j, k = arr.shape[0]-1
for i in prange(1, k-1, schedule='static',
^
------------------------------------------------------------
/home/student/.cache/ipython/cython/_cython_magic_01f16d263991d5b51fc55754d032c5d4.pyx:8:19: prange() can only be used without the GIL
In [86]:
%%cython -a
import cython
from cython.parallel import prange
import numpy as np
@cython.boundscheck(False)
def mean3filter3b(double[::1] arr, double[::1] out):
cdef int i, j, k = arr.shape[0]-1
for i in range(1, k-1):
for j in range(i-1, i+1):
out[i] += arr[j]
with nogil:
for i in prange(1, k-1, schedule='static',
chunksize=(k-2) // 2, num_threads=4):
out[i] /= 3
out[0] = (arr[0] + arr[1]) / 2
out[-1] = (arr[-1] + arr[-2]) / 2
return np.asarray(out)
Out[86]:
Cython: _cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1.pyx
Generated by Cython 0.22.1
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 cython
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: from cython.parallel import prange
+03: import numpy as np
__pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
04:
05: @cython.boundscheck(False)
+06: def mean3filter3b(double[::1] arr, double[::1] out):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_1mean3filter3b(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_1mean3filter3b = {"mean3filter3b", (PyCFunction)__pyx_pw_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_1mean3filter3b, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_1mean3filter3b(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
__Pyx_memviewslice __pyx_v_arr = { 0, 0, { 0 }, { 0 }, { 0 } };
__Pyx_memviewslice __pyx_v_out = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("mean3filter3b (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_arr,&__pyx_n_s_out,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_arr)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_out)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("mean3filter3b", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "mean3filter3b") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __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_arr = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[0]); if (unlikely(!__pyx_v_arr.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_out = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[1]); if (unlikely(!__pyx_v_out.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("mean3filter3b", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1.mean3filter3b", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_mean3filter3b(__pyx_self, __pyx_v_arr, __pyx_v_out);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_mean3filter3b(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_arr, __Pyx_memviewslice __pyx_v_out) {
int __pyx_v_i;
int __pyx_v_j;
int __pyx_v_k;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("mean3filter3b", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_15);
__Pyx_XDECREF(__pyx_t_16);
__Pyx_XDECREF(__pyx_t_17);
__Pyx_XDECREF(__pyx_t_18);
__Pyx_XDECREF(__pyx_t_19);
__Pyx_AddTraceback("_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1.mean3filter3b", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_arr, 1);
__PYX_XDEC_MEMVIEW(&__pyx_v_out, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__13 = PyTuple_Pack(5, __pyx_n_s_arr, __pyx_n_s_out, __pyx_n_s_i, __pyx_n_s_j, __pyx_n_s_k); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple__13);
__Pyx_GIVEREF(__pyx_tuple__13);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_8c69ac4eb3ae7bc63d68edbbdc8f45f1_1mean3filter3b, NULL, __pyx_n_s_cython_magic_8c69ac4eb3ae7bc63d); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_mean3filter3b, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_student_cache_ipython_cyth, __pyx_n_s_mean3filter3b, 6, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 6; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+07: cdef int i, j, k = arr.shape[0]-1
__pyx_v_k = ((__pyx_v_arr.shape[0]) - 1);
+08: for i in range(1, k-1):
__pyx_t_1 = (__pyx_v_k - 1);
for (__pyx_t_2 = 1; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+09: for j in range(i-1, i+1):
__pyx_t_3 = (__pyx_v_i + 1);
for (__pyx_t_4 = (__pyx_v_i - 1); __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
__pyx_v_j = __pyx_t_4;
+10: out[i] += arr[j]
__pyx_t_5 = __pyx_v_j;
if (__pyx_t_5 < 0) __pyx_t_5 += __pyx_v_arr.shape[0];
__pyx_t_6 = __pyx_v_i;
if (__pyx_t_6 < 0) __pyx_t_6 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_6)) )) += (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_5)) )));
}
}
+11: with nogil:
{
#ifdef WITH_THREAD
PyThreadState *_save;
Py_UNBLOCK_THREADS
#endif
/*try:*/ {
/* … */
/*finally:*/ {
/*normal exit:*/{
#ifdef WITH_THREAD
Py_BLOCK_THREADS
#endif
goto __pyx_L9;
}
__pyx_L9:;
}
}
+12: for i in prange(1, k-1, schedule='static',
__pyx_t_1 = (__pyx_v_k - 1);
if (1 == 0) abort();
{
#if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
#undef likely
#undef unlikely
#define likely(x) (x)
#define unlikely(x) (x)
#endif
__pyx_t_7 = (__pyx_t_1 - 1) / 1;
if (__pyx_t_7 > 0)
{
#ifdef _OPENMP
#pragma omp parallel
#endif /* _OPENMP */
{
#ifdef _OPENMP
#pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i)
/* … */
__pyx_t_1 = (__pyx_v_k - 1);
if (1 == 0) abort();
{
#if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
#undef likely
#undef unlikely
#define likely(x) (x)
#define unlikely(x) (x)
#endif
__pyx_t_7 = (__pyx_t_1 - 1) / 1;
if (__pyx_t_7 > 0)
{
#ifdef _OPENMP
#pragma omp parallel
#endif /* _OPENMP */
{
#ifdef _OPENMP
#pragma omp for firstprivate(__pyx_v_i) lastprivate(__pyx_v_i) schedule(static, __pyx_t_8) num_threads(4)
#endif /* _OPENMP */
for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_7; __pyx_t_3++){
{
__pyx_v_i = 1 + 1 * __pyx_t_3;
13: chunksize=(k-2) // 2, num_threads=4):
+14: out[i] /= 3
__pyx_t_2 = __pyx_v_i;
if (__pyx_t_2 < 0) __pyx_t_2 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_2)) )) /= 3.0;
}
}
}
}
}
#if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
#undef likely
#undef unlikely
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
}
+15: out[0] = (arr[0] + arr[1]) / 2
__pyx_t_9 = 0;
if (__pyx_t_9 < 0) __pyx_t_9 += __pyx_v_arr.shape[0];
__pyx_t_10 = 1;
if (__pyx_t_10 < 0) __pyx_t_10 += __pyx_v_arr.shape[0];
__pyx_t_11 = 0;
if (__pyx_t_11 < 0) __pyx_t_11 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_11)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_9)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_10)) )))) / 2.0);
+16: out[-1] = (arr[-1] + arr[-2]) / 2
__pyx_t_12 = -1;
if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_v_arr.shape[0];
__pyx_t_13 = -2;
if (__pyx_t_13 < 0) __pyx_t_13 += __pyx_v_arr.shape[0];
__pyx_t_14 = -1;
if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_v_out.shape[0];
*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_out.data) + __pyx_t_14)) )) = (((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_12)) ))) + (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_arr.data) + __pyx_t_13)) )))) / 2.0);
+17: return np.asarray(out)
__Pyx_XDECREF(__pyx_r);
__pyx_t_16 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_16);
__pyx_t_17 = __Pyx_PyObject_GetAttrStr(__pyx_t_16, __pyx_n_s_asarray); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_17);
__Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
__pyx_t_16 = __pyx_memoryview_fromslice(__pyx_v_out, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_16);
__pyx_t_18 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_17))) {
__pyx_t_18 = PyMethod_GET_SELF(__pyx_t_17);
if (likely(__pyx_t_18)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_17);
__Pyx_INCREF(__pyx_t_18);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_17, function);
}
}
if (!__pyx_t_18) {
__pyx_t_15 = __Pyx_PyObject_CallOneArg(__pyx_t_17, __pyx_t_16); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
__Pyx_GOTREF(__pyx_t_15);
} else {
__pyx_t_19 = PyTuple_New(1+1); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_19);
__Pyx_GIVEREF(__pyx_t_18); PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_18); __pyx_t_18 = NULL;
__Pyx_GIVEREF(__pyx_t_16);
PyTuple_SET_ITEM(__pyx_t_19, 0+1, __pyx_t_16);
__pyx_t_16 = 0;
__pyx_t_15 = __Pyx_PyObject_Call(__pyx_t_17, __pyx_t_19, NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 17; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_15);
__Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
}
__Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
__pyx_r = __pyx_t_15;
__pyx_t_15 = 0;
goto __pyx_L0;
In [91]:
del rin, rout
In [89]:
rin = np.random.rand(1e8)
rout = np.empty_like(rin)
In [90]:
%timeit mean3filter3b(rin, rout)
The slowest run took 14.04 times longer than the fastest. This could mean that an intermediate result is being cached
1 loops, best of 3: 683 ms per loop
In [84]:
%timeit mean3filter3(rin, rout)
10 loops, best of 3: 45.6 ms per loop
In [ ]:
In [92]:
%%cython -a
# distutils: language=c++
import cython
from libcpp.vector cimport vector
@cython.boundscheck(False)
def build_list_with_vector(double[::1] in_arr):
cdef vector[double] out
cdef int i
for i in range(in_arr.shape[0]):
out.push_back(in_arr[i])
return out
Out[92]:
Cython: _cython_magic_9e62336531da4dc6d78b22908dd4ed1c.pyx
Generated by Cython 0.22.1
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: # distutils: language=c++
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: import cython
03: from libcpp.vector cimport vector
04:
05:
06: @cython.boundscheck(False)
+07: def build_list_with_vector(double[::1] in_arr):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_1build_list_with_vector(PyObject *__pyx_self, PyObject *__pyx_arg_in_arr); /*proto*/
static PyMethodDef __pyx_mdef_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_1build_list_with_vector = {"build_list_with_vector", (PyCFunction)__pyx_pw_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_1build_list_with_vector, METH_O, 0};
static PyObject *__pyx_pw_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_1build_list_with_vector(PyObject *__pyx_self, PyObject *__pyx_arg_in_arr) {
__Pyx_memviewslice __pyx_v_in_arr = { 0, 0, { 0 }, { 0 }, { 0 } };
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("build_list_with_vector (wrapper)", 0);
assert(__pyx_arg_in_arr); {
__pyx_v_in_arr = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_arg_in_arr); if (unlikely(!__pyx_v_in_arr.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_9e62336531da4dc6d78b22908dd4ed1c.build_list_with_vector", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_build_list_with_vector(__pyx_self, __pyx_v_in_arr);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_build_list_with_vector(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_in_arr) {
std::vector<double> __pyx_v_out;
int __pyx_v_i;
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("build_list_with_vector", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_4);
__Pyx_AddTraceback("_cython_magic_9e62336531da4dc6d78b22908dd4ed1c.build_list_with_vector", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__PYX_XDEC_MEMVIEW(&__pyx_v_in_arr, 1);
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
/* … */
__pyx_tuple__13 = PyTuple_Pack(4, __pyx_n_s_in_arr, __pyx_n_s_in_arr, __pyx_n_s_out, __pyx_n_s_i); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_tuple__13);
__Pyx_GIVEREF(__pyx_tuple__13);
/* … */
__pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_9e62336531da4dc6d78b22908dd4ed1c_1build_list_with_vector, NULL, __pyx_n_s_cython_magic_9e62336531da4dc6d7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_build_list_with_vector, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
__pyx_codeobj__14 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__13, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_student_cache_ipython_cyth, __pyx_n_s_build_list_with_vector, 7, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 7; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
08: cdef vector[double] out
09: cdef int i
+10: for i in range(in_arr.shape[0]):
__pyx_t_1 = (__pyx_v_in_arr.shape[0]);
for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
__pyx_v_i = __pyx_t_2;
+11: out.push_back(in_arr[i])
__pyx_t_3 = __pyx_v_i;
if (__pyx_t_3 < 0) __pyx_t_3 += __pyx_v_in_arr.shape[0];
try {
__pyx_v_out.push_back((*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_in_arr.data) + __pyx_t_3)) ))));
} catch(...) {
__Pyx_CppExn2PyErr();
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
}
}
+12: return out
__Pyx_XDECREF(__pyx_r);
__pyx_t_4 = __pyx_convert_vector_to_py_double(__pyx_v_out); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_4);
__pyx_r = __pyx_t_4;
__pyx_t_4 = 0;
goto __pyx_L0;
In [93]:
build_list_with_vector(np.random.rand(10))
Out[93]:
[0.26085286315839795,
0.9763933277734224,
0.9676751436173779,
0.6887305413123229,
0.009623500824120224,
0.2690635362697693,
0.46649754307129254,
0.9523794831061152,
0.3025492210533033,
0.5987448617009814]
In [94]:
%%cython -a
#distutils: language=c++
from cython.operator cimport dereference as deref, preincrement as inc
from libcpp.vector cimport vector
from libcpp.map cimport map as cppmap
cdef class Graph:
cdef cppmap[int, vector[int]] _adj
cpdef int has_node(self, int node):
return self._adj.find(node) != self._adj.end()
cdef void add_node(self, int new_node):
cdef vector[int] out
if not self.has_node(new_node):
self._adj[new_node] = out
def add_edge(self, int u, int v):
self.add_node(u)
self.add_node(v)
self._adj[u].push_back(v)
self._adj[v].push_back(u)
def __getitem__(self, int u):
return self._adj[u]
cdef vector[int] _degrees(self):
cdef vector[int] deg
cdef int first = 0
cdef vector[int] edges
cdef cppmap[int, vector[int]].iterator it = self._adj.begin()
while it != self._adj.end():
deg.push_back(deref(it).second.size())
it = inc(it)
return deg
def degrees(self):
return self._degrees()
Out[94]:
Cython: _cython_magic_207f54e3e5ad780456f48229a083fca4.pyx
Generated by Cython 0.22.1
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: #distutils: language=c++
__pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
02: from cython.operator cimport dereference as deref, preincrement as inc
03:
04: from libcpp.vector cimport vector
05: from libcpp.map cimport map as cppmap
06:
+07: cdef class Graph:
struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph {
PyObject_HEAD
struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_vtab;
std::map<int,std::vector<int> > _adj;
};
struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph {
int (*has_node)(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *, int, int __pyx_skip_dispatch);
void (*add_node)(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *, int);
std::vector<int> (*_degrees)(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *);
};
static struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_vtabptr_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph;
08: cdef cppmap[int, vector[int]] _adj
09:
+10: cpdef int has_node(self, int node):
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_1has_node(PyObject *__pyx_v_self, PyObject *__pyx_arg_node); /*proto*/
static int __pyx_f_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_has_node(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self, int __pyx_v_node, int __pyx_skip_dispatch) {
int __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("has_node", 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_has_node); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __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_207f54e3e5ad780456f48229a083fca4_5Graph_1has_node)) {
__pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_node); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_3);
__Pyx_INCREF(__pyx_t_1);
__pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
__pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
if (likely(__pyx_t_5)) {
PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
__Pyx_INCREF(__pyx_t_5);
__Pyx_INCREF(function);
__Pyx_DECREF_SET(__pyx_t_4, function);
}
}
if (!__pyx_t_5) {
__pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
__Pyx_GOTREF(__pyx_t_2);
} else {
__pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_6);
__Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
__Pyx_GIVEREF(__pyx_t_3);
PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
__pyx_t_3 = 0;
__pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_2);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
}
__Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
__pyx_t_7 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_7 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
__pyx_r = __pyx_t_7;
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
goto __pyx_L0;
}
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 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_WriteUnraisable("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.has_node", __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_207f54e3e5ad780456f48229a083fca4_5Graph_1has_node(PyObject *__pyx_v_self, PyObject *__pyx_arg_node); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_1has_node(PyObject *__pyx_v_self, PyObject *__pyx_arg_node) {
int __pyx_v_node;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("has_node (wrapper)", 0);
assert(__pyx_arg_node); {
__pyx_v_node = __Pyx_PyInt_As_int(__pyx_arg_node); if (unlikely((__pyx_v_node == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.has_node", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_has_node(((struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self), ((int)__pyx_v_node));
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_has_node(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self, int __pyx_v_node) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("has_node", 0);
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __Pyx_PyInt_From_int(__pyx_f_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_has_node(__pyx_v_self, __pyx_v_node, 1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __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_207f54e3e5ad780456f48229a083fca4.Graph.has_node", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+11: return self._adj.find(node) != self._adj.end()
__pyx_r = (__pyx_v_self->_adj.find(__pyx_v_node) != __pyx_v_self->_adj.end());
goto __pyx_L0;
12:
+13: cdef void add_node(self, int new_node):
static void __pyx_f_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_add_node(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self, int __pyx_v_new_node) {
std::vector<int> __pyx_v_out;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("add_node", 0);
/* … */
/* function exit code */
__Pyx_RefNannyFinishContext();
}
14: cdef vector[int] out
+15: if not self.has_node(new_node):
__pyx_t_1 = ((!(((struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self->__pyx_vtab)->has_node(__pyx_v_self, __pyx_v_new_node, 0) != 0)) != 0);
if (__pyx_t_1) {
+16: self._adj[new_node] = out
(__pyx_v_self->_adj[__pyx_v_new_node]) = __pyx_v_out;
goto __pyx_L3;
}
__pyx_L3:;
17:
+18: def add_edge(self, int u, int v):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_3add_edge(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_3add_edge(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
int __pyx_v_u;
int __pyx_v_v;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("add_edge (wrapper)", 0);
{
static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_u,&__pyx_n_s_v,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_u)) != 0)) kw_args--;
else goto __pyx_L5_argtuple_error;
case 1:
if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_v)) != 0)) kw_args--;
else {
__Pyx_RaiseArgtupleInvalid("add_edge", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
}
if (unlikely(kw_args > 0)) {
if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "add_edge") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __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_u = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_u == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_v_v = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_v == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L5_argtuple_error:;
__Pyx_RaiseArgtupleInvalid("add_edge", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.add_edge", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_2add_edge(((struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self), __pyx_v_u, __pyx_v_v);
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_2add_edge(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self, int __pyx_v_u, int __pyx_v_v) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("add_edge", 0);
/* … */
/* function exit code */
__pyx_r = Py_None; __Pyx_INCREF(Py_None);
goto __pyx_L0;
__pyx_L1_error:;
__Pyx_AddTraceback("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.add_edge", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+19: self.add_node(u)
((struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self->__pyx_vtab)->add_node(__pyx_v_self, __pyx_v_u);
+20: self.add_node(v)
((struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self->__pyx_vtab)->add_node(__pyx_v_self, __pyx_v_v);
+21: self._adj[u].push_back(v)
try {
(__pyx_v_self->_adj[__pyx_v_u]).push_back(__pyx_v_v);
} catch(...) {
__Pyx_CppExn2PyErr();
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
}
+22: self._adj[v].push_back(u)
try {
(__pyx_v_self->_adj[__pyx_v_v]).push_back(__pyx_v_u);
} catch(...) {
__Pyx_CppExn2PyErr();
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 22; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
}
23:
+24: def __getitem__(self, int u):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_u); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_arg_u) {
int __pyx_v_u;
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
assert(__pyx_arg_u); {
__pyx_v_u = __Pyx_PyInt_As_int(__pyx_arg_u); if (unlikely((__pyx_v_u == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 24; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
}
goto __pyx_L4_argument_unpacking_done;
__pyx_L3_error:;
__Pyx_AddTraceback("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
__Pyx_RefNannyFinishContext();
return NULL;
__pyx_L4_argument_unpacking_done:;
__pyx_r = __pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_4__getitem__(((struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self), ((int)__pyx_v_u));
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_4__getitem__(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self, int __pyx_v_u) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("__getitem__", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_AddTraceback("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+25: return self._adj[u]
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_convert_vector_to_py_int((__pyx_v_self->_adj[__pyx_v_u])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
26:
+27: cdef vector[int] _degrees(self):
static std::vector<int> __pyx_f_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph__degrees(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self) {
std::vector<int> __pyx_v_deg;
CYTHON_UNUSED int __pyx_v_first;
std::map<int,std::vector<int> > ::iterator __pyx_v_it;
std::vector<int> __pyx_r;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("_degrees", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_WriteUnraisable("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph._degrees", __pyx_clineno, __pyx_lineno, __pyx_filename, 0, 0);
__pyx_L0:;
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
28: cdef vector[int] deg
+29: cdef int first = 0
__pyx_v_first = 0;
30: cdef vector[int] edges
+31: cdef cppmap[int, vector[int]].iterator it = self._adj.begin()
__pyx_v_it = __pyx_v_self->_adj.begin();
+32: while it != self._adj.end():
while (1) {
__pyx_t_1 = ((__pyx_v_it != __pyx_v_self->_adj.end()) != 0);
if (!__pyx_t_1) break;
+33: deg.push_back(deref(it).second.size())
try {
__pyx_v_deg.push_back((*__pyx_v_it).second.size());
} catch(...) {
__Pyx_CppExn2PyErr();
{__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
}
+34: it = inc(it)
__pyx_v_it = (++__pyx_v_it);
}
+35: return deg
__pyx_r = __pyx_v_deg;
goto __pyx_L0;
36:
+37: def degrees(self):
/* Python wrapper */
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_7degrees(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_7degrees(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
PyObject *__pyx_r = 0;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("degrees (wrapper)", 0);
__pyx_r = __pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_6degrees(((struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self));
/* function exit code */
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
static PyObject *__pyx_pf_46_cython_magic_207f54e3e5ad780456f48229a083fca4_5Graph_6degrees(struct __pyx_obj_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *__pyx_v_self) {
PyObject *__pyx_r = NULL;
__Pyx_RefNannyDeclarations
__Pyx_RefNannySetupContext("degrees", 0);
/* … */
/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_AddTraceback("_cython_magic_207f54e3e5ad780456f48229a083fca4.Graph.degrees", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
__Pyx_XGIVEREF(__pyx_r);
__Pyx_RefNannyFinishContext();
return __pyx_r;
}
+38: return self._degrees()
__Pyx_XDECREF(__pyx_r);
__pyx_t_1 = __pyx_convert_vector_to_py_int(((struct __pyx_vtabstruct_46_cython_magic_207f54e3e5ad780456f48229a083fca4_Graph *)__pyx_v_self->__pyx_vtab)->_degrees(__pyx_v_self)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
__Pyx_GOTREF(__pyx_t_1);
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
goto __pyx_L0;
39:
In [95]:
g0 = Graph()
In [96]:
g0.add_edge(1, 5)
g0.add_edge(1, 6)
In [97]:
g0[1]
Out[97]:
[5, 6]
In [98]:
g0.has_node(1)
Out[98]:
1
In [99]:
g0.degrees()
Out[99]:
[2, 1, 1]
In [100]:
import networkx as nx
g = nx.barabasi_albert_graph(100000, 6)
with open('graph.txt', 'w') as fout:
for u, v in g.edges_iter():
fout.write('%i,%i\n' % (u, v))
In [101]:
%timeit list(g.degree())
10 loops, best of 3: 51.7 ms per loop
In [102]:
myg = Graph()
def line2edges(line):
u, v = map(int, line.rstrip().split(','))
return u, v
edges = map(line2edges, open('graph.txt'))
for u, v in edges:
myg.add_edge(u, v)
In [103]:
%timeit mydeg = myg.degrees()
100 loops, best of 3: 9.83 ms per loop
Use setup.py
to build your Cython files.
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [
Extension("prange_demo", ["prange_demo.pyx"],
include_dirs=[np.get_include()],
extra_compile_args=['-fopenmp'],
extra_link_args=['-fopenmp', '-lgomp']),
]
)
In [2]:
import numpy as np
from mean3 import mean3filter
mean3filter(np.random.rand(10))
Out[2]:
array([ 0.6960285 , 0.56840097, 0.38207445, 0.28536657, 0.37981228,
0.52849249, 0.60342301, 0.59280659, 0.59454272, 0.67086538])
In [ ]:
Content source: dboonz/aspp2015
Similar notebooks: