__init__.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. """
  2. Cython optimize zeros API
  3. =========================
  4. The underlying C functions for the following root finders can be accessed
  5. directly using Cython:
  6. - `~scipy.optimize.bisect`
  7. - `~scipy.optimize.ridder`
  8. - `~scipy.optimize.brenth`
  9. - `~scipy.optimize.brentq`
  10. The Cython API for the zeros functions is similar except there is no ``disp``
  11. argument. Import the zeros functions using ``cimport`` from
  12. `scipy.optimize.cython_optimize`. ::
  13. from scipy.optimize.cython_optimize cimport bisect, ridder, brentq, brenth
  14. Callback signature
  15. ------------------
  16. The zeros functions in `~scipy.optimize.cython_optimize` expect a callback that
  17. takes a double for the scalar independent variable as the 1st argument and a
  18. user defined ``struct`` with any extra parameters as the 2nd argument. ::
  19. double (*callback_type)(double, void*)
  20. Examples
  21. --------
  22. Usage of `~scipy.optimize.cython_optimize` requires Cython to write callbacks
  23. that are compiled into C. For more information on compiling Cython, see the
  24. `Cython Documentation <http://docs.cython.org/en/latest/index.html>`_.
  25. These are the basic steps:
  26. 1. Create a Cython ``.pyx`` file, for example: ``myexample.pyx``.
  27. 2. Import the desired root finder from `~scipy.optimize.cython_optimize`.
  28. 3. Write the callback function, and call the selected zeros function passing
  29. the callback, any extra arguments, and the other solver parameters. ::
  30. from scipy.optimize.cython_optimize cimport brentq
  31. # import math from Cython
  32. from libc cimport math
  33. myargs = {'C0': 1.0, 'C1': 0.7} # a dictionary of extra arguments
  34. XLO, XHI = 0.5, 1.0 # lower and upper search boundaries
  35. XTOL, RTOL, MITR = 1e-3, 1e-3, 10 # other solver parameters
  36. # user-defined struct for extra parameters
  37. ctypedef struct test_params:
  38. double C0
  39. double C1
  40. # user-defined callback
  41. cdef double f(double x, void *args):
  42. cdef test_params *myargs = <test_params *> args
  43. return myargs.C0 - math.exp(-(x - myargs.C1))
  44. # Cython wrapper function
  45. cdef double brentq_wrapper_example(dict args, double xa, double xb,
  46. double xtol, double rtol, int mitr):
  47. # Cython automatically casts dictionary to struct
  48. cdef test_params myargs = args
  49. return brentq(
  50. f, xa, xb, <test_params *> &myargs, xtol, rtol, mitr, NULL)
  51. # Python function
  52. def brentq_example(args=myargs, xa=XLO, xb=XHI, xtol=XTOL, rtol=RTOL,
  53. mitr=MITR):
  54. '''Calls Cython wrapper from Python.'''
  55. return brentq_wrapper_example(args, xa, xb, xtol, rtol, mitr)
  56. 4. If you want to call your function from Python, create a Cython wrapper, and
  57. a Python function that calls the wrapper, or use ``cpdef``. Then, in Python,
  58. you can import and run the example. ::
  59. from myexample import brentq_example
  60. x = brentq_example()
  61. # 0.6999942848231314
  62. 5. Create a Cython ``.pxd`` file if you need to export any Cython functions.
  63. Full output
  64. -----------
  65. The functions in `~scipy.optimize.cython_optimize` can also copy the full
  66. output from the solver to a C ``struct`` that is passed as its last argument.
  67. If you don't want the full output, just pass ``NULL``. The full output
  68. ``struct`` must be type ``zeros_full_output``, which is defined in
  69. `scipy.optimize.cython_optimize` with the following fields:
  70. - ``int funcalls``: number of function calls
  71. - ``int iterations``: number of iterations
  72. - ``int error_num``: error number
  73. - ``double root``: root of function
  74. The root is copied by `~scipy.optimize.cython_optimize` to the full output
  75. ``struct``. An error number of -1 means a sign error, -2 means a convergence
  76. error, and 0 means the solver converged. Continuing from the previous example::
  77. from scipy.optimize.cython_optimize cimport zeros_full_output
  78. # cython brentq solver with full output
  79. cdef zeros_full_output brentq_full_output_wrapper_example(
  80. dict args, double xa, double xb, double xtol, double rtol,
  81. int mitr):
  82. cdef test_params myargs = args
  83. cdef zeros_full_output my_full_output
  84. # use my_full_output instead of NULL
  85. brentq(f, xa, xb, &myargs, xtol, rtol, mitr, &my_full_output)
  86. return my_full_output
  87. # Python function
  88. def brent_full_output_example(args=myargs, xa=XLO, xb=XHI, xtol=XTOL,
  89. rtol=RTOL, mitr=MITR):
  90. '''Returns full output'''
  91. return brentq_full_output_wrapper_example(args, xa, xb, xtol, rtol,
  92. mitr)
  93. result = brent_full_output_example()
  94. # {'error_num': 0,
  95. # 'funcalls': 6,
  96. # 'iterations': 5,
  97. # 'root': 0.6999942848231314}
  98. """