-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
238 lines (159 loc) · 6.65 KB
/
Copy pathmain.py
File metadata and controls
238 lines (159 loc) · 6.65 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from scipy.signal import convolve, convolve2d, correlate2d
from scipy.optimize import curve_fit
from astropy.table import Table, Column
import time
import pdb
class Grid:
"""
N-dimensional grid of two-state spins (1 = up, -1 = down).
Parameters
----------
Each argument is its own parameter
shape : int or tuple of ints
if int (>0), initialize spin chain with length shape
if tuple (of ints all > 0), initialize
init : float or str
if float, probability that a given spin is initialized in up state. Number-like
types will be cast to float
if str, will attempt to look for a preset grid initialization
"""
def __init__(self, shape, init=0.5):
# Check user input
shape_type_error = ValueError('shape must be either a positive integer or tuple of positive integers.')
cast_warning = False
if type(shape) == int:
if int <= 0:
raise shape_type_error
shape = (shape)
elif (type(shape) == list) or (type(shape) == np.ndarray):
# Check that all items in list are positive integers
for item in shape:
if type(item) != int:
try:
item = int(item)
if cast_warning == False:
print('Warning: One or more dimensions in shape has been cast to int.')
except:
raise shape_type_error
if int <= 0:
raise shape_type_error
shape = tuple(shape)
presets = []
pup_given = True # remains true if user directly gives a probability for init
init_type_error = ValueError('init must be either a float in [0, 1] or recognized str preset.')
if type(init) == str:
if init not in presets:
raise init_type_error
pup_given = False
else:
try:
init = float(init)
except:
raise init_type_error
if (init > 1) or (init < 0):
raise init_type_error
# Initialize grid
if pup_given:
self.grid = np.random.choice([1, -1], shape, p=[init, 1-init])
else:
pass # Populate this section when the first preset is added
assert np.shape(self.grid) == shape
class Interaction:
"""
Object representing terms in the Hamiltonian of the Ising model.
Parameters
----------
grid : Grid
Ising grid described by interactions
strength : float
Coupling strength
couplings : array-like (stored as list) with tuple elements
First N dimensions of couplings must be the same as grid. Last dimension
has length equal to number of spins coupled together, i.e., K such that
the interaction enters into H as J*s1*s2*...*sK
"""
def __init__(self, grid, strength, couplings):
## TODO: Write some user checks to make sure they enter couplings correctly
self.strength = strength
self.couplings = couplings
class FieldCoupling(Interaction):
"""
Term in the Hamiltonian which enters as h*Si for specified spins Si.
Parameters
----------
grid : Grid
Ising grid described by interactions
strength : float
Coupling strength
preset : str
Setting describing which spins couple to the field. Valid presets:
'all', all spins couple to field (default)
'probabilistic', spins randomly couple to field with probability randomp
randomp : float in [0,1], inclusive
if preset == 'probabilistic', couple spins to field with this probability.
otherwise, this parameter is ignored.
"""
def __init__(self, strength, preset='all', randomp=None):
# Check user input
strength_type_error = ValueError('strength must be a float.')
if type(strength) != float:
try:
strength = float(strength)
except:
raise strength_type_error
preset_type_error = ValueError('preset must be a str.')
preset_sel_error = ValueError('A valid preset was not given.')
presets = ['all', 'probabilistic']
if type(preset) != str:
raise preset_type_error
elif preset not in presets:
raise preset_sel_error
# Warn user if randomp is ignored
if (preset != 'probabilistic') and (randomp != None):
print('Warning: randomp parameter was ignored.')
# Build coupling list
shape = list(grid.grid.shape)
Ndims = len(shape)
# Populate couplings list
if preset == 'all':
# Create array where last index is coordinate number, second to last is point number (there is only one),
# and other dimensions are just grid dimensions
couplings = np.indices(shape)
couplings = np.array([couplings])
couplings = np.rollaxis(couplings, 0, start=len(coupling.shape))
couplings = np.rollaxis(couplings, 0, start=len(coupling.shape))
self.couplings = couplings
# Fuck this format can't take into account that one interaction can optionally couple fields
# more generally, it can't handle if different points are involved in different numbers of couplings fuck
# Define strength
self.strength = strength
class DipoleCoupling(Interaction):
"""
Term in the Hamiltonian which enters as J*Si*Sj for specified pairs of Si, Sj.
Parameters
----------
grid : Grid
Ising grid described by interactions
strength : float
Coupling strength
preset : str
Setting describing which spins are coupled to each other. Valid presets:
'prismnn', spins are coupled to their neighbors
'prismtri', spins are coupled to six neighbors in triangular fashion in first two dimensions,
nn interactions in the others
'prismhex', spins are coupled to three neighbors in hexagonal fashion,
nn interactions in the others
'glassnn', randomly initialize prismnn bonds with probability glassp
'glasstri', randomly initialize prismnn bonds with probability glassp
'glasshex', randomly initialize prismnn bonds with probability glassp
glassp : float in [0,1], inclusive
if the preset is a glass, this describes the bond probability.
Otherwise, this parameter is ignored.
"""
...
# Define strength
self.strength = strength
#