In [14]:
%pylab inline
%load_ext autoreload
%autoreload 2
%load_ext Cython
from InstanceVariables import InstanceVariables
import SimulationInstance
import SimulationInstanceVectorized
import Cython_resources.main as sim_cyth
Before looking at the results of each simulation instance, both vectorized and not, let us first define the variables used and their values for each. The following parameter values are those used in the Santos, Santos, Pacheco paper supporting material.
As well as this, let us define 4 of the main social norms investigated
In [14]:
SternJudging = [[1, 0 ],
[0, 1]]
SimpleStanding = [[1, 1],
[0, 1]]
Shunning = [[1, 0],
[0, 1]]
ImageScore = [[1, 1],
[0, 0]]
Now a function containing all the predefined variables for use in testing:
In [15]:
def SSP(population_size, generations, socialnorm):
runs = 1
mutation_rate = np.power(10*population_size, -1)
execution_error = 0.08
reputation_assignment_error = 0.01
private_assessment_error = 0.01
reputation_update_probability = 1
cost = 1
benefit = 5
SimulationInstance.simulate(runs, generations, population_size,
mutation_rate, execution_error, reputation_assignment_error, private_assessment_error,
reputation_update_probability, socialnorm,
cost, benefit)
In [15]:
%%timeit
SSP(50, 3*np.power(10,3), SternJudging, optimized=False)
The best case was 4.73 seconds in the unoptimized simulation, now if we test the optimized simulation.
In [14]:
%%timeit
SSP(50, 3*np.power(10,3), SternJudging, optimized=True)
The best case was 2.48 seconds for the optimized simulation. Compared to the 4.73 seconds it took for the unoptimized, we have a almost twice as quick of a simulation. However before we say it is ONLY twice as quick. Let us give the example of a population of size 1000, 20 times larger than what we've tested. Given we are only testing these with 3000 generations compared to the 300 000 generations required for the simulation to be accurate, it is simply to measure the speedup.
In [18]:
%%timeit
SSP(1000, 3*np.power(10,3), SternJudging, optimized=False)
As you can see, the amount of time the unoptimized program requires to run only 3000 generations with a population of 1000 is 1 minute and 29 seconds.
In [6]:
%%timeit
SSP(1000, 3*np.power(10,3), SternJudging, optimized=True)
Now for the optimized simulation, the time taken is only 1.61 seconds, which is extremely close to the time taken for a population of size 50.
In [4]:
runs = 1
generations = 3*np.power(10, 2)
population_size = 10
socialnorm = [[0, 0], [0, 1]]
mutation_rate = np.power(10.0*population_size, -1.0)
execution_error = 0.08
reputation_assignment_error = 0.01
private_assessment_error = 0.01
reputation_update_probability = 1.0
cost = 1
benefit = 5
variables = InstanceVariables(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
Test the fitness function for small population sizes and then for larger population sizes
In [31]:
%%timeit
SimulationInstance.fitness_function(0, 1, variables)
In [32]:
%%timeit
SimulationInstanceVectorized.fitness_function(0, 1, variables)
In [33]:
population_size = 50
variables = InstanceVariables(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
In [34]:
%%timeit
SimulationInstance.fitness_function(0, 1, variables)
In [35]:
%%timeit
SimulationInstanceVectorized.fitness_function(0, 1, variables)
In [36]:
population_size = 100
variables = InstanceVariables(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
In [37]:
%%timeit
SimulationInstance.fitness_function(0, 1, variables)
In [38]:
%%timeit
SimulationInstanceVectorized.fitness_function(0, 1, variables)
In [11]:
non_vectorized_times = []
vectorized_times = []
p_sizes = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 150, 160, 180, 200, 240, 280, 320, 400, 500, 600]
for p_size in p_sizes:
population_size = p_size
variables = InstanceVariables(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
non_vector_result = %timeit -o SimulationInstance.fitness_function(0, 1, variables)
vector_result = %timeit -o SimulationInstanceVectorized.fitness_function(0, 1, variables)
non_vectorized_times.append(non_vector_result)
vectorized_times.append(vector_result)
In [12]:
v_times = [time_obj.best for time_obj in vectorized_times]
non_v_times = [time_obj.best for time_obj in non_vectorized_times]
line_vectorized, = plt.plot(p_sizes, v_times, linewidth=1.5, label='Vectorized')
line_non_vectorized, = plt.plot(p_sizes, non_v_times, label='Non vectorized', marker='^')
# plt.ylim((-0.01, 1.05))
# plt.xlim((-0.1, 125))
plt.legend(handles=[line_vectorized, line_non_vectorized], loc='upper left', bbox_to_anchor=(1,1))
plt.grid(b=True, which='both')
plt.rcParams["figure.figsize"][0] = 9
plt.rcParams["figure.figsize"][1] = 5
# plt.xticks([10*i for i in range(13)])
# plt.yticks([0.1*i for i in range(11)])
plt.ylabel('Run time (s)')
plt.xlabel('Population size')
plt.show()
In [17]:
runs = 1
generations = 3*np.power(10, 2)
population_size = 10
socialnorm = np.array([[0, 0], [0, 1]])
mutation_rate = np.power(10.0*population_size, -1.0)
execution_error = 0.08
reputation_assignment_error = 0.01
private_assessment_error = 0.01
reputation_update_probability = 1.0
cost = 1
benefit = 5
In [18]:
%%timeit
sim_cyth.simulation_instance.run_instance(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
In [19]:
%%timeit
SimulationInstance.simulate(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
In [29]:
cython_time_objects = []
pure_python_time_objects = []
python_vectorized_time_objects = []
p_sizes = [5, 10, 20, 30, 40, 50, 60, 70, 90, 110, 130, 160, 180]
for p_size in p_sizes:
population_size = p_size
variables = InstanceVariables(runs, generations, population_size, mutation_rate,
execution_error, reputation_assignment_error,
private_assessment_error, reputation_update_probability,
socialnorm, cost, benefit)
cython_result = %timeit -r 1 -o sim_cyth.simulation_instance.run_instance(runs, generations, population_size, mutation_rate, \
execution_error, reputation_assignment_error, \
private_assessment_error, reputation_update_probability, \
socialnorm, cost, benefit)
pure_python_result = %timeit -r 1 -o SimulationInstance.simulate(runs, generations, population_size, mutation_rate, \
execution_error, reputation_assignment_error, \
private_assessment_error, reputation_update_probability, \
socialnorm, cost, benefit)
pyth_vector_result = %timeit -r 1 -o SimulationInstanceVectorized.run_instance(runs, generations, population_size, mutation_rate, \
execution_error, reputation_assignment_error, \
private_assessment_error, reputation_update_probability, \
socialnorm, cost, benefit)
cython_time_objects.append(cython_result)
pure_python_time_objects.append(pure_python_result)
python_vectorized_time_objects.append(pyth_vector_result)
In [34]:
cyth_times = [time_obj.best for time_obj in cython_time_objects]
pure_pyth_times = [time_obj.best for time_obj in pure_python_time_objects]
pyth_vector_times = [time_obj.best for time_obj in python_vectorized_time_objects]
line_cyth, = plt.plot(p_sizes, cyth_times, linewidth=1.5, label='Cython')
line_pure_pyth, = plt.plot(p_sizes, pure_pyth_times, label='Pure Python', marker='^')
line_vectorized, = plt.plot(p_sizes, pyth_vector_times, label='Python Vectorized', marker='o')
# plt.ylim((-0.01, 1.05))
# plt.xlim((-0.1, 125))
plt.legend(handles=[line_cyth, line_pure_pyth, line_vectorized], loc='upper left', bbox_to_anchor=(1,1))
plt.grid(b=True, which='both')
plt.rcParams["figure.figsize"][0] = 9
plt.rcParams["figure.figsize"][1] = 5
# plt.xticks([10*i for i in range(13)])
# plt.yticks([0.1*i for i in range(11)])
plt.ylabel('Run time (s)')
plt.xlabel('Population size')
plt.show()
In [ ]: