我有一些数字代码要在SciPy中运行。它涉及到多项式指数的复杂有理函数,所以它的计算成本相当高;因此,我用C编写了它,并用ctypes调用它。最重要的用例是作为scipy.integrate.quad公司,但我偶尔也需要直接打电话。你知道吗
我函数的“自然”签名是
double f(double x, double y, double z){}
ctypes documentation建议与相应的Python一起使用
import ctypes
so = ctypes.CDLL('/path/to/f.so')
f = so.f
f.restype = ctypes.c_double
f.argtypes = (ctypes.c_double, ctypes.c_double, ctypes.c_double)
无论如何,把它称为被积函数,SciPy requires a certain function signature
double f(int n, double args[n]){}
在Python代码中指定为
import ctypes
so = ctypes.CDLL('/path/to/f.so')
f = so.f
f.restype = ctypes.c_double
f.argtypes = (ctypes.c_int, ctypes.c_double)
要在执行积分时传递参数y
和z
,它们将作为名为args
的元组传递给quad
。你知道吗
scipy.integrate.quad(f, lowerlimit, upperlimit, args=(y,z))
这就不清楚如何直接调用f
。我天真的尝试是
f(3, (x,y,z))
但这会导致参数2的类型错误。有几个变种也同样失败了。这并不奇怪;ctypes期望函数调用只有一个整数参数,后跟一个双参数。你知道吗
我完全不知道quad
如何y
和z
进入f
。我试着查看SciPy源代码,但我必须承认,我在尝试将Python到C到Fortran的调用跟踪时迷失了方向。你知道吗
我可以只编写另一个函数作为直接调用或集成的包装器,但只使用一种形式似乎更为优雅,至少,我想了解SciPy调用是如何工作的。你知道吗
如何直接调用f
的SciPy被积函数形式,传递所有三个参数x
、y
和z
?你知道吗
我使用的是python3.4.3、numpy1.11.2和scipy0.18.1。你知道吗
编辑:注意f
可以通过更改其argtypes来调用:
f.argtypes = (ctypes.c_int, 3*ctypes.c_double)
f(3, (3*ctypes.c_double)(x, y, z))
不过,我还是很好奇西皮在做什么。一直来回设置argtypes充其量也是不雅观和不方便的。你知道吗
编辑2:请注意,经过上一次编辑之后,这个问题现在基本上是this one的副本,它在右侧列中弹出了一个有用的窗口。你知道吗
我不知道这是否有助于
ctypes
的情况,但是当调用Python integrad时,这些scipy
函数将自由变量与参数连接起来。换句话说当以0.5计算时,它会
(x,)+args
:所以用
c
签名:n
是参数数,args[n]
是表示值数组的指针。你知道吗我正在使用
cython
及其扩展类型来试验这类调用https://cython.readthedocs.io/en/latest/src/tutorial/cdef_classes.html
Passing a cython function vs a cython method to scipy.integrate
您需要有正确的函数签名,但是Python argtypes类型应该是
POINTER(c_double)
。C中的数组衰减到函数参数中的指针:C示例(Windows)
c类型示例
您无法在Python级别修复此问题。文档https://docs.scipy.org/doc/scipy/reference/tutorial/integrate.html#faster-integration-using-ctypes说明
在您的情况下,您必须在C级别添加一个函数
把它喂给四轮车。你知道吗
相关问题 更多 >
编程相关推荐