我想用Numba修饰多重积分的被积函数,以便可以通过以下方式调用它SciPy Nquad功能作为低级可调用。理想情况下,装饰器应允许任意数量的变量以及来自 Nquad 的任意数量的附加参数args争论。这是建立在一个优秀的今年早些时候的问答 https://stackoverflow.com/questions/49683653/how-to-pass-additional-parameters-to-numba-cfunc-passed-as-lowlevelcallable-to-s,但扩展到多个变量和参数的情况。
作为示例,假设以下具有 N 个变量和 K 个参数的多重积分:
以下代码有效,但仅适用于两个变量和两个参数 (N=2,K=2)。它不适用于更一般的情况。这是因为装饰器中的一些参数是手动枚举的(xx[0],xx[1],xx[2],xx[3]在装饰器中wrapped功能)。必须针对每个不同数量的变量或参数来编辑装饰器。如果可能的话,我想避免这种情况。请注意,被积函数函数本身利用了 Numpy 对象和方法,因此不存在这个问题。
import numpy as np
import scipy.integrate as si
import numba
from numba import cfunc,carray
from numba.types import intc, CPointer, float64
from scipy import LowLevelCallable
def jit_integrand_function(integrand_function):
jitted_function = numba.jit(integrand_function, nopython=True)
@cfunc(float64(intc, CPointer(float64)))
def wrapped(n, xx):
return jitted_function(xx[0], xx[1], xx[2], xx[3])
#xx = carray(xx,len(xx))
#return jitted_function(xx)
return LowLevelCallable(wrapped.ctypes)
@jit_integrand_function
def integrand(*args):
d = np.array([args])
return -np.exp(d.prod())
#Two variable, two parameter example
parms = np.array([2,3])
print si.nquad(integrand,[[0,1],[0,1]],parms)
理想的代码应该只使用一个装饰器被积函数还可以运行的函数:
#Three variable, three parameter example
parms2 = np.array([1,2,3])
print si.nquad(integrand,[[0,1],[0,1],[0,1]],parms2)
努巴文件 http://numba.pydata.org/numba-doc/dev/user/cfunc.html#dealing-with-pointers-and-array-memory参考一个carray http://numba.pydata.org/numba-doc/dev/reference/utils.html#numba.carray当在回调中给定低级指针和数组大小时,该函数应该返回 Numpy 数组。也许,这可以用于将代码推广到二变量二参数情况之外。我(不成功的)尝试实现这一点是在两行注释掉的代码中。
如有帮助,将不胜感激。事实上,Numba 开发人员之一指出 https://groups.google.com/a/continuum.io/forum/#!topic/numba-users/teVqeKWnJl4SciPy 集成是编写 Numba 的原因之一,但缺乏该领域的文档和示例。