Help improve code efficiency - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Help improve code efficiency (/thread-16045.html) |
Help improve code efficiency - benbrown03 - Feb-12-2019 if anyone could help me improve the efficiency of this code it would be greatly appreciated. I would like it to only loop over the newly contaminated cells at each time step instead of looping over the whole grid. Any other ideas welcome. import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib import colors import random import os print("=== Cellular Automata for Radioactive Waste Disposal ===") # ======= User Inputs L = 20.0 # km numCells = 100 # This needs to remain the same for! totalTime = (40 * 12) # number of time steps (in months) print_every_n_steps = 480 # don't make this too small! print_time_every = 200 source_x = 0.2 # x - coordinate location of source of radio active waste source_y = 0.2 # y - coordinate location of course of radio active waste city_x = 12 city_y = 16 cell_city_x = int(numCells * (city_x / L)) cell_city_y = int(numCells * (city_y / L)) verbosity = 0 #Permeability Maximum Variable # *** Model Developement 3 *** Kmax = 3.5#Permeability Maximum Variable #K = np.loadtxt("perm.txt", dtype='f', delimiter=' ') Ktmp = np.loadtxt("perm.txt") K=Ktmp.astype(np.float) cmap = mpl.cm.jet norm = mpl.colors.Normalize(vmin=0, vmax = 1) fig, ax = plt.subplots() ax.imshow(K, cmap=cmap, norm=norm) ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2) ax.axes.get_xaxis().set_visible(False) ax.axes.get_yaxis().set_visible(False) results_dir = os.path.join(os.getcwd(),'solutions/') if not os.path.isdir(results_dir): os.makedirs(results_dir) plt.savefig(results_dir + "perm.png") cell_source_x = int(numCells * (source_x / L)) cell_source_y = int(numCells * (source_y / L)) count = 0 for n in range(0, 20): C = np.zeros((numCells ,numCells )) C[cell_source_x, cell_source_y] = 1; #1 is contaminated iteration = str(n+1) print("Iteration:" + iteration) #C[cell_city_x][cell_city_y] = 1 #will show city for t in range(0,totalTime+1): if (t % print_time_every == 0) : print("Time = " + str(t)) Cnew = np.zeros((numCells ,numCells )) for i in range(0,numCells): for j in range(0,numCells): if (C[i][j] == 0) :#and i+1 j+1 ==0 etc if(verbosity > 0): print("Cell " + str(i) + " , " + str(j)) # *** Model Developement 1 ** #sij = contaminated neighbours sij = 0 #using 'if' and 'elif' to assess the 9 different cases for a given cell (i,j) if(i!=0 and i!=numCells-1 and j!=0 and j!=numCells-1): sij= C[i][j+1] + C[i][j-1] + C[i-1][j] + C[i-1][j-1] + C[i-1][j+1] + C[i+1][j] + C[i+1][j-1] + C[i+1][j+1] elif(i==0 and j!=0 and j!=numCells-1):#mid left sij= C[i][j+1] + C[i][j-1] + C[i+1][j+1] + C[i+1][j] + C[i+1][j-1] elif(i==numCells-1 and j!=0 and j!=numCells-1):#mid right sij= C[i][j+1] + C[i][j-1] + C[i-1][j+1] + C[i-1][j] + C[numCells-1][numCells-1] elif(i!=0 and i!=numCells-1 and j==numCells-1):#mid top sij= C[i-1][j] + C[i-1][j-1] + C[i][j-1] + C[i+1][j-1] + C[i+1][j] elif(i!=0 and i!=numCells-1 and j==0):#mid bottom sij= C[i-1][j] + C[i-1][j+1] + C[i][j+1] + C[i+1][j+1] + C[i+1][j] elif(i == 0 and j==0) : #bottom left sij = C[0][1] + C[1][0] + C[1][1] elif(i==0 and j==numCells-1):#top left sij = C[1][numCells-1] + C[0][numCells-2] + C[1][numCells-2] elif(i==numCells-1 and j==0):#bottom right sij = C[numCells-1][1] + C[numCells-2][0] + C[numCells-2][1] else:#top right sij = C[numCells-1][numCells-2] + C[numCells-2][numCells-1] + C[numCells-2][numCells-2] # *** Model Developement 2 *** p = (sij/8)*((K[i][j])/Kmax) #gives probability n = random.uniform(0,1) if p>n: Cnew[i][j]=1#make this =p to give range of intensity? else : Cnew[i][j] = 0 C = Cnew; # Set new contamination Matrix to old C. #this is how it goes through, adding on each time # Plot grid and save to file if (t % print_every_n_steps == 0) : cmap = mpl.cm.jet norm = mpl.colors.Normalize(vmin=0, vmax = 1) fig, ax = plt.subplots() ax.imshow(C, cmap=cmap, norm=norm) ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2) ax.axes.get_xaxis().set_visible(False) ax.axes.get_yaxis().set_visible(False) results_dir = os.path.join(os.getcwd(),'solutions/') if not os.path.isdir(results_dir): os.makedirs(results_dir) plt.savefig(results_dir + "Run:" + (iteration) + "_solution_time_" + str(t) + ".png") city = C[cell_city_x][cell_city_y] if city == 1: print("City Dead") count += 1 else: print("City Alive") print(count) RE: Help improve code efficiency - ichabod801 - Feb-12-2019 Just keep a list of the contaminated cells and loop over that. They seem to get contaminated at only one point, so you can just append them at that point. If you only want the newly contaminated cells, reset the list each generation. RE: Help improve code efficiency - benbrown03 - Feb-12-2019 (Feb-12-2019, 03:38 PM)ichabod801 Wrote: Thread I understand what you mean i'm just struggling to implement it but will continue trying. any extra help would be perfect. RE: Help improve code efficiency - ichabod801 - Feb-12-2019 When you do Cnew[i][j] = 1 , just append a tuple of the coordinates to you contaminated list: contaminated.append((i, j)) . Then you loop through that list with for cx, xy in contaminated: . Now, you'll have to do the check for the next set of cells in reverse. I would suggest a dictionary of tuples, reset each generation to empty. Ideally this would be a defaultdict, but you could just use get with a 0 default. So go through the neighbors of each contaminated space, and add one to the dictionary for the neighbor's coordinates. After all the contaminated squares are checked, loop through the dictionary and use the totals to check for new contaminations. Add those to your contaminated list. RE: Help improve code efficiency - benbrown03 - Feb-19-2019 (Feb-12-2019, 08:22 PM)ichabod801 Wrote: When you do you make it sound so easy!! i have tried to implement this but i have had no luck. RE: Help improve code efficiency - ichabod801 - Feb-19-2019 Does this work? I don't have the files necessary to test it. import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib import colors import random import os import collections print("=== Cellular Automata for Radioactive Waste Disposal ===") # ======= User Inputs L = 20.0 # km numCells = 100 # This needs to remain the same for! totalTime = (40 * 12) # number of time steps (in months) print_every_n_steps = 480 # don't make this too small! print_time_every = 200 source_x = 0.2 # x - coordinate location of source of radio active waste source_y = 0.2 # y - coordinate location of course of radio active waste city_x = 12 city_y = 16 cell_city_x = int(numCells * (city_x / L)) cell_city_y = int(numCells * (city_y / L)) verbosity = 0 #Permeability Maximum Variable # *** Model Developement 3 *** Kmax = 3.5#Permeability Maximum Variable #K = np.loadtxt("perm.txt", dtype='f', delimiter=' ') Ktmp = np.loadtxt("perm.txt") K=Ktmp.astype(np.float) cmap = mpl.cm.jet norm = mpl.colors.Normalize(vmin=0, vmax = 1) fig, ax = plt.subplots() ax.imshow(K, cmap=cmap, norm=norm) ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2) ax.axes.get_xaxis().set_visible(False) ax.axes.get_yaxis().set_visible(False) results_dir = os.path.join(os.getcwd(),'solutions/') if not os.path.isdir(results_dir): os.makedirs(results_dir) plt.savefig(results_dir + "perm.png") cell_source_x = int(numCells * (source_x / L)) cell_source_y = int(numCells * (source_y / L)) count = 0 for n in range(0, 20): C = np.zeros((numCells ,numCells )) C[cell_source_x, cell_source_y] = 1; #1 is contaminated contaminated = set() contaminated.add((cell_source_x, cell_source_y)) iteration = str(n+1) print("Iteration:" + iteration) #C[cell_city_x][cell_city_y] = 1 #will show city for t in range(0,totalTime+1): if (t % print_time_every == 0) : print("Time = " + str(t)) Cnew = np.zeros((numCells ,numCells )) neighbors = collections.defaultdict(int) for source_x, source_y in contaminated: for off_x, off_y in [(0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)]: neighbor_x, neighbor_y = source_x + off_x, source_y + off_y if 0 <= neighbor_x < numCells and 0 <= neighbor_y <= numCells: neighbors[(neighbor_x, neighbor_y)] += 1 for coordinates, count in neighbors.items(): possible_x, possible_y = coordinates # *** Model Developement 2 *** p = (count/8)*((K[possible_x][possible_y])/Kmax) #gives probability n = random.uniform(0,1) if p>n: Cnew[possible_x][possible_y]=1#make this =p to give range of intensity? contaminated.add(coordinates) C = Cnew; # Set new contamination Matrix to old C. #this is how it goes through, adding on each time # Plot grid and save to file if (t % print_every_n_steps == 0) : cmap = mpl.cm.jet norm = mpl.colors.Normalize(vmin=0, vmax = 1) fig, ax = plt.subplots() ax.imshow(C, cmap=cmap, norm=norm) ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2) ax.axes.get_xaxis().set_visible(False) ax.axes.get_yaxis().set_visible(False) results_dir = os.path.join(os.getcwd(),'solutions/') if not os.path.isdir(results_dir): os.makedirs(results_dir) plt.savefig(results_dir + "Run:" + (iteration) + "_solution_time_" + str(t) + ".png") city = C[cell_city_x][cell_city_y] if city == 1: print("City Dead") count += 1 else: print("City Alive") print(count) RE: Help improve code efficiency - benbrown03 - Feb-19-2019 (Feb-19-2019, 08:04 PM)ichabod801 Wrote: import numpy as npthat looks to be loads faster thank you so much for your help i get this error come up after running it a few times Traceback (most recent call last): File "main.py", line 90, in <module> Cnew[possible_x][possible_y]=1#make this =p to give range of intensity? IndexError: index 100 is out of bounds for axis 0 with size 100 RE: Help improve code efficiency - ichabod801 - Feb-19-2019 Whoops, change line 81 to this: if 0 <= neighbor_x < numCells and 0 <= neighbor_y < numCells: RE: Help improve code efficiency - benbrown03 - Feb-20-2019 (Feb-19-2019, 08:04 PM)ichabod801 Wrote: if 0 <= neighbor_x < numCells and 0 <= neighbor_y < numCells: (Feb-19-2019, 10:08 PM)ichabod801 Wrote: Whoops, change line 81 to this:if 0 <= neighbor_x < numCells and 0 <= neighbor_y < numCells: It seems to be running well now thank you the solutions we get from it seems to be different to the previous code the spread of waste seems to be different. almost like it skips loads. RE: Help improve code efficiency - ichabod801 - Feb-20-2019 I've gone over the code, I don't see anything that should be making a functional difference. The only thing I explicitly left out was setting Cnew cells to 0, I figured that was taken care of by the initialization using np.zeros. I'm not sure what you mean by "skipping load" though. |