The algorithm:
- Place seed at the center of the canvas.
- Release a random walker from the edge.
- Random walker sticks to the neighboring sites of the seed/previous points.
- Repeat N(particles) times.
For a 500x500 matrix with 50k iterations, it would easily take one full day to compute. How to reduce the computation time drastically?
Why 50k particles, cause it's a part of the assignment!
Logically program is correct.
I tried profiling, it didn't tell me a whole lot. The while loop is causing the issue? Any suggestions to improve the efficiency of my code?
import time
import numpy as np
import random
import matplotlib.pyplot as plt
from numba import jit, cuda, prange
#from numba import roc
starttime = time.time()
arr = [h,w] = [500,500] #track of height and width of canvas
particles = 50000
sticking_coeff = 0.5
canvas = np.zeros((h, w)).astype(int) #the blank n * n matrix
canvas[h//2,w//2] = 1 #make center element is 1
#// to get the floor value
stick = []
stick.append([h//2 + 1, w//2])#below 1
stick.append([[h//2 - 1, w//2]])#above 1
stick.append([h//2, w//2 + 1])#right of 1
stick.append([h//2, w//2 - 1])#left of 1
#@jit(nopython=True, parallel=True)
#@roc.jit(device=True)
#@numba.jit()
@jit(cache=True)
def walk(A, B, canvas):# A: row B: Column
while True:
#print('while')
x = np.random.randint(4)#0: row 1: column
if x == 0:#forward option
A += 1
#print('A+')
elif x == 1:
B += 1
#print('B+')
elif x == 2:
A -= 1 #reverse option
#print('A-')
else:
B -= 1
#print('B-')
#take care of overflow
if A < 0:
A = 0
#print('A=0')
elif B < 0:
B = 0
#print('B=0')
if A >= h:
A -= 1
#print('A-1')
elif B >= w:
B -= 1
#print('B-1')
positi = [A , B]
if positi in stick:
if np.random.rand() < sticking_coeff:
for site in [[positi[0] + 1, positi[1]],
[positi[0] - 1, positi[1]],
[positi[0], positi[1] + 1],
[positi[0], positi[1] - 1]]:
if site not in stick:
stick.append(site)
canvas[positi[0] , positi[1]] = 1
break # <-- Also, this is require, I think
else:
continue
return canvas
for i in prange(particles):
print('particle ',i+1)
selec = random.sample(set(['A','B','C','D']),1)
#pos1 = randrange(0, len(arr))
pos = np.random.randint(0, len(arr))
print(selec)
if selec == ['A']:
#arr[:,0]#first column
#arr[pos,0] = 1
walk(pos,0,canvas)
elif selec == ['B']:
#arr[:,-1]#last column
#arr[pos,-1] = 1
walk(pos,-1,canvas)
elif selec == ['C']:
#arr[0,:]#first row
#arr[0,pos] =1
walk(0,pos,canvas)
else:
#arr[-1,:]#last row
#arr[-1,pos] = 1
walk(-1,pos,canvas)
plt.matshow(canvas)
plt.savefig("rand_walk.png",dpi=2000)
print('That took {} seconds'.format(time.time() - starttime))