我正在研究如何使用Python编写代码,并试图重新创建我在大学期间编写的代码。
该代码基于应用于流行病学的2D Ising模型。它的作用是:
calc_h
计算能量。 metropolis
函数中完成的。max_iterations
。
-代码对{{1}中具有-1值的元素数量(即s
变量)和具有1值的元素数量(即i
变量)进行计数。 }函数。该脚本每500个iteratons追加到一个文本文件中。问题
我运行了脚本,除了执行时间太长之外,计数在15500处停止。代码不会引发任何错误,但是它一直在继续。我等待了大约3个小时才能完成,但仍然最多只能进行15500次迭代。
我尝试注释掉对csv块的写操作,而是先打印值以观察它的发生,然后我看到它再次在15500处停止。
我不知道出什么问题了,因为它不会引发任何错误,并且代码也不会停止。
这是整个脚本。我在每个块下面都描述了该零件的作用:
countSI
此部分初始化2D数组的大小。出于观察目的,我选择了100 x 100格。
import numpy as np
import random as r
import math as m
import csv
init_size = input("Input array size: ")
size = int(init_size)
我将此函数用于
def check_overflow(indx, size): if indx == size - 1: return -indx else: return 1
函数,以初始化圆形边界条件。简而言之,晶格的边缘相互连接。
calc_h
此函数通过将一个单元格的值与其顶部,底部,左侧和右侧邻居的乘积之和乘以常数
def calc_h(pop, J1, size): h_sum = 0 r = 0 c = 0 while r < size: buffr = check_overflow(r, size) while c < size: buffc = check_overflow(c, size) h_sum = h_sum + J1*pop[r,c] * pop[r,c-1] * pop[r-1,c] * pop[r+buffr,c] * pop[r,c+buffc] c = c + 1 c = 0 r = r + 1 return h_sum
来计算系统的能量。
J
这取决于
def metropolis(h, h0, T_): if h <= h0: return 1 else: rand_h = r.random() p = m.exp(-(h - h0)/T_) if rand_h <= p: return 1 else: return 0
得到什么来确定是否接受从-1到1的更改。
calc_h
这部分计算格子中-1和1的数量。
def countSI(pop, sz, iter):
s = np.count_nonzero(pop == -1)
i = np.count_nonzero(pop == 1)
row = [iter, s, i]
with open('data.txt', 'a') as si_csv:
tally_data = csv.writer(si_csv)
tally_data.writerow(row)
si_csv.seek(0)
二维数组在
def main(): J = 1 T = 4.0 max_iterations = 150000 population = np.full((size, size), -1, np.int8) #initialize population array
中初始化。
population
这是主循环,在其中选择了一个随机单元,并且是否接受更改由函数
h_0 = calc_h(population, J, size) turn = 1 while turn <= max_iterations: inf_x = r.randint(1,size) - 1 inf_y = r.randint(1,size) - 1 while population[inf_x,inf_y] == 1: inf_x = r.randint(1,size) - 1 inf_y = r.randint(1,size) - 1 population[inf_x, inf_y] = 1 h = calc_h(population, J, size) accept_i = metropolis(h,h_0,T)
确定。
metropolis
该脚本每500次迭代进行一次计数。
if (accept_i == 0):
population[inf_x, inf_y] = -1
if turn%500 == 0 :
countSI(population, size, turn)
预期输出是一个文本文件,该文本文件每进行500次迭代就记录一次 turn = turn + 1
h_0 = h
main()
和s
的数目。看起来像这样:
i
我不知道从哪里开始解决。起初,我以为引起csv的问题是导致该问题的原因,但通过print函数进行的研究证明并非如此。我试图使它尽可能简洁。
希望你们能提供帮助!我真的很想学习这种语言并开始模拟很多东西,我认为这个小型项目对我来说是一个很好的起点。
非常感谢!
答案 0 :(得分:1)
@randomir in the comments提供的答案:
您的代码可能是错误的。每当要翻转的旋转次数小于迭代次数时,它将阻塞在嵌套的while循环中。在上一条注释的示例中,人口总数为10000,您想翻转15500次旋转。请注意,一旦旋转(具有100%概率)向上旋转,由于大都会采样,它将以较小的概率向下旋转。
有效。