Cython 优化求根 API#
以下求根器的底层 C 函数可以使用 Cython 直接访问
求根函数的 Cython API 类似,只是没有 disp
参数。使用 cimport
从 scipy.optimize.cython_optimize
导入求根函数。
from scipy.optimize.cython_optimize cimport bisect, ridder, brentq, brenth
回调签名#
cython_optimize
中的求零点函数需要一个回调函数,该回调函数将标量自变量的双精度值作为第一个参数,并将带有任何额外参数的用户定义 struct
作为第二个参数。
double (*callback_type)(double, void*) noexcept
示例#
使用 cython_optimize
需要使用 Cython 编写编译为 C 语言的回调函数。有关编译 Cython 的更多信息,请参阅 Cython 文档。
以下是基本步骤
创建一个 Cython
.pyx
文件,例如:myexample.pyx
。从
cython_optimize
导入所需的求根器。编写回调函数,并调用所选的求根函数,传入回调函数、任何额外参数和其他求解器参数。
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 函数,请创建一个 Cython
.pxd
文件。
完整输出#
cython_optimize
中的函数还可以将求解器的完整输出复制到一个作为最后一个参数传入的 C struct
中。如果您不需要完整输出,只需传入 NULL
。完整输出 struct
必须是 zeros_full_output
类型,该类型在 scipy.optimize.cython_optimize
中定义,包含以下字段:
int funcalls
: 函数调用次数int iterations
: 迭代次数int error_num
: 错误码double root
: 函数根
根由 cython_optimize
复制到完整输出 struct
中。错误码为 -1 表示符号错误,-2 表示收敛错误,0 表示求解器已收敛。继续上一个示例
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}