一维谐振子的变分蒙特卡罗

时间:2017-05-12 18:53:28

标签: python algorithm physics

这是我编写的代码,用于查找谐振子的基态能量。为了避免舍入误差,我在原子系统单元中编写了薛定谔方程:

H = -d2 / dx2 + 1 / 2x ^ 2

以下是代码:

import numpy as np
from random import random
import matplotlib.pyplot as plt

Nwalker=300;MCSteps=5000
x=[0]*Nwalker
nAccept=0;eSum=0
Lambda=0.2

# Define Building Block Functions
    # 1.Initialize function, for setting random walkers' initial positions
    # 2.Probability function, allowing acceptance or rejection
    # 3.MetropolisStep function, 
    # 4.oneMonteCarloStep function, performing Nwalker MetopolisSteps

#.......................START.....................
#.................................................

def initialize():

    for i in range(Nwalker):
        x[i]=random()-0.5

def p(xTrial,x):

    # compute the ratio of rho(xTrial) / rho(x)
    return np.exp(-2*Lambda*(xTrial**2-x**2))

def eLocal(x):

    # compute the local energy
    return Lambda + x**2*(0.5-2*Lambda**2)

def MetropolisStep():

    global eSum,nAccept
    # chose a walker at random
    n=int(random()*Nwalker)
    # make a trial move
    delta=0.05*(random()-1)
    xTrial=x[n]+delta

    # Metropolis test
    w=p(xTrial,x[n])

    if w>=random():
        x[n]=xTrial
        nAccept+=1

    # accumulate energy
    e=eLocal(x[n])
    eSum+=e

def oneMonteCarloStep():
   # perform 'Nwalker' Metropolis steps
   for i in range(Nwalker):
       MetropolisStep()

#...............................................
#.....................END.......................


initialize()

# perform 20% of MCSteps as thermalization steps

thermSteps=int(0.2*MCSteps)
print('Performing', thermSteps,'thermalization steps ...')

for i in range(thermSteps):
    oneMonteCarloStep()

# production steps

print('Performing',MCSteps,'production steps ...')  
nAccept=0;eSum=0

for i in range(MCSteps):
    oneMonteCarloStep()             

# compute and print energy
eAve=eSum/(Nwalker*MCSteps)

print(eAve)             
print(nAccept/(Nwalker*MCSteps))

我实际上遵循了本网站建议的算法。 http://www.physics.buffalo.edu/phy411-506/topic5/

对于Lambda = 0.5,我得到= 0.5,这非常好。但是对于Lambda的其他值,我得到了非常奇怪的平均能量值。如您所见,链接文章中显示了平均能量与Lambda的正确图表。

有人可以告诉我我的代码有什么问题吗?代码似乎与文章中编写的代码差不多。不知道为什么它不起作用。

添加图片......

enter image description here

0 个答案:

没有答案