Converting hard integral to lambda function with lambdify
Asked Answered
N

3

6

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
Nammu answered 22/5, 2016 at 20:25 Comment(0)
V
8

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).

Vaucluse answered 26/5, 2016 at 19:36 Comment(1)
Maybe create a reimann sum first? f = sp.lambdify(x, sp.Integral(t**t,(t,0,x)).as_sum(n = 100))Soracco
N
1

Finally, i find next solution for this. I look around this and find out that return lambda is function. and when you call it with a number it return object (Integarl).

So i can call evalf() to this object and it will return a number. Like this:

import sympy as sp
import numpy as np
x = sp.symbols('x')
f = sp.lambdify(x,sp.integrate(t**t,(t,0,x)))
def return_number(z):
    return f(z).evalf()
return_number(2) #return 2.83387674524687

It works.

Nammu answered 22/5, 2016 at 20:54 Comment(1)
evalf uses mpmath to compute the integral, which can be more accurate than scipy.integrate.quad, but also slower.Vaucluse
A
0

Sympy cannot find a closed-form analytic solution for this integral, hence it returns an un-evaluated sympy integral object. Since it appears you are fine with a numerical solution, you can use the scipy's quad function for this purpose

import scipy.integrate

def f(x):
    return scipy.integrate.quad(lambda t: t**t, 0,x)[0]

f(2)

2.83387674525

Antivenin answered 22/5, 2016 at 20:33 Comment(1)
Yes, thank you very much for that solution, but i want combine sympy and scipy together. Switching from sympy function to scipy and back.Nammu

© 2022 - 2024 — McMap. All rights reserved.