pfincent
pfincent

Reputation: 485

Trying to plot hydrogen wave functions using Sympy module

I'm trying to plot the radial part of the hydrogen wave function.

My idea was to use sympy.physics.hydrogen.R_nl as well as matplotlib and numpy.

Since the hydrogen.R_nl function returns a symbol string, I tried using the lambdify method to convert to a function that I would be able to plot:

import matplotlib.pyplot as plt
import numpy as np
from sympy.abc import n, l, r, Z
from sympy.physics import hydrogen
from sympy.utilities.lambdify import lambdify

R_nl = lambdify((n, l, r, Z), hydrogen.R_nl(n, l, r, Z))

Z = 1
n, l = 1, 0
r = np.linspace(0, 10, 1000)

plt.plot(r, R_nl(n, l, r, Z))

Upon execution I get the following error:

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
 <ipython-input-4-886beb2c570c> in <module>()
 ---> 13 plot(r, R_nl(n, l, r, Z))

 /anaconda3/lib/python3.6/site-packages/numpy/__init__.py in <lambda>(_Dummy_148, _Dummy_149, _Dummy_150, _Dummy_151)

NameError: name 'factorial' is not defined

Using sympy.plotting.plot instead of matplotlib.pyplot.plot doesn't work either.

Thanks in advance for your help!

EDIT: The package versions I'm using are sympy=1.1.1, numpy=1.14.3 and matplotlib=2.2.2

Upvotes: 1

Views: 1884

Answers (2)

tel
tel

Reputation: 13999

Edit: there's a bug in Sympy

Turns out there's a bug in Sympy that makes lambdify((n, l, r, Z), hydrogen.R_nl(n, l, r, Z)) give the wrong result. I've submitted a bug report. Basically, it comes down a conflict in the signatures of assoc_laguerre in Scipy and Sympy.

Until this gets fixed, you'll need to lambdify R_nl as so:

lambdify((n, l, r, Z), hydrogen.R_nl(n, l, r, Z), ('numpy', 'math', 'sympy'))

This explicitly specifies the list of modules that lambdify can use to evaluate the function that you pass it (same as the code in the workaround section below), and tells it not to use Scipy.

The problem/solution

You code works as is. The Sympy folks have been actively fixing lambdify for a while, so you probably just have an old version. You should upgrade your version of Sympy.

Workaround

If you can't upgrade, here's a workaround that will explicitly tell lambdify where to find the definition of factorial:

import matplotlib.pyplot as plt
import numpy as np
from sympy.abc import n, l, r, Z
from sympy.physics import hydrogen
from sympy.utilities.lambdify import lambdify

R_nl = lambdify((n, l, r, Z), hydrogen.R_nl(n, l, r, Z), ('numpy', 'math', 'sympy'))

Z = 1
n, l = 1, 0
r = np.linspace(0, 10, 1000)

plt.plot(r, R_nl(n, l, r, Z))

Output:

enter image description here

Upvotes: 2

Yakov Dan
Yakov Dan

Reputation: 3372

From your code, what you want to achieve is evaluate the function R_nl for Z=1, n=1, l=0 at different values of r. Here's how:

import matplotlib.pyplot as plt
import numpy as np
from sympy.abc import n, l, r, Z
from sympy.physics import hydrogen
from sympy.utilities.lambdify import lambdify

R_nl = lambdify(r, hydrogen.R_nl(1, 0, r, 1))
r = np.linspace(0, 10, 1000)

plt.plot(r, R_nl(r))

Upvotes: 1

Related Questions