Statistiques
| Révision :

root / Ising / MP / Ising2D-MP.py @ 18

Historique | Voir | Annoter | Télécharger (4,9 ko)

1 18 equemene
#!/usr/bin/env python
2 18 equemene
#
3 18 equemene
# Ising2D model in serial mode
4 18 equemene
#
5 18 equemene
# CC BY-NC-SA 2011 : <emmanuel.quemener@ens-lyon.fr>
6 18 equemene
7 18 equemene
import sys
8 18 equemene
import numpy
9 18 equemene
from PIL import Image
10 18 equemene
from math import exp
11 18 equemene
from random import random
12 18 equemene
import time
13 18 equemene
import getopt
14 18 equemene
import matplotlib.pyplot as plt
15 18 equemene
16 18 equemene
from multiprocessing import Pool
17 18 equemene
18 18 equemene
def ImageOutput(sigma,prefix):
19 18 equemene
    Max=sigma.max()
20 18 equemene
    Min=sigma.min()
21 18 equemene
22 18 equemene
    # Normalize value as 8bits Integer
23 18 equemene
    SigmaInt=(255*(sigma-Min)/(Max-Min)).astype('uint8')
24 18 equemene
    image = Image.fromarray(SigmaInt)
25 18 equemene
    image.save("%s.jpg" % prefix)
26 18 equemene
27 18 equemene
def Metropolis(sigma,J,B,T,iterations):
28 18 equemene
    start=time.time()
29 18 equemene
30 18 equemene
    SizeX,SizeY=sigma.shape
31 18 equemene
32 18 equemene
    for p in xrange(0,iterations):
33 18 equemene
        # Random access coordonate
34 18 equemene
        X,Y=numpy.random.randint(SizeX),numpy.random.randint(SizeY)
35 18 equemene
36 18 equemene
        DeltaE=J*sigma[X,Y]*(2*(sigma[X,(Y+1)%SizeY]+
37 18 equemene
                                sigma[X,(Y-1)%SizeY]+
38 18 equemene
                                sigma[(X-1)%SizeX,Y]+
39 18 equemene
                                sigma[(X+1)%SizeX,Y])+B)
40 18 equemene
41 18 equemene
        if DeltaE < 0. or random() < exp(-DeltaE/T):
42 18 equemene
            sigma[X,Y]=-sigma[X,Y]
43 18 equemene
    duration=time.time()-start
44 18 equemene
    return(duration)
45 18 equemene
46 18 equemene
def Magnetization(sigma,M):
47 18 equemene
    return(numpy.sum(sigma)/(sigma.shape[0]*sigma.shape[1]*1.0))
48 18 equemene
49 18 equemene
def Energy(sigma,J):
50 18 equemene
    # Copier et caster
51 18 equemene
    E=numpy.copy(sigma).astype(numpy.float32)
52 18 equemene
53 18 equemene
    # Appel par slice
54 18 equemene
    E[1:-1,1:-1]=-J*E[1:-1,1:-1]*(E[:-2,1:-1]+E[2:,1:-1]+
55 18 equemene
                                  E[1:-1,:-2]+E[1:-1,2:])
56 18 equemene
57 18 equemene
    # Bien nettoyer la peripherie
58 18 equemene
    E[:,0]=0
59 18 equemene
    E[:,-1]=0
60 18 equemene
    E[0,:]=0
61 18 equemene
    E[-1,:]=0
62 18 equemene
63 18 equemene
    Energy=numpy.sum(E)
64 18 equemene
65 18 equemene
    return(Energy/(E.shape[0]*E.shape[1]*1.0))
66 18 equemene
67 18 equemene
def DisplayCurves(T,E,M,J,B):
68 18 equemene
69 18 equemene
    plt.xlabel("Temperature")
70 18 equemene
    plt.ylabel("Energy")
71 18 equemene
72 18 equemene
    Experience,=plt.plot(T,E,label="Energy")
73 18 equemene
74 18 equemene
    plt.legend()
75 18 equemene
    plt.show()
76 18 equemene
77 18 equemene
78 18 equemene
if __name__=='__main__':
79 18 equemene
80 18 equemene
    # Set defaults values
81 18 equemene
    # Coupling factor
82 18 equemene
    J=1.
83 18 equemene
    # Magnetic Field
84 18 equemene
    B=0.
85 18 equemene
    # Size of Lattice
86 18 equemene
    Size=256
87 18 equemene
    # Default Temperatures (start, end, step)
88 18 equemene
    Tmin=0.1
89 18 equemene
    Tmax=5
90 18 equemene
    Tstep=0.1
91 18 equemene
    # Default Number of Iterations
92 18 equemene
    Iterations=Size*Size
93 18 equemene
    # Default Number of Procs Used
94 18 equemene
    Procs=4
95 18 equemene
96 18 equemene
    # Curves is True to print the curves
97 18 equemene
    Curves=False
98 18 equemene
99 18 equemene
    try:
100 18 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hcj:b:z:i:s:e:p:u:",["coupling=","magneticfield=","size=","iterations=","tempstart=","tempend=","tempstep=","units"])
101 18 equemene
    except getopt.GetoptError:
102 18 equemene
        print '%s -j <Coupling Factor> -b <Magnetic Field> -z <Size of Lattice> -i <Iterations> -s <Minimum Temperature> -e <Maximum Temperature> -p <steP Temperature> -u <Unit of process> -c (Print Curves)' % sys.argv[0]
103 18 equemene
        sys.exit(2)
104 18 equemene
105 18 equemene
    for opt, arg in opts:
106 18 equemene
        if opt == '-h':
107 18 equemene
            print '%s -j <Coupling Factor> -b <Magnetic Field> -z <Size of Lattice> -i <Iterations> -s <Minimum Temperature> -e <Maximum Temperature> -p <steP Temperature> -c (Print Curves)' % sys.argv[0]
108 18 equemene
            sys.exit()
109 18 equemene
        elif opt == '-c':
110 18 equemene
            Curves=True
111 18 equemene
        elif opt in ("-j", "--coupling"):
112 18 equemene
            J = float(arg)
113 18 equemene
        elif opt in ("-b", "--magneticfield"):
114 18 equemene
            B = float(arg)
115 18 equemene
        elif opt in ("-s", "--tempmin"):
116 18 equemene
            Tmin = float(arg)
117 18 equemene
        elif opt in ("-e", "--tempmax"):
118 18 equemene
            Tmax = arg
119 18 equemene
        elif opt in ("-p", "--tempstep"):
120 18 equemene
            Tstep = numpy.uint32(arg)
121 18 equemene
        elif opt in ("-i", "--iterations"):
122 18 equemene
            Iterations = int(arg)
123 18 equemene
        elif opt in ("-z", "--size"):
124 18 equemene
            Size = int(arg)
125 18 equemene
        elif opt in ("-u", "--unit"):
126 18 equemene
            Procs = int(arg)
127 18 equemene
128 18 equemene
    print "Process Units : %s" % Procs
129 18 equemene
    print "Coupling Factor J : %s" % J
130 18 equemene
    print "Magnetic Field B :  %s" % B
131 18 equemene
    print "Size of lattice : %s" % Size
132 18 equemene
    print "Iterations : %s" % Iterations
133 18 equemene
    print "Temperature on start : %s" % Tmin
134 18 equemene
    print "Temperature on end : %s" % Tmax
135 18 equemene
    print "Temperature step : %s" % Tstep
136 18 equemene
137 18 equemene
    LAPIMAGE=False
138 18 equemene
139 18 equemene
    sigmaIn=numpy.where(numpy.random.randn(Size,Size)>0,1,-1).astype(numpy.int8)
140 18 equemene
141 18 equemene
    ImageOutput(sigmaIn,"Ising2D_Serial_%i_Initial" % (Size))
142 18 equemene
143 18 equemene
    Trange=numpy.arange(Tmin,Tmax+Tstep,Tstep)
144 18 equemene
145 18 equemene
    E=[]
146 18 equemene
    M=[]
147 18 equemene
148 18 equemene
    def MetropolisStrip(T):
149 18 equemene
        # Indispensable d'utiliser copy : [:] ne fonctionne pas avec numpy !
150 18 equemene
        sigma=numpy.copy(sigmaIn)
151 18 equemene
        duration=Metropolis(sigma,J,B,T,Iterations)
152 18 equemene
        ImageOutput(sigma,"Ising2D_Serial_%i_%1.1f_Final" % (Size,T))
153 18 equemene
        print "CPU Time : %f" % (duration)
154 18 equemene
        E,M=Energy(sigma,J),Magnetization(sigma,B)
155 18 equemene
        print "Total Energy at Temperature %f : %f" % (T,E)
156 18 equemene
        print "Total Magnetization at Temperature %f : %f" % (T,M)
157 18 equemene
        return(T,E,M)
158 18 equemene
159 18 equemene
    pool=Pool(processes=Procs)
160 18 equemene
    print "Start on %i processors..." % Procs
161 18 equemene
    # Apply MAP to POOL
162 18 equemene
    # MAP: distribution of usecases T to be applied to MetropolisStrip
163 18 equemene
    Results=pool.map(MetropolisStrip,Trange)
164 18 equemene
165 18 equemene
    if Curves:
166 18 equemene
        DisplayCurves(Trange,E,M,J,B)
167 18 equemene
168 18 equemene
    # Save output
169 18 equemene
    numpy.savez("Ising2D_MP_%i_%.8i" % (Size,Iterations),(Trange,E,M))