-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathvariational.py
84 lines (73 loc) · 2.03 KB
/
variational.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import math, random, pylab
# parameters for harmonic oscillator
hbar = 1.0
m = 1.0
k = 1.0
omega0 = (k/m)**0.5
# input number of grid points, steps, random seed
N = input('number of grid points -> ')
nstep = input('number of steps -> ')
seed = input('random number seed -> ')
random.seed(seed)
# setup grid and initial guess
xmin = -5.0
xmax = 5.0
dx = (xmax-xmin)/(N-1)
x = pylab.arange(xmin, xmax+0.1*dx, dx)
psi = pylab.ones(N) # initial guess
psi[0] = psi[N-1] = 0.0 # endpoints fixed at zero
# compute energy, potential, normalization
V = pylab.zeros(N)
E = pylab.zeros(nstep+1)
ssq = 0
for i in range(1, N-1):
V[i] = k*x[i]**2/2.0
H = -hbar**2*(psi[i-1]-2.0*psi[i]+psi[i+1])/(2*m*dx**2)
H += V[i]*psi[i]
E[0] += psi[i]*H*dx
ssq += psi[i]**2*dx
E[0] /= ssq
psi /= ssq**0.5
# prepare animated plot
pylab.ion()
xfine = pylab.arange(xmin, xmax, 0.01)
psi0 = [(m*omega0/(math.pi*hbar))**0.25*math.exp(-0.5*m*omega0*xx**2/hbar)
for xx in xfine]
pylab.plot(xfine, psi0)
(line, ) = pylab.plot(x, psi, 'o-')
pylab.ylabel('$\psi$')
pylab.xlabel('x')
# perform the evolution
n = 1
while n <= nstep:
# choose a random point and a random amount to change psi
tmp = pylab.copy(psi) # temporary wavefunction trial
j = random.choice(range(1, N-1))
tmp[j] *= random.uniform(0.8, 1.2)
# normalize and compute energy
E[n] = 0.0
ssq = 0.0
for i in range(1, N-1):
H = -hbar**2*(tmp[i-1]-2.0*tmp[i]+tmp[i+1])/(2*m*dx**2)
H += V[i]*tmp[i]
E[n] += tmp[i]*H*dx
ssq += tmp[i]**2*dx
E[n] /= ssq
# test if the trial wavefunction reduces energy
if E[n] < E[n-1]:
# update current wavefunction
psi = tmp/ssq**0.5
# update plot
line.set_ydata(psi)
pylab.title('%d moves'%n)
pylab.draw()
# increment step count
n += 1
# freeze animation and plot energy as a function of time
pylab.ioff()
pylab.figure()
pylab.plot(range(nstep+1), E)
pylab.ylabel('$E / \hbar\omega_0$')
pylab.xlabel('step number')
pylab.grid()
pylab.show()