0

I want to perform a convolution that contains a sympy symbolic variable, then convert it to a numpy array.

My MWE is:

from numpy import pi, float64, linspace
from scipy.signal import fftconvolve
import matplotlib.pyplot as plt
from sympy import symbols
from sympy.utilities.lambdify import lambdify

a = 0.657
b = 0.745
c = 0.642
d = 0.343

x = symbols('x')
f = 2*b / ((x-a)**2 + b**2)
g = 2*d / ((x-c)**2 + d**2)
fog = fftconvolve(f,g,mode='same')

fog_fun = lambdify(x,fog,'numpy') # returns a numpy-ready function
xlist = linspace(-20,20,int(1e3))
my_fog = fog_fun(xlist)

dx = xlist[1]-xlist[0]

fog1 = 4*pi*(b+d)/((x-a-c)**2+(b+d)**2) # correct analytic solution

plt.figure()
plt.plot(x,fog1,lw=2,label='analytic')
plt.plot(x,my_fog*dx,lw=2,label='sympy')
plt.grid()
plt.legend(loc='best')
plt.show()

I have tried to use the solution suggested here, but I get the error TypeError: can't convert expression to float. I'm not sure how to fix this.

(Note: this is a MWE. The actual f and g I'm actually using are much more complicated than the Lorentzians defined in this post.)

Medulla Oblongata
  • 2,871
  • 6
  • 27
  • 49

1 Answers1

1

The error you have is with the sympy line, as you're trying to plot the symbolic terms,

plt.plot(x,fog1,lw=2,label='analytic')

if you use the converted my_fog against xlist

plt.plot(xlist,my_fog*dx,lw=2,label='sympy')

it looks like a Lorentzian distribution,

enter image description here

Ed Smith
  • 10,665
  • 2
  • 36
  • 51
  • Great thanks. Is there a way for Python to "forget" that `x` is a symbolic variable? After I calculate the `fftconvolve` and turn the expression into a numpy array, I also want to convert the `x` into an array. – Medulla Oblongata Jul 01 '19 at 09:00
  • Your `xlist = linspace(-20,20,int(1e3))` is the conversion of symbolic `x` into a Numpy array. As a sympy expression, matplotlib would not know which range to plot over, etc so when you lambdafy functions you need to create Numpy arrays to tell them over which range you want to plot (see also https://stackoverflow.com/questions/35390187/using-sympy-equations-for-plotting) which shows another way to do this, although I think this is just syntactic sugar for the linspace approach. – Ed Smith Jul 01 '19 at 09:08