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