You are on page 1of 23

Quantum Mechanics with Python

Numerical Methods for Physicists, Lecture 4

Mat Medo, Yi-Cheng Zhang


Physics Department, Fribourg University, Switzerland

March 11, 2013

Medo & Zhang (UNIFR)

Quantum Python

1 / 19

Schrdinger equation (here in 1D)

i~

(x, t)
~2 2 (x, t)
+ V (x)(x, t)
=
t
2m
x 2

PDE with complex numbers


scipy.integrate.complex_ode re-maps a given
complex-valued differential equation to a set of real-valued ones
and uses scipy.integrate.ode to integrate them
But we have partial derivatives. . .

Medo & Zhang (UNIFR)

Quantum Python

2 / 19

Schrdinger equation (here in 1D)

i~

(x, t)
~2 2 (x, t)
+ V (x)(x, t)
=
t
2m
x 2

PDE with complex numbers


scipy.integrate.complex_ode re-maps a given
complex-valued differential equation to a set of real-valued ones
and uses scipy.integrate.ode to integrate them
But we have partial derivatives. . .
1

Do re-mapping to real values and use Finite-Difference


Time-Domain (FDTD) as we did for the heat equation

Use the split-step Fourier method

QuTiP: a quantum toolbox in Python

Re-mapping & Escript (fast finite elements for PDEs)

Medo & Zhang (UNIFR)

Quantum Python

2 / 19

FDTD: re-mapping

Re-mapping to real-valued variables:


(x, t) = (x, t) + i(x, t)
Schrdinger equation decouples:
(x, t)
~2 2 (x, t)
+ V (x)(x, t)
=
t
2m x 2
~2 2 (x, t)
(x, t)
=
~
V (x)(x, t)
t
2m x 2

Discretization in time and space: xl = l x, tn = n t


(xl , tn ) := n (l),
Medo & Zhang (UNIFR)

(xt , tn ) := n (l)

Quantum Python

3 / 19

FDTD: discretization

Real and complex part of shifted by half-interval from each


otherthis allows us to use the second-order approximation for
time derivatives which is more precise (O(t) vs O(t 2 ))
(xl , tn+1/2 )
(xl , tn+1 ) (xl , tn )
n+1 (l) n (l)

=
t
t
t
(x
,
t
)

(x
,
t
)
(xl , tn )
n+1/2 (l) n1/2 (l)
l n+1/2
l n1/2

=
t
t
t
Spatial derivatives exactly as before
2 n (l)
n (l + 1) 2n (l) + n (l 1)

x 2
x 2
Medo & Zhang (UNIFR)

Quantum Python

4 / 19

FDTD: equations

Compute the future state from the current state


{n , n1/2 } {n+1 , n+1/2 }
Update equations are
n+1/2 (l) = n1/2 (l) c2 V (l)n (l) +


+ c1 n (l 1) 2n (l) + n (l + 1)
n+1 (l) = n (l) + c2 V (l) n+1/2 (l)


c1 n+1/2 (l 1) 2 n+1/2 (l) + n+1/2 (l + 1)
Where c1 := ~t/(2mx 2 ) and c2 := t/~
Medo & Zhang (UNIFR)

Quantum Python

5 / 19

FDTD: practical issues 1


It is easier to work in units where ~ = m = 1
 2
The scheme is stable only if t ~ m ~x 2 +


maxx,t V (x,t) 1
2

See http://www.scipy.org/Cookbook/SchrodingerFDTD
(there is the rest of theory as well)
This is only orientational (e.g., V (x) somewhere does not
necessarily mean t 0)
Finer grid = smaller time steps needed
To reach the same physical time, simulation time grows as 1/x 3
Check whether we are really in the stable (convergent) regime:
halve t and see whether the results change substantially (they
should not)

We are typically interested in the probability density , not in


and themselves
Medo & Zhang (UNIFR)

Quantum Python

6 / 19

FDTD: practical issues 2


