#!/usr/bin/env python # coding: utf-8 # In[1]: get_ipython().run_line_magic('load_ext', 'cython') # In[2]: get_ipython().run_cell_magic('cython', '', '\nimport numpy as np\nfrom scipy.optimize.cython_optimize cimport brentq\n\n# import math from Cython\nfrom libc cimport math\n\nCNT = 1e5\nC0_ARG = 1.0 + np.linspace(-0.05, 0.05, int(CNT), dtype=np.dtype("f8"))\nC1_ARG = 0.7\nXLO, XHI = 0.0, 1.0 # lower and upper search boundaries\nXTOL, RTOL = 1e-3, 1e-3\nMITR = 10 # other solver parameters\n\n# user defined struct for extra parameters\nctypedef struct test_params:\n double C0\n double C1\n\n\n# user defined callback\ncdef double f(double x, void *args):\n cdef test_params *myargs = args\n return myargs.C0 - math.exp(-(x - myargs.C1))\n\n\n# Cython wrapper function\ncdef int brentq_wrapper_loop_example(double[:] c0, double c1, double xa, double xb,\n double xtol, double rtol, int mitr, double[:] result):\n cdef Py_ssize_t i = 0\n cdef test_params myargs\n\n myargs.C1 = c1\n\n while i < CNT:\n myargs.C0 = c0[i]\n result[i] = brentq(\n f, xa, xb, &myargs, xtol, rtol, mitr, NULL)\n i += 1\n return 0\n\n\n# Python function\ndef brentq_loop_example(c0=C0_ARG, c1=C1_ARG, xa=XLO, xb=XHI, xtol=XTOL, rtol=RTOL,\n mitr=MITR):\n \'\'\'Calls Cython wrapper from Python.\'\'\'\n cdef double[:] result = np.empty_like(c0)\n if not brentq_wrapper_loop_example(c0, c1, xa, xb, xtol, rtol, mitr, result):\n return result\n') # In[3]: get_ipython().run_line_magic('timeit', 'brentq_loop_example()') # In[4]: x_loop = brentq_loop_example() np.asarray(x_loop)[:10] # In[5]: get_ipython().run_cell_magic('cython', '', '\nfrom scipy.optimize.cython_optimize cimport brentq\nimport numpy as np\n\n# import math from Cython\nfrom libc cimport math\n\nCNT = 1e5\nC0_ARG = 1.0 + np.linspace(-0.05, 0.05, int(CNT), dtype=np.dtype("f8"))\nC1_ARG = 0.7\nXLO, XHI = 0., 1.0 # lower and upper search boundaries\nXTOL, RTOL, MITR = 1e-3, 1e-3, 10 # other solver parameters\n\n# user defined struct for extra parameters\nctypedef struct test_params:\n double C0\n double C1\n\n\n# user defined callback\ncdef double f(double x, void *args):\n cdef test_params *myargs = args\n return myargs.C0 - math.exp(-(x - myargs.C1))\n\n\n# Cython wrapper function\ncdef double brentq_wrapper_map_example(dict args, double xa, double xb,\n double xtol, double rtol, int mitr):\n # Cython automatically casts dictionary to struct\n cdef test_params myargs = args\n return brentq(\n f, xa, xb, &myargs, xtol, rtol, mitr, NULL)\n\n\n# Python function\ndef brentq_map_example(c0=C0_ARG, c1=C1_ARG, xa=XLO, xb=XHI, xtol=XTOL, rtol=RTOL,\n mitr=MITR):\n \'\'\'Calls Cython wrapper from Python.\'\'\'\n args = [{\'C0\': c0_, \'C1\': c1} for c0_ in c0]\n return map(lambda a: brentq_wrapper_map_example(a, xa, xb, xtol, rtol, mitr), args)\n') # In[6]: get_ipython().run_line_magic('timeit', 'list(brentq_map_example())') # In[7]: x_map = list(brentq_map_example()) # In[8]: assert np.allclose(np.asarray(x_map), np.asarray(x_loop)) # In[9]: from scipy.optimize import brentq import numpy as np CNT = 1e5 C0_ARG = 1.0 + np.linspace(-0.05, 0.05, int(CNT), np.float64) C1_ARG = 0.7 XLO, XHI = 0., 1.0 # lower and upper search boundaries XTOL, RTOL, MITR = 1e-3, 1e-3, 10 # other solver parameters # user defined callback def f(x, args): return args['C0'] - np.exp(-(x - args['C1'])) # Python function def brentq_np_example(c0=C0_ARG, c1=C1_ARG, xa=XLO, xb=XHI, xtol=XTOL, rtol=RTOL, mitr=MITR): '''Calls Cython wrapper from Python.''' args = [{'C0': c0_, 'C1': c1} for c0_ in c0] return map(lambda a: brentq(f, xa, xb, a, xtol, rtol, mitr), args) # In[10]: get_ipython().run_line_magic('timeit', 'list(brentq_np_example())') # In[11]: x_np = list(brentq_np_example()) # In[12]: assert np.allclose(np.asarray(x_map), np.asarray(x_np)) # In[13]: get_ipython().run_cell_magic('cython', '', '\ncimport cython\nfrom cython.parallel import prange\nimport numpy as np\nfrom scipy.optimize.cython_optimize cimport brentq\n\n# import math from Cython\nfrom libc cimport math\n\nCNT = 1e5\nC0_ARG = 1.0 + np.linspace(-0.05, 0.05, int(CNT), dtype=np.dtype("f8"))\nC1_ARG = 0.7\nXLO, XHI = 0.0, 1.0 # lower and upper search boundaries\nXTOL, RTOL = 1e-3, 1e-3\nMITR = 10 # other solver parameters\n\n# user defined struct for extra parameters\nctypedef struct test_params:\n double C0\n double C1\n\n\n# user defined callback\n@cython.initializedcheck(False)\n@cython.boundscheck(False) # turn off boundscheck for this function\n@cython.wraparound(False)\n@cython.cdivision(True)\ncdef double f(double x, void *args) nogil:\n # nogil doesn\'t seem to matter here\n # works w/ or w/o, same benchmark time\n cdef test_params *myargs = args\n return myargs.C0 - math.exp(-(x - myargs.C1))\n\n\n# Cython wrapper function\n@cython.initializedcheck(False)\n@cython.boundscheck(False) # turn off boundscheck for this function\n@cython.wraparound(False)\n@cython.cdivision(True)\ncdef int brentq_wrapper_prange_example(double[:] c0, double c1, double xa, double xb,\n double xtol, double rtol, int mitr, double[:] result):\n cdef Py_ssize_t i\n cdef test_params myargs\n\n myargs.C1 = c1\n\n for i in prange(c0.shape[0], nogil=True):\n myargs.C0 = c0[i]\n result[i] = brentq(\n f, xa, xb, &myargs, xtol, rtol, mitr, NULL)\n return 0\n\n\n# Python function\ndef brentq_prange_example(c0=C0_ARG, c1=C1_ARG, xa=XLO, xb=XHI, xtol=XTOL, rtol=RTOL,\n mitr=MITR):\n \'\'\'Calls Cython wrapper from Python.\'\'\'\n cdef double[:] result = np.empty_like(c0)\n if not brentq_wrapper_prange_example(c0, c1, xa, xb, xtol, rtol, mitr, result):\n return result\n') # In[14]: get_ipython().run_line_magic('timeit', 'brentq_prange_example()') # In[15]: x_prange = brentq_prange_example() # In[16]: assert np.allclose(np.asarray(x_map), np.asarray(x_prange)) # In[ ]: