新闻与更新

16
VMC教程更新了!
布莱恩·克拉克(Bryan Clark)
VMC教程现已更新以在一个维度中包括优化(包括相关采样)
16
VMC教程现在发布了!
布莱恩·克拉克(Bryan Clark)
现在已经发布了有关如何编写简单变分的蒙特卡洛代码的教程。

导航

外部资源

在本教程中,我们将编写一个跨蒙特卡洛代码,以计算氢原子的性质。

变分蒙特卡洛


变量蒙特卡洛是一种评估积分$ \ frac {\ int | \ psi(r)|^2 o(r)dr} {\ int | \ psi(r)|^2} dr的方法。$

为此,我们使用马尔可夫链蒙特卡洛。这以以下方式起作用:

  1. 选择粒子的新试用地点
  2. 评估新试验位置波形的比率
  3. 如果比率平方更大,则随机数,然后保留新的试用地点,否则请保留旧的试用地点。

氢分子的试验波函数


我们将编写一个简单的变异蒙特卡洛代码来计算氢分子的键长。
笔记:您将需要在本节中分析一些数据。确保您对Python统计软件包我们提供了。

为了简单起见,该实验室将重点放在氢分子上。由于它只有两个电子(一个旋转和一个旋转),因此我们不必关心计算决定因素。我们将优化两个非常简单的试验波函数$ \ psi_1 $和$ \ psi_2 $。让我们的分子以$ \ pm l/2 \ hat {x} $的质子为中心。

第一个试验功能是一个简单的以债券为中心的高斯,其宽度由参数$ \ alpha $,$ \ psi(r_1,r_1,r_2; \ alpha)= \ exp [ - \ alpha(| r_1 |^2+| r_2 |)控制宽度。^2)] $,其中$ \ alpha $要进行优化。

我们将用作数据结构,以将离子(电子)的坐标存储为2D Numpy阵列。第一个坐标将是粒子,第二个坐标是坐标。因此,要访问第二个粒子,请调用坐标[1]并访问Y元素,请调用坐标[1,1](请记住,在Python中,所有数组从0开始计数)

构建波函数


让我们首先为我们的波功能构建测试。我们将使用$ \ alpha = 0.5 $。Wave功能应该做什么?它采用离子的位置,电子的位置并给出一个数字。然后让我们将测试定义为

导入numpy def wavefunction1_test1(waveFunction):coords = numpy.Array([[[[1.0,0,0.5,0.3],[ -  0.2,0.1,-0.1]])ions = numpy.Array([[ -  0.77,0.0.0.0],],[0.7,0.0,0.0]]))如果numpy.abs(WaveFunction(COORDS,ION,离子)-0.496585)<1E-5:返回true else:返回false:if(waveFunction1_test1(psi))打印“波功能测试失败”

现在,你应该写波力

DEF PSI(坐标,离子):#您的代码在此处返回Val

记住将其放在测试上方的文件中的某个位置。有用的知识包括

  1. 导入numpy导入数学应该位于文件的顶部
  2. numpy.dot计算点产品和
  3. Math.sqrt是正方形的。

编写代码后,运行测试并验证您的波函数正在工作!(如果您没有得到此值,请在这里停止并解决问题。在损坏的基础上构建将使将来很难进行调试)。

构建蒙特卡洛代码


生产我们的蒙特卡洛代码的下一步是决定我们将如何移动粒子。一种天然的(尽管不是最好的)方法是简单地将粒子移入其当前位置的小盒子中。让我们从此开始作为我们的基本方法。

现在,我们准备将所有内容放在我们的第一个蒙特卡洛代码中!在我们的第一次尝试中,我们将只计算一件事:我们的举动的接受率。观察我们的基本过程将是:

