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):
Contains instances of the agent class as a list and manipulates them to
simulate movement, aggregation and receiving evidence.
"""
def __init__(self, size, numOptions, distrust, w):
"""
Initialising method for Population class
......@@ -32,9 +33,9 @@ class Population(object):
list containing instances of the Agent class
"""
self._size = size
self._numOptions = numOptions
self._agents = self.initAgents(distrust, w)
self._size = int(size)
self._numOptions = int(numOptions)
self._agents = self.initAgents(float(distrust), float(w))
def initAgents(self, distrust, w):
"""
......@@ -42,8 +43,8 @@ class Population(object):
"""
# Initialise agents with completely equivalent beliefs / uniform
populationBeliefs = ((1.0 / self._numOptions)
* np.ones((self._size, self._numOptions)))
populationBeliefs = ((1.0 / self._numOptions) *
np.ones((self._size, self._numOptions)))
agents = [Agent(i, belief, distrust, w, self._numOptions)
for i, belief in enumerate(populationBeliefs)]
return agents
......@@ -67,18 +68,9 @@ class Population(object):
np.random.shuffle(movedAgents)
return movedAgents
def aggregation(self, movedAgents, neighbourhoodSize):
"""
Picks the last k agents for aggregation. Single agent performs the
aggregation calculation and then all update on returned belief.
"""
# No aggregation
if neighbourhoodSize == 0:
pass
# Population aggregates as a whole
elif neighbourhoodSize == self._size:
def aggregationWholePopulation(self, agents):
# Define the neighbourhood as the whole population
neighbourhood = movedAgents
neighbourhood = agents
# One agent calculates new belief from pooling
retBelief = neighbourhood[0].aggregate(neighbourhood[1:])
......@@ -87,18 +79,40 @@ class Population(object):
if retBelief is not None:
for a in neighbourhood:
a.setBelief(retBelief)
# Population aggregates in subsets
else:
for i, a in enumerate(movedAgents):
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, i + neighbourhoodSize)
neighbourhood = np.array(movedAgents).take(indices,
indices = range(i + 1, i + neighbourhoodSize)
neighbourhood = np.array(agents).take(indices,
mode='wrap')
# Calculate pooling belief
retBelief = a.aggregate(neighbourhood)
if retBelief is not None:
a.setBelief(retBelief)
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):
"""
Picks the last k agents for aggregation. Single agent performs the
aggregation calculation and then all update on returned belief.
N.B. Assumes movedAgents is shuffled list of population._agents
"""
if neighbourhoodSize >= self._size:
# Population aggregates as a whole
self.aggregationWholePopulation(movedAgents)
elif neighbourhoodSize > 0:
# Population aggregates in subsets
self.aggregationLocalised(movedAgents, neighbourhoodSize)
else:
# No aggregation
pass
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