是否可以将cython函数作为参数传递给scipy函数?

是否可以将cython函数作为参数传递给scipy函数?,scipy,cython,Scipy,Cython,Scipy有许多函数,它们接受可调用的python来执行某些操作。特别是,我正在使用一个数学优化函数scipy.optimize.leastsq,该函数接受Python可调用作为目标函数参数。在最小化过程中,leastsq可以多次调用此目标函数 我的分析表明,在这个目标函数上花费了很多时间。我使用Cython加速了函数的某些部分。但是,函数本身仍然是一个Python函数,重复调用它(正如leastsq所做的那样)会产生一些开销 我想如果函数是Cython函数(使用cdef而不是def),我可以进

Scipy有许多函数,它们接受可调用的python来执行某些操作。特别是,我正在使用一个数学优化函数
scipy.optimize.leastsq
,该函数接受Python可调用作为目标函数参数。在最小化过程中,
leastsq
可以多次调用此目标函数

我的分析表明,在这个目标函数上花费了很多时间。我使用Cython加速了函数的某些部分。但是,函数本身仍然是一个Python函数,重复调用它(正如
leastsq
所做的那样)会产生一些开销

我想如果函数是Cython函数(使用
cdef
而不是
def
),我可以进一步提高速度。因此,我将对
leastsq
的调用放在Cython扩展中,并将Cython目标函数传递给它。但是当我这样做时,我在
leastsq
调用中得到一个编译错误:

Cannot convert 'object (object, object, object)' to Python object
有没有办法将Cython函数作为参数传递给这些需要python可调用函数的Scipy函数?


或者,在我的例子中,是否有任何方法可以访问底层的
leastsq
实现并将Cython目标函数传递给它?目前无法传递中的cdef函数。向底层Fortran代码传递回调函数也是不可能的,因为它是用f2py包装的,而f2py不知道Cython

您可以做的是:

  • 将函数编写为Cython的
    def
    函数。这些可以传递到所有Scipy的例程中。这并没有消除使用Python回调机制带来的额外函数调用开销(这可能并不重要!),但您可以加快函数的实现,这可能就足够了。只要记住
    cdef
    中出现的变量,就像编写Cython代码时一样

  • 从Scipy或netlib.org复制MINPACK源代码,并直接自己使用。通过用低级函数回调机制替换Python函数回调机制,消除了剩余的函数调用开销


(已经讨论过添加一个协议来传递低级函数指针,这正是为此目的,任何需要它的基于Python的系统都可以采用该协议,但恐怕设计尚未完成,也没有在Cython&Scipy中实现。)

谢谢。我已经做了第一个建议,将我的目标函数保持为python函数,并在cython中加速其代码。我得到了一些加速,但没有太多,因为原始代码已经基本上用numpy矢量化了。关于第二个建议,我已经挖掘了一段时间,试图在_minpack.pyd中调用lmdif,并通过签名
cdef int raw\u multipack\u lm_函数(int*m,int*n,double*x,double*fvec,int*iflag)传递我的目标函数
,但我有很多错误,我被卡住了,我想知道你是否可以给我举一些例子来说明如何做到这一点。我手头没有一个例子。但是,我建议您重新检查该时间是否仍在函数中使用,例如,just via time.time()。我认为使用第二个选项的性能改进不是很重要,除非您的函数的评估速度相当快。好的。我已经测量了目标函数中花费的时间与最少TSQ优化所花费的时间。我花了大约69%的时间在目标函数上进行测试,结果是41次目标函数评估。我认为花费在呼叫开销上的时间一定是剩余31%的一小部分。对于python调用,我将保持原样,并将重点放在加快目标函数的速度上。谢谢你的帮助。