def vmc(wf,ions,numSteps):r = numpy.zeros(((2,2),float)movesAttempted = 0.0 movesAccepted = 0.0 = 0.0,用于xrange(0,numSteps)的步骤:for ptcl in xrange(0,len(renge)):a = 5#让粒子“ ptcl”#决定您是否接受或拒绝#更新的moveSattEmpt和movesAccept#在这里您将在下一步的“接受率”中计算其他内容:“可接受比率:”,MovesAccept/movestemptpermempt return返回

要检查您是否正确地将VMC代码放在一起,应该发现,如果您将粒子在其当前位置周围的长度1.5(每个方向)的盒子中移动,则将获得约0.323的接受率。有用的事情包括

  1. numpy.random.rand()将在0和1之间均匀返回一个随机数
  2. 平方数做a2( ^将不起作用)
  3. 请记住,您接受了与波形之比的举动平方
  4. 您可以使用 +添加两个相同大小的阵列

恭喜!如果您获得了这个数字,您将成功生产了第一个(有点毫无用处)QMC代码!

计算密度


笔记:如果您按时运行低,请随时跳过此部分

当然,我们希望我们的QMC代码计算一些内容。在本节中,我们将学习如何计算粘结方向的密度。在下一节中,我们将致力于计算能量。能量将使我们陷入有关纽带,测量键长等的各种有趣的问题。

在X方向上计算密度的关键是建立直方图。这是学习有关在Python中学习面向对象的编程的好时机。在面向对象的编程中,您定义一个类。一类本质上是组合在一起的一组函数和数据,以便这些函数可以访问数据,而无需它们是参数的一部分。让我们定义一个

类直方图:def init(self,startpoint,endpoint,numpoints):#我们将编写代码以设置我们的类。def add(self,data):#ADD在此处def plot(self):#让我们绘制直方图
关于Python课程,有几件事要注意。首先,每个功能都可以自己作为第一个论点。任何可访问的变量都必须访问类本地的(但不是函数本地)的变量self.myvar。此外,在声明类时,我们不需要声明任何变量,因为我们可以动态创建新的变量。例如,如果您想创建一个类别的类变量三角洲,你可以说self.delta = 0.3并且将创建这个新变量。

编写代码时要知道的有用的知识包括:
  1. 进口塔在您的代码顶部
  2. pylab.plot(x,y)会准备一个情节,pylab.show()将显示。
  3. numpy r.zeros(20,浮点)将创建具有20个零的浮子数组。
  4. int(x)将从浮子返回整数。
  5. 请记住,如果您希望您的班级存储一个数组以将您的直方图放入您的直方图self.mydata = numpy.zeros(numpoints,float)
我们可以使用以下代码测试直方图:
myHist =直方图()mythist.init(-10,10,100)sigma = 3.0 randnums = numpy.random.randn(100000)*r in in randnums中的r sigma:myhist.add(r)mythist.plot()

这应该产生一条高斯曲线,标准偏差为3.0。检查以确保在继续之前!现在,使用您的直方图类来计算氢分子键方向的密度。您应该期望看到这样的东西(如果您做了足够的VMC步骤!):


计算当地能源


量子蒙特卡洛最重要的数量之一是平均能量。平均能量定义为$ \ langle h \ psi / \ psi \ rangle \ equiv \ equiv \ langle e_l \ rangle。$。因此,我们需要计算本地能量$ e_l $。回想一下,$ \ frac {h \ psi} {\ psi} = \ frac {( - \ nabla^2/2 + v)\ psi} {\ psi} $。$(v \ psi)/\ psi $项相对容易评估,因为它仅减少到$ v(r)= - \ sum_ {ie} \ frac {1} {1} {r_ {ie}}} + sum_ + \ sum_ {ee} \ frac {1} {r_ {ee}}+\ sum_ {ii} \ frac {1} {r_ {ii}} $(用于电子(e)和离子(e)和离子(i)的系统)。虽然在真实的代码中,我们希望对$ \ nabla^2 \ psi / \ psi $项具有分析衍生物,在本教程中,我们将专注于使用有限的差异进行计算(无论如何,重要的是要拥有它很重要以有限的差异计算以检查您的分析衍生物)。然后,让我们添加一个函数,该函数采用波函数和坐标阵列,然后返回局部能量的动能组件。换句话说,实施功能
def laplacianpsioverpsi(波函数,坐标,离子):#应该返回局部能量def locunenergy(波函数,坐标,离子)的动力学件#:#这应该返回局部能量。
请记住,$ \ frac {\ partial^2 f} {\ partial x^2} \ about \ frac {f(x+\ delta)+f(x- \ delta)-2f(x)} {\ delta^2}$

要验证您的代码是否正确,请设置离子,以使键长为1.4并通过

r = numpy.zeros((2,3),float)r [0] = [1.0,0.3,0.2] r [1] = [2.0,-0.2,0.1]
您应该以总当地能源为-1.819

现在,将局部能量的计算添加到您的VMC函数中。让VMC函数返回一个能量列表。拥有这些能量后,请使用统计软件包来计算能量和误差以及绘制能量。

您最终应该看到这样的情节:


您应该注意到有关此情节的几件事

  1. 这很刺耳。
  2. 如果您计算能源列表的统计数据,您的答案约为-0.86。
  3. 您的差异很大。

周围的课程


