我有一个Python脚本,可以对2D晶格的Ising模型进行蒙特卡罗模拟。 MC模拟令人尴尬地平行,每个温度的采样可以分配到不同的线程。我想为此使用多处理模块,但对此包是新的。我怎么能这样做?
from __future__ import division
import numpy as np
from numpy.random import rand
import matplotlib.pyplot as plt
import multiprocessing as mp
nt = 5
N = 16
Energy = np.zeros(nt)
Magnetization = np.zeros(nt)
T = np.linspace(1, 5, nt)
## monte carlo moves
def mcmove(config, beta):
for i in range(N):
for j in range(N):
a = np.random.randint(0, N)
b = np.random.randint(0, N)
s = config[a, b]
nb = config[(a+1)%N,b] + config[a,(b+1)%N] + config[(a-1)%N,b] + config[a,(b-1)%N]
cost = 2*s*nb
if cost < 0:
s *= -1
elif rand() < np.exp(-cost*beta):
s *= -1
config[a, b] = s
return config
# calculate thermodynamic variables
def calcEnergy(config):
energy = 0
for i in range(len(config)):
for j in range(len(config)):
S = config[i,j]
nb = config[(i+1)%N, j] + config[i,(j+1)%N] + config[(i-1)%N, j] + config[i,(j-1)%N]
energy += -nb*S
return energy/4.
def calcMag(config):
mag = np.sum(config)
return mag
def simulate():
# -->: parallelize T
for m in range(len(T)):
E1 = M1 = 0
def initialstate(N):
state = 2*np.random.randint(2, size=(N,N))-1
return state
eqSteps = 2000
config = initialstate(N)
for i in range(eqSteps):
mcmove(config, 1.0/T[m])
mcSteps = 2000
for i in range(mcSteps):
mcmove(config, 1.0/T[m])
Ene = calcEnergy(config)
Mag = calcMag(config)
E1 = E1 + Ene
M1 = M1 + Mag
Energy[m] = E1/(mcSteps*N*N)
Magnetization[m] = M1/(mcSteps*N*N)
return Magnetization, Energy
Magnetization, Energy = simulate()
print Magnetization, Energy
答案 0 :(得分:1)
你走了:
from __future__ import division
import numpy as np
from numpy.random import rand
import matplotlib.pyplot as plt
import multiprocessing as mp
nt = 5
N = 16
Energy = np.zeros(nt)
Magnetization = np.zeros(nt)
T = np.linspace(1, 5, nt)
## monte carlo moves
def mcmove(config, beta):
for i in range(N):
for j in range(N):
a = np.random.randint(0, N)
b = np.random.randint(0, N)
s = config[a, b]
nb = config[(a+1)%N,b] + config[a,(b+1)%N] + config[(a-1)%N,b] + config[a,(b-1)%N]
cost = 2*s*nb
if cost < 0:
s *= -1
elif rand() < np.exp(-cost*beta):
s *= -1
config[a, b] = s
return config
# calculate thermodynamic variables
def calcEnergy(config):
energy = 0
for i in range(len(config)):
for j in range(len(config)):
S = config[i,j]
nb = config[(i+1)%N, j] + config[i,(j+1)%N] + config[(i-1)%N, j] + config[i,(j-1)%N]
energy += -nb*S
return energy/4.
def calcMag(config):
mag = np.sum(config)
return mag
def run_one(m):
E1 = M1 = _Energy = _Magnetization = 0
def initialstate(N):
state = 2 * np.random.randint(2, size=(N, N)) - 1
return state
eqSteps = 2000
config = initialstate(N)
for i in range(eqSteps):
mcmove(config, 1.0 / m)
mcSteps = 2000
for i in range(mcSteps):
mcmove(config, 1.0 / m)
Ene = calcEnergy(config)
Mag = calcMag(config)
E1 = E1 + Ene
M1 = M1 + Mag
_Energy= E1 / (mcSteps * N * N)
_Magnetization = M1 / (mcSteps * N * N)
return _Energy, _Magnetization
def parallel_sim():
p = mp.Pool()
results = p.map(run_one, T)
p.close()
p.join()
_e = []
_m = []
for _r in results:
_e.append(_r[0])
_m.append(_r[1])
return _e, _m
print parallel_sim()
我对算法一无所知,请确认我没有破坏它。现在,它将T的每个元素映射到并行进程。