【问题标题】:scipy.integrate.quad ctypes function error "quadpack.error: quad: first argument is a ctypes function pointer with incorrect signature"scipy.integrate.quad ctypes 函数错误“quadpack.error:quad:第一个参数是签名不正确的 ctypes 函数指针”
【发布时间】:2015-06-23 22:24:12
【问题描述】:

我正在尝试将scipy.integrate.nquadctypes 函数一起使用。我完全按照Faster integration using Ctypes 上的说明进行操作。

ctypes 集成只需几个简单的步骤即可完成:

  1. 用函数签名double f(int n, double args[n]) 在C 中编写一个被积函数,其中args 是一个包含函数f 的参数的数组。

//testlib.c

double f(int n, double args[n])    
{
   return args[0] - args[1] * args[2]; //corresponds to x0 - x1 * x2
}
  1. 现在将此文件编译为共享/动态库(快速搜索将对此有所帮助,因为它依赖于操作系统)。用户必须链接使用的任何数学库等。在 Linux 上,这看起来像:

$ gcc -shared -o testlib.so -fPIC testlib.c

输出库将被称为testlib.so,但它可能具有不同的文件扩展名。现在已经创建了一个库,可以使用 ctypes 将其加载到 Python 中。

  1. 使用ctypes 将共享库加载到Python 中并设置restypesargtypes - 这允许Scipy 解释函数 正确:

>>> import ctypes

>>> from scipy import integrate

>>> lib = ctypes.CDLL('/**/testlib.so') # Use absolute path to testlib

>>> func = lib.f # Assign specific function to name func (for simplicity)

>>> func.restype = ctypes.c_double

>>> func.argtypes = (ctypes.c_int, ctypes.c_double)

请注意,无论参数数量如何,argtypes 将始终为 (ctypes.c_int, ctypes.c_double),而 restype 将始终为 ctypes.c_double

  1. 现在像往常一样集成库函数,这里使用nquad

>>> integrate.nquad(func, [[0,10],[-10,0],[-1,1]])

(1000.0, 1.1102230246251565e-11)

但是,在最后一步,我并没有得到积分的结果,而是出现以下错误:

>>> integrate.nquad(func,[[0,1.0],[-2.0,3.0],[1.0,2.0]])

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 618, in nquad
      return _NQuad(func, ranges, opts).integrate(*args)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 670, in integrate

    value, abserr = quad(f, low, high, args=args, **opt)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 254, in quad

    retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 319, in _quad

    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 670, in integrate

    value, abserr = quad(f, low, high, args=args, **opt)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 254, in quad

    retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 319, in _quad

    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 670, in integrate

    value, abserr = quad(f, low, high, args=args, **opt)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 254, in quad

    retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)

  File "/home/bfn097/apps/scipy/0.13.3_mkl-11.1.2_gcc-4.4.7/lib64/python/scipy/integrate/quadpack.py", line 319, in _quad

    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)

quadpack.error: quad: first argument is a ctypes function pointer with incorrect signature

我正在使用 gcc-4.4.7、python 2.6.6、numpy-1.7.1、scipy-0.13.3

【问题讨论】:

  • 函数签名中的 double args[n]double *args 相同
  • 您已关注faster-integration-using-ctypes。看来这是0.140.13中不存在的新功能。
  • 我使用的是 scipy-0.15.1。 integrate.nquad(func,[[0,1.0],[-2.0,3.0],[1.0,2.0]]) 产生(-1.25, 1.4017986003800292e-13) 其中func 是您问题中的ctypes 函数。
  • @nymk 你是对的。我尝试了 0.15.1,它可以工作。

标签: python-2.7 scipy ctypes integrate


【解决方案1】:

参数的类型应该是:ctypes.POINTER(ctypes.c_double)

但是您是否考虑过使用cffi?除了比ctypes 更快之外,您也不必手写参数内容,只需复制C 声明并让cffi 解析它们。

【讨论】:

  • scipy.integrate.quad 不懂cffi,只懂ctypes 函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 2020-11-04
相关资源
最近更新 更多