This is my first post, I am trying to make an ising model simulation using a monte carlo algorithm. I order to optimise the code I am currently trying to use Cython. However for now the execution time of the python and cython programm are identical. If anyone has an idea to either improve the cython implementation or to make the program run faster without using cython please let me know.
Thanks
PS : here is the code
#cython: language_level=3
import numpy as np
import time
cimport numpy as np
cpdef gen_neighbors_2d(int a):
cdef int n = a * a
cdef np.ndarray neighbors = np.zeros((n, 4), dtype=np.int32)
cdef int i, j, index
for i in range(a):
for j in range(a):
index = i * a + j
neighbors[index, 0] = i * a + (j - 1) % a # left
neighbors[index, 1] = i * a + (j + 1) % a # right
neighbors[index, 2] = ((i - 1) % a) * a + j # up
neighbors[index, 3] = ((i + 1) % a) * a + j # down
return neighbors
cpdef int MH_single_flip(np.ndarray[int, ndim=2] neighbors_list, double T, int iterations, int size):
cdef np.ndarray[int, ndim=1] spins = np.random.choice([-1, 1], size=size)
cdef int step, n, spin, delta_E
for step in range(iterations):
n = np.random.randint(0, size)
spin = spins[n]
delta_E = 2 * spin * np.add.reduce(spins[neighbors_list[n]])
if delta_E < 0 or -T*np.log(np.random.random(1)[0]) > delta_E:
spins[n] = -1*spin
return spins
neighbors_list = gen_neighbors_2d(100)
T_list = np.linspace(1, 4, 1000)
size = neighbors_list.shape[0]
t1 = time.time()
for T in range(len(T_list)):
blank_var = MH_single_flip(neighbors_list, T_list[T], 5000, size)
t2 = time.time()
print(t2-t1)
I at first tried to run the cython code without any variable definitions but it only made the code run 5 percent faster. Any of the upgrades I added after that increased performance by more than 1 percent. Any help is welcome !