Coverage for moptipy / examples / bitstrings / ising2d.py: 50%
32 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-24 08:49 +0000
1"""
2The two-dimensional Ising problem.
4The two-dimensional Ising problem describes a torus. For each bit that differs
5from its right-side neighboring bit, a penalty of 1 is incurred. For each bit
6differing from its above neighbor, another penalty of 1 is added.
7The optimum is a bit string of either all ones or all zeros.
8The optimal objective value is 0.
9The worst possible objective value is `2*n`.
111. Simon Fischer. A Polynomial Upper Bound for a Mutation-Based Algorithm on
12 the Two-Dimensional Ising Model. In Kalyanmoy Deb, editor, Genetic and
13 Evolutionary Computation Conference, June 26-30, 2004, Seattle, WA, USA,
14 Proceedings, Part I, Lecture Notes in Computer Science (LNCS), volume 3102,
15 Springer Berlin, Heidelberg. pages 1100-1112.
16 doi: https://doi.org/10.1007/978-3-540-24854-5_108.
172. Carola Doerr and Furong Ye and Naama Horesh and Hao Wang and Ofer M. Shir
18 and Thomas Bäck. Benchmarking Discrete Optimization Heuristics with
19 IOHprofiler. Applied Soft Computing 88:106027, March 2020,
20 doi: https://doi.org/10.1016/j.asoc.2019.106027.
213. Thomas Weise, Zhize Wu, Xinlu Li, Yan Chen, and Jörg Lässig. Frequency
22 Fitness Assignment: Optimization without Bias for Good Solutions can be
23 Efficient. *IEEE Transactions on Evolutionary Computation (TEVC)*.
24 27(4):980-992. August 2023.
25 doi: https://doi.org/10.1109/TEVC.2022.3191698
27This is code is part of the research work of Mr. Jiazheng ZENG (曾嘉政),
28a Master's student at the Institute of Applied Optimization
29(应用优化研究所) of the School of Artificial
30Intelligence and Big Data (人工智能与大数据学院) at
31Hefei University (合肥大学) in
32Hefei, Anhui, China (中国安徽省合肥市) under the supervision of
33Prof. Dr. Thomas Weise (汤卫思教授).
34"""
35from typing import Callable, Final, Iterator, cast
37import numba # type: ignore
38import numpy as np
40from moptipy.examples.bitstrings.bitstring_problem import (
41 SquareBitStringProblem,
42)
45@numba.njit(nogil=True, cache=True)
46def ising2d(x: np.ndarray, k: int) -> int:
47 """
48 Calculate the two-dimensional Ising model.
50 :param x: the flat numpy array representing the bitstring
51 :param k: the side length of the square grid (i.e., `sqrt(len(x)))`
52 :return: the two-dimensional Ising objective
54 >>> test_k = 2
55 >>> y = np.array([False] * test_k * test_k)
56 >>> ising2d(y, test_k)
57 0
59 >>> y.fill(True)
60 >>> ising2d(y, test_k)
61 0
63 >>> y[2] = not y[2]
64 >>> ising2d(y, test_k)
65 4
67 >>> ising2d(np.array([True, False, False, True]), 2)
68 8
70 >>> test_k = 3
71 >>> y = np.array([False] * test_k * test_k)
72 >>> ising2d(y, test_k)
73 0
75 >>> y.fill(True)
76 >>> ising2d(y, test_k)
77 0
79 >>> y[4] = not y[4]
80 >>> ising2d(y, test_k)
81 4
83 >>> y[5] = not y[5]
84 >>> ising2d(y, test_k)
85 6
87 >>> y[3] = not y[3]
88 >>> ising2d(y, test_k)
89 6
91 >>> test_k = 5
92 >>> y = np.array([False] * test_k * test_k)
93 >>> ising2d(y, test_k)
94 0
96 >>> y.fill(True)
97 >>> ising2d(y, test_k)
98 0
100 >>> y[5] = not y[5]
101 >>> ising2d(y, test_k)
102 4
104 >>> y[6] = not y[6]
105 >>> ising2d(y, test_k)
106 6
108 >>> y[7] = not y[7]
109 >>> ising2d(y, test_k)
110 8
112 >>> y[6] = not y[6]
113 >>> ising2d(y, test_k)
114 8
116 >>> y[10] = not y[10]
117 >>> ising2d(y, test_k)
118 10
120 >>> y[12] = not y[12]
121 >>> ising2d(y, test_k)
122 12
124 >>> y[11] = not y[11]
125 >>> ising2d(y, test_k)
126 12
128 >>> y[6] = not y[6]
129 >>> ising2d(y, test_k)
130 10
132 # 16 bits, torus width = 4, and 2 true bits
133 >>> ising2d(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 4)
134 8
136 # 16 bits, torus width = 4, and 3 true bits
137 >>> ising2d(np.array([0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 4)
138 12
140 # 16 bits, torus width = 4, and 3 true bits
141 >>> ising2d(np.array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 4)
142 10
144 # 16 bits, torus width = 4, and 1 true bit
145 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 4)
146 4
148 # 16 bits, torus width = 4, and 4 true bits
149 >>> ising2d(np.array([0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 4)
150 10
152 # 16 bits, torus width = 4, and 4 true bits
153 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1]), 4)
154 10
156 # 16 bits, torus width = 4, and 4 true bits
157 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0]), 4)
158 12
160 # 16 bits, torus width = 4, and 4 true bits
161 >>> ising2d(np.array([0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0]), 4)
162 12
164 # 16 bits, torus width = 4, and 10 true bits
165 >>> ising2d(np.array([0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1]), 4)
166 14
168 # 16 bits, torus width = 4, and 8 true bits
169 >>> ising2d(np.array([1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0]), 4)
170 22
172 # 16 bits, torus width = 4, and 12 true bits
173 >>> ising2d(np.array([1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0]), 4)
174 12
176 # 16 bits, torus width = 4, and 13 true bits
177 >>> ising2d(np.array([0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1]), 4)
178 12
180 # 16 bits, torus width = 4, and 0 true bits
181 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 4)
182 0
184 # 16 bits, torus width = 4, and 16 true bits
185 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 4)
186 0
188 # 25 bits, torus width = 5, and 1 true bit
189 >>> ising2d(np.array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
191 4
193 # 25 bits, torus width = 5, and 1 true bit
194 >>> ising2d(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
195 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
196 4
198 # 25 bits, torus width = 5, and 1 true bit
199 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
200 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
201 4
203 # 25 bits, torus width = 5, and 4 true bits
204 >>> ising2d(np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
205 ... 0, 1, 0, 1, 0, 0, 0, 0]), 5)
206 12
208 # 25 bits, torus width = 5, and 5 true bits
209 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
210 ... 1, 0, 1, 0, 0, 1, 0, 0]), 5)
211 16
213 # 25 bits, torus width = 5, and 5 true bits
214 >>> ising2d(np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
215 ... 1, 0, 0, 0, 0, 0, 0, 1]), 5)
216 16
218 # 25 bits, torus width = 5, and 5 true bits
219 >>> ising2d(np.array([0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0,
220 ... 0, 0, 0, 0, 0, 0, 0, 1]), 5)
221 18
223 # 25 bits, torus width = 5, and 5 true bits
224 >>> ising2d(np.array([0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0,
225 ... 0, 0, 0, 0, 0, 0, 0, 1]), 5)
226 20
228 # 25 bits, torus width = 5, and 13 true bits
229 >>> ising2d(np.array([1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1,
230 ... 1, 0, 1, 0, 1, 0, 0, 1]), 5)
231 26
233 # 25 bits, torus width = 5, and 21 true bits
234 >>> ising2d(np.array([1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1,
235 ... 1, 1, 1, 1, 1, 1, 1, 1]), 5)
236 12
238 # 25 bits, torus width = 5, and 24 true bits
239 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
240 ... 1, 1, 1, 1, 1, 1, 1, 1]), 5)
241 4
243 # 25 bits, torus width = 5, and 12 true bits
244 >>> ising2d(np.array([1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0,
245 ... 0, 1, 0, 0, 1, 0, 1, 0]), 5)
246 24
248 # 25 bits, torus width = 5, and 0 true bits
249 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 ... 0, 0, 0, 0, 0, 0, 0, 0]), 5)
251 0
253 # 25 bits, torus width = 5, and 25 true bits
254 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
255 ... 1, 1, 1, 1, 1, 1, 1, 1]), 5)
256 0
258 # 36 bits, torus width = 6, and 3 true bits
259 >>> ising2d(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
260 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
261 12
263 # 36 bits, torus width = 6, and 4 true bits
264 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265 ... 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 6)
266 12
268 # 36 bits, torus width = 6, and 2 true bits
269 >>> ising2d(np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
270 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
271 8
273 # 36 bits, torus width = 6, and 1 true bit
274 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
275 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
276 4
278 # 36 bits, torus width = 6, and 6 true bits
279 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
280 ... 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0]), 6)
281 18
283 # 36 bits, torus width = 6, and 6 true bits
284 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
285 ... 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0]), 6)
286 18
288 # 36 bits, torus width = 6, and 6 true bits
289 >>> ising2d(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,
290 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]), 6)
291 18
293 # 36 bits, torus width = 6, and 6 true bits
294 >>> ising2d(np.array([0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
295 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 6)
296 18
298 # 36 bits, torus width = 6, and 12 true bits
299 >>> ising2d(np.array([0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
300 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0]), 6)
301 28
303 # 36 bits, torus width = 6, and 15 true bits
304 >>> ising2d(np.array([1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0,
305 ... 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1]), 6)
306 34
308 # 36 bits, torus width = 6, and 26 true bits
309 >>> ising2d(np.array([1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1,
310 ... 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1]), 6)
311 30
313 # 36 bits, torus width = 6, and 20 true bits
314 >>> ising2d(np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1,
315 ... 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0]), 6)
316 32
318 # 36 bits, torus width = 6, and 0 true bits
319 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 6)
321 0
323 # 36 bits, torus width = 6, and 36 true bits
324 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
325 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 6)
326 0
328 # 49 bits, torus width = 7, and 6 true bits
329 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
330 ... 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 ... 0, 0, 0, 0, 1, 0, 0, 0, 1, 0]), 7)
332 24
334 # 49 bits, torus width = 7, and 4 true bits
335 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
336 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
337 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
338 16
340 # 49 bits, torus width = 7, and 2 true bits
341 >>> ising2d(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
342 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
344 8
346 # 49 bits, torus width = 7, and 1 true bit
347 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
348 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
349 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 7)
350 4
352 # 49 bits, torus width = 7, and 7 true bits
353 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
354 ... 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
355 ... 0, 1, 0, 0, 0, 0, 0, 1, 0, 0]), 7)
356 24
358 # 49 bits, torus width = 7, and 7 true bits
359 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
360 ... 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
361 ... 1, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 7)
362 26
364 # 49 bits, torus width = 7, and 7 true bits
365 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
366 ... 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
367 ... 0, 0, 1, 0, 1, 0, 0, 0, 1, 0]), 7)
368 28
370 # 49 bits, torus width = 7, and 7 true bits
371 >>> ising2d(np.array([0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
372 ... 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0,
373 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]), 7)
374 26
376 # 49 bits, torus width = 7, and 14 true bits
377 >>> ising2d(np.array([0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1,
378 ... 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
379 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]), 7)
380 36
382 # 49 bits, torus width = 7, and 12 true bits
383 >>> ising2d(np.array([0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0,
384 ... 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
385 ... 1, 0, 0, 1, 0, 0, 1, 0, 0, 0]), 7)
386 38
388 # 49 bits, torus width = 7, and 15 true bits
389 >>> ising2d(np.array([0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0,
390 ... 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
391 ... 1, 1, 1, 0, 0, 1, 0, 0, 1, 0]), 7)
392 42
394 # 49 bits, torus width = 7, and 29 true bits
395 >>> ising2d(np.array([1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
396 ... 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0,
397 ... 0, 1, 1, 1, 1, 0, 1, 1, 1, 1]), 7)
398 48
400 # 49 bits, torus width = 7, and 0 true bits
401 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
402 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
403 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 7)
404 0
406 # 49 bits, torus width = 7, and 49 true bits
407 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
408 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
409 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 7)
410 0
412 # 64 bits, torus width = 8, and 5 true bits
413 >>> ising2d(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
414 ... 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
415 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
416 ... 0, 0, 0]), 8)
417 20
419 # 64 bits, torus width = 8, and 7 true bits
420 >>> ising2d(np.array([0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
421 ... 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1,
422 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,
423 ... 0, 0, 0]), 8)
424 26
426 # 64 bits, torus width = 8, and 2 true bits
427 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
428 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
429 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
430 ... 0, 0, 0]), 8)
431 8
433 # 64 bits, torus width = 8, and 4 true bits
434 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
435 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,
436 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
437 ... 0, 0, 0]), 8)
438 14
440 # 64 bits, torus width = 8, and 8 true bits
441 >>> ising2d(np.array([0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
442 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
443 ... 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
444 ... 1, 0, 0]), 8)
445 30
447 # 64 bits, torus width = 8, and 8 true bits
448 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
449 ... 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
450 ... 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
451 ... 0, 0, 0]), 8)
452 28
454 # 64 bits, torus width = 8, and 8 true bits
455 >>> ising2d(np.array([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
456 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
457 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
458 ... 0, 1, 0]), 8)
459 30
461 # 64 bits, torus width = 8, and 8 true bits
462 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
463 ... 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
464 ... 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
465 ... 0, 0, 0]), 8)
466 26
468 # 64 bits, torus width = 8, and 37 true bits
469 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1,
470 ... 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
471 ... 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0,
472 ... 1, 1, 0]), 8)
473 58
475 # 64 bits, torus width = 8, and 36 true bits
476 >>> ising2d(np.array([0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,
477 ... 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
478 ... 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1,
479 ... 1, 1, 1]), 8)
480 62
482 # 64 bits, torus width = 8, and 55 true bits
483 >>> ising2d(np.array([1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
484 ... 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
485 ... 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1,
486 ... 1, 1, 1]), 8)
487 32
489 # 64 bits, torus width = 8, and 38 true bits
490 >>> ising2d(np.array([0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
491 ... 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1,
492 ... 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1,
493 ... 1, 0, 1]), 8)
494 68
496 # 64 bits, torus width = 8, and 0 true bits
497 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
498 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
499 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
500 ... 0, 0, 0]), 8)
501 0
503 # 64 bits, torus width = 8, and 64 true bits
504 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
505 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
506 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
507 ... 1, 1, 1]), 8)
508 0
510 # 81 bits, torus width = 9, and 1 true bit
511 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
512 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
513 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
515 4
517 # 81 bits, torus width = 9, and 5 true bits
518 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
519 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
520 ... 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
521 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
522 20
524 # 81 bits, torus width = 9, and 1 true bit
525 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
526 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
527 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
528 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
529 4
531 # 81 bits, torus width = 9, and 3 true bits
532 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
533 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
534 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
535 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
536 12
538 # 81 bits, torus width = 9, and 9 true bits
539 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
540 ... 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
541 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
542 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 9)
543 30
545 # 81 bits, torus width = 9, and 9 true bits
546 >>> ising2d(np.array([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
547 ... 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
548 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
549 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
550 32
552 # 81 bits, torus width = 9, and 9 true bits
553 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
554 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
555 ... 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
556 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]), 9)
557 32
559 # 81 bits, torus width = 9, and 9 true bits
560 >>> ising2d(np.array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
561 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
562 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0,
563 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 9)
564 36
566 # 81 bits, torus width = 9, and 11 true bits
567 >>> ising2d(np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
568 ... 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
569 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
570 ... 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]), 9)
571 40
573 # 81 bits, torus width = 9, and 40 true bits
574 >>> ising2d(np.array([1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0,
575 ... 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1,
576 ... 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1,
577 ... 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0]), 9)
578 88
580 # 81 bits, torus width = 9, and 35 true bits
581 >>> ising2d(np.array([0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0,
582 ... 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0,
583 ... 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0,
584 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1]), 9)
585 70
587 # 81 bits, torus width = 9, and 79 true bits
588 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
589 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
590 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
591 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 9)
592 8
594 # 81 bits, torus width = 9, and 0 true bits
595 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
596 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
597 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
598 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 9)
599 0
601 # 81 bits, torus width = 9, and 81 true bits
602 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
603 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
604 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
605 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 9)
606 0
608 # 100 bits, torus width = 10, and 3 true bits
609 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
610 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
611 ... 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
612 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
613 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), 10)
614 12
616 # 100 bits, torus width = 10, and 5 true bits
617 >>> ising2d(np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
620 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
621 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
622 20
624 # 100 bits, torus width = 10, and 2 true bits
625 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
626 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
627 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
628 ... 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
629 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
630 8
632 # 100 bits, torus width = 10, and 1 true bit
633 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
634 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
635 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
636 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
637 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
638 4
640 # 100 bits, torus width = 10, and 10 true bits
641 >>> ising2d(np.array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
642 ... 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
643 ... 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644 ... 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
645 ... 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]), 10)
646 40
648 # 100 bits, torus width = 10, and 10 true bits
649 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
650 ... 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
651 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
652 ... 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
653 ... 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]), 10)
654 38
656 # 100 bits, torus width = 10, and 10 true bits
657 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
658 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
659 ... 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1,
660 ... 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
661 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
662 28
664 # 100 bits, torus width = 10, and 10 true bits
665 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
666 ... 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
667 ... 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
668 ... 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
669 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0]), 10)
670 36
672 # 100 bits, torus width = 10, and 91 true bits
673 >>> ising2d(np.array([1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
674 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
675 ... 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
676 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
677 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 10)
678 32
680 # 100 bits, torus width = 10, and 32 true bits
681 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
682 ... 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
683 ... 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
684 ... 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1,
685 ... 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0]), 10)
686 68
688 # 100 bits, torus width = 10, and 89 true bits
689 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
690 ... 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
691 ... 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
692 ... 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
693 ... 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0]), 10)
694 42
696 # 100 bits, torus width = 10, and 92 true bits
697 >>> ising2d(np.array([0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
698 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1,
699 ... 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
700 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
701 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 10)
702 30
704 # 100 bits, torus width = 10, and 0 true bits
705 >>> ising2d(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
706 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
707 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
708 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
709 ... 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 10)
710 0
712 # 100 bits, torus width = 10, and 100 true bits
713 >>> ising2d(np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
714 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
715 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
716 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
717 ... 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), 10)
718 0
719 """
720 n: Final[int] = len(x) # Get the length of the bit string.
721 result: int = n + n # Start with worst-case result.
723 prev_row_start: int = n - k # The start of the bottom row.
724 cur_row_start: int = 0 # The start index of the first row.
725 for _ in range(k): # Iterate over the rows.
726 prev_j: int = k - 1 # The previous index = last element.
727 for j in range(k): # Iterate over the current row.
728 center = x[cur_row_start + j] # The current element.
729 if center == x[prev_row_start + j]: # One row above the same?
730 result -= 1 # If above element same, no penalty.
731 if center == x[cur_row_start + prev_j]: # Element to the right.
732 result -= 1 # If right element same, no penalty.
733 prev_j = j # Previous element <-- current element.
734 prev_row_start = cur_row_start # Previous row <-- current row.
735 cur_row_start += k # k elements per row.
737 return result
740class Ising2d(SquareBitStringProblem):
741 """
742 The two-dimensional Ising model.
744 >>> ising = Ising2d(16)
745 >>> ising.n
746 16
747 >>> ising.k
748 4
749 >>> ising.evaluate(np.array([False, False, False, False,
750 ... False, False, False, False,
751 ... False, False, False, False,
752 ... False, False, False, False]))
753 0
754 >>> ising.evaluate(np.array([False, False, False, False,
755 ... False, True, False, False,
756 ... False, False, False, False,
757 ... False, False, False, False]))
758 4
759 >>> ising.evaluate(np.array([False, False, False, False,
760 ... True, True, True, True,
761 ... False, False, False, False,
762 ... False, False, False, False]))
763 8
764 >>> ising.evaluate(np.array([False, True, False, False,
765 ... True, True, True, True,
766 ... False, True, False, False,
767 ... False, True, False, False]))
768 12
769 >>> ising.evaluate(np.array([False, True, False, False,
770 ... True, True, True, True,
771 ... False, True, False, False,
772 ... False, True, False, True]))
773 16
774 >>> ising.evaluate(np.array([False, True, False, False,
775 ... True, True, True, True,
776 ... False, True, False, False,
777 ... True, True, True, True]))
778 16
779 """
781 def evaluate(self, x: np.ndarray) -> int:
782 """
783 Evaluate a solution to the 2D Ising problem.
785 :param x: the bit string to evaluate
786 :returns: the value of the 2D Ising Model for the string
787 """
788 return ising2d(x, self.k)
790 def upper_bound(self) -> int:
791 """
792 Get the upper bound of the two-dimensional Ising model.
794 :return: twice the length of the bit string
796 >>> Ising2d(49).upper_bound()
797 98
798 """
799 return 2 * self.n
801 def __str__(self) -> str:
802 """
803 Get the name of the two-dimensional Ising model objective function.
805 :return: ising2d_ + length of string
807 >>> Ising2d(16)
808 ising2d_16
809 """
810 return f"ising2d_{self.n}"
812 @classmethod
813 def default_instances(
814 cls: type, scale_min: int = 2, scale_max: int = 100) \
815 -> Iterator[Callable[[], "Ising2d"]]:
816 """
817 Get the 56 default instances of the :class:`Ising2d` problem.
819 :param scale_min: the minimum permitted scale, by default `2`
820 :param scale_max: the maximum permitted scale, by default `100`
821 :returns: a sequence of default :class:`Ising2d` instances
823 >>> len(list(Ising2d.default_instances()))
824 9
826 >>> [x() for x in Ising2d.default_instances()]
827 [ising2d_4, ising2d_9, ising2d_16, ising2d_25, ising2d_36, \
828ising2d_49, ising2d_64, ising2d_81, ising2d_100]
829 """
830 return cast("Iterator[Callable[[], Ising2d]]",
831 super().default_instances( # type: ignore
832 scale_min, scale_max))