Scipy有很多函数接受python可调用来执行某些操作。特别是,我正在使用数学优化函数scipy.optimize.leastsq
,它接受Python可调用作为目标函数参数。在最小化过程中,可以通过leastsq
多次调用此目标函数。
我的分析表明,该目标函数花费了大量时间。我已经使用Cython加速了函数的某些部分。但是,函数本身仍然是一个Python函数,并且重复调用它(如leastsq
那样)会产生一些开销。
如果函数是Cython函数(使用cdef
而不是def
),我想我可以进一步提高速度。所以我把我的调用放在Cython扩展中的leastsq
并传递一个Cython目标函数。但是当我这样做时我在 leastsq
电话中收到了编译错误:
Cannot convert 'object (object, object, object)' to Python object
有没有办法将Cython函数作为参数传递给需要python callables的Scipy函数?
或者,就我而言,有没有办法访问基础 leastsq
实现并将Cython目标函数传递给它?
答案 0 :(得分:6)
目前无法传递cdef
个函数。将回调函数传递给底层的Fortran代码也是不可能的,因为它包含了f2py而不知道Cython。
你能做的是:
将您的函数编写为Cython的def
函数。这些可以传递给所有Scipy的例程。这不会消除使用Python的回调机制带来的额外函数调用开销(这可能不重要!),但是可以加速函数的实现,这可能就足够了。只需记住cdef
出现的变量,就像编写Cython代码时一样。
从Scipy或netlib.org复制MINPACK源代码,并直接自行使用。这通过用低级别的函数替换Python函数回调机制来消除剩余的函数调用开销。
(已经讨论过添加一个协议,用于为此目的准确传递低级函数指针,任何需要它的基于Python的系统都可以采用它,但是AFAIK的设计没有完成,并且没有在Cython& Scipy中实现。)