1.通过传递额外的参数scipy.integrate.quad
该
quad文件说:
如果用户希望改善集成性能,则
f可以使用scipy.LowLevelCallable以下签名之一:double func(double x)double func(double x, void *user_data)double func(int n, double *xx)double func(int n, double *xx, void *user_data)该
user_data是包含在该数据scipy.LowLevelCallable。在与该呼叫的形式xx,n是的长度xx包含阵列xx[0]== x和 所述物品的其余部分都包含在数字args的论点quad。
因此,要将额外的参数传递给
integrandthrough
quad,最好使用
double func(int n, double *xx)签名。
您可以将一个装饰器写入被积分函数,以将其转换为
LowLevelCallable类似形式:
import numpy as npimport scipy.integrate as siimport numbafrom numba import cfuncfrom numba.types import intc, CPointer, float64from scipy import LowLevelCallabledef 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]) return LowLevelCallable(wrapped.ctypes)@jit_integrand_functiondef integrand(t, *args): a = args[0] return np.exp(-t/a) / t**2def do_integrate(func, a): """ Integrate the given function from 1.0 to +inf with additional argument a. """ return si.quad(func, 1, np.inf, args=(a,))print(do_integrate(integrand, 2.))>>>(0.326643862324553, 1.936891932288535e-10)
或者,如果您不需要装饰器,请
LowLevelCallable手动创建并将其传递给
quad。
2.包装被积函数
我不确定以下内容是否满足您的要求,但是您也可以包装
integrand功能以达到相同的结果:
import numpy as npfrom numba import cfuncimport numba.typesdef get_integrand(*args): a = args[0] def integrand(t): return np.exp(-t/a) / t**2 return integrandnb_integrand = cfunc(numba.float64(numba.float64))(get_integrand(2.))import scipy.integrate as sidef do_integrate(func): """ Integrate the given function from 1.0 to +inf. """ return si.quad(func, 1, np.inf)print(do_integrate(get_integrand(2)))>>>(0.326643862324553, 1.936891932288535e-10)print(do_integrate(nb_integrand.ctypes))>>>(0.326643862324553, 1.936891932288535e-10)
3.从voidptr
转换为python类型
我认为这还不可能。从2016年的讨论来看,似乎
voidptr只是在这里将上下文传递给C回调。
void
*指针的情况适用于API,其中外来C代码并非每次都尝试取消对指针的引用,而只是将其传递回回调,以作为回调在两次调用之间保持状态的方式。我认为目前这不是特别重要,但是我想提出这个问题。
并尝试以下操作:
numba.types.RawPointer('p').can_convert_to( numba.typing.context.Context(), CPointer(numba.types.Any)))>>>None似乎也不鼓励!



