通过cython函数与cython方法进行scipy.integrate [英] Passing a cython function vs a cython method to scipy.integrate

查看:213
本文介绍了通过cython函数与cython方法进行scipy.integrate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试研究如何使用cython加快涉及我定义的类中完成的集成的计算.我试图更好地了解cython如何与用户定义的python类一起工作.我想了解更多有关为什么发生以下所述错误的信息.

I am trying work out how to use cython to speed up a calculation involving integration that is done within a class I have defined. I'm trying to understand better how cython works with user-defined python classes. I'd like to understand more about why the error described below occurs.

我在名为ex.pyx

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的三种方式

It shows three ways of calling scipy.integrate.quad from within a class

  1. 使用在类外部定义的cython积分函数:integrate_other(好!)
  2. 使用在类integrate_self中定义的cython被积函数(产生错误)
  3. 将在类内部定义的cython被整数函数包装在类内部定义的python函数中:integrate_wrap_self(确定!)
  1. Using a cython integrand function defined outside the class: integrate_other (ok!)
  2. Using a cython integrand function defined inside the class: integrate_self (produces error)
  3. Wrapping the cython integrand function defined inside the class in a python function defined inside the class: integrate_wrap_self (ok!)

上面的cython代码可以正常编译.现在,我将这些集成方法称为

The above cython code compiles fine. Now I call each of these integrate methods, e.g.

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方法传递的实例参数吗?

  • Why can scipy.integrate be passed as a cython function or a python method (so now with instance as first argument) but not as a cython method? The error: TypeError: wrap() takes exactly 2 positional arguments (1 given) implies the issue is with the instance argument that is passed with the cython method I think?

此错误是由于我对cython的误解还是scipy的局限性造成的?

Is this error coming from my misunderstanding of how to do cython, or a limitation of scipy?

如果我想通过cython加快速度,我打算在类中计算积分(通过在类中也调用被积分函数)的计划是不好的解决方案吗?披露:实际代码将调用GSL集成函数,而不是scipy.

Is my intended plan of calculating an integral within a class (by calling an integrand function also within the class) a poor solution if I want to speed up via cython? Disclosure: the real code will call GSL integration functions, not scipy.

推荐答案

在hpaulj的帮助下:答案是_integrand方法需要声明为cpdef而不是cdef

From hpaulj's help above: the answer is the _integrand method needs to be declared cpdef not cdef

cpdef double _integrand(self, double x):
    """Cython: integrand inside the class"""
    cdef double f = log(x) / sqrt(x)
    return f

这篇关于通过cython函数与cython方法进行scipy.integrate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