Cython优化零API

可以使用Cython直接访问以下根查找器的底层C函数:

ZEROS函数的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*)

示例

使用 cython_optimize requires Cython to write callbacks that are compiled into C. For more information on compiling Cython, see the Cython Documentation

以下是基本步骤:

  1. 创建Cython .pyx 文件,例如: myexample.pyx

  2. 从导入所需的根查找器 cython_optimize

  3. 编写回调函数,并调用选定的零函数,传递回调、任何额外参数和其他求解器参数。::

    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):
        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)
    
  4. 如果要从Python调用函数,请创建Cython包装器和调用包装器的Python函数,或使用 cpdef 。然后,在Python中,您可以导入并运行该示例。::

    from myexample import brentq_example
    
    x = brentq_example()
    # 0.6999942848231314
    
  5. 创建Cython .pxd 如果需要导出任何Cython函数,请使用该文件。

全部输出

中的函数 cython_optimize 还可以将求解器的完整输出复制到C struct 这是作为其最后一个参数传递的。如果您不想要完整的输出,只需传递 NULL 。全部产出 struct 必须为type 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 brent_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}