[英]Passing a cython function vs a cython method to scipy.integrate
我正在嘗試研究如何使用cython來加快涉及在我定義的類中完成的集成的計算。 我試圖更好地了解cython如何與用戶定義的python類一起工作。 我想了解更多有關為什么發生以下描述的錯誤的信息。
我在名為ex.pyx
的文件中包含以下cython代碼
from libc.math cimport log
from libc.math cimport sqrt
import scipy.integrate as integ
cdef double integrand_outside(double x):
"""Cython: integrand outside the class"""
cdef double f = log(x) / sqrt(x)
return f
cdef class CalcSomething(object):
def integrate_other(self, double a, double b):
"""This does the integral with the integrand outside the class"""
return integ.quad(integrand_outside, a, b)[0]
def integrate_self(self, double a, double b):
"""This does the integral with the integrand inside the class"""
return integ.quad(self._integrand, a, b)[0]
def integrate_wrap_self(self, double a, double b):
"""This does the integral with the integrand inside the class"""
return integ.quad(self.wrap_integrand, a, b)[0]
def wrap_integrand(self, double x):
"""Python method that wraps _integrand"""
return self._integrand(x)
cdef double _integrand(self, double x):
"""Cython: integrand inside the class"""
cdef double f = log(x) / sqrt(x)
return f
它顯示了從類中調用scipy.integrate.quad
三種方式
integrate_other
(確定!) integrate_self
(產生錯誤) integrate_wrap_self
(好!) 上面的cython代碼編譯良好。 現在,我將這些集成方法分別稱為
import ex
calcSomething = ex.CalcSomething()
a = 0.001
b = 0.1
calcSomething.integrate_other(a,b) # works
calcSomething.integrate_wrap_self(a,b) # works
calcSomething.integrate_self(a,b) # doesn't work
這是回溯:
Traceback (most recent call last):
File "../examples/example.py", line 10, in <module>
print "integrate self =", calcSomething.integrate_self(a,b) # doesn't work
File "ex.pyx", line 17, in ex.CalcSomething.integrate_self (ex.c:989)
return integ.quad(self._integrand, a, b)[0]
File "/home/alex/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/scipy/integrate/quadpack.py", line 281, in quad
retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
File "/home/alex/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/scipy/integrate/quadpack.py", line 345, in _quad
return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
File "stringsource", line 30, in cfunc.to_py.__Pyx_CFunc_double____CalcSomething____double___to_py.wrap (ex.c:1560)
TypeError: wrap() takes exactly 2 positional arguments (1 given)
這是我的問題:
為什么可以將scipy.integrate
作為cython函數或python方法(因此現在將實例作為第一個參數)而不作為cython方法傳遞? 錯誤: TypeError: wrap() takes exactly 2 positional arguments (1 given)
暗示問題出在我想用cython方法傳遞的實例參數上?
這個錯誤是由於我對cython的誤解還是對scipy
的限制scipy
?
如果我想通過cython加快速度,我打算在類中計算積分(通過在類中也調用被積分函數)的計划不是很好的解決方案嗎? 披露:實際代碼將調用GSL集成函數,而不是scipy
。
從上面的hpaulj的幫助中:答案是_integrand
方法需要聲明為cpdef
而不是cdef
cpdef double _integrand(self, double x):
"""Cython: integrand inside the class"""
cdef double f = log(x) / sqrt(x)
return f
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.