让我们盘点我们所在的地方。我们有功能
psi(坐标,离子)laplacianpsioverpsi(波函数,坐标,离子,离子)局部环(波函数,坐标,离子)
目前,$ \ alpha $将这些波置符编码为硬编码,但是在一分钟内,我们将需要改变它!这意味着我们要么必须使$ \ alpha $成为全局变量(丑!),在所有这些功能中添加另一个参数alpha,要么将波函数捆绑到类中。后者是最优雅的解决方案。想象一下我们定义以下类:
类WaveFunctionClass:DEF PSI(self,coords):#Stuff在这里def laplacianpsioverpsi(self,coords):#stuff在这里def localenergy(self,coords):#stuff shere def setions def setions(self,ions ions ions ions ions ions ions ions ions ions):#在这里def setalpha(def setalpha)自我,alpha):#stuff在这里

请注意,我们不必传递尽可能多的事情(例如Alpha和Ions),并且我们仍然没有丑陋的全球变量。当然,这意味着您将不得不使用一些函数调用来访问,以便您到目前为止在代码中拥有。继续进行使用此类所需的代码中的更改。(浏览“计算密度”部分现在可能很有帮助)

您应该能够使用以下代码测试对类的修改(如果您只有直方图和文件中的WaveFunctionClass,则可以工作!):):

导入统计量wf = waveFunctionClass()如numpy.Array([[[[1.0,0.5,0.3],[ -  0.2,0.1 \,-0.1])和is',wf.psi(numpy.Array([[[1.0,0.5,0.3])0.1,-0.1]]))r = numpy.zeros((2,3),float)r [0] = [1.0,0,3,0.2] r [1] = [2.0,-0.2,0.1]局部能量应为-1.819,并且为“,wf.localenergy(r)印刷”该VMC运行的接受率应为0.323,并绘制密度\如上所述。(Numpy.Array(Elist))打印“您的统计数据应大约为(-0.885,1.325,0.028,5.613)”,Mystats

更好的接受率


笔记:如果您按时运行低,请随时跳过此部分

30%的接受率不是不良的接受率。事实证明,我们可以做得更好!回想一下,蒙特卡洛的接受率为$ a(r \ rightarrow r')= \ min \ left [\ frac {\ pi(r')} {\ pi(r)} \ frac {t(r'\'\ \'\rightarrow r)} {t(r \ rightarrow r')},1 \ right] $,在我们的计算中,我们有$ \ pi(r)= | \ psi(r)|^2 $。

现在,让我们定义量子力$ f(r)\ equiv \ frac {\ nabla \ psi(r)} {\ psi(r)} $。然后选择一个新的点$ r'$,带有概率$ p(r')= \ exp [ - (r-r' - \ tau f(r))^2/(4 \ lambda \ tau)$。请注意,这将产生$ t(r \ rightarrow r')$和$ t(r'\ rightarrow r)$的非平凡价值。如果您实施了这种新的蒙特卡洛举动,您会发现接受比(对于小$ \ tau $)将大约1.尝试修改VMC方法以使用此数量:

有关实施此操作的暗示:

  • 最大的困难是实现$ \ nabla \ psi / \ psi $。请记住,这个数量是向量。

我的代码很慢:(


您可能已经注意到您的代码很慢!这是因为您已经用Python写了它。即使这样,您也可以做一些事情来加快代码。
  • 将数值衍生物切换为分析衍生物。数值衍生物真的很慢!
  • DO单粒子移动的波功能更新
  • pythonize:我们一直在用python写作,但并非以一种非常的pythonic方式写作。python的“循环”确实很慢。另一方面,列表综合和矩阵操作要快得多。找到代码的慢部分并加快它们的速度!
  • 使用Cython!Cython本质上是Python的一种版本,可让您添加类型并加速Python。(不过,一些Python功能不起作用)。
  • 好吧,Python很慢。也许您应该尝试C ++(或Fortran或Fortress或Ocaml)。
挑战:认为您的代码特别快?时间并将其添加到我们的快速Python(或其他语言)代码的排行榜中。更好的是:作为书面快速VMC代码的示例,贡献您的快速代码(以任何语言为例)。
现在,我们已经学习了如何使用变异蒙特卡洛计算积分。但是,通常,我们不知道我们的波函数实际是什么(在这种情况下,我们不知道$ \ alpha $的正确值是什么)。在下一节中,我们将使用变分原理选择参数的最佳值。一旦我们开始学习如何优化,我们就可以负担得起使波浪功能更加复杂!

继续上下一节...