{ "cells": [ { "cell_type": "markdown", "metadata": { "toc": "true" }, "source": [ "# Table of Contents\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Requirements" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "\n", "import numba" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import cython\n", "%load_ext cython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# KL Functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## klGauss" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Generating some data:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "def random_Gaussian(sig2=0.25):\n", " return sig2 * np.random.randn()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.12 µs ± 74.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "%timeit (random_Gaussian(), random_Gaussian())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In pure Python:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def klGauss(x: float, y: float, sig2=0.25) -> float:\n", " return (x - y)**2 / (2 * sig2**x)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.37 µs ± 54.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "%timeit klGauss(random_Gaussian(), random_Gaussian())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With numba:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "@numba.jit(nopython=True)\n", "def klGauss_numba(x: float, y: float, sig2=0.25) -> float:\n", " return (x - y)**2 / (2 * sig2**x)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on CPUDispatcher in module __main__:\n", "\n", "klGauss_numba(x:float, y:float, sig2=0.25) -> float\n", "\n" ] } ], "source": [ "help(klGauss_numba)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The slowest run took 13.64 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "4.87 µs ± 7.2 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], "source": [ "%timeit klGauss_numba(random_Gaussian(), random_Gaussian())" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.43 µs ± 29.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n" ] } ], "source": [ "%timeit klGauss_numba(random_Gaussian(), random_Gaussian())" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Speed up using Numba for klGauss was: 0.015 faster!\n" ] } ], "source": [ "print(f\"Speed up using Numba for klGauss was: {(1290-993)/(20300-993):.2g} faster!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With Cython" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", " \n", "Generated by Cython 0.29.1
\n", "\n",
" Yellow lines hint at Python interaction.
\n",
" Click on a line that starts with a \"+
\" to see the C code that Cython generated for it.\n",
"
1:
\n",
"+2: def klGauss_cython(double x, double y, double sig2=0.25) -> double:\n", "
/* Python wrapper */\n", "static PyObject *__pyx_pw_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_1klGauss_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", "static PyMethodDef __pyx_mdef_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_1klGauss_cython = {\"klGauss_cython\", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_1klGauss_cython, METH_VARARGS|METH_KEYWORDS, 0};\n", "static PyObject *__pyx_pw_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_1klGauss_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", " double __pyx_v_x;\n", " double __pyx_v_y;\n", " double __pyx_v_sig2;\n", " PyObject *__pyx_r = 0;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"klGauss_cython (wrapper)\", 0);\n", " {\n", " static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_y,&__pyx_n_s_sig2,0};\n", " PyObject* values[3] = {0,0,0};\n", " if (unlikely(__pyx_kwds)) {\n", " Py_ssize_t kw_args;\n", " const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n", " switch (pos_args) {\n", " case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n", " CYTHON_FALLTHROUGH;\n", " case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " CYTHON_FALLTHROUGH;\n", " case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " CYTHON_FALLTHROUGH;\n", " case 0: break;\n", " default: goto __pyx_L5_argtuple_error;\n", " }\n", " kw_args = PyDict_Size(__pyx_kwds);\n", " switch (pos_args) {\n", " case 0:\n", " if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;\n", " else goto __pyx_L5_argtuple_error;\n", " CYTHON_FALLTHROUGH;\n", " case 1:\n", " if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"klGauss_cython\", 0, 2, 3, 1); __PYX_ERR(0, 2, __pyx_L3_error)\n", " }\n", " CYTHON_FALLTHROUGH;\n", " case 2:\n", " if (kw_args > 0) {\n", " PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_sig2);\n", " if (value) { values[2] = value; kw_args--; }\n", " }\n", " }\n", " if (unlikely(kw_args > 0)) {\n", " if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"klGauss_cython\") < 0)) __PYX_ERR(0, 2, __pyx_L3_error)\n", " }\n", " } else {\n", " switch (PyTuple_GET_SIZE(__pyx_args)) {\n", " case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n", " CYTHON_FALLTHROUGH;\n", " case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " break;\n", " default: goto __pyx_L5_argtuple_error;\n", " }\n", " }\n", " __pyx_v_x = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_x == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 2, __pyx_L3_error)\n", " __pyx_v_y = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_y == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 2, __pyx_L3_error)\n", " if (values[2]) {\n", " __pyx_v_sig2 = __pyx_PyFloat_AsDouble(values[2]); if (unlikely((__pyx_v_sig2 == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 2, __pyx_L3_error)\n", " } else {\n", " __pyx_v_sig2 = ((double)0.25);\n", " }\n", " }\n", " goto __pyx_L4_argument_unpacking_done;\n", " __pyx_L5_argtuple_error:;\n", " __Pyx_RaiseArgtupleInvalid(\"klGauss_cython\", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 2, __pyx_L3_error)\n", " __pyx_L3_error:;\n", " __Pyx_AddTraceback(\"_cython_magic_49fb421fab37e1decb48fdb471e97e6b.klGauss_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __Pyx_RefNannyFinishContext();\n", " return NULL;\n", " __pyx_L4_argument_unpacking_done:;\n", " __pyx_r = __pyx_pf_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_klGauss_cython(__pyx_self, __pyx_v_x, __pyx_v_y, __pyx_v_sig2);\n", "\n", " /* function exit code */\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "\n", "static PyObject *__pyx_pf_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_klGauss_cython(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_x, double __pyx_v_y, double __pyx_v_sig2) {\n", " PyObject *__pyx_r = NULL;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"klGauss_cython\", 0);\n", "/* … */\n", " /* function exit code */\n", " __pyx_L1_error:;\n", " __Pyx_XDECREF(__pyx_t_3);\n", " __Pyx_AddTraceback(\"_cython_magic_49fb421fab37e1decb48fdb471e97e6b.klGauss_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __pyx_r = NULL;\n", " __pyx_L0:;\n", " __Pyx_XGIVEREF(__pyx_r);\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "/* … */\n", " __pyx_tuple_ = PyTuple_Pack(3, __pyx_n_s_x, __pyx_n_s_y, __pyx_n_s_sig2); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 2, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_tuple_);\n", " __Pyx_GIVEREF(__pyx_tuple_);\n", "/* … */\n", " __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_49fb421fab37e1decb48fdb471e97e6b_1klGauss_cython, NULL, __pyx_n_s_cython_magic_49fb421fab37e1decb); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 2, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " if (PyDict_SetItem(__pyx_d, __pyx_n_s_klGauss_cython, __pyx_t_1) < 0) __PYX_ERR(0, 2, __pyx_L1_error)\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", "
+3: return (x - y)**2 / (2 * sig2**x)\n", "
__Pyx_XDECREF(__pyx_r);\n", " __pyx_t_1 = pow((__pyx_v_x - __pyx_v_y), 2.0);\n", " __pyx_t_2 = (2.0 * pow(__pyx_v_sig2, __pyx_v_x));\n", " if (unlikely(__pyx_t_2 == 0)) {\n", " PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n", " __PYX_ERR(0, 3, __pyx_L1_error)\n", " }\n", " __pyx_t_3 = PyFloat_FromDouble((__pyx_t_1 / __pyx_t_2)); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_3);\n", " __pyx_r = __pyx_t_3;\n", " __pyx_t_3 = 0;\n", " goto __pyx_L0;\n", "
Generated by Cython 0.29.1
\n", "\n",
" Yellow lines hint at Python interaction.
\n",
" Click on a line that starts with a \"+
\" to see the C code that Cython generated for it.\n",
"
1: from libc.math cimport log\n", "
2:
\n",
"+3: def klBern_cython(double x, double y) -> double:\n", "
/* Python wrapper */\n", "static PyObject *__pyx_pw_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_1klBern_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", "static PyMethodDef __pyx_mdef_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_1klBern_cython = {\"klBern_cython\", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_1klBern_cython, METH_VARARGS|METH_KEYWORDS, 0};\n", "static PyObject *__pyx_pw_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_1klBern_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", " double __pyx_v_x;\n", " double __pyx_v_y;\n", " PyObject *__pyx_r = 0;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"klBern_cython (wrapper)\", 0);\n", " {\n", " static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_y,0};\n", " PyObject* values[2] = {0,0};\n", " if (unlikely(__pyx_kwds)) {\n", " Py_ssize_t kw_args;\n", " const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n", " switch (pos_args) {\n", " case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " CYTHON_FALLTHROUGH;\n", " case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " CYTHON_FALLTHROUGH;\n", " case 0: break;\n", " default: goto __pyx_L5_argtuple_error;\n", " }\n", " kw_args = PyDict_Size(__pyx_kwds);\n", " switch (pos_args) {\n", " case 0:\n", " if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;\n", " else goto __pyx_L5_argtuple_error;\n", " CYTHON_FALLTHROUGH;\n", " case 1:\n", " if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"klBern_cython\", 1, 2, 2, 1); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " }\n", " if (unlikely(kw_args > 0)) {\n", " if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"klBern_cython\") < 0)) __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {\n", " goto __pyx_L5_argtuple_error;\n", " } else {\n", " values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " }\n", " __pyx_v_x = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_x == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_y = __pyx_PyFloat_AsDouble(values[1]); if (unlikely((__pyx_v_y == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " goto __pyx_L4_argument_unpacking_done;\n", " __pyx_L5_argtuple_error:;\n", " __Pyx_RaiseArgtupleInvalid(\"klBern_cython\", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_L3_error:;\n", " __Pyx_AddTraceback(\"_cython_magic_0ce0e64bf037172e33037b12661fd5c4.klBern_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __Pyx_RefNannyFinishContext();\n", " return NULL;\n", " __pyx_L4_argument_unpacking_done:;\n", " __pyx_r = __pyx_pf_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_klBern_cython(__pyx_self, __pyx_v_x, __pyx_v_y);\n", "\n", " /* function exit code */\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "\n", "static PyObject *__pyx_pf_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_klBern_cython(CYTHON_UNUSED PyObject *__pyx_self, double __pyx_v_x, double __pyx_v_y) {\n", " PyObject *__pyx_r = NULL;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"klBern_cython\", 0);\n", "/* … */\n", " /* function exit code */\n", " __pyx_L1_error:;\n", " __Pyx_XDECREF(__pyx_t_4);\n", " __Pyx_AddTraceback(\"_cython_magic_0ce0e64bf037172e33037b12661fd5c4.klBern_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __pyx_r = NULL;\n", " __pyx_L0:;\n", " __Pyx_XGIVEREF(__pyx_r);\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "/* … */\n", " __pyx_tuple_ = PyTuple_Pack(2, __pyx_n_s_x, __pyx_n_s_y); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_tuple_);\n", " __Pyx_GIVEREF(__pyx_tuple_);\n", "/* … */\n", " __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_0ce0e64bf037172e33037b12661fd5c4_1klBern_cython, NULL, __pyx_n_s_cython_magic_0ce0e64bf037172e33); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " if (PyDict_SetItem(__pyx_d, __pyx_n_s_klBern_cython, __pyx_t_1) < 0) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", "
+4: x = max(1e-7, min(1 - 1e-7, x))\n", "
__pyx_t_1 = __pyx_v_x;\n", " __pyx_t_2 = (1.0 - 1e-7);\n", " if (((__pyx_t_1 < __pyx_t_2) != 0)) {\n", " __pyx_t_3 = __pyx_t_1;\n", " } else {\n", " __pyx_t_3 = __pyx_t_2;\n", " }\n", " __pyx_t_1 = __pyx_t_3;\n", " __pyx_t_3 = 1e-7;\n", " if (((__pyx_t_1 > __pyx_t_3) != 0)) {\n", " __pyx_t_2 = __pyx_t_1;\n", " } else {\n", " __pyx_t_2 = __pyx_t_3;\n", " }\n", " __pyx_v_x = __pyx_t_2;\n", "
+5: x = max(1e-7, min(1 - 1e-7, x))\n", "
__pyx_t_2 = __pyx_v_x;\n", " __pyx_t_1 = (1.0 - 1e-7);\n", " if (((__pyx_t_2 < __pyx_t_1) != 0)) {\n", " __pyx_t_3 = __pyx_t_2;\n", " } else {\n", " __pyx_t_3 = __pyx_t_1;\n", " }\n", " __pyx_t_2 = __pyx_t_3;\n", " __pyx_t_3 = 1e-7;\n", " if (((__pyx_t_2 > __pyx_t_3) != 0)) {\n", " __pyx_t_1 = __pyx_t_2;\n", " } else {\n", " __pyx_t_1 = __pyx_t_3;\n", " }\n", " __pyx_v_x = __pyx_t_1;\n", "
+6: return x * log(x/y) + (1-x) * log((1-x)/(1-y))\n", "
__Pyx_XDECREF(__pyx_r);\n", " if (unlikely(__pyx_v_y == 0)) {\n", " PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n", " __PYX_ERR(0, 6, __pyx_L1_error)\n", " }\n", " __pyx_t_1 = (1.0 - __pyx_v_x);\n", " __pyx_t_2 = (1.0 - __pyx_v_y);\n", " if (unlikely(__pyx_t_2 == 0)) {\n", " PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n", " __PYX_ERR(0, 6, __pyx_L1_error)\n", " }\n", " __pyx_t_4 = PyFloat_FromDouble(((__pyx_v_x * log((__pyx_v_x / __pyx_v_y))) + ((1.0 - __pyx_v_x) * log((__pyx_t_1 / __pyx_t_2))))); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 6, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_4);\n", " __pyx_r = __pyx_t_4;\n", " __pyx_t_4 = 0;\n", " goto __pyx_L0;\n", "
Generated by Cython 0.29.1
\n", "\n",
" Yellow lines hint at Python interaction.
\n",
" Click on a line that starts with a \"+
\" to see the C code that Cython generated for it.\n",
"
1: from libc.math cimport log\n", "
2:
\n",
"+3: cpdef double threshold_cython(int t0, int s, int t, double delta):\n", "
static PyObject *__pyx_pw_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_1threshold_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", "static double __pyx_f_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_threshold_cython(int __pyx_v_t0, int __pyx_v_s, int __pyx_v_t, double __pyx_v_delta, CYTHON_UNUSED int __pyx_skip_dispatch) {\n", " double __pyx_r;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"threshold_cython\", 0);\n", "/* … */\n", " /* function exit code */\n", " __pyx_L1_error:;\n", " __Pyx_WriteUnraisable(\"_cython_magic_4e48b0e25538ff2883ba5a92832943be.threshold_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);\n", " __pyx_r = 0;\n", " __pyx_L0:;\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "\n", "/* Python wrapper */\n", "static PyObject *__pyx_pw_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_1threshold_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", "static PyObject *__pyx_pw_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_1threshold_cython(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", " int __pyx_v_t0;\n", " int __pyx_v_s;\n", " int __pyx_v_t;\n", " double __pyx_v_delta;\n", " PyObject *__pyx_r = 0;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"threshold_cython (wrapper)\", 0);\n", " {\n", " static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_t0,&__pyx_n_s_s,&__pyx_n_s_t,&__pyx_n_s_delta,0};\n", " PyObject* values[4] = {0,0,0,0};\n", " if (unlikely(__pyx_kwds)) {\n", " Py_ssize_t kw_args;\n", " const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n", " switch (pos_args) {\n", " case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);\n", " CYTHON_FALLTHROUGH;\n", " case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n", " CYTHON_FALLTHROUGH;\n", " case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " CYTHON_FALLTHROUGH;\n", " case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " CYTHON_FALLTHROUGH;\n", " case 0: break;\n", " default: goto __pyx_L5_argtuple_error;\n", " }\n", " kw_args = PyDict_Size(__pyx_kwds);\n", " switch (pos_args) {\n", " case 0:\n", " if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_t0)) != 0)) kw_args--;\n", " else goto __pyx_L5_argtuple_error;\n", " CYTHON_FALLTHROUGH;\n", " case 1:\n", " if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_s)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython\", 1, 4, 4, 1); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " CYTHON_FALLTHROUGH;\n", " case 2:\n", " if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_t)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython\", 1, 4, 4, 2); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " CYTHON_FALLTHROUGH;\n", " case 3:\n", " if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_delta)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython\", 1, 4, 4, 3); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " }\n", " if (unlikely(kw_args > 0)) {\n", " if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"threshold_cython\") < 0)) __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {\n", " goto __pyx_L5_argtuple_error;\n", " } else {\n", " values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n", " values[3] = PyTuple_GET_ITEM(__pyx_args, 3);\n", " }\n", " __pyx_v_t0 = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_t0 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_s = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_s == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_t = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_t == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_delta = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_delta == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " goto __pyx_L4_argument_unpacking_done;\n", " __pyx_L5_argtuple_error:;\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython\", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_L3_error:;\n", " __Pyx_AddTraceback(\"_cython_magic_4e48b0e25538ff2883ba5a92832943be.threshold_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __Pyx_RefNannyFinishContext();\n", " return NULL;\n", " __pyx_L4_argument_unpacking_done:;\n", " __pyx_r = __pyx_pf_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_threshold_cython(__pyx_self, __pyx_v_t0, __pyx_v_s, __pyx_v_t, __pyx_v_delta);\n", "\n", " /* function exit code */\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "\n", "static PyObject *__pyx_pf_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_threshold_cython(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_t0, int __pyx_v_s, int __pyx_v_t, double __pyx_v_delta) {\n", " PyObject *__pyx_r = NULL;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"threshold_cython\", 0);\n", " __Pyx_XDECREF(__pyx_r);\n", " __pyx_t_1 = PyFloat_FromDouble(__pyx_f_46_cython_magic_4e48b0e25538ff2883ba5a92832943be_threshold_cython(__pyx_v_t0, __pyx_v_s, __pyx_v_t, __pyx_v_delta, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " __pyx_r = __pyx_t_1;\n", " __pyx_t_1 = 0;\n", " goto __pyx_L0;\n", "\n", " /* function exit code */\n", " __pyx_L1_error:;\n", " __Pyx_XDECREF(__pyx_t_1);\n", " __Pyx_AddTraceback(\"_cython_magic_4e48b0e25538ff2883ba5a92832943be.threshold_cython\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __pyx_r = NULL;\n", " __pyx_L0:;\n", " __Pyx_XGIVEREF(__pyx_r);\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "
+4: return log((s - t0 + 1) * (t - s) / delta)\n", "
__pyx_t_1 = (((__pyx_v_s - __pyx_v_t0) + 1) * (__pyx_v_t - __pyx_v_s));\n", " if (unlikely(__pyx_v_delta == 0)) {\n", " PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n", " __PYX_ERR(0, 4, __pyx_L1_error)\n", " }\n", " __pyx_r = log((((double)__pyx_t_1) / __pyx_v_delta));\n", " goto __pyx_L0;\n", "
Generated by Cython 0.29.1
\n", "\n",
" Yellow lines hint at Python interaction.
\n",
" Click on a line that starts with a \"+
\" to see the C code that Cython generated for it.\n",
"
1: from libc.math cimport log\n", "
2:
\n",
"+3: def threshold_cython2(int t0, int s, int t, double delta) -> double:\n", "
/* Python wrapper */\n", "static PyObject *__pyx_pw_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_1threshold_cython2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/\n", "static PyMethodDef __pyx_mdef_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_1threshold_cython2 = {\"threshold_cython2\", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_1threshold_cython2, METH_VARARGS|METH_KEYWORDS, 0};\n", "static PyObject *__pyx_pw_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_1threshold_cython2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {\n", " int __pyx_v_t0;\n", " int __pyx_v_s;\n", " int __pyx_v_t;\n", " double __pyx_v_delta;\n", " PyObject *__pyx_r = 0;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"threshold_cython2 (wrapper)\", 0);\n", " {\n", " static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_t0,&__pyx_n_s_s,&__pyx_n_s_t,&__pyx_n_s_delta,0};\n", " PyObject* values[4] = {0,0,0,0};\n", " if (unlikely(__pyx_kwds)) {\n", " Py_ssize_t kw_args;\n", " const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);\n", " switch (pos_args) {\n", " case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);\n", " CYTHON_FALLTHROUGH;\n", " case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n", " CYTHON_FALLTHROUGH;\n", " case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " CYTHON_FALLTHROUGH;\n", " case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " CYTHON_FALLTHROUGH;\n", " case 0: break;\n", " default: goto __pyx_L5_argtuple_error;\n", " }\n", " kw_args = PyDict_Size(__pyx_kwds);\n", " switch (pos_args) {\n", " case 0:\n", " if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_t0)) != 0)) kw_args--;\n", " else goto __pyx_L5_argtuple_error;\n", " CYTHON_FALLTHROUGH;\n", " case 1:\n", " if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_s)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython2\", 1, 4, 4, 1); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " CYTHON_FALLTHROUGH;\n", " case 2:\n", " if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_t)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython2\", 1, 4, 4, 2); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " CYTHON_FALLTHROUGH;\n", " case 3:\n", " if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_delta)) != 0)) kw_args--;\n", " else {\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython2\", 1, 4, 4, 3); __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " }\n", " if (unlikely(kw_args > 0)) {\n", " if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, \"threshold_cython2\") < 0)) __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {\n", " goto __pyx_L5_argtuple_error;\n", " } else {\n", " values[0] = PyTuple_GET_ITEM(__pyx_args, 0);\n", " values[1] = PyTuple_GET_ITEM(__pyx_args, 1);\n", " values[2] = PyTuple_GET_ITEM(__pyx_args, 2);\n", " values[3] = PyTuple_GET_ITEM(__pyx_args, 3);\n", " }\n", " __pyx_v_t0 = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_t0 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_s = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_s == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_t = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_t == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_v_delta = __pyx_PyFloat_AsDouble(values[3]); if (unlikely((__pyx_v_delta == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 3, __pyx_L3_error)\n", " }\n", " goto __pyx_L4_argument_unpacking_done;\n", " __pyx_L5_argtuple_error:;\n", " __Pyx_RaiseArgtupleInvalid(\"threshold_cython2\", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 3, __pyx_L3_error)\n", " __pyx_L3_error:;\n", " __Pyx_AddTraceback(\"_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc.threshold_cython2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __Pyx_RefNannyFinishContext();\n", " return NULL;\n", " __pyx_L4_argument_unpacking_done:;\n", " __pyx_r = __pyx_pf_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_threshold_cython2(__pyx_self, __pyx_v_t0, __pyx_v_s, __pyx_v_t, __pyx_v_delta);\n", "\n", " /* function exit code */\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "\n", "static PyObject *__pyx_pf_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_threshold_cython2(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_t0, int __pyx_v_s, int __pyx_v_t, double __pyx_v_delta) {\n", " PyObject *__pyx_r = NULL;\n", " __Pyx_RefNannyDeclarations\n", " __Pyx_RefNannySetupContext(\"threshold_cython2\", 0);\n", "/* … */\n", " /* function exit code */\n", " __pyx_L1_error:;\n", " __Pyx_XDECREF(__pyx_t_2);\n", " __Pyx_AddTraceback(\"_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc.threshold_cython2\", __pyx_clineno, __pyx_lineno, __pyx_filename);\n", " __pyx_r = NULL;\n", " __pyx_L0:;\n", " __Pyx_XGIVEREF(__pyx_r);\n", " __Pyx_RefNannyFinishContext();\n", " return __pyx_r;\n", "}\n", "/* … */\n", " __pyx_tuple_ = PyTuple_Pack(4, __pyx_n_s_t0, __pyx_n_s_s, __pyx_n_s_t, __pyx_n_s_delta); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_tuple_);\n", " __Pyx_GIVEREF(__pyx_tuple_);\n", "/* … */\n", " __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_46_cython_magic_8a5a8f9968b73b8b7b920f92f30405bc_1threshold_cython2, NULL, __pyx_n_s_cython_magic_8a5a8f9968b73b8b7b); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_1);\n", " if (PyDict_SetItem(__pyx_d, __pyx_n_s_threshold_cython2, __pyx_t_1) < 0) __PYX_ERR(0, 3, __pyx_L1_error)\n", " __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;\n", "
+4: return log((s - t0 + 1) * (t - s) / delta)\n", "
__Pyx_XDECREF(__pyx_r);\n", " __pyx_t_1 = (((__pyx_v_s - __pyx_v_t0) + 1) * (__pyx_v_t - __pyx_v_s));\n", " if (unlikely(__pyx_v_delta == 0)) {\n", " PyErr_SetString(PyExc_ZeroDivisionError, \"float division\");\n", " __PYX_ERR(0, 4, __pyx_L1_error)\n", " }\n", " __pyx_t_2 = PyFloat_FromDouble(log((((double)__pyx_t_1) / __pyx_v_delta))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 4, __pyx_L1_error)\n", " __Pyx_GOTREF(__pyx_t_2);\n", " __pyx_r = __pyx_t_2;\n", " __pyx_t_2 = 0;\n", " goto __pyx_L0;\n", "