0

I am implementing cellular automata (CA) to simulate tumor growth. My goal is to simulate CA in three dimensions. However, my code is very slow. I was hoping to simulate 10^6 cells in reasonable time (within 1 hour). Is there any way to speed up my code? I have hard time to find bottleneck of my code.

My code is:

   for generation in np.arange(100):
        print(len(TC.keys()))
        keys = list(TC.keys())
        keys = np.array(keys)
        for cell in np.ndenumerate(keys): # for each tumor cell
            cell_id = cell[1]
            division, migration, death = TC[cell_id].action(TC_pdivision, TC_pmigration, TC_pdeath)
            if death:
                del TC[cell_id] # remove tumor cell from dictionary
            else:  
                # find free spot
                ngh = TC[cell_id].freeSpots(cells,TC[cell_id].neighbors(TC[cell_id].x,TC[cell_id].y,TC[cell_id].z))      
               if np.size(ngh)>0:
                   ngh = np.reshape(ngh,[int(np.shape(ngh)[0]/3),3])
                   x,y,z = spot(ngh)
                  cell_id_new = positionToID(x,y,z)
                  if migration:
                     TC[cell_id_new] = TC.pop(cell_id)
                  elif division:
                     TC[cell_id_new] = TumorCell(x, y, z)

That is, each tumor is defined with position in three dimensions (x,y,z). Each tumor cell is one entry in dictionary. I am using function PositionToID function to convert (x,y,z):
def positionToID(x,y,z): id = int(x + (y - 1) * gridSize + (z - 1) * gridSize * gridSize) return id

So, tumor cell is defined as follows:

TC[id] = [some_tumor_cell_properties]

Function neighbor generate (x,y,z) of all 26 adjacent cells, and freespots is:

    def freeSpots(self, cells, ngh):
    freeSpots = np.array([])
    for neighbor in ngh:
        currNeighbor = tuple(neighbor)
        if currNeighbor not in cells:
            freeSpots = np.append(freeSpots, np.array(currNeighbor))
    return freeSpots

responsible of checking for each adjacent cell if it is occupied or not. Freespots is fast so it is not an issue with this function.

I guess, the problem is with iterator. I tried to iterate over all tumor cells by extracting keys of dictionary TC (tumor cell) and converting them to numpy.array. Next, I applied ndenumare for iteration over all cells.

Is there any way to improve performance of my code? Thank you in advance for your help.

Emilia
  • 21
  • 3
  • Pick a different language? – Scott Hunter Dec 23 '19 at 15:26
  • You can try the timit module to locate where your code is slow. https://docs.python.org/3.8/library/timeit.html From a glance it could be related to all the arrays you are creating, but I need to look into it more. – user2379875 Dec 23 '19 at 15:34
  • Stop using numpy. Using it like this is slow. For example, `freeSpots = np.append(freeSpots, np.array(currNeighbor))` is quadratic time – juanpa.arrivillaga Dec 23 '19 at 17:04
  • very good point, I modified heavily freeSpots function. After change, my code for 10^4 cells run in about 20 seconds. And for 10^6 the code run for 6 minutes. Is it the best what can be done? – Emilia Dec 23 '19 at 18:56

0 Answers0