forked from mglerner/MCIsing
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMCIsing2d.py
More file actions
executable file
·116 lines (100 loc) · 3.31 KB
/
Copy pathMCIsing2d.py
File metadata and controls
executable file
·116 lines (100 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
from __future__ import division
import numpy as np
import pylab
from numpy.random import random #import only one function from somewhere
from numpy.random import randint
from numpy import mod, exp
import scipy
import matplotlib.cm as cm
from time import sleep
import sys
def initialize(size):
"""
Initialize a random array where our spins are all up or down.
"""
return np.random.choice([-1, 1], size=(size, size)).tolist()
#@profile
def deltaU(s,i,j,size):
"""
Compute delta U of flipping a given dipole at i,j
Note periodic boundary conditions, which is why we need to know the size.
This function returns deltaU/2
"""
above = s[(i+1) % size][j]
below = s[(i-1) % size][j]
right = s[i][(j+1) % size]
left = s[i][(j-1) % size]
return s[i][j]*(above+below+left+right)
def deltaUtest(s,i,j,size):
return s[i][j]*(s[(i+1) % size][j] + s[(i-1) % size][j] +
s[i][(j+1) % size] + s[i][(j-1) % size])
def colorsquare(s,fig):
fig.clear()
pylab.imshow(s,interpolation='nearest',cmap=cm.Greys_r)
fig.canvas.draw()
#ax.set_title("Trial %s of %s"%(trial,numtrials))
pylab.draw()
def shouldshow(iteration,size,showevery):
if showevery is 1:
return True
if showevery == -1:
return False
if showevery is None:
#if size <= 10:
# showevery = 1
# delay = 5
if size < 100:
showevery = int(size*size/2)
else:
showevery = size*size
return divmod(iteration,showevery)[1] == 0
@profile
def simulate(size, T, showevery=None, graphics=True):
"""
Arguments:
- `size`: lattice length
- `T`: in units of epsilon/k
- `showevery`: how often to update the display. If None, a heuristic will be used.
"""
# Some magic to set up plotting
#pylab.ion() # You need this if running standalone
import time
start = time.time()
if graphics:
fig = pylab.figure()
ax = fig.add_subplot(111)
s = initialize(size)
if graphics:
colorsquare(s,fig)
pylab.show()
numtrials = 100*size**2
print "numtrials",numtrials
"""b_factor pre-calculates the Boltzmann factors for our 4 possible
positive energies. delatU returns an int -4 <= dU <= 4. b_factor is
of length 5 to save a subtraction, i.e. we want b_factor[4]. b_factor[0]
is never used but is retained for convenience.
"""
b_factor = [exp(-2*i/T) for i in xrange(5)]
rands = random(numtrials)
for trial in xrange(numtrials):
i = randint(size) # choose random row
j = randint(size) # and random column
ediff = deltaUtest(s,i,j,size)
if ediff <= 0: # flipping reduces the energy
s[i][j] *= -1
else:
if rands[trial] < b_factor[ediff]:
s[i][j] *= -1
if graphics and shouldshow(trial,size,showevery):
print "Showing iteration",trial
colorsquare(s,fig)
if graphics: colorsquare(s,fig)
stop = time.time()
print "That took",stop-start,"seconds, or",numtrials/(stop-start),"trials per second"
if __name__ == '__main__':
#raw_input() # you need this.
if len(sys.argv) == 1:
simulate(50, 1, graphics=False)
else:
simulate(int(sys.argv[1]), 1, graphics=False)