簡體   English   中英

通過cython函數與cython方法進行scipy.integrate

[英]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三種方式

  1. 使用在類外部定義的cython被積分函數: integrate_other (確定!)
  2. 使用在類內定義的cython被積分函數: integrate_self (產生錯誤)
  3. 將在類內部定義的cython被整數函數包裝在類內部定義的python函數中: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM