adjsim package

Submodules

adjsim.analysis module

Analysis module.

This module contains trackers, which are used to extract data from the simulation at simulation runtime.

Designed and developed by Sever Topan.

class adjsim.analysis.AgentCountTracker

Bases: adjsim.analysis.Tracker

Counts the number of agents at each timestep.

data

list – The number of agents at each timestep.

__call__(simulation)

Tracks the number of agents in the simulation.

plot(block=True)

Plots the data attribute using pyplot.

class adjsim.analysis.AgentTypeCountTracker

Bases: adjsim.analysis.Tracker

Counts the number of agents at each timestep by type.

data

dict – The number of agents at each timestep, organized by type entries in this dictionary.

__call__(simulation)

Tracks the number of agents in the simulation by type.

plot(block=True)

Plots the data attribute using pyplot.

class adjsim.analysis.QLearningHistoryTracker(qlearning_module)

Bases: adjsim.analysis.Tracker

Tracks the loss history of a given QLearningDecision module.

data

dict – A list of agent losses (per timestep).

__call__(simulation)

No-op; data is stored upon simulation completion

plot(block=True)

Plots the data attribute using pyplot.

class adjsim.analysis.Tracker

Bases: object

The abstract base tracker object. Trackers used to analyze the simulation.

All trackers must derive from this object. Trackers obtain data from the simulation after each iteration and must store the obtained data in their data attribute. This is done by implementing the __call__ method, and storing relevant data from the call method into the tracker’s data attribute.

data

object – the data to store in the tracker.

__call__(simulation)

Tracks data from the simulation.

This functor call method is called after each simulation step. Desired data must be stored into the tracker’s data attribute.

Parameters:simulation (Simulation) – The simulation to track.
plot()

Plots the data attribute using pyplot.

adjsim.callback module

Callback module.

This module contains callback objects, which are used to invoke user code at specific times during the simulation.

Designed and developed by Sever Topan.

class adjsim.callback.AgentChangedCallback

Bases: adjsim.callback.SingleParameterCallback

Callback specialization class for changed agent properties.

class adjsim.callback.Callback

Bases: object

The abstract base callback object. Callbacks are events that are called at specific times during the simulation.

subscriptions

set – The callables that will be called.

__call__(callback)

Calls the callbacks.

is_registered(callback)

Checks if a callback is registered.

register(*args, **kwargs)

Registers a callback.

unregister(*args, **kwargs)

Unregisters a callback.

class adjsim.callback.SimulationMilestoneCallback

Bases: adjsim.callback.SingleParameterCallback

Callback specialization class for simulation milestones.

class adjsim.callback.SingleParameterCallback

Bases: adjsim.callback.Callback

Callback class for a single parameter callback.

__call__(parameter)

Calls all suscribed callables with the given parameter.

Parameters:parameter (object) – the callback parameter.
is_registered(callback)

Checks callback registration.

Parameters:callback (callable) – the callback.
Returns:True if the callback has previously been registered
register(callback)

Registers the callback.

Parameters:callback (callable) – the callback.
unregister(callback)

Unregisters the callback.

Parameters:callback (callable) – the callback.

adjsim.color module

Color module.

Contains color constants for visual simulations.

Designed and developed by Sever Topan.

adjsim.core module

Core adjsim module.

This module contains the core features of the ABM engine, specifically, the Simulation and Agent objects and the facilities to allow them to interact with one another.

Designed and developed by Sever Topan.

class adjsim.core.Agent

Bases: object

The base Agent class.

All agents added to a simulation must be derived from this.

actions

_ActionSuite – The _ActionSuite container that holds all actions.

decision

decision.Decision – The decision object that the agent will use to determine action invocation.

order

int – The order in which this agent will take its step relative to others. Equal orders result in no step order guarantee.

step_complete

bool – whether or not the agent has completed its step.

id

uuid – A unique identifier for the agent. Read-only.

class adjsim.core.Simulation

Bases: object

The base Simulation object.

This is the core object that is used to run adjsim simulations.

callbacks

_CallbackSuite – The Simulation’s callbacks.

agents

_AgentSuite – The Simulation’s agents.

trackers

_TrackerSuite – The Simulation’s trackers.

indices

_IndexSuite – The Simulation’s indices.

end_condition

callable – The Simulation’s end condition.

time

int – The current Simulation time. Reflects step count.

end()

Ends a simulation instance.

Note

This function triggers the simulation_ended callback.

simulate(num_timesteps)

Performs a given number of simulation steps while handling simulation start/end.

Note

This convinience method simply calls start, step(num_timesteps), and end.

Parameters:num_timesteps (int) – the number of timesteps to simulate.
start()

Starts a simulation instance.

Note

This must be called before a call to the step function. This function triggers the simulation_started callback.

step(num_timesteps=1)

Performs a given number of simulation steps.

Note

This is where ABM loop occurs. This function must be called after the simulation has been started.

Parameters:num_timesteps (int) – the number of timesteps to simulate.
class adjsim.core.SpatialAgent(pos=array([0, 0]))

Bases: adjsim.core.Agent

The Spatial Agent class.

Builds upon Agent to incorporate 2d spatial coordinates representing the agent’s position. Any agent that desires to have the movement callback invoked when position is changed should inherit from this class.

DEFAULT_POS = array([0, 0])
pos

np.ndarray – Obtains agent position. The returned array is NOT writeable.

x

int – Obtains agent’s x-coordinate.

y

int – Obtains agent’s y-coordinate.

class adjsim.core.VisualAgent(pos=array([0, 0]), size=10, color=<PyQt5.QtGui.QColor object>, style=1)

Bases: adjsim.core.SpatialAgent

The Visual Agent class.

Builds upon SpatialAgent to allow for agents to be visualized when simulated with a VisualSimulation. Visual agents appear as circles with visual properties delineated by this class’s attributes.

size

int – The size of the visualized agent.

color

QtGui.QColor – The color of the visualized agent.

style

QtCore.Qt.Pattern – The pattern of the visualized agent.

DEFAULT_COLOR = <PyQt5.QtGui.QColor object>
DEFAULT_SIZE = 10
DEFAULT_STYLE = 1
class adjsim.core.VisualSimulation

Bases: adjsim.core.Simulation

The Visual Simulation object.

This derivation of the Simulation object uses PyQt5 to render a visual representation of an active simulation.

step(num_timesteps=1)

Perform a given number of visual simulation steps.

Parameters:num_timesteps (int) – The number of timesteps to simulate.

adjsim.decision module

Decision module.

This module contains the different decision functors used by agents to call actions. Also contains helper classes used by these.

Designed and developed by Sever Topan.

class adjsim.decision.ArrayConstraint

Bases: object

Abstract base class for array constraints.

satisfies(value)
class adjsim.decision.Decision

Bases: object

The base decision class.

A decision is a functor that performs selective and structured agent computation during a simulation step.

__call__(simulation, source)

Perform computation.

class adjsim.decision.DecisionMutableBool(perturbation_scale=0.3)

Bases: adjsim.decision.DecisionMutableValue

Contains a boolean that the decision module will modify.

A decision mutable bool represents a value that a particular decision module will try to optimize for. perturbation_scale relates to the probability the locus will flip its value.

DEFAULT_PERTURBATION_SCALE = 0.3
perturbation_scale

float – Obtain the perturbation scale.

value

bool – Obtain the value.

class adjsim.decision.DecisionMutableBoolArray(shape, perturbation_scale=1.0)

Bases: adjsim.decision.DecisionMutableValue

Contains an array of booleans that the decision module will modify.

A decision mutable bool array represents a value that a particular decision module will try to optimize for. perturbation_scale relates to the probability the locus will flip its value.

DEFAULT_PERTURBATION_SCALE = 1.0
perturbation_scale

float – Obtain the perturbation scale.

shape

np.array – Obtain the array shape.

value

np.array – Obtain the value.

class adjsim.decision.DecisionMutableFloat(min_val, max_val, perturbation_scale=1.0)

Bases: adjsim.decision.DecisionMutableValue

Contains a bounded float that the decision module will modify.

A decision mutable float represents a value that a particular decision module will try to optimize for. This float must be given viable bounds between which the decision module will try to find an optimal value to fulfill its loss function.

Bounds are inclusive: value in [min_val, max_val]. perturbation_scale relates to the scale of the np.random.normal.

DEFAULT_PERTURBATION_SCALE = 1.0
max_val

float – Obtain the maximum bound.

min_val

float – Obtain the minimum bound.

perturbation_scale

float – Obtain the perturbation scale.

value

float – Obtain the value.

class adjsim.decision.DecisionMutableFloatArray(shape, constraint, perturbation_scale=1.0)

Bases: adjsim.decision.DecisionMutableValue

Contains an float array that the decision module will modify.

A decision mutable float array represents a value that a particular decision module will try to optimize for. This float must be given viable constraints between which the decision module will try to find an optimal value to fulfill its loss function.

A constraint must be specified.

perturbation_scale relates to the scale of the np.random.normal.

DEFAULT_PERTURBATION_SCALE = 1.0
constraint

ArrayContraint – Obtain a copy of the constraint.

perturbation_scale

float – Obtain the perturbation scale.

shape

np.array – Obtain the array shape.

value

np.array – Obtain the value.

class adjsim.decision.DecisionMutableInt(min_val, max_val, perturbation_scale=1.0)

Bases: adjsim.decision.DecisionMutableValue

Contains a bounded integer that the decision module will modify.

A decision mutable integer represents a value that a particular decision module will try to optimize for. This integer must be given viable bounds between which the decision module will try to find an optimal value to fulfill its loss function.

Bounds are inclusive: value in [min_val, max_val]. perturbation_scale relates to the scale of the np.random.normal.

DEFAULT_PERTURBATION_SCALE = 1.0
max_val

int – Obtain the maximum bound.

min_val

int – Obtain the minimum bound.

perturbation_scale

float – Obtain the perturbation scale.

value

int – Obtain the value.

class adjsim.decision.DecisionMutableIntArray(shape, constraint, perturbation_scale=1.0)

Bases: adjsim.decision.DecisionMutableValue

Contains an integer array that the decision module will modify.

A decision mutable integer array represents a value that a particular decision module will try to optimize for. This integer must be given viable constraints between which the decision module will try to find an optimal value to fulfill its loss function.

A constraint must be specified. SumContraint is not supported. perturbation_scale relates to the scale of the np.random.normal.

DEFAULT_PERTURBATION_SCALE = 1.0
constraint

ArrayContraint – Obtain a copy of the constraint.

perturbation_scale

float – Obtain the perturbation scale.

shape

np.array – Obtain the array shape.

value

np.array – Obtain the value.

class adjsim.decision.DecisionMutableValue

Bases: object

Base class for decision mutable objects.

A decision mutable value represents a value that a particular decision module will try to optimize for. They are used to parameterize functions within AdjSim’s definition of an ‘action’.

class adjsim.decision.FunctionalDecision(perception, loss)

Bases: adjsim.decision.Decision

An abastract decision class that uses adjsim’s functional step implementation.

Essentially, the agent acts as a function. The inputs to this function are retrieved from the perception callable. This is referred to as an observation. The observation is then used in the rest of the decision process to decide which action to call, and what to set decision mutable values to.

The loss callable is used to determine how well an agent is performing. The decision module can employ reinforcement learning through optimizing the loss function via intelligently selected action premises.

Parameters:
  • perception (callable) – The perception callable. Can return any value.
  • loss (callable) – The loss callable. Must return a float-convertible object.
__call__(simulation, source)

Perform computation.

class adjsim.decision.NoCastDecision

Bases: object

A decision to not do any computation during a simulation step.

__call__(simulation, source)

Perform no computation.

class adjsim.decision.PerturbativeQLearningDecision(perception, loss, simulation, input_file_name='C:\Users\Sev\Anaconda3\envs\adjsim\lib\site-packages\sphinx\__main__.qlearning.pkl', output_file_name='C:\Users\Sev\Anaconda3\envs\adjsim\lib\site-packages\sphinx\__main__.qlearning.pkl', discount_factor=0.95, nonconformity_probability=0.3, perturbation_config=<adjsim.decision.PerturbativeQLearningDecision.Config object>)

Bases: adjsim.decision.QLearningDecision

A decision module based on Q-Learning.

This module employs Q-Learning (https://en.wikipedia.org/wiki/Q-learning), a reinforcement learning technique, to incrementally enhance its performance as measured by the provided loss function. Over many simulations, the performance of the agent will be increased.

The difference between this and the canonical QLearning decision module is the non-conformity behaviour. Non-conforming calls will perturb existing action premises instead of generating completely new ones

Parameters:
  • perception (callable) – The perception callable. Can return any value.
  • loss (callable) – The loss callable. Must return a float-convertible object.
  • callbacks (_CallbackSuite) – The simulation’s callback suite. Used by the decision module to register neccessary callbacks.
  • input_file_name (string) – The name of the .pkl file from which to read a previous Q-Table. The previous Q-Table will be used as a starting point in the current simulation.
  • output_file_name (string) – The name of the .pkl file where the new Q-Table will be saved.
  • discount_factor (float) – The dscount factor (gamma) used in the temporal-differnce calculation of agent loss. Defaults to 0.95.
  • nonconformity_probability (float) – When an agent finds an existing entry in its Q-Table, it will still choose to perform a random action with a probability equivalent to nonconformity_probability. Defaults to 0.3.
class Config(reorder_probability=0.2, ignore_proabability=0.3, local_perturbation_probability=0.7)

Bases: object

Configuration object for Perturbative Q-Learning. There are 3 types of mutually-inclusive perturbations that can take place. The values contained within this object represent the probability that the given perturbation will take place.

Parameters:
  • reorder_probability (float) – Probability that the existing action sequence will be reordered.
  • ignore_probability (float) – Proability that existing actions will be removed from the sequence.
  • local_perturbation_probability (float) – Probability that local pertrurbations will be induced upon the individual elements of the existing action sequence.
DEFAULT_IGNORE_PROBABILITY = 0.3
DEFAULT_LOCAL_PERTURBATION_PROBABILITY = 0.7
DEFAULT_REORDER_PROBABILITY = 0.2
ignore_probability

float – obtain the probability that existing actions will be ignored.

local_perturbation_probability

float – obtain the probability that existing actions will be locally perturbed.

reorder_probability

float – obtain the probability that reordering will take place.

config

Config – obtain the perturbation configuration object.

class adjsim.decision.PositiveSumConstraint(sum_constraint)

Bases: adjsim.decision.ArrayConstraint

Constrain a decision-mutable array so that all elements sum to a given value. All elements will be positive.

satisfies(value)
class adjsim.decision.QLearningDecision(perception, loss, simulation, input_file_name='C:\Users\Sev\Anaconda3\envs\adjsim\lib\site-packages\sphinx\__main__.qlearning.pkl', output_file_name='C:\Users\Sev\Anaconda3\envs\adjsim\lib\site-packages\sphinx\__main__.qlearning.pkl', discount_factor=0.95, nonconformity_probability=0.3)

Bases: adjsim.decision.FunctionalDecision

A decision module based on Q-Learning.

This module employs Q-Learning (https://en.wikipedia.org/wiki/Q-learning), a reinforcement learning technique, to incrementally enhance its performance as measured by the provided loss function. Over many simulations, the performance of the agent will be increased.

Parameters:
  • perception (callable) – The perception callable. Can return any value.
  • loss (callable) – The loss callable. Must return a float-convertible object.
  • callbacks (_CallbackSuite) – The simulation’s callback suite. Used by the decision module to register neccessary callbacks.
  • input_file_name (string) – The name of the .pkl file from which to read a previous Q-Table. The previous Q-Table will be used as a starting point in the current simulation.
  • output_file_name (string) – The name of the .pkl file where the new Q-Table will be saved.
  • discount_factor (float) – The dscount factor (gamma) used in the temporal-differnce calculation of agent loss. Defaults to 0.95.
  • nonconformity_probability (float) – When an agent finds an existing entry in its Q-Table, it will still choose to perform a random action with a probability equivalent to nonconformity_probability. Defaults to 0.3.
DEFAULT_DISCOUNT_FACTOR = 0.95
DEFAULT_IO_FILE_NAME = 'C:\\Users\\Sev\\Anaconda3\\envs\\adjsim\\lib\\site-packages\\sphinx\\__main__.qlearning.pkl'
DEFAULT_NONCONFORMITY_FACTOR = 0.3
__call__(simulation, source)

The functor call that executes Q-learning.

Agents randomly choose actions if they have never encountered a particular observation before. Otherwise, They conditionally execute the previously encountered action premise (note nonconformity_probability).

Information regarding randomly chosen abilities is stored in the history bank until simulation completion.

Parameters:
  • simulation (Simulation) – The Simulation.
  • source (Agent) – The source Agent.
print_debug = False
print_q_table()

Debug printing of the Q-Table

class adjsim.decision.RandomRepeatedCastDecision

Bases: adjsim.decision.Decision

A decision to cast multiple randomly-chosen action during a simulation step.

Actions are repeatedly cast until the agent’s step_complete attribute is set to True.

class adjsim.decision.RandomSingleCastDecision

Bases: adjsim.decision.Decision

A decision to cast a single randomly-chosen action during a simulation step.

__call__(simulation, source)

Call a single randomly-selected action.

class adjsim.decision.RangeConstraint(min_val, max_val)

Bases: adjsim.decision.ArrayConstraint

Constrain a decision-mutable array so that all elements fall in a given range.

satisfies(value)

adjsim.index module

Index module.

This module contains indices for fast lookup of agents given certain properties.

Designed and developed by Sever Topan.

class adjsim.index.GridIndex(simulation)

Bases: adjsim.index.Index

An Index that stores agent location based on discrete entries within a grid.

The grid spans infinite space, and its dimensions are defined by the grid_size paramenter upon initialization. GridIndex must be initialized before it can be used in a simulation.

NEIGHBOUR_ITERATION_ARRAYS = [array([1, 0]), array([1, 1]), array([0, 1]), array([-1, 1]), array([-1, 0]), array([-1, -1]), array([ 0, -1]), array([ 1, -1])]
NEIGHBOUR_ITERATION_LIST = [[1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1], [0, -1], [1, -1]]
get_inhabitants(pos)

Obtain a list of all agents agents inhabiting a given cell or a list of cells.

Parameters:pos (np.ndarray, list) – The query position, or a list of query positions.
Returns:A list of agents.
get_neighbour_coordinates(pos)

Obtain the cells neighbouring a given cell.

Parameters:pos (np.ndarray) – The query position.
Returns:A list of 2d np.ndarray objects listing the cells neighbouring a given cell.
get_neighbours(pos)

Obtain a list of all agents agents inhabiting cells neighbouring a given position.

Parameters:pos (np.ndarray, list) – The query position.
Returns:A list of agents.
initialize(grid_size)

Initialize the index with the given grid size.

Parameters:grid_size (int) – The size of the grid.
class adjsim.index.Index

Bases: object

Base index object.

adjsim.utility module

Utility module.

This module contains miscellaneous utility objects and functions for use in adjsim.

Designed and developed by Sever Topan.

exception adjsim.utility.ActionException

Bases: Exception

MESSAGE = 'An exception has occurred while calling an action.\n\n Action must be a callable that takes in a Simulation object.\n The callable return values will be ignored. Changes should be made in place in the Simulation object.\n Actions should set step_complete to True once no subsequent actions need be called.\n '
exception adjsim.utility.DecisionException

Bases: Exception

MESSAGE = 'An error has occurred while invoking a decision module.\n\n Decision must be a callable takes in Simulation and a source agent. It should perform the\n neccessary computation for a given agent.\n '
exception adjsim.utility.EndConditionException

Bases: Exception

MESSAGE = 'An error has occurred while invoking the end_condition.\n\n An end condition must be a callable that takes in Simulation and returns a bool.\n '
exception adjsim.utility.IndexInitializationException

Bases: Exception

MESSAGE = "The index has not been initialized prior to invocation of a query.\n \n Please call the index's 'initialize' method before querying it.\n "
class adjsim.utility.InheritableDict(*args, **kwargs)

Bases: collections.abc.MutableMapping

An inheritable dict interface.

Overridable functions: __getitem__, __setitem__, __delitem__, __iter__, __len__.

class adjsim.utility.InheritableSet(*args, **kwargs)

Bases: collections.abc.MutableSet

An inheritable set interface.

Overridable functions: __contains__, __iter__, __len__, add, discard.

add(value)
discard(value)
exception adjsim.utility.InvalidAgentException

Bases: Exception

MESSAGE = 'An agent must inherit from the Agent object.'
exception adjsim.utility.InvalidCallbackException

Bases: Exception

MESSAGE = 'A callback of invalid format has been supplied.'
exception adjsim.utility.LossException

Bases: Exception

MESSAGE = 'An error has occurred while invoking a loss callable.\n \n Loss must be a callable that accepts simualtion and source agent as arguments.\n It must return a float-convertibale object. The lower the loss, the better the \n action is considered to be.\n '
exception adjsim.utility.MissingAttributeException

Bases: Exception

MESSAGE = 'An attribute that was registered with the observation found is not present in the target agent.'
exception adjsim.utility.PerceptionException

Bases: Exception

MESSAGE = 'An error has occurred while invoking a perception callable.\n \n Perception must be a callable that accepts simualtion and source agent as arguments.\n The perception function must return a tuple of types to be associated with a given agent state.\n '
exception adjsim.utility.SimulatonWorkflowException

Bases: Exception

MESSAGE = "Steps have been invoked on a non-running simulation.\n\n Please call 'start' in the simulation before 'step'. \n Follow up simulation completion with a call to 'end'.\n "
exception adjsim.utility.TrackerException

Bases: Exception

MESSAGE = 'An Exception has occurred while calling a Tracker.\n\n Simulation.trackers should be a list of callable functors that inherit from Tracker.\n They must implement their __call__ method to take a Simulation object, and return the data that is desired.\n '
adjsim.utility.distance(lhs, rhs)

Obtain the the distance between two np.ndarray functions.

Parameters:
  • lhs (np.ndarray) – the left hand side argument.
  • rhs (np.ndarray) – the right hand side argument.
adjsim.utility.distance_square(lhs, rhs)

Obtain the square of the distance between two np.ndarray functions.

Parameters:
  • lhs (np.ndarray) – the left hand side argument.
  • rhs (np.ndarray) – the right hand side argument.
adjsim.utility.sigmoid(x)

Apply the sigmoid function.

Parameters:x (float) – The value to apply the sigmoid to.
adjsim.utility.sigmoid_clamp(x, clamp_min, clamp_max)

Apply the sigmoid function and skew the results to vertiacally span between clamp_min and clamp_max.

Parameters:
  • x (float) – The value to apply the sigmoid to.
  • clamp_min (float) – The value to skew the minimum to.
  • clamp_max (float) – The value to skew the maximum to.

adjsim.visual module

Core AdjSim Module.

This module contains the core features of the ABM engine, specifically, the Simulation and Agent objects and the facilities to allow them to interact with one another.

Designed and developed by Sever Topan.

class adjsim.visual.AdjGraphicsView(screen_geometry, update_semaphore)

Bases: PyQt5.QtWidgets.QGraphicsView

The Graphics View of the Visual Simulation.

timestepAnimationCallback()
update(agent_set)

The Visual update method, called after each timestep.

Parameters:agent_set (list) – The list of VisualAgent objects that will be rendered.
class adjsim.visual.AdjThread(app, simulation, simulation_length=None)

Bases: PyQt5.QtCore.QThread

PyQt must run on the main thread, so we use this thread to run the simulation

run()

Run the simulation upon thread initialization.

update_signal
class adjsim.visual.AgentEllipse(agent, scene)

Bases: PyQt5.QtWidgets.QGraphicsEllipseItem

The Ellipse that represents the visual agents.

hoverEnterEvent(event)
hoverLeaveEvent(event)
class adjsim.visual.AgentEllipseAdapter(target)

Bases: PyQt5.QtCore.QObject

An adapter between QPropertyAnimation and QGraphicsEllipseItem

This is in place because of PyQt’s inablility to handle this functionality via multiple inheritance.

size
x
y