Commit 506862db authored by Chanelle Lee's avatar Chanelle Lee
Browse files

Making progress on population tests. Separated out the aggregation function...

Making progress on population tests. Separated out the aggregation function for readability. Completed tests up to and including aggregation. All pass.
parent b07d50ec
...@@ -10,6 +10,7 @@ class Population(object): ...@@ -10,6 +10,7 @@ class Population(object):
Contains instances of the agent class as a list and manipulates them to Contains instances of the agent class as a list and manipulates them to
simulate movement, aggregation and receiving evidence. simulate movement, aggregation and receiving evidence.
""" """
def __init__(self, size, numOptions, distrust, w): def __init__(self, size, numOptions, distrust, w):
""" """
Initialising method for Population class Initialising method for Population class
...@@ -32,9 +33,9 @@ class Population(object): ...@@ -32,9 +33,9 @@ class Population(object):
list containing instances of the Agent class list containing instances of the Agent class
""" """
self._size = size self._size = int(size)
self._numOptions = numOptions self._numOptions = int(numOptions)
self._agents = self.initAgents(distrust, w) self._agents = self.initAgents(float(distrust), float(w))
def initAgents(self, distrust, w): def initAgents(self, distrust, w):
""" """
...@@ -42,8 +43,8 @@ class Population(object): ...@@ -42,8 +43,8 @@ class Population(object):
""" """
# Initialise agents with completely equivalent beliefs / uniform # Initialise agents with completely equivalent beliefs / uniform
populationBeliefs = ((1.0 / self._numOptions) populationBeliefs = ((1.0 / self._numOptions) *
* np.ones((self._size, self._numOptions))) np.ones((self._size, self._numOptions)))
agents = [Agent(i, belief, distrust, w, self._numOptions) agents = [Agent(i, belief, distrust, w, self._numOptions)
for i, belief in enumerate(populationBeliefs)] for i, belief in enumerate(populationBeliefs)]
return agents return agents
...@@ -67,38 +68,51 @@ class Population(object): ...@@ -67,38 +68,51 @@ class Population(object):
np.random.shuffle(movedAgents) np.random.shuffle(movedAgents)
return movedAgents return movedAgents
def aggregationWholePopulation(self, agents):
# Define the neighbourhood as the whole population
neighbourhood = agents
# One agent calculates new belief from pooling
retBelief = neighbourhood[0].aggregate(neighbourhood[1:])
# All agents update to new belief
if retBelief is not None:
for a in neighbourhood:
a.setBelief(retBelief)
def aggregationLocalised(self, agents, neighbourhoodSize):
# Need to store the beliefs initially so that they don't change during
# the calculations
retBeliefs = []
for i, a in enumerate(agents):
# Locate agent's neighbourhood
indices = range(i + 1, i + neighbourhoodSize)
neighbourhood = np.array(agents).take(indices,
mode='wrap')
# Calculate pooling belief
retBeliefs.append(a.aggregate(neighbourhood))
# Now can update all the beliefs of all agents
for i, a in enumerate(agents):
if retBeliefs[i] is not None:
a.setBelief(retBeliefs[i])
def aggregation(self, movedAgents, neighbourhoodSize): def aggregation(self, movedAgents, neighbourhoodSize):
""" """
Picks the last k agents for aggregation. Single agent performs the Picks the last k agents for aggregation. Single agent performs the
aggregation calculation and then all update on returned belief. aggregation calculation and then all update on returned belief.
N.B. Assumes movedAgents is shuffled list of population._agents
""" """
# No aggregation if neighbourhoodSize >= self._size:
if neighbourhoodSize == 0: # Population aggregates as a whole
pass self.aggregationWholePopulation(movedAgents)
# Population aggregates as a whole elif neighbourhoodSize > 0:
elif neighbourhoodSize == self._size: # Population aggregates in subsets
# Define the neighbourhood as the whole population self.aggregationLocalised(movedAgents, neighbourhoodSize)
neighbourhood = movedAgents
# One agent calculates new belief from pooling
retBelief = neighbourhood[0].aggregate(neighbourhood[1:])
# All agents update to new belief
if retBelief is not None:
for a in neighbourhood:
a.setBelief(retBelief)
# Population aggregates in subsets
else: else:
for i, a in enumerate(movedAgents): # No aggregation
# Locate agent's neighbourhood pass
indices = range(i, i + neighbourhoodSize)
neighbourhood = np.array(movedAgents).take(indices,
mode='wrap')
# Calculate pooling belief
retBelief = a.aggregate(neighbourhood)
if retBelief is not None:
a.setBelief(retBelief)
def receiveEvidence(self, evidence): def receiveEvidence(self, evidence):
""" """
......
import pytest
import numpy.testing
from noComparisonSimulation.population import *
from noComparisonSimulation.agent import Agent
def test_initialise_valid():
size = 10
num_options = 4
distrust = 0.001
w = 1.0
expected_belief = np.array([0.25, 0.25, 0.25, 0.25])
population = Population(size, num_options, distrust, w)
# Check population attributes
assert population._size == size
assert population._numOptions == num_options
# Check initialised agents correctly
assert len(population._agents) == size
assert [agent.idNum for agent in population._agents] == list(range(size))
for agent in population._agents:
assert isinstance(agent, Agent)
assert agent._distrust == distrust
assert agent._w == w
assert len(agent._belief) == num_options
numpy.testing.assert_almost_equal(agent._belief, expected_belief,
decimal=4)
def test_retBeliefs():
size = 10
num_options = 4
population = Population(size, num_options, 0.001, 1.0)
numpy.testing.assert_almost_equal(population.retBeliefs(),
1.0 / num_options * np.ones((size,
num_options)
),
decimal=4)
def test_moveAgents():
population = Population(10, 4, 0.001, 1.0)
pop_before_move = population._agents
moved_agents = population.moveAgents()
pop_after_move = population._agents
# Check that move doesn't affect the populations list of agents
assert pop_before_move == pop_after_move
# Check that all the agents are still accounted for
assert set(pop_before_move) == set(moved_agents)
def test_aggregationWholePopulation_valid_no_change():
population = Population(10, 4, 0.001, 1.0)
population.aggregationWholePopulation(population._agents)
numpy.testing.assert_almost_equal(population.retBeliefs(),
0.25 * np.ones((10, 4)),
decimal=4)
def test_aggregationWholePopulation_valid():
population = Population(3, 3, 0.001, 1.0)
population_beliefs_before_agg = np.array([[0.6, 0.3, 0.1],
[0.0, 0.25, 0.75],
[0.1, 0.2, 0.7]])
population_beliefs_after_agg = np.array([[0.0, 0.2222, 0.7778],
[0.0, 0.2222, 0.7778],
[0.0, 0.2222, 0.7778]])
# Unfortunately hacky way of getting variation in population beliefs
for i, agent in enumerate(population._agents):
agent.setBelief(population_beliefs_before_agg[i])
population.aggregationWholePopulation(population._agents)
numpy.testing.assert_almost_equal(population.retBeliefs(),
population_beliefs_after_agg,
decimal=4)
def test_aggregationLocalised_valid_no_change():
population = Population(10, 4, 0.001, 1.0)
population.aggregationLocalised(population._agents, 3)
numpy.testing.assert_almost_equal(population.retBeliefs(),
0.25 * np.ones((10, 4)),
decimal=4)
def test_aggregationLocalised_valid():
population = Population(3, 3, 0.001, 1.0)
population_beliefs_before_agg = np.array([[0.6, 0.3, 0.1],
[0.0, 0.25, 0.75],
[0.1, 0.2, 0.7]])
population_beliefs_after_agg = np.array([[0.0, 0.5, 0.5],
[0.0, 0.0870, 0.9130],
[0.3158, 0.3158, 0.3684]])
# Unfortunately hacky way of getting variation in population beliefs
for i, agent in enumerate(population._agents):
agent.setBelief(population_beliefs_before_agg[i])
population.aggregationLocalised(population._agents, 2)
numpy.testing.assert_almost_equal(population.retBeliefs(),
population_beliefs_after_agg,
decimal=4)
@pytest.mark.parametrize("neighbourhoodSize, expected", [
(0, np.array([[0.6, 0.3, 0.1],
[0.0, 0.25, 0.75],
[0.1, 0.2, 0.7]])),
(-1, np.array([[0.6, 0.3, 0.1],
[0.0, 0.25, 0.75],
[0.1, 0.2, 0.7]])),
(2, np.array([[0.0, 0.5, 0.5],
[0.0, 0.0870, 0.9130],
[0.3158, 0.3158, 0.3684]])),
(3, np.array([[0.0, 0.2222, 0.7778],
[0.0, 0.2222, 0.7778],
[0.0, 0.2222, 0.7778]])),
(10, np.array([[0.0, 0.2222, 0.7778],
[0.0, 0.2222, 0.7778],
[0.0, 0.2222, 0.7778]]))
])
def test_aggregation_valid(neighbourhoodSize, expected):
population = Population(3, 3, 0.001, 1.0)
population_beliefs_before_agg = np.array([[0.6, 0.3, 0.1],
[0.0, 0.25, 0.75],
[0.1, 0.2, 0.7]])
# Unfortunately hacky way of getting variation in population beliefs
for i, agent in enumerate(population._agents):
agent.setBelief(population_beliefs_before_agg[i])
population.aggregation(population._agents, neighbourhoodSize)
numpy.testing.assert_almost_equal(population.retBeliefs(),
expected,
decimal=4)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment