pythonscipynumba

How to pass several additional parameters to numba cfunc passed as LowLevelCallable to scipy.integrate.quad


I am trying to replicate the technique descrived in the paragraph 1. of the selected answer to another question: How to pass additional parameters to numba cfunc passed as LowLevelCallable to scipy.integrate.quad.

However, I don't know how to modify the implementation so that xx[1] is an array of float and not a unique float.


Solution

  • I solved the issue by modifiying the code by Jacques Gaudin in https://stackoverflow.com/a/49732825/3925704 to:

    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):
            values = carray(xx, n)
            return jitted_function(values)
        return LowLevelCallable(wrapped.ctypes)
    
    @jit_integrand_function
    def integrand(args):
        t = args[0]
        a = args[1]
        return np.exp(-t/a) / t**2
    
    def 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,))