added single and multi core deviation
This commit is contained in:
parent
3e3af78ccd
commit
726cc6394f
@ -43,8 +43,8 @@ if __name__ == "__main__":
|
||||
random.seed(1000)
|
||||
# best single is 400/400 with 0,2 ca speed and 0,09 redraw / multi is 300/300 with 0.083
|
||||
neighborhood = MooreNeighborhood(EdgeRule.FIRST_AND_LAST_CELL_OF_DIMENSION_ARE_NEIGHBORS)
|
||||
ca = make_cellular_automaton(dimension=[100, 100], neighborhood=neighborhood, rule=TestRule(), state_class=MyState)
|
||||
ca_processor = CellularAutomatonProcessor(process_count=4, cellular_automaton=ca)
|
||||
ca = make_cellular_automaton(dimension=[400, 400], neighborhood=neighborhood, rule=TestRule(), state_class=MyState)
|
||||
ca_processor = CellularAutomatonProcessor(process_count=1, cellular_automaton=ca)
|
||||
|
||||
ca_window = PyGameFor2D(window_size=[1000, 800], cellular_automaton=ca)
|
||||
ca_window.main_loop(cellular_automaton_processor=ca_processor, ca_iterations_per_draw=10)
|
||||
ca_window.main_loop(cellular_automaton_processor=ca_processor, ca_iterations_per_draw=1)
|
||||
|
Binary file not shown.
@ -3,31 +3,30 @@ from ctypes import c_float, c_bool
|
||||
|
||||
|
||||
class CellState:
|
||||
_state_save_slot_count = 2
|
||||
"""
|
||||
This is the base class for all cell states.
|
||||
When using the cellular automaton display, inherit this class and implement get_state_draw_color.
|
||||
"""
|
||||
|
||||
_state_save_slot_count = 2
|
||||
|
||||
def __init__(self, initial_state=(0., ), draw_first_state=True):
|
||||
self._state_slots = [RawArray(c_float, initial_state) for i in range(self.__class__._state_save_slot_count)]
|
||||
self._active = [RawValue(c_bool, False) for i in range(self.__class__._state_save_slot_count)]
|
||||
self._active[0].value = True
|
||||
if draw_first_state:
|
||||
self._dirty = RawValue(c_bool, True)
|
||||
else:
|
||||
self._dirty = RawValue(c_bool, False)
|
||||
self._state_slots = [list(initial_state) for i in range(self.__class__._state_save_slot_count)]
|
||||
self._active = [False for i in range(self.__class__._state_save_slot_count)]
|
||||
self._active[0] = True
|
||||
self._dirty = draw_first_state
|
||||
|
||||
def is_active(self, iteration):
|
||||
return self._active[self.__calculate_slot(iteration)]
|
||||
return self._active[self._calculate_slot(iteration)]
|
||||
|
||||
def set_active_for_next_iteration(self, iteration):
|
||||
self._active[self.__calculate_slot(iteration + 1)].value = True
|
||||
self._active[self._calculate_slot(iteration + 1)] = True
|
||||
|
||||
def is_set_for_redraw(self):
|
||||
return self._dirty.value
|
||||
return self._dirty
|
||||
|
||||
def was_redrawn(self):
|
||||
self._dirty.value = False
|
||||
self._dirty = False
|
||||
|
||||
def get_state_of_last_iteration(self, current_iteration_index):
|
||||
return self.get_state_of_iteration(current_iteration_index - 1)
|
||||
@ -37,7 +36,7 @@ class CellState:
|
||||
:param iteration: Uses the iteration index, to differ between concurrent states.
|
||||
:return The state for this iteration.
|
||||
"""
|
||||
return self._state_slots[self.__calculate_slot(iteration)]
|
||||
return self._state_slots[self._calculate_slot(iteration)]
|
||||
|
||||
def set_state_of_iteration(self, new_state, iteration):
|
||||
""" Will set the new state for the iteration modulo number of saved states.
|
||||
@ -45,25 +44,50 @@ class CellState:
|
||||
:param iteration: Uses the iteration index, to differ between concurrent states.
|
||||
:return True if state has changed.
|
||||
"""
|
||||
changed = self._change_state(new_state, iteration)
|
||||
self._dirty |= changed
|
||||
self._active[self._calculate_slot(iteration)] = False
|
||||
return changed
|
||||
|
||||
def _change_state(self, new_state, iteration):
|
||||
current_state = self.get_state_of_iteration(iteration)
|
||||
|
||||
changed = False
|
||||
for i in range(len(current_state)):
|
||||
for i, ns in enumerate(new_state):
|
||||
try:
|
||||
if current_state[i] != new_state[i]:
|
||||
if current_state[i] != ns:
|
||||
changed = True
|
||||
current_state[i] = new_state[i]
|
||||
current_state[i] = ns
|
||||
except IndexError:
|
||||
raise IndexError("New State length or type is invalid!")
|
||||
|
||||
self._dirty.value |= changed
|
||||
self._active[self.__calculate_slot(iteration)].value = False
|
||||
return changed
|
||||
|
||||
def get_state_draw_color(self, iteration):
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def __calculate_slot(cls, iteration):
|
||||
def _calculate_slot(cls, iteration):
|
||||
return iteration % cls._state_save_slot_count
|
||||
|
||||
|
||||
class SynchronousCellState(CellState):
|
||||
def __init__(self, initial_state=(0., ), draw_first_state=True):
|
||||
super().__init__(initial_state, draw_first_state)
|
||||
self._state_slots = [RawArray(c_float, initial_state) for i in range(self.__class__._state_save_slot_count)]
|
||||
self._active = [RawValue(c_bool, False) for i in range(self.__class__._state_save_slot_count)]
|
||||
self._active[0].value = True
|
||||
self._dirty = RawValue(c_bool, draw_first_state)
|
||||
|
||||
def set_active_for_next_iteration(self, iteration):
|
||||
self._active[self._calculate_slot(iteration + 1)].value = True
|
||||
|
||||
def is_set_for_redraw(self):
|
||||
return self._dirty.value
|
||||
|
||||
def was_redrawn(self):
|
||||
self._dirty.value = False
|
||||
|
||||
def set_state_of_iteration(self, new_state, iteration):
|
||||
changed = self._change_state(new_state, iteration)
|
||||
self._dirty.value |= changed
|
||||
self._active[self._calculate_slot(iteration)].value = False
|
||||
return changed
|
||||
|
@ -17,11 +17,18 @@ class CellularAutomatonProcessor:
|
||||
self.ca = cellular_automaton
|
||||
cells = {i: (c.state, c.neighbours) for i, c in enumerate(self.ca.cells)}
|
||||
self.evolve_range = range(len(self.ca.cells))
|
||||
self.pool = multiprocessing.Pool(processes=process_count,
|
||||
initializer=_init_process,
|
||||
initargs=(cells,
|
||||
self.ca.evolution_rule,
|
||||
self.ca.evolution_iteration_index))
|
||||
self._evolve_method = lambda x, y: None
|
||||
|
||||
if process_count > 1:
|
||||
self.pool = multiprocessing.Pool(processes=process_count,
|
||||
initializer=_init_process,
|
||||
initargs=(cells,
|
||||
self.ca.evolution_rule,
|
||||
self.ca.evolution_iteration_index))
|
||||
self._evolve_method = self.pool.map
|
||||
else:
|
||||
_init_process(cells, self.ca.evolution_rule, self.ca.evolution_iteration_index)
|
||||
self._evolve_method = lambda x, y: list(map(x, y))
|
||||
for cell in self.ca.cells:
|
||||
del cell.neighbours
|
||||
|
||||
@ -31,7 +38,7 @@ class CellularAutomatonProcessor:
|
||||
|
||||
def evolve(self):
|
||||
self.ca.evolution_iteration_index.value += 1
|
||||
self.pool.map(_process_routine, self.evolve_range)
|
||||
self._evolve_method(_process_routine, self.evolve_range)
|
||||
|
||||
|
||||
global_cells = None
|
||||
|
Loading…
Reference in New Issue
Block a user