2017-09-27 4 views
3

J'ai un script Python qui fait des simulations de Monte Carlo du modèle d'Ising d'un réseau 2D. Les simulations de MC sont parallèles de manière embarrassante, l'échantillonnage pour chaque température peut être distribué à différents fils. Je veux utiliser un module multi-traitement pour cela, mais nouveau pour ce paquet. Comment puis-je faire ceci?Comment paralléliser Ising Model en Python (package multi-traitement)?

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 

Répondre

0

Ici, vous allez:

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() 

Je ne sais rien à propos de l'algorithme, s'il vous plaît vérifier que je ne l'ai pas le casser. Maintenant, il associe chaque élément de T à des processus parallèles.

+0

Merci! Ça a marché! – user3503316

+0

Vous pouvez accepter la réponse si elle répond à votre question. – Hannu