Search code examples
pythonfunctionsympyintegrallambdify

Converting hard integral to lambda function with lambdify


I would like to lambdify the function Integral(t**t,(t,0,x)). It works, but my new function, which was returned by lambdify, doesn't return a number but only sympy.integrals.integrals.Integral class. But I don't want that, I want it to return a float number.

Here is my code:

import sympy as sp
import numpy as np
f = sp.lambdify(x,sp.integrate(t**t,(t,0,x)))
print(f(2)) #return Integral(t**t, (t, 0, 2))
#but i want 2.83387674524687

Solution

  • lambdify doesn't support scipy.integrate.quad directly yet, but it's not difficult to add the appropiate definition. One simply needs to tell lambdify how to print Integral:

    def integral_as_quad(expr, lims):
        var, a, b = lims
        return scipy.integrate.quad(lambdify(var, expr), a, b)
    
    f = lambdify(x, Integral(t**t,(t,0,x)), modules={"Integral": integral_as_quad})
    

    The result is

    In [42]: f(2)
    Out[42]: (2.8338767452468625, 2.6601787439517466e-10)
    

    What we're doing here is defining a function integral_as_quad, which translates a SymPy Integral into a scipy.integrate.quad call, recursively lambdifying the integrand (if you have more complicated or symbolic integration limits, you'll want to recursively lambdify those as well).