Python中本机/C代码回调的组合
我大量使用Python中的数值分析库,例如Scipy的优化和集成例程,其中许多例程都使用回调函数作为主要参数,该函数对某种目标函数进行求值。出于性能原因,我经常在本机代码中实现这些回调(通常使用Cython或Numba生成C代码,这些代码经过编译、链接,然后封装在Python对象中)。许多Scipy例程现在接受一个实例,这是一个包含指向C函数的指针及其签名信息的对象。如果例程本身是用C或Cython实现的,那么完全绕过Python解释器可以大大减少开销 我试图找出最好的方法是创建Python函数,这些函数接受这些类型的本机回调对象,以某种方式对它们进行转换,然后返回另一个本机回调。一个例子是一个函数,它接受一个预测给定Python中本机/C代码回调的组合,python,scipy,ctypes,python-c-api,scientific-computing,Python,Scipy,Ctypes,Python C Api,Scientific Computing,我大量使用Python中的数值分析库,例如Scipy的优化和集成例程,其中许多例程都使用回调函数作为主要参数,该函数对某种目标函数进行求值。出于性能原因,我经常在本机代码中实现这些回调(通常使用Cython或Numba生成C代码,这些代码经过编译、链接,然后封装在Python对象中)。许多Scipy例程现在接受一个实例,这是一个包含指向C函数的指针及其签名信息的对象。如果例程本身是用C或Cython实现的,那么完全绕过Python解释器可以大大减少开销 我试图找出最好的方法是创建Python函数
x
的y
回调以及一个观察到的y
值数组,并返回另一个回调,该回调计算预测与观察值相比的误差。然后可以将结果传递给scipy.optimize.minimize()
常规Python函数的实现如下所示:
import numpy as np
def make_error_callback(f, y_obs):
def g(x):
y = f(x)
return np.sum((y - y_obs) ** 2)
return g
目标是,如果
f
是一个本机回调,可以在不调用Python解释器的情况下对其进行评估,那么g
也应该是make\u error\u callback
可能必须在Cython或类似的东西中实现(最糟糕的情况是使用Python的C API实现实际的C)。f
和g
的实际Python类型将是封装C函数指针的东西,如scipy.LowLevelCallable
使用Numba也不会太复杂。示例: