In [1]:
%pylab inline


Populating the interactive namespace from numpy and matplotlib

Ising model simulations

From:

1) Monte Carlo Simulation of the Ising Model using Python: Explanations, code and video


In [3]:
import numpy as np
SIZE=5
STEPS=10
#----------------------------------------------------------------------#
#   Check periodic boundary conditions 
#----------------------------------------------------------------------#
def bc(i):
    return i%SIZE

#----------------------------------------------------------------------#
#   Calculate internal energy
#----------------------------------------------------------------------#
def energy(system, N, M):
    return -1 * system[N,M] * (system[bc(N-1), M] 
                               + system[bc(N+1), M] 
                               + system[N, bc(M-1)] 
                               + system[N, bc(M+1)])

#----------------------------------------------------------------------#
#   Build the system
#----------------------------------------------------------------------#
def build_system():
    system = np.random.random_integers(0,1,(SIZE,SIZE))
    system[system==0] =- 1

    return system

#----------------------------------------------------------------------#
#   The Main monte carlo loop
#----------------------------------------------------------------------#
def main(T):
    system = build_system()

    for step, x in enumerate(range(STEPS)): #list(enumerate(range(STEPS)))
        M = np.random.randint(0,SIZE)
        N = np.random.randint(0,SIZE)

        E = -2. * energy(system, N, M)

        if E <= 0.:
            system[N,M] *= -1
        elif np.exp(-1./T*E) > np.random.rand():
            system[N,M] *= -1
        print system

#----------------------------------------------------------------------#
#   Run the menu for the monte carlo simulation
#----------------------------------------------------------------------#
def run():
    print '='*30
    print '\tMonte Carlo Statistics for an ising model with'
    print '\t\tperiodic boundary conditions'
    print '='*30

    print "Choose the temperature for your run (0.1-100)"
    T = float(raw_input())
    main(T)

In [4]:
run()


==============================
	Monte Carlo Statistics for an ising model with
		periodic boundary conditions
==============================
Choose the temperature for your run (0.1-100)
10
[[-1 -1 -1 -1 -1]
 [ 1  1 -1  1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1 -1 -1]
 [-1 -1 -1 -1 -1]]
[[-1 -1 -1 -1 -1]
 [ 1  1 -1  1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1 -1 -1]
 [ 1 -1 -1 -1 -1]]
[[-1 -1 -1 -1 -1]
 [ 1  1 -1  1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1 -1 -1]
 [ 1 -1 -1 -1 -1]]
[[-1 -1 -1 -1 -1]
 [ 1  1 -1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1 -1 -1 -1 -1]]
[[-1 -1 -1 -1 -1]
 [ 1  1 -1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1  1 -1 -1 -1]]
[[-1  1 -1 -1 -1]
 [ 1  1 -1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1  1 -1 -1 -1]]
[[-1  1 -1 -1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1  1 -1 -1 -1]]
[[ 1  1 -1 -1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1  1 -1 -1 -1]]
[[ 1 -1 -1 -1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1  1 -1 -1 -1]]
[[ 1 -1 -1 -1 -1]
 [ 1  1  1  1 -1]
 [ 1  1  1  1  1]
 [ 1  1  1 -1 -1]
 [ 1  1  1 -1 -1]]

2)


In [3]:
#!/usr/bin/env python
"""
Monte Carlo simulation of the 2D Ising model
"""

from scipy import *
from scipy import weave
from pylab import *

Nitt = 1000000  # total number of Monte Carlo steps
N = 10          # linear dimension of the lattice, lattice-size= N x N
warm = 1000     # Number of warmup steps
measure=100     # How often to take a measurement


def CEnergy(latt):
    "Energy of a 2D Ising lattice at particular configuration"
    Ene = 0
    for i in range(len(latt)):
        for j in range(len(latt)):
            S = latt[i,j]
            WF = latt[(i+1)%N, j] + latt[i,(j+1)%N] + latt[(i-1)%N,j] + latt[i,(j-1)%N]
            Ene += -WF*S # Each neighbor gives energy 1.0
    return Ene/2. # Each par counted twice

def RandomL(N):
    "Radom lattice, corresponding to infinite temerature"
    latt = zeros((N,N), dtype=int)
    for i in range(N):
        for j in range(N):
            latt[i,j] = sign(2*rand()-1)
    return latt

