cython 和 numpy:'cfunc.to_py:65:25: 'ndarray' 不是类型标识符'
cython and numpy: 'cfunc.to_py:65:25: 'ndarray' is not a type identifier'
我有一个 cdef 函数,它接受两个 numpy.ndarrays 作为参数 (1)。它给了我一个“cfunc.to_py:65:25: 'ndarray' 不是类型标识符”错误。
当我用 def (python) 函数 (2) 或 cpdef (3) 替换 cdef 时,错误消失了。这是一个错误吗?我该如何解决这个问题?代码如下。
(1) cdef float F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
(2) def F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
(3) cpdef float F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
# cython: profile=True
# cython: boundscheck=False
# cython: wraparound=False
cimport cython
from libc.stdlib cimport malloc
from scipy.optimize import minimize
cimport numpy as np
import numpy as np
# due to instabilities associated with "constraint optimization" with bounds
# we will transform the problem so that that it becomes an unconstraint optimization problem without bounds
def transform(x):
x1 = x * x / (1 + x * x)
s = 1 - sum(x1)
return x1, s
# on the next cython update try cdef float F(..)
@cython.cdivision(True)
cdef float F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
cdef float s
cdef float *z_non_labor = <float *>malloc(lenx * sizeof(float))
cdef float z_labor
cdef float labor
cdef float value
cdef float summation
cdef float non_labor
cdef float x
cdef float ynl
for i from 0 <= i < lenx:
x = xx[i]
z_non_labor[i] = x * x / (1 + x * x)
s = 0
for i from 0 <= i < lenx:
s += z_non_labor[i]
z_labor = 1 - s
summation = 0
for i from 0 <= i < lenx:
ynl = y_non_labor[i]
summation += (z_non_labor[i] / ynl) ** gamma
non_labor = summation ** one_by_gamma
labor = z_labor / wage
# labor and non-labor inputs together
value = (labor ** l) * (non_labor ** one_minus_l)
return - value
def optimization(np.ndarray seed_weights,
np.ndarray input_prices,
float wage,
float gamma,
float one_by_gamma,
float l,
float one_minus_l):
cdef int lenx
lenx = len(seed_weights)
args=(input_prices,
wage,
gamma,
one_by_gamma,
l,
one_minus_l,
lenx)
return minimize(F, seed_weights, args=args, method='Nelder-Mead')
我认为这是一个相当晦涩的错误。解释如下。工作轮在答案的最后。
在 Cython 0.21 上我得到一个不同的错误
filename.pyx:73:21: Cannot convert 'float (ndarray, ndarray, float,
float, float, float, float, int)' to Python object.
这对我来说很有意义,因为 minimise
将可调用的 Python 对象作为其第一个答案,而 cdef
仅生成一个 C 函数。 [cpdef
生成两者并在可能的地方调用 C 函数]
在 Cython 0.22 和 0.23 上我得到了你描述的错误。完整的错误是
@cname("__Pyx_CFunc_float____ndarray____ndarray____float____float____float____float____float____int___to_py")
cdef object __Pyx_CFunc_float____ndarray____ndarray____float____float____float____float____float____int___to_py(float (*f)(ndarray, ndarray, float, float, float, float, float, int) except *):
def wrap(ndarray xx, ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
^
------------------------------------------------------------
cfunc.to_py:30:25: 'ndarray' is not a type identifier
您会注意到,这是针对您未定义的函数 wrap
。 wrap
似乎只是因为你正在调用 minimize
才生成,它意识到你在这里需要一个 Python 对象,所以很有帮助地为你制作了一个 def
函数(如果你注释掉对 minimize
的调用错误消失了)。这似乎是围绕 Cython 0.22 进行的增强。
不幸的是,wrap 的代码使用 ndarray
而不是您定义的 np.ndarray
(这一定是一个错误!)。 解决方法是添加以下行
from numpy cimport ndarray
(这使得 ndarray
本身成为一个有效类型)。
但是,鉴于 minimize
需要通过 Python 兼容的包装器调用它,您最好使用 cpdef
(也可以通过 Python 兼容的包装器,但是以不同的方式生成的包装器没有错误)。使用 cpdef
几乎没有任何缺点 - 该函数仍将尽可能作为纯 C 函数被快速调用,并且在 Python 中也能正常工作(尽管速度稍慢)。
我有一个 cdef 函数,它接受两个 numpy.ndarrays 作为参数 (1)。它给了我一个“cfunc.to_py:65:25: 'ndarray' 不是类型标识符”错误。 当我用 def (python) 函数 (2) 或 cpdef (3) 替换 cdef 时,错误消失了。这是一个错误吗?我该如何解决这个问题?代码如下。
(1) cdef float F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
(2) def F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
(3) cpdef float F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
# cython: profile=True
# cython: boundscheck=False
# cython: wraparound=False
cimport cython
from libc.stdlib cimport malloc
from scipy.optimize import minimize
cimport numpy as np
import numpy as np
# due to instabilities associated with "constraint optimization" with bounds
# we will transform the problem so that that it becomes an unconstraint optimization problem without bounds
def transform(x):
x1 = x * x / (1 + x * x)
s = 1 - sum(x1)
return x1, s
# on the next cython update try cdef float F(..)
@cython.cdivision(True)
cdef float F(np.ndarray xx, np.ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
cdef float s
cdef float *z_non_labor = <float *>malloc(lenx * sizeof(float))
cdef float z_labor
cdef float labor
cdef float value
cdef float summation
cdef float non_labor
cdef float x
cdef float ynl
for i from 0 <= i < lenx:
x = xx[i]
z_non_labor[i] = x * x / (1 + x * x)
s = 0
for i from 0 <= i < lenx:
s += z_non_labor[i]
z_labor = 1 - s
summation = 0
for i from 0 <= i < lenx:
ynl = y_non_labor[i]
summation += (z_non_labor[i] / ynl) ** gamma
non_labor = summation ** one_by_gamma
labor = z_labor / wage
# labor and non-labor inputs together
value = (labor ** l) * (non_labor ** one_minus_l)
return - value
def optimization(np.ndarray seed_weights,
np.ndarray input_prices,
float wage,
float gamma,
float one_by_gamma,
float l,
float one_minus_l):
cdef int lenx
lenx = len(seed_weights)
args=(input_prices,
wage,
gamma,
one_by_gamma,
l,
one_minus_l,
lenx)
return minimize(F, seed_weights, args=args, method='Nelder-Mead')
我认为这是一个相当晦涩的错误。解释如下。工作轮在答案的最后。
在 Cython 0.21 上我得到一个不同的错误
filename.pyx:73:21: Cannot convert 'float (ndarray, ndarray, float,
float, float, float, float, int)' to Python object.
这对我来说很有意义,因为 minimise
将可调用的 Python 对象作为其第一个答案,而 cdef
仅生成一个 C 函数。 [cpdef
生成两者并在可能的地方调用 C 函数]
在 Cython 0.22 和 0.23 上我得到了你描述的错误。完整的错误是
@cname("__Pyx_CFunc_float____ndarray____ndarray____float____float____float____float____float____int___to_py")
cdef object __Pyx_CFunc_float____ndarray____ndarray____float____float____float____float____float____int___to_py(float (*f)(ndarray, ndarray, float, float, float, float, float, int) except *):
def wrap(ndarray xx, ndarray y_non_labor, float wage, float gamma, float one_by_gamma, float l, float one_minus_l, int lenx):
^
------------------------------------------------------------
cfunc.to_py:30:25: 'ndarray' is not a type identifier
您会注意到,这是针对您未定义的函数 wrap
。 wrap
似乎只是因为你正在调用 minimize
才生成,它意识到你在这里需要一个 Python 对象,所以很有帮助地为你制作了一个 def
函数(如果你注释掉对 minimize
的调用错误消失了)。这似乎是围绕 Cython 0.22 进行的增强。
不幸的是,wrap 的代码使用 ndarray
而不是您定义的 np.ndarray
(这一定是一个错误!)。 解决方法是添加以下行
from numpy cimport ndarray
(这使得 ndarray
本身成为一个有效类型)。
但是,鉴于 minimize
需要通过 Python 兼容的包装器调用它,您最好使用 cpdef
(也可以通过 Python 兼容的包装器,但是以不同的方式生成的包装器没有错误)。使用 cpdef
几乎没有任何缺点 - 该函数仍将尽可能作为纯 C 函数被快速调用,并且在 Python 中也能正常工作(尽管速度稍慢)。