I need to do numerical integration in 6D in python. Since the scipy.integrate.nquad function is slow, I'm currently trying to speed up the process by defining the integrand as scipy.LowLevelCallable with Numba.
I was able to do this in 1D using scipy.integrate.quad, replicating the example below :
import numpy as np from numba import cfunc from scipy import integrate def integrand(t): return np.exp(-t) / t**2 nb_integrand = cfunc("float64(float64)")(integrand)
10,000 cycles, best 3: 128 μs per cycle
# integration with compiled function %timeit integrate.quad(nb_integrand.ctypes, 1, np.inf)
100,000 cycles, best of 3: 7.08 μs per loop
When I want to do this now with nquad, the nquad documentation says:
If the user wants to improve integration performance, then f may be scipy.LowLevelCallable with one of the signatures:
double func(int n, double *xx) double func(int n, double *xx, void *user_data)
where n is the number of additional parameters, and args - the array doubles the additional parameters, the xx array contains the coordinates. User_data is the data contained in scipy.LowLevelCallable.
But the following code gives me an error:
from numba import cfunc import ctypes def func(n_arg,x): xe = x[0] xh = x[1] return np.sin(2*np.pi*xe)*np.sin(2*np.pi*xh) nb_func = cfunc("float64(int64,CPointer(float64))")(func) integrate.nquad(nb_func.ctypes, [[0,1],[0,1]], full_output=True)
error: quad: the first argument is the ctypes function pointer with the wrong signature
Is it possible to compile a function with numba, which can be used with nquad directly in the code and without defining the function in an external file?
Thank you in advance!