Its nice to have a reversible algorithm (as in the leap-frog kind of
integration schemes)
Evolve your system to the future and back and get the initial state

Evolved wave-function needs to stay normalized


Force normalization by hand after each step (possible but
non-systematic)
Find a unitary algorithm which preserves the norm
See Numerical recipes in C (Section 19.2) by Press et al
We approximated the time evolution operator U(t) = exp[iHt] as
U(t) 1 iHt whereas it is better to use
U(t) = exp[iHt]

1 21 iHt
1 + 12 iHt

Then naturally U(t)U(t) = 1


Medo & Zhang (UNIFR)

Quantum Python

7 / 19

Detour: animations with Python

Sometimes better than static figures


Especially valuable if you want to impress. . .
First approach:
Write a script that saves many figures, say frame-001.gif,
frame-002.gif, etc.
Use avconv (formerly ffmpeg) to create an animation
avconv -an -r 4 -i frame-%03d.png animation.avi
Or use gifsicle to create an animated gif
gifsicle -delay=100 -loop -no-transparent -O2
list_of_files > output.gif

Second approach: animate with Matplotlib (v1.1 and higher)


http://jakevdp.github.com/blog/2012/08/18/
matplotlib-animation-tutorial/
Medo & Zhang (UNIFR)

Quantum Python

8 / 19

Split-step Fourier method: the idea


The potential part of the Schrdinger equation is simple to solve
i~

pot
= V (x) = (x, t + t) = (x, t)eiV (x)t/~
t

Inverse Fourier transform of


1
(x, t) =
2

