Cython API оптимизации нахождения корней#
К базовым C-функциям следующих методов поиска корней можно получить прямой доступ с помощью Cython:
Cython API для функций поиска корней аналогичен, за исключением того, что нет
disp аргумент. Импортировать функции нахождения корней с помощью cimport из
scipy.optimize.cython_optimize.
from scipy.optimize.cython_optimize cimport bisect, ridder, brentq, brenth
Сигнатура обратного вызова#
Функции zeros в cython_optimize ожидают callback-функцию, которая принимает double для скалярной независимой переменной в качестве 1-го аргумента и пользовательский struct с любыми дополнительными параметрами в качестве второго аргумента.
double (*callback_type)(double, void*) noexcept
Примеры#
Использование cython_optimize требует Cython для написания callback-функций, которые компилируются в C. Для получения дополнительной информации о компиляции Cython см.
Документация Cython.
Это основные шаги:
Создать Cython
.pyxфайл, например:myexample.pyx.Импортировать желаемый искатель корней из
cython_optimize.Напишите callback-функцию и вызовите выбранную функцию поиска корня, передав callback, любые дополнительные аргументы и другие параметры решателя.
from scipy.optimize.cython_optimize cimport brentq # import math from Cython from libc cimport math myargs = {'C0': 1.0, 'C1': 0.7} # a dictionary of extra arguments XLO, XHI = 0.5, 1.0 # lower and upper search boundaries XTOL, RTOL, MITR = 1e-3, 1e-3, 10 # other solver parameters # user-defined struct for extra parameters ctypedef struct test_params: double C0 double C1 # user-defined callback cdef double f(double x, void *args) noexcept: cdef test_params *myargs = <test_params *> args return myargs.C0 - math.exp(-(x - myargs.C1)) # Cython wrapper function cdef double brentq_wrapper_example(dict args, double xa, double xb, double xtol, double rtol, int mitr): # Cython automatically casts dictionary to struct cdef test_params myargs = args return brentq( f, xa, xb, <test_params *> &myargs, xtol, rtol, mitr, NULL) # Python function def brentq_example(args=myargs, xa=XLO, xb=XHI, xtol=XTOL, rtol=RTOL, mitr=MITR): '''Calls Cython wrapper from Python.''' return brentq_wrapper_example(args, xa, xb, xtol, rtol, mitr)
Если вы хотите вызвать свою функцию из Python, создайте обёртку на Cython и функцию Python, которая вызывает обёртку, или используйте
cpdef. Затем, в Python, вы можете импортировать и запустить пример.from myexample import brentq_example x = brentq_example() # 0.6999942848231314
Создать Cython
.pxdфайл, если нужно экспортировать какие-либо функции Cython.
Полный вывод#
Функции в cython_optimize также можно скопировать полный
вывод из решателя в C struct который передаётся в качестве последнего аргумента.
Если вам не нужен полный вывод, просто передайте NULL. Полный вывод
struct должен быть типа zeros_full_output, который определен в
scipy.optimize.cython_optimize со следующими полями:
int funcalls: количество вызовов функцииint iterations: количество итерацийint error_num: номер ошибкиdouble root: корень функции
Корень копируется с помощью cython_optimize к полному выводу
structbobcatCA (2) +
from scipy.optimize.cython_optimize cimport zeros_full_output
# cython brentq solver with full output
cdef zeros_full_output brentq_full_output_wrapper_example(
dict args, double xa, double xb, double xtol, double rtol,
int mitr):
cdef test_params myargs = args
cdef zeros_full_output my_full_output
# use my_full_output instead of NULL
brentq(f, xa, xb, &myargs, xtol, rtol, mitr, &my_full_output)
return my_full_output
# Python function
def brent_full_output_example(args=myargs, xa=XLO, xb=XHI, xtol=XTOL,
rtol=RTOL, mitr=MITR):
'''Returns full output'''
return brentq_full_output_wrapper_example(args, xa, xb, xtol, rtol,
mitr)
result = brent_full_output_example()
# {'error_num': 0,
# 'funcalls': 6,
# 'iterations': 5,
# 'root': 0.6999942848231314}