scipy.integrate.quad ctypes函数错误" quadpack.error:quad:第一个参数是一个带有错误签名的ctypes函数指针"

时间:2015-06-23 22:24:13

标签: python-2.7 scipy ctypes integrate

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

  

ctypes集成可以通过几个简单的步骤完成:

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

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

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

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

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

        >>> 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
        2. 集成库函数         

          >>> 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

1 个答案:

答案 0 :(得分:0)

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

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