由于某些原因,以下代码中的执行时间增加了大约(10:1) (4min vs 40min):
def E_site(lattice, i, j):
N = len(lattice)
Nb = lattice[(i+1)%N,j] + lattice[(i-1)%N,j] + lattice[i,(j+1)%N] + lattice[i, (j-1)%N]
return -lattice[i, j]*Nb
def metropolis(lattice, T, Neq):
for n in range(Neq):
N = len(lattice)
i = np.random.randint(0, N)
j = np.random.randint(0, N)
Ei = E_site(lattice, i, j)
lattice[i, j] *= -1
Ef = E_site(lattice, i, j)
dE = Ef - Ei
if dE < 0 or np.random.rand() < np.exp(-dE/T):
pass
else:
lattice[i,j] *= -1
return lattice
def equilibrate(lattice, T, N_equilibration, show_stats):
if show_stats == False:
lattice = metropolis(lattice, T, N_equilibration)
return lattice
def simulate_temperatures(Ti, Tmax, Tstep, N_eq, N_post):
avg_m_list, avg_E_list = [], []
T = Ti
while(T <= Tmax):
s = time.clock()
if T <= 2:
N_eq = int(1e3)
lattice = init_lattice(20,0.5)
eq_lattice = equilibrate(lattice, T, N_eq, False)
else:
lattice = init_lattice(20,0.5)
eq_lattice = equilibrate(lattice, T, N_eq, False)
E, m = [], []
for i in range(N_post):
lattice = metropolis(eq_lattice,T,N_eq)
E.append(total_avg_E(lattice))
m.append(calcMag(lattice))
T += Tstep代码2
def E_site(self, i, j):
N = len(self.lattice)
Nb = self.lattice[(i+1)%N,j] + self.lattice[(i-1)%N,j] + self.lattice[i,(j+1)%N] + self.lattice[i, (j-1)%N]
return -self.lattice[i, j]*Nb
def alternative_metropolis(self, Neq, T):
for n in range(Neq):
N = len(self.lattice)
i = np.random.randint(0, N)
j = np.random.randint(0, N)
Ei = self.E_site(i, j)
self.lattice[i, j] *= -1
Ef = self.E_site(i, j)
dE = Ef - Ei
if dE < 0 or np.random.rand() < np.exp(-dE/T):
pass
else:
self.lattice[i,j] *= -1
def alternative_several_temperatures(self, Ti, Tf):
Tlist = np.arange(Ti, Tf, 0.1)
for T in Tlist:
s = time.clock()
for i in range(len(self.lattice)):
for j in range(len(self.lattice)):
if random() < 0.49:
self.lattice[i,j] = 1
else:
self.lattice[i,j] = -1
self.alternative_metropolis(int(1e7), T)我把在某个时刻调用的所有函数放在一起,让你检查它们看起来是一样的,除了代码2在一个类里面。然后,在Npost的Code1 > simulate_temperatures > for循环中,有一个对metropolis的调用。大都会内部循环,将完成Npost*Neq次。因此,如果Npost = 1e4,Neq = 1e3,那么内部大都市循环总共执行1e7次。
如果您转到代码2中的方法alternative_several_temperatures,您会看到alternative_metropolis方法有一个参数1e7,这是alternative_metropolis内的循环将被执行的次数。因此,所有的函数在我看来都是一样的,为什么代码2在40min运行,而代码1在Npost = 1e4,Neq = 1e3的情况下运行4分钟?我做错了什么数学题吗?
*实际上,由于平衡函数调用,代码2做了更多的迭代。
发布于 2020-06-24 03:29:06
这里发生了很多事情,所以很难确定,但我假设您每秒调用此代码数千次。如果是这样的话,这很可能是罪魁祸首:
i = np.random.randint(0, N)
j = np.random.randint(0, N)这种现象被称为“熵池耗尽”。本质上,您的计算机通过从各种来源(键盘敲击、鼠标移动、环境温度等)累积熵来生成熵。这种熵积累的速度相当慢。当您请求额外的随机整数并且熵池已经耗尽时,机器会阻塞,等待更多的熵变得可用。
要解决这个问题,您需要使用一个较小的“真”随机数子集和一个伪随机数生成器来填补空白。例如,您可以创建一个“熵提供者”类,它每10,000次调用才用一个新的随机整数重新设定PRNG的种子。
https://stackoverflow.com/questions/62542184
复制相似问题