def SamplePython(Nitt, latt, PW):
    "Monte Carlo sampling for the Ising model in Pythons"
    Ene = CEnergy(latt)  # Starting energy
    Mn=sum(latt)         # Starting magnetization
    
    Naver=0       # Measurements
    Eaver=0.0
    Maver=0.0
    
    N2 = N*N
    for itt in range(Nitt):
        t = int(rand()*N2)
        (i,j) = (t % N, t/N)
        S = latt[i,j]
        WF = latt[(i+1)%N, j] + latt[i,(j+1)%N] + latt[(i-1)%N,j] + latt[i,(j-1)%N]
        P = PW[4+S*WF]
        if P>rand(): # flip the spin
            latt[i,j] = -S
            Ene += 2*S*WF
            Mn -= 2*S
            
        if itt>warm and itt%measure==0:
            Naver += 1
            Eaver += Ene
            Maver += Mn

    return (Maver/Naver, Eaver/Naver)


def SampleCPP(Nitt, latt, PW, T):
    "The same Monte Carlo sampling in C++"
    Ene = float(CEnergy(latt))  # Starting energy
    Mn = float(sum(latt))       # Starting magnetization

    # Measurements
    aver = zeros(5,dtype=float) # contains: [Naver, Eaver, Maver]
    
    code="""
    using namespace std;
    int N2 = N*N;
    for (int itt=0; itt<Nitt; itt++){
        int t = static_cast<int>(drand48()*N2);
        int i = t % N;
        int j = t / N;
        int S = latt(i,j);
        int WF = latt((i+1)%N, j) + latt(i,(j+1)%N) + latt((i-1+N)%N,j) + latt(i,(j-1+N)%N);
        double P = PW(4+S*WF);
        if (P > drand48()){ // flip the spin
            latt(i,j) = -S;
            Ene += 2*S*WF;
            Mn -= 2*S;
        }
        if (itt>warm && itt%measure==0){
            aver(0) += 1;
            aver(1) += Ene;
            aver(2) += Mn;
            aver(3) += Ene*Ene;
            aver(4) += Mn*Mn;
        }
    }
    """
    weave.inline(code, ['Nitt','latt','N','PW','Ene','Mn','warm', 'measure', 'aver'],
                 type_converters=weave.converters.blitz, compiler = 'gcc')
    aE = aver[1]/aver[0]
    aM = aver[2]/aver[0]
    cv = (aver[3]/aver[0]-(aver[1]/aver[0])**2)/T**2
    chi = (aver[4]/aver[0]-(aver[2]/aver[0])**2)/T
    return (aM, aE, cv, chi)


if __name__ == '__main__':
    
    latt = RandomL(N)
    PW = zeros(9, dtype=float)

    wT = linspace(4,0.5,100)
    wMag=[]
    wEne=[]
    wCv=[]
    wChi=[]
    for T in wT:
        
        # Precomputed exponents
        PW[4+4] = exp(-4.*2/T)
        PW[4+2] = exp(-2.*2/T)
        PW[4+0] = exp(0.*2/T)
        PW[4-2] = exp( 2.*2/T)
        PW[4-4] = exp( 4.*2/T)
    
        #(maver, eaver) = SamplePython(Nitt, latt, PW)
        (aM, aE, cv, chi) = SampleCPP(Nitt, latt, PW, T)
        wMag.append( aM/(N*N) )
        wEne.append( aE/(N*N) )
        wCv.append( cv/(N*N) )
        wChi.append( chi/(N*N) )
        
        print T, aM/(N*N), aE/(N*N), cv/(N*N), chi/(N*N)
        
    plot(wT, wEne, label='E(T)')
    plot(wT, wCv, label='cv(T)')
    plot(wT, wMag, label='M(T)')
    xlabel('T')
    legend(loc='best')
    show()
    plot(wT, wChi, label='chi(T)')
    xlabel('T')
    legend(loc='best')
    show()


