gpt4 book ai didi

python - 如何在cython的函数参数中键入函数

转载 作者:行者123 更新时间:2023-12-05 00:47:11 25 4
gpt4 key购买 nike

我做了一个在 python 中进行优化的函数(我们称之为 optimizer )。它需要将要优化的函数(我们称之为 objective )作为函数参数之一。 objective是一个接受一维 np.ndarray 的函数并返回 float数字(与 C++ 中的 double 相同?)。

我读过这篇 post ,但我不确定它是否真的和我的问题一样,当我使用 ctypedef int (*f_type)(int, str) 时,但我收到错误 Cannot convert 'f_type' to Python object在编译过程中。它仅适用于 C 函数吗?如何输入python函数?

编辑:我的代码看起来像:

cpdef optimizer(objective, int num_particle, int dim,
np.ndarray[double, ndim=1] lower_bound,
np.ndarray[double, ndim=1] upper_bound):

cdef double min_value
cdef np.ndarray[double, ndim=2] positions = np.empty((num_particle,dim), dtype=np.double)
cdef np.ndarray[double, ndim=1] fitness = np.empty(num_particle, dtype=np.double)
cdef int i, j

# do lots of stuff not shown here
# involve the following code:
for i in range(num_particle):
fitness[i] = objective(positions[i])

return min_value

我想知道是否可以输入 objective使代码运行得更快。

最佳答案

我收到错误消息

Cannot convert Python object argument to type 'f_type'



我认为这比你声称得到的更有意义 - 你试图将一个 Python 对象传递给函数。请确保您报告的错误消息是您的代码实际生成的。您对 objective 类型的描述需要也与您显示的代码不匹配。

但是,一般来说:不,您不能给目标函数一个类型说明符来加速它。通用 Python 可调用对象比 C 函数指针携带更多信息(例如引用计数、任何闭包捕获变量的详细信息等)。

一种可能的替代方法是从 cdef class 继承。用合适的 cdef函数,因此您至少可以在特定情况下获得适当的性能:
# an abstract function pointer class
cdef class FPtr:
cdef double function(self,double[:] x) except? 0.0:
# I'm assuming you might want to pass exceptions back to Python - use 0.0 to indicate that there might have been an error
raise NotImplementedError()

# an example class that inherits from the abstract pointer type
cdef class SumSq(FPtr):
cdef double function(self,double[:] x) except? 0.0:
cdef double sum=0.0
for i in range(x.shape[0]):
sum += x[i]**2
return sum

# an example class that just wraps a Python callable
# this will be no faster, but makes the code generically usable
cdef class PyFPtr(FPtr):
cdef object f
def __init__(self,f):
self.f = f

cdef double function(self,double[:] x) except? 0.0:
return self.f(x) # will raise an exception if the types don't match

def example_function(FPtr my_callable):
import numpy as np
return my_callable.function(np.ones((10,)))

使用此 example_function(SumSq())按预期工作(并以 Cython 速度运行); example_function(PyFPtr(lambda x: x[0]))按预期工作(可调用中没有 Cython 速度); example_function(PyFPtr(lambda x: "hello"))按预期给出类型错误。

关于python - 如何在cython的函数参数中键入函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52252511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com