2017-02-03 1 views
3

Je me suis appris l'algorithme de Metropolis et j'ai décidé d'essayer de le coder en Python. J'ai choisi de simuler le modèle Ising. J'ai une compréhension amateur de Python et que voici ce que je suis venu avec -Simulation du modèle Ising en Python

import numpy as np, matplotlib.pyplot as plt, matplotlib.animation as animation 

def Ising_H(x,y): 

    s = L[x,y] * (L[(x+1) % l,y] + L[x, (y+1) % l] + L[(x-1) % l, y] + L[x,(y-1) % l]) 
    H = -J * s 
    return H 

def mcstep(*args): #One Monte-Carlo Step - Metropolis Algorithm 

    x = np.random.randint(l) 
    y = np.random.randint(l) 
    i = Ising_H(x,y) 
    L[x,y] *= -1 
    f = Ising_H(x,y) 
    deltaH = f - i 
    if(np.random.uniform(0,1) > np.exp(-deltaH/T)): 
     L[x,y] *= -1 

    mesh.set_array(L.ravel()) 
    return mesh, 

def init_spin_config(opt): 

    if opt == 'h': 
     #Hot Start 
     L = np.random.randint(2, size=(l, l)) #lxl Lattice with random spin configuration 
     L[L==0] = -1 
     return L 

    elif opt =='c': 
     #Cold Start 
     L = np.full((l, l), 1, dtype=int) #lxl Lattice with all +1 
     return L 

if __name__=="__main__": 

    l = 15 #Lattice dimension 
    J = 0.3 #Interaction strength 
    T = 2.0 #Temperature 
    N = 1000 #Number of iterations of MC step 
    opt = 'h' 

    L = init_spin_config(opt) #Initial spin configuration 

    #Simulation Vizualization 
    fig = plt.figure(figsize=(10, 10), dpi=80) 
    fig.suptitle("T = %0.1f" % T, fontsize=50) 
    X, Y = np.meshgrid(range(l), range(l)) 
    mesh = plt.pcolormesh(X, Y, L, cmap = plt.cm.RdBu) 
    a = animation.FuncAnimation(fig, mcstep, frames = N, interval = 5, blit = True) 
    plt.show() 

En plus d'un « KeyError » d'une exception Tkinter et bandes blanches lorsque je tente un 16x16 ou quoi que ce soit au-dessus de cela, il semble et fonctionne bien. Maintenant, ce que je veux savoir, c'est si c'est juste parce que -

Je suis mal à l'aise avec la façon dont j'ai utilisé FuncAnimation pour faire la simulation de Monte Carlo ET animer mon tracé de maillage - cela a-t-il même un sens?

Et que diriez-vous de ce démarrage à froid? Tout ce que je reçois est un écran rouge.

Aussi, s'il vous plaît parlez-moi de KeyError et de la bande blanche.

Le 'KeyError' est venu comme -

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1540, in __call__ 
     return self.func(*args) 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 590, in callit 
    func(*args) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/backends/backend_tkagg.py", line 147, in _on_timer 
     TimerBase._on_timer(self) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/backend_bases.py", line 1305, in _on_timer 
     ret = func(*args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 1049, in _step 
     still_going = Animation._step(self, *args) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 855, in _step 
     self._draw_next_frame(framedata, self._blit) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 873, in _draw_next_frame 
     self._pre_draw(framedata, blit) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 886, in _pre_draw 
     self._blit_clear(self._drawn_artists, self._blit_cache) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 926, in _blit_clear 
     a.figure.canvas.restore_region(bg_cache[a]) 
KeyError: <matplotlib.axes._subplots.AxesSubplot object at 0x7fd468b2f2d0> 
+0

Où obtenez-vous spécifiquement une KeyError? Pourriez-vous fournir une trace de pile? – lordingtar

Répondre

3

Vous demandez beaucoup de questions à la fois.

  • KeyError: ne peut pas être reproduit. Il est étrange que cela ne devrait se produire que pour certaines tailles de tableau et pas d'autres. Peut-être quelque chose ne va pas avec le back-end, vous pouvez essayer d'utiliser un autre en plaçant ces lignes en haut du script
    import matplotlib
    matplotlib.use("Qt4Agg")
  • bandes blanches: ne peuvent être reproduits soit, mais peut-être ils viennent de une mise à l'échelle automatisée des axes. Pour éviter cela, vous pouvez définir les limites des axes manuellement plt.xlim(0,l-1) plt.ylim(0,l-1)
  • Utilisation FuncAnimation pour faire la simulation de Monte Carlo est parfaitement bien. Bien sûr, ce n'est pas la méthode la plus rapide, mais si vous voulez suivre votre simulation à l'écran, il n'y a rien de mal à cela. On peut cependant se demander pourquoi il n'y aurait qu'un seul spin retourné par unité de temps. Mais c'est plus une question de physique que de programmation.

  • écran rouge pour le démarrage à froid: Dans le cas du démarrage à froid, vous initialiser votre grille avec seulement 1 s. Cela signifie que la valeur maximale et maximale dans la grille est 1. Par conséquent, la carte de la couleur de la pcolorme est normalisée à la plage [1,1] et est entièrement rouge. En général, vous voulez que la palette de couleurs couvre [-1,1], ce qui peut être fait en utilisant les arguments vmin et vmax.

    mesh = plt.pcolormesh(X, Y, L, cmap = plt.cm.RdBu, vmin=-1, vmax=1)
    Cela devrait vous donner le comportement attendu également pour le "démarrage à froid".

+0

Je n'ai aucune idée de KeyError, mais j'ai mis à jour la réponse avec une solution possible. – ImportanceOfBeingErnest

+0

Votre réponse m'a aidé à résoudre le problème de démarrage à froid et à supprimer les bandes blanches, merci! Comme vous l'avez dit, c'était la plage incorrecte qui était le problème dans les deux cas.J'ai également édité ma question avec la trace de pile pour le problème de KeyError, si vous voulez jeter un coup d'oeil! Je suis d'accord que le FuncAnimation ne serait pas le plus rapide, je cherchais à jouer et à voir le système atteindre un équilibre. Je préférerais regarder les fonctions d'aimantation et d'autocorrélation. Mais existe-t-il un autre moyen de mettre à jour dynamiquement un graphique matplotlib et de visualiser la simulation? –

+0

Au lieu d'utiliser 'FuncAnimation' vous pouvez aussi appeler le' mcstep' manuellement ou dans une boucle, ce qui nécessiterait d'ajouter 'fig.canvas.draw()' et éventuellement 'plt.pause (1e-5)' pour mettre à jour le tracer et empêcher la fenêtre de devenir insensible. Mais permettez-moi de demander: Quelle serait la raison de ne pas utiliser FuncAnimation? – ImportanceOfBeingErnest