, t)eikx dk
(k

By substituting this into the Schrdinger equation


i~

~2 k 2
= (k
, t + t) kin
, t)ei~k 2 t/2m
=
+ iV
= (k
t
2m
k

Fast Fourier transform (FFT) allows us to switch between and


Medo & Zhang (UNIFR)

Quantum Python

9 / 19

Split-step Fourier method: the algorithm

Discretize the x and k -space by choosing a, b, N, k0 :


x = (b a)/N,

k = 2/(b a),

xn = a + n x,

k0 = /x,

km = k0 + m k

This should be sufficient to represent states of (initial and later)


The choice can be tricky, experiment a bit to see if it works fine
2

Discretize the wave-functions:


n (t) := (xn , t),

Vn := V (xn ),

Evolve the system by one time step

Repeat 3 until the end time is reached


Medo & Zhang (UNIFR)

Quantum Python

m (t) = (k
m , t)

10 / 19

Split-step Fourier method: point 3

A half step in x: n n exp[iVn t/2~]

m from n
FFT: computes

m
m exp[i~k 2 t/2m]
A full step in k :

m
Inverse FFT: computes n from

A second half step in x: n n exp[iVn t/2~]


Splitting the x-step in two parts produces a numerically more
stable algorithm (as in leapfrog integration in mechanics which is
reversible and conserves energy)
See http://jakevdp.github.com/blog/2012/09/05/
quantum-python/ for more details
Medo & Zhang (UNIFR)

Quantum Python

11 / 19

Split-step Fourier method: tunelling


Output of ex4-1.py (see also the animation at the url above):
1.0

norm = 1.000

1.0

t=4

0.8

0.8

0.6

0.6

0.4

0.4

0.2

0.2

0.0 150
1.0

100

50

50

norm = 1.000

100

150

0.0 150
1.0

t=8

0.8

0.8

0.6

0.6

0.4

0.4

0.2

0.2

0.0 150

100

Medo & Zhang (UNIFR)

50

50

100

150

norm = 1.000

100

50

t=6

50

norm = 1.000

0.0 150

Quantum Python

100

50

100

150

t = 10

50

100

150

12 / 19

Fast Fourier transform

Discrete Fourier transform is rather slow to compute: O(N 2 )


where N is the number of points where the transform is computed
The beauty of FFT: O(N 2 ) is reduced to O(N log N) (similar as
quicksort improving over bubble sort and alike)
The idea behind: discrete Fourier transform with N points can be
written as a sum of two transforms with N/2 points
Using this recursively, we move to N/4 points, etc.
Thats why its best to use FFT for N which is a power of two

fft and ifft from scipy.fftpack implement it


FFT works best when is a power of two (because of how it is
constructed)
N 6= 2x is possible but usually leads to slower computation

Medo & Zhang (UNIFR)

Quantum Python

13 / 19

QuTiP & Escript


QuTiP:
QM is not as difficult as one might think: Its only linear algebra!
States, operators, time evolution, gates, visualization
http://qutip.blogspot.ch and
http://code.google.com/p/qutip

Escript:
For non-linear, time-dependent partial differential equations
https://launchpad.net/escript-finley

Medo & Zhang (UNIFR)

Quantum Python

14 / 19

What about the stationary states?

Until now we addressed only time evolution in QM


Stationary state n satisfies


~2 2
Hn = En n
+ V (r) n = En n
2m
Boundary conditions in a box: (a) = (b) = 0
We fix (a) = 0 and find E so that (b) is zero too

In open space: limx (x) = limx (x) = 0


For a symmetric potential, we simplify by realizing that eigenstates
are also symmetric
Even eigenstates: 0 (0) = 0; odd eigenstates: (0) = 0
We need E for which (x) does go to zero as x grows
Medo & Zhang (UNIFR)

Quantum Python

15 / 19

Stationary states: integration

Again (xn ) := n , V (xn ) = Vn


In addition, ~ = m = 1 and h = x
The approximation for f 00 (x) plus the Schrdinger equation
1
00n + Vn n = En = 00n = 2(Vn E)n
2
n1 2n + n+1
00n =
= n+1 = 2n n1 + 2(Vn E)h2
h2
Once 0 and 1 are given, the rest can be computed

Medo & Zhang (UNIFR)

Quantum Python

16 / 19

Stationary states: integration

Again (xn ) := n , V (xn ) = Vn


In addition, ~ = m = 1 and h = x
The approximation for f 00 (x) plus the Schrdinger equation
1
00n + Vn n = En = 00n = 2(Vn E)n
2
n1 2n + n+1
00n =
= n+1 = 2n n1 + 2(Vn E)h2
h2
Once 0 and 1 are given, the rest can be computed

Much better (order of 4 instead of 2 above) is Numerovs method



2
h2
(2 5h6 fn )yn (1 + 12
fn1 )yn1
d2
+ f (x) y (x) = 0 = yn+1 =
2
2
h
dx
1 + 12 fn+1
Medo & Zhang (UNIFR)

Quantum Python

16 / 19

Stationary states: continuation

How to find the right E: the shooting method

Medo & Zhang (UNIFR)

Quantum Python

17 / 19

Stationary states: continuation

How to find the right E: the shooting method

It is best to write a function, say psi_end(E), which takes E as


an argument and returns (x) at some (not too) distant point x
Finding E efficiently: e.g., brentq(f,a,b) from
scipy.optimize finds a root of f between a and b
Medo & Zhang (UNIFR)

Quantum Python

17 / 19

Stationary states: LHO


We first plot (xm ) for a range of energies
40

even
odd

(4)

20
0
20
400

Medo & Zhang (UNIFR)

Quantum Python

18 / 19

Stationary states: LHO


We first plot (xm ) for a range of energies
40

even
odd

(4)

20
0
20
400

Then individual roots can be found


ex4-1.py gives 0.501 and 1.500 for the first two eigenstates
Medo & Zhang (UNIFR)

Quantum Python

18 / 19

Try this at home

1: Reversibility and unitarity


Implement the Finite-Difference Time-Domain algorithm. Is it reversible? Is it
unitary?
2: Ground state
p
Find the ground state energy of potential V (x) = exp( |x|) in the units
where ~ = m = 1. Can you find also the first excited state?

Medo & Zhang (UNIFR)

Quantum Python

19 / 19

You might also like