Statistiques
| Révision :

root / Ising / Numpy-C / Ising2D.py @ 91

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

1 18 equemene
#!/usr/bin/env python
2 18 equemene
#
3 18 equemene
# Ising2D model in serial mode using external C library
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
import array_module_np
16 18 equemene
from numpy.random import randint as nprnd
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
94 18 equemene
    # Curves is True to print the curves
95 18 equemene
    Curves=False
96 18 equemene
97 18 equemene
    try:
98 18 equemene
        opts, args = getopt.getopt(sys.argv[1:],"hcj:b:z:i:s:e:p:",["coupling=","magneticfield=","size=","iterations=","tempstart=","tempend=","tempstep="])
99 18 equemene
    except getopt.GetoptError:
100 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]
101 18 equemene
        sys.exit(2)
102 18 equemene
103 18 equemene
104 18 equemene
    for opt, arg in opts:
105 18 equemene
        if opt == '-h':
106 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]
107 18 equemene
            sys.exit()
108 18 equemene
        elif opt == '-c':
109 18 equemene
            Curves=True
110 18 equemene
        elif opt in ("-j", "--coupling"):
111 18 equemene
            J = float(arg)
112 18 equemene
        elif opt in ("-b", "--magneticfield"):
113 18 equemene
            B = float(arg)
114 18 equemene
        elif opt in ("-s", "--tempmin"):
115 18 equemene
            Tmin = float(arg)
116 18 equemene
        elif opt in ("-e", "--tempmax"):
117 18 equemene
            Tmax = float(arg)
118 18 equemene
        elif opt in ("-p", "--tempstep"):
119 18 equemene
            Tstep = float(arg)
120 18 equemene
        elif opt in ("-i", "--iterations"):
121 18 equemene
            Iterations = int(arg)
122 18 equemene
        elif opt in ("-z", "--size"):
123 18 equemene
            Size = int(arg)
124 18 equemene
125 18 equemene
    print "Coupling Factor J : %s" % J
126 18 equemene
    print "Magnetic Field B :  %s" % B
127 18 equemene
    print "Size of lattice : %s" % Size
128 18 equemene
    print "Iterations : %s" % Iterations
129 18 equemene
    print "Temperature on start : %s" % Tmin
130 18 equemene
    print "Temperature on end : %s" % Tmax
131 18 equemene
    print "Temperature step : %s" % Tstep
132 18 equemene
    Trange=numpy.arange(Tmin,Tmax+Tstep,Tstep)
133 18 equemene
    print "Temperatures explored : %s" % Trange
134 18 equemene
135 18 equemene
    LAPIMAGE=False
136 18 equemene
137 18 equemene
    sigmaIn=numpy.where(numpy.random.randn(Size,Size)>0,1,-1).astype(numpy.int32)
138 18 equemene
139 18 equemene
    ImageOutput(sigmaIn,"Ising2D_Serial_%i_Initial" % (Size))
140 18 equemene
141 18 equemene
142 18 equemene
    E=[]
143 18 equemene
    M=[]
144 18 equemene
145 18 equemene
    for T in Trange:
146 18 equemene
        # Indispensable d'utiliser copy : [:] ne fonctionne pas avec numpy !
147 18 equemene
        sigma=numpy.copy(sigmaIn)
148 18 equemene
        # duration=Metropolis(sigma,J,B,T,Iterations)
149 18 equemene
        SeedW,SeedZ=numpy.int32(nprnd(2**31-1)),numpy.int32(nprnd(2**31-1))
150 18 equemene
        start=time.time()
151 18 equemene
        array_module_np.array_metropolis_np(sigma,J,B,T,Iterations,SeedW,SeedZ)
152 18 equemene
        duration=time.time()-start
153 18 equemene
        E=numpy.append(E,Energy(sigma,J))
154 18 equemene
        M=numpy.append(M,Magnetization(sigma,B))
155 18 equemene
        ImageOutput(sigma,"Ising2D_Serial_%i_%1.1f_Final" % (Size,T))
156 18 equemene
157 18 equemene
        print "CPU Time : %f" % (duration)
158 18 equemene
        print "Total Energy at Temperature %f : %f" % (T,E[-1])
159 18 equemene
        print "Total Magnetization at Temperature %f : %f" % (T,M[-1])
160 18 equemene
161 18 equemene
    if Curves:
162 18 equemene
        DisplayCurves(Trange,E,M,J,B)
163 18 equemene
164 18 equemene
    # Save output
165 18 equemene
    numpy.savez("Ising2D_Serial_%i_%.8i" % (Size,Iterations),(Trange,E,M))