Statistiques
| Révision :

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

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