4.0 -0.000378416257884 -0.55766142757 0.173422621726 1.07515209127
3.96464646465 -0.00934828311142 -0.558490339373 0.180777568461 1.1013455304
3.92929292929 0.00279707678446 -0.569642606868 0.180832006574 1.12308366756
3.89393939394 0.00332565822405 -0.576930623686 0.182996922039 1.16996956683
3.85858585859 -0.00556812493743 -0.580186204825 0.19313967117 1.18307604827
3.82323232323 0.00341375513064 -0.595835418961 0.193739496227 1.27746051711
3.78787878788 -0.00851336470117 -0.597601361498 0.197075175825 1.30458345575
3.75252525253 0.00442486735409 -0.604705175693 0.201906826026 1.36379672729
3.71717171717 -0.000352387626389 -0.610399439383 0.212404702417 1.37692904586
3.68181818182 0.0175573130443 -0.617343077385 0.222611546795 1.36437636532
3.64646464646 -0.000462508759636 -0.62835519071 0.223602869085 1.47866447158
3.61111111111 -0.000496546200821 -0.634473921313 0.231500744044 1.53981522265
3.57575757576 -0.0201461607769 -0.639018920813 0.238072438808 1.58699686248
3.5404040404 -0.000326358994894 -0.654632095305 0.24411641156 1.76758501315
3.50505050505 0.00808489338272 -0.660106116728 0.242671740977 1.7388619394
3.4696969697 0.00522174391831 -0.671662829112 0.258369860106 1.81039960696
3.43434343434 -0.0021643808189 -0.679887876664 0.273257988182 1.94315711408
3.39898989899 2.4026429072e-05 -0.691052157373 0.270109178705 2.00821910429
3.36363636364 -0.00157172890179 -0.700598658524 0.291179921161 2.18249051319
3.32828282828 -0.00266292922214 -0.703525878466 0.283573284779 2.12612569554
3.29292929293 0.0193693062369 -0.718510361398 0.306083546127 2.21941828761
3.25757575758 -0.00526379016919 -0.729618580438 0.326807265737 2.41360251506
3.22222222222 -0.000144158574432 -0.740790869957 0.332772860162 2.51451511549
3.18686868687 -0.0177775553108 -0.758238061868 0.346517068685 2.80809013881
3.15151515152 0.00923015316849 -0.76103313645 0.357097231804 2.76747764233
3.11616161616 -0.00329362298528 -0.775312844129 0.379073424962 3.05617919551
3.08080808081 -0.0111502652918 -0.788631494644 0.395437873249 3.14154173728
3.04545454545 0.0065992591851 -0.8086775453 0.410137722894 3.4715130958
3.0101010101 0.0073060366403 -0.828763640004 0.420795178893 3.70523529369
2.97474747475 0.010705776354 -0.833905295825 0.444892488031 3.93598271863
2.93939393939 0.00571428571429 -0.858059865852 0.489506285821 4.27187063944
2.90404040404 0.0378135949544 -0.86913204525 0.512036172754 4.61614117938
2.86868686869 -0.0431895084593 -0.892277505256 0.542914531775 5.05130610727
2.83333333333 -0.0422564821303 -0.898920812894 0.593630003006 5.17869022593
2.79797979798 0.00877965762339 -0.933855240765 0.600066586647 6.06507996264
2.76262626263 -0.0130003003304 -0.954541996196 0.651548555666 6.59934959237
2.72727272727 0.00473921313445 -0.977010711783 0.74109742853 7.20682340646
2.69191919192 0.00775252778056 -1.00341175293 0.733803439131 7.66581100301
2.65656565657 0.0442666933627 -1.03959155071 0.865524620693 9.08088600881
2.62121212121 0.0146641305436 -1.07367304034 0.91656454733 10.3325816478
2.58585858586 0.0582360596656 -1.10672139353 0.994366777023 11.2590313492
2.55050505051 -0.0193873260587 -1.12748823706 0.993656796692 12.0353010884
2.51515151515 0.076788467314 -1.13635398939 1.05499319419 11.839330172
2.4797979798 -0.0663089398338 -1.20490139153 1.17271917075 14.6428034525
2.44444444444 -0.0262568825708 -1.23557913705 1.23989534666 16.1816973687
2.40909090909 0.106973671038 -1.27939933927 1.24251782294 17.5800677178
2.37373737374 0.0897086795475 -1.32700370407 1.30529523642 19.592163123
2.33838383838 -0.161567724497 -1.38510361398 1.34788019948 21.4842182251
2.30303030303 -0.185389928922 -1.43129041946 1.27371935897 23.2978920504
2.26767676768 -0.194828311142 -1.47648813695 1.28957469283 25.31948255
2.23232323232 -0.126745419962 -1.50970067074 1.1821988201 27.8567753518
2.19696969697 0.588319151066 -1.57309440384 1.17380010683 15.9924623834
2.16161616162 -0.0803023325658 -1.60315547102 1.04793903903 33.2619591274
2.12626262626 -0.490447492241 -1.63026929623 1.05772031823 23.6433201972
2.09090909091 0.0891640804885 -1.6716508159 0.954644654366 36.8643225465
2.05555555556 -0.0295905496046 -1.7065251777 0.85709964825 39.1844571884
2.0202020202 0.500844929422 -1.74171188307 0.66441911807 29.0381027335
1.98484848485 0.918556412053 -1.7581820002 0.660336062343 0.269384789565
1.94949494949 0.927450195215 -1.78166383021 0.639468828672 0.255614776811
1.91414141414 0.936444088497 -1.80335168686 0.547173970013 0.177461598699
1.87878787879 0.939279207128 -1.81706677345 0.588719082893 0.243107020886
1.84343434343 0.949170087096 -1.83822204425 0.498509412703 0.147135458987
1.80808080808 0.286731404545 -1.85217739513 0.500903780079 45.8185549275
1.77272727273 -0.960364400841 -1.86918009811 0.422383380046 0.100734710433
1.73737373737 -0.963918310141 -1.87998398238 0.405929096534 0.0878788002132
1.70202020202 -0.971404544999 -1.90127540294 0.328876541976 0.0603570651237
1.66666666667 -0.973092401642 -1.90814696166 0.318341776892 0.0688559958752
1.63131313131 -0.977313044349 -1.92161377515 0.285208075745 0.0587994613841
1.59595959596 -0.981049154069 -1.93253378717 0.244307395108 0.0377881670895
1.56060606061 -0.982452697968 -1.93787566323 0.240019022881 0.0372541433816
1.52525252525 -0.985502052257 -1.94737811593 0.204471520937 0.0275877978084
1.4898989899 -0.987366102713 -1.95373310642 0.182572713475 0.0237700530974
1.45454545455 -0.988397236961 -1.95816998699 0.176582687472 0.0244113758892
1.41919191919 -0.990103113425 -1.96374411853 0.157793751212 0.0204199413322
1.38383838384 -0.991716888577 -1.96918210031 0.138835212133 0.015572814821
1.34848484848 -0.993012313545 -1.97411552708 0.129178412539 0.0147962675841
1.31313131313 -0.994085494043 -1.97796776454 0.107899216845 0.0115894351341
1.27777777778 -0.995591150265 -1.98334167584 0.0890739846867 0.00874536626737
1.24242424242 -0.996159775753 -1.98548002803 0.0820977944045 0.00786336602718
1.20707070707 -0.996944639103 -1.9883511863 0.06848720499 0.00617337549604
1.17171717172 -0.997531284413 -1.99048152968 0.0579766701737 0.00482833063685
1.13636363636 -0.997947742517 -1.99217138853 0.0536149516484 0.00463679322258
1.10101010101 -0.998360196216 -1.9936329963 0.0432992215938 0.00333097245386
1.06565656566 -0.998784663129 -1.99530683752 0.0349865387457 0.00270596568346
1.0303030303 -0.998976874562 -1.99601962158 0.0303156502247 0.00215653121811
0.994949494949 -0.999209130043 -1.99690859946 0.0261533626234 0.00176033846437
0.959595959596 -0.999591550706 -1.99838622485 0.0141723162431 0.000892330949414
0.924242424242 -0.999653618981 -1.99863850235 0.0133212750122 0.000814551815271
0.888888888889 -0.999791770948 -1.99917909701 0.00840880534712 0.000490667174081
0.853535353535 -0.99981779958 -1.99927920713 0.00815161453366 0.000451191118304
0.818181818182 -0.999895885474 -1.9995835419 0.00495102287197 0.000253177305975
0.782828282828 -0.999913905296 -1.99965962559 0.00450289177368 0.000229241830121
0.747474747475 -0.999949944939 -1.99980378416 0.00288862727378 0.000144310400149
0.712121212121 -0.999965962559 -1.99986385024 0.00214417038928 9.54318260189e-05
0.676767676768 -0.999987986785 -1.99995194714 0.000838820533451 3.54804139512e-05
0.641414141414 -0.999997997798 -1.99999199119 0.000155717498853 6.24246287857e-06
0.606060606061 -1.0 -2.0 0.0 0.0
0.570707070707 -0.999997997798 -1.99999199119 0.000196692578824 7.0158653591e-06
0.535353535354 -1.0 -2.0 0.0 0.0
0.5 -1.0 -2.0 0.0 0.0

In [11]:
STEPS=5
list(enumerate(range(STEPS)))


Out[11]:
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

In [10]:
a.next()


Out[10]:
(2, 2)

In [ ]: