Model

BPTK API Documentation for the Model class
Keywords

agent-based modeling, system dynamics, bptk, bptk-py, python, business prototyping

Model

Model Constructor

Model(starttime=0, stoptime=0, dt=1, name=’’, scheduler=None, data_collector=None)

This is the main agent base / System dynamics / Hybrid model class

It can run manually generated SD models, AB Models or define hybrid models.

  • Parameters

    • name – String. Name of the model.

    • scheduler – Scheduler. Scheduler object (e.g. simultaneousScheduler). This is configurable, so that you can add your own scheduling algorithms.

    • data_collector – DataCollector Instance of DataCollector. This is configurable, so that you can add your own data collection algorithms.

Model.add_equation

add_equation(equation, lambda_method)

Add an equation by name, computed by a function of the time. This is how a hand-written hybrid model gives its System Dynamics side an equation without building it from stocks, flows and converters.

  • Parameters

    equation – String. The name of the equation. If the model already has an equation of that name, the new one replaces it and a warning is logged.

    lambda_method – Callable. A function of the time t that returns the equation’s value, for example lambda t: 2 * t.

Model.agent

agent(agent_id)

Get an agent by ID.

Retrieve one agent by its ID

  • Parameters

    agent_id – Integer. ID of agent that is to be retrieved.

  • Returns

    Agent object

Model.agent_count

agent_count(agent_type) Get count of agents of a given type.

  • Parameters

    agent_type – String. Agent type to get count for

  • Returns

    Integer. Number of agents (Integer)

Model.agent_count_per_state

agent_count_per_state(agent_type, state)

Get number of agents in a specific state

  • Parameters

    • agent_type – String. Agent type to get count for

    • state – String. The state of agents to get count for

  • Returns

    Integer.

Model.agent_ids

agent_ids(agent_type)

Get agent IDs.

Retrieve agent IDs for all agents of type agent_type.

  • Parameters

    agent_type – String. Agent type to get IDs for

  • Returns

    List of IDs

Model.begin_episode

begin_episode(episode_no)

Called at beginning of an episode.

When running a simulation repeatedly in episodes (e.g. because you are training the model using reinforcement learning), this method is called by the framework to allow tidy up at the beginning of an episode, e.g. a “soft” reset of the simulation.

The default implementation calls begin_episode on each agent.

  • Parameters

    episode_no – Integer. The number of the episode

Model.begin_round

begin_round(time, sim_round, step)

Called at the beginning of a simulation round.

Should be called by the Scheduler at the beginning of each round, before the agents act methods are called. Add any logic here that is needed to update dynamic properties.

  • Parameters

    • time – Integer. The current timestep of the simulation, i.e.(round+step*dt)

    • sim_round – Integer The current round of the simulation.

    • step – Integer. The step number of round

Model.biflow

biflow(name) Create a System Dynamics biflow

  • Parameters

    name – String. Name of the biflow

  • Returns

    A Biflow object

Model.broadcast_event

broadcast_event(agent_type, event_factory)

Broadcast an event to all agents of a particular agent_type

  • Parameters

    • agent_type – String. Agent type that is to receive the event

    • num_agents – Integer. Number of random agents that should receive the event

    • event_factory – Function. The factory (typicalla a lambda function) that generates the desired event for a given target agent type. The function receives the agent_id as its parameter.

Model.configure

configure(config)

Called to configure the model using a dictionary. This method is called by the framework if you instantiate models from scenario files. But you can also call the method directly.

It replaces the agents of an earlier configuration, together with the events still queued for them, so a model can be configured and run again.

  • Parameters

    config – Dict. Dictionary containing the config: {“runspecs”:,”properties”:,”agents”:}.

Model.constant

constant(name)

Returns a Constant object with the given name - if a Constant with the given name already exists within the model, this one is returned. Else a new Constant object is created, stored and returned.

  • Parameters

    name – String. Name of the constant

Returns: Constant.

A Constant object

Model.converter

converter(name)

Returns a Converter object with the given name - if a Converter with the given name already exists within the model, this one is returned, else a new Converter object is created, stored and returned.

  • Parameters

    name – String. Name of the converter

  • Returns

    A Converter object

Model.create_agent

create_agent(agent_type, agent_properties) Create one agent of the given type and with the given properties.

Internally this method then uses the registered agent factories to actually create an agent.

  • Parameters

    • agent_type – String. Type of agent

    • agent_properties – Dict. The properties to initialize the agent with.

Model.create_agents

create_agents(agent_spec)

Create agents according to the agent specificaction.

The agent specification is a dictionary containing the agent name and properties. Internally, this method then uses the registered agent factories to actually create the agents.

  • Parameters

    agent_spec – Dict. Specification of an agent using a dictionary with format {“name”:, “count”: }

Model.delete_agent

delete_agent(agent_id)

Remove one agent from the model, while it runs or before.

  • Parameters

    agent_id – Integer. The id of the agent to remove.

Model.delete_agents

delete_agents(agent_ids)

Remove several agents from the model at once.

  • Parameters

    agent_ids – List. The ids of the agents to remove.

Model.end_episode

end_episode(episode_no)

Called at the end of an episode.

When running a simulation repeatedly in episodes, this method is called by the framework to allow tidy up at the end of an episode.

The default implementation calls end_episode on each agent.

  • Parameters

    episode_no – Integer. The number of the episode

Model.end_round

end_round(time, sim_round, step)

Called at end of a simulation round.

Should be called by the Scheduler at the end of each round, before the agents act methods are called. Add any logic here that is needed to update dynamic properties.

  • Parameters

    • time – Integer. The current timestep of the simulation, i.e.(round+step*dt)

    • sim_round – Integer The current round of the simulation.

    • step – Integer. The step number of round

Model.enqueue_event

enqueue_event(event)

Called by the framework to enqueue events.

In general you don’t need to override this method or call it directly.

  • Parameters

    event – Event. Instance of the event.

Model.equation_prefix

property equation_prefix()

An id that is unique within this model that can be used to generate unique equation names.

This method is useful when auto-generating equations.

  • Returns

    Integer. An id that is unique within the model.

Model.evaluate_equation

evaluate_equation(name, t)

Evaluate an System Dynamics element’s equation at timestep t.

  • Parameters

    • name – String. Name of the equation.

    • t – Float. Timestep to evaluate for

Return: Float

The value of the equation at time t.

Model.flow

flow(name)

Returns a Flow object with the given name - if a Flow with the given name already exists within the model, this one is returned, else a new Flow object is created, stored and returned.

  • Parameters

    name – String. Name of the flow

  • Returns

    A Flow object

Model.function

function(name, fn, elementwise=True)

Returns a Lambda function that wraps the function fn. A function of that name defined earlier is replaced, and the equations that call it compute with the new one.

The document User Defined Functions illustrates how such functions can be used.

  • Parameters

    • name – String. Name of the function.

    • fn – Function A function that will be used within a SD DSL model. The function must accept at least a model parameter and a time t parameter.

    • elementwise – Boolean (Default=True). What an arrayed argument means. True calls the function once per index, so the result is an array of the same shape - the rule every operator follows. False hands the whole array over instead: a list for an unnamed array, a dict keyed by the labels for a named one, nested for a matrix, and the result is a single value. The element-wise form runs on the Rust engine. elementwise=False does not: a run that asks for the Rust backend raises RustBackendError, and a run that does not stays on the Python engine.

Returns: A function which wraps the user defined function for use within SD DSL models.

Model.get_property

get_property(name)

Get a property of the model by name.

The value of the model properties can also be accessed directly as a model attribute, i.e. as self.

  • Parameters

    name – String. Name of property

  • Returns

    Dictionary for property

Model.get_property_value

get_property_value(name) Get a property of the model by name.

The value of the model properties can also be accessed directly as a model attribute, i.e. as self.

  • Parameters

    name – String. Name of property

  • Returns

    Value of the property.

Model.get_random_integer

static get_random_integer(min_value, max_value)

A random integer within bounds

This method is useful for simulating random behaviour.

  • Parameters

    • min_value – Integer. Min value for random integer

    • max_value – Integer. max value for random integer

  • Returns

    Random integer.

Model.instantiate_model

instantiate_model()

Set properties during model initialization.

This method does nothing in the parent class and can be overriden in child classes. It is called by the frame directly after the model is instantiated.

Implement this method in your model to perform any kind of initialization you may need. Typically you would register your agent factories hier and set up model properties.

Model.next_agent

next_agent(agent_type, state)

Get the next agent by type and state.

Runs through the internal agent store and retrieves the first agent that matches in type and state.

  • Parameters

    • agent_type – String. Agent type

    • state – String. State the agent is in

  • Returns

    The first agent object that matches the criterian None otherwise.

Model.plot_lookup

plot_lookup(lookup_names, config=None, format=“plot”, matplotlib_rc_settings=None)

Plots lookup functions for the given list of lookup names.

  • Parameters

    lookup_names – String or List. A name or list of names of lookup functions. The list can be passed as a Python list or a comma separated string.

    format – String (Default “plot”). What to return: “plot” draws the diagram and returns nothing, “axes” returns the matplotlib Axes, “df” returns the underlying dataframe. “plot” relies on the notebook displaying the figure as a side effect, which only Jupyter’s inline backend does — in marimo, and in a plain script, use “axes”.

    matplotlib_rc_settings – Dict (Default None). matplotlib settings for this one plot, laid over the central plotting configuration rather than replacing it.

Model.random_agents

random_agents(agent_type, num_agents)

Retreive a number of random agents

  • Parameters

    • agent_type – String. Type of agent to retrieve.

    • num_agents – Number of agents of this type to retreive.

  • Returns

    List of agent IDs. The number of IDs might be less then num_agents if fewer agents are available.

Model.random_events

random_events(agent_type, num_agents, event_factory)

Distribute events to a number of random agents

  • Parameters

    • agent_type – String. Agent type that is to receive the event

    • num_agents – Integer. Number of random agents that should receive the event

    • event_factory – Function. The factory (typicalla a lambda function) that generates the desired event for a given target agent type. The function receives the agent_id as its parameter.

Model.register_agent_factory

register_agent_factory(agent_type, agent_factory)

Register an agent factory.

Agent factories are used at run-time to populate the model with agents. This method is used to register an agent factory, which is typically just a lambda function which returns an agent.

  • Parameters

    • agent_type – String. Type of agent to register

    • agent_factory – Function. Function that returns an agent given an id and the model. Typically a lambda, but not limited to that. Input: agent_id, model -> Output: Agent of agent_type

Model.reset

reset()

Reset the model.

Clear out all agents, agent and event statistics and resets the cache of SD equations.

The agent factories are kept though, so you could directly reconfigure the model using the configure method.

Model.reset_cache

reset_cache()

Reset cache of all System Dynamics equations and call the reset_cache method on all agents. Clear the agent statistics.

Model.run

run(show_progress_widget=False, collect_data=True)

Run the simulation.

This esssentially just calls the run method of the models scheduler. Only relevant for agent-based models, does nothing on pure SD DSL models.

  • Parameters

    • show_progress_widget – Boolean (Default=False). If True, shows a progress bar while the simulation runs. It is built on tqdm, so it works in a terminal, in marimo and in Jupyter alike.

    • collect_data – Boolean (Default=True). If True, data is automatically collected in the models DataCollector, e.g. for plotting the model behaviour. If you are training the model e.g. using reinforcement learning, it might be useful to turn data collection of.

Model.run_specs

run_specs(starttime, stoptime, dt)

Configure the runspecs of the model.

  • Parameters

    • starttime – Integer. The starttime of the model.

    • stoptime – Integer. The stoptime of the model.

    • dt – The dt of the model.

Model.run_step

run_step(step, show_progress_widget=False, collect_data=True)

Run a simulation step.

This esssentially just calls the run method of the models scheduler.

  • Parameters

    • step – Int. The step to run

    • show_progress_widget – Boolean (Default=False). If True, shows a progress bar while the simulation runs. It is built on tqdm, so it works in a terminal, in marimo and in Jupyter alike.

    • collect_data – Boolean (Default=True). If True, data is automatically collected in the models DataCollector, e.g. for plotting the model behaviour. If you are training the model e.g. using reinforcement learning, it might be useful to turn data collection off.

Model.set_property

set_property(name, property_spec)

Configure a property of the model itself, as opposed to the properties of individual agents.

Properties set via this mechanism are stored internally in a dictionary of properties, the value of the property directly can be access directly as an object attribute, i.e. as self..

A property set this way is not collected by the standard data collector and cannot be plotted directly - collect_agent_statistics sees the agents, not the model. Reading it back through get_property, or as an attribute, is what it is for.

  • Parameters

    • name – String. Name of the property to set.

    • property_spec – Dict. Specification of property: {“type”:<type of property, free form string>,”value”:}. In principle the property can store any kind of value, the type is currently not evaluated by the framework

Model.set_property_value

set_property_value(name, value)

Set the value of a model property by name.

Model properties can also be set directly via the model attributes, i.e. as self.=

  • Parameters

    • name – String. Name of property.

    • value – Any. Value of the property to set.

Model.set_scenario_manager

set_scenario_manager(scenario_manager)

Set the name of the scenario manager that is handling this model. Used by the bptk class during scenario registration.

  • Parameters

    scenario_manager – String. Name of the scenario manager.

Model.simulate

simulate(equations, backend=“python”)

Run the model once, without a scenario manager, and return the results.

  • Parameters

    equations – List. The equations to include in the results.

    backend – String (Default “python”). "python" or "rust".

  • Returns

    A Pandas DataFrame with the time as index (named "t") and one column per equation.

  • Raises

    RustBackendError if backend="rust" was asked for and the model cannot run on the engine. It is not computed on the Python engine instead.

Model.statistics

statistics()

Get statistics from DataCollector.

  • Returns

    The DataCollector used to collect the simulation statistics.

Model.to_json

to_json()

Serialise the model to the JSON format the Rust engine loads.

You rarely need to call this — run_scenarios(backend="rust") does it for you. It is useful when you want to know whether a model can run on the Rust engine, because this is where the answer is decided: it raises ValueError for anything the engine cannot express, naming what it tripped over.

  • Returns

    A JSON string.

  • Raises

    ValueError for anything the engine cannot express - a user-defined function registered with elementwise=False, or one in a model that also has agents. An ordinary user-defined function serialises: it becomes a node the engine answers by calling back into Python. In a run, that ValueError becomes a RustBackendError; see Execution Backends.

Model.stock

stock(name)

Returns a Stock object with the given name - if a Stock with the given name already exists within the model, this one is returned, else a new Stock object is created, stored and returned.

  • Parameters

    name – String. Name of the stock.

  • Returns

    The Stock object.