Is there a method to plot and numerically integrate a sympy function with parameters?

Question:

I’m doing a number of symbolic calculations in a Jupyter notebook and would like to plot the functions and calculate numeric integrals before continuing with other symbolic calculations.

I have tried to lambdify the function, but I can only get plots and integrals if I actually retype the function definition. Is there some way to do these operations directly with the symbolic form? If not, is there a way to correctly lambdify the function with fixed input parameters a and b?

from sympy import *
from sympy.utilities.lambdify import lambdify 
import matplotlib.pyplot as plt
import numpy as np
import scipy.integrate as int
x,a,b = symbols('x a b')
u = log(exp(-b*x**2/2) + 1/a)
t = np.linspace(-5,5,100)
# Attempt to lambdify u:
f = (lambda x,a=1,b=3: lambdify((x,a,b),u, modules = ['numpy','sympy']))
y = [f(t[i]) for i in range(len(t))]
plt.plot(t,y)
int.quad(f,-5,5)
# Gives error:
Traceback (most recent call last):

  File "C:Users...AppDataLocalContinuumanaconda3libsite-packagesIPythoncoreinteractiveshell.py", line 3296, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)

  File "<ipython-input-86-75a94a575357>", line 2, in <module>
    y = [f(t[i]) for i in range(len(t))]

  File "<ipython-input-86-75a94a575357>", line 2, in <listcomp>
    y = [f(t[i]) for i in range(len(t))]

  File "<ipython-input-86-75a94a575357>", line 1, in <lambda>
    f = (lambda x,a=1,b=3: lambdify((x,a,b),u, modules = ['numpy','sympy']))

  File "C:Users...AppDataLocalContinuumanaconda3libsite-packagessympyutilitieslambdify.py", line 476, in lambdify
    c = compile(funcstr, filename, 'exec')

  File "<lambdifygenerated-10>", line 1
    def _lambdifygenerated(-5.0, 1, 3):
                           ^
SyntaxError: invalid syntax

# But explicitly typing u works:
f = (lambda x, a=1, b=3: log(a + exp(b*x**2/2)))
y = [f(t[i]) for i in range(len(t))]
plt.plot(t,y)
int.quad(f,-5,5)
(126.10732269388095,1.0767576643095748 −07)
Asked By: John Peach

||

Answers:

Lambdify creates a function: you call it once to get the function then you call that function many times. You can do it like this:

In [11]: a = Symbol('a')                                                                                                          

In [12]: b = Symbol('b')                                                                                                          

In [13]: u = log(exp(-b*x**2/2) + 1/a)                                                                                            

In [14]: flambda = lambdify((x,a,b),u, modules = ['numpy','sympy'])                                                               

In [16]: flambda(1, 1, 3)                                                                                                         
Out[16]: 0.20141327798275246

In [17]: f = lambda x,a=1,b=3: flambda(x, a, b)                                                                                   

In [18]: f(1)                                                                                                                     
Out[18]: 0.20141327798275246
Answered By: Oscar Benjamin