cadCAD/demos/simple_tracker_inline.ipynb

475 lines
57 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# SIMCad Demos: Simple Tracker"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Configuration\n",
"We begin with a simple configuration file that only defines a single exogenous state: a sinusoidal `signal`"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"# SimCAD related imports\n",
"from datetime import timedelta\n",
"from SimCAD.configuration import Configuration\n",
"from SimCAD.configuration.utils import exo_update_per_ts, ep_time_step\n",
"\n",
"# System specific imports\n",
"import numpy as np\n",
"\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# List of all the states in the system and their initial conditions\n",
"# In the current version of SimCAD, `timestamp` is mandatory\n",
"# The `signal` state is the exogenous state that we'll model\n",
"initial_conditions = {\n",
" 'signal': float(0),\n",
" 'timestamp': '2018-01-01 00:00:00'\n",
"}\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"\n",
"\n",
"\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# Definitions of functions that update the exogenous states\n",
"# Functions must return a tuple containing the name of the state being updated and its new value\n",
"# For now, ignore all the arguments passed to the function, except `s`, \n",
"# which contains a copy of the current values of all the states\n",
"\n",
"# Definition of the function that updates the `timestamp` state\n",
"# In the current version of SimCAD, `timestamp` is a mandatory state\n",
"ts_format = '%Y-%m-%d %H:%M:%S'\n",
"t_delta = timedelta(days=0, minutes=0, seconds=1) # In this example, a time_step is defined as 1 second. The user can change this\n",
"def time_model(step, sL, s, _input):\n",
" y = 'timestamp'\n",
" x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta)\n",
" return (y, x)\n",
"\n",
"# Definition of the function that updates the `signal` state\n",
"# It's a simple sine wave with amplitude 1 and period 50 time_steps\n",
"period = 50\n",
"def sinusoid(step, sL, s, _input):\n",
" y = 'signal'\n",
" x = s['time_step']\n",
" x = np.sin(x * 2 * np.pi / period)\n",
" return (y, x)\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"\n",
"\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# This maps the exogenous states to their corresponding updating functions\n",
"exogenous_states = exo_update_per_ts(\n",
" {\n",
" 'signal': sinusoid, # The `signal` state is updated by the `sinusoid` function defined above\n",
" 'timestamp': time_model # The `timestamp` state is updated by the `time_model` function defined above\n",
" }\n",
")\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# Settings of general simulation parameters, unrelated to the system itself\n",
"# `T` is the number of discrete units of time the simulation will run for\n",
"# `N` is the number of times the simulation will be run\n",
"# In this example, we'll run the simulation once (N=1) and its duration will be of 50 discrete units of time\n",
"sim_config = {\n",
" 'T': range(50),\n",
" 'N': 1\n",
"}\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"\n",
"# We'll ignore these components of the configuration for now\n",
"env_processes = {}\n",
"seeds = {}\n",
"mechanisms = {}\n",
"\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# The configurations above are then packaged into a `Configuration` object\n",
"config = Configuration(sim_config=sim_config,\n",
" state_dict=initial_conditions,\n",
" seed=seeds,\n",
" exogenous_states=exogenous_states,\n",
" env_processes=env_processes,\n",
" mechanisms=mechanisms)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Running the engine\n",
"We are now ready to run the engine with the configuration defined above. Instantiate an ExecutionMode, an ExecutionContext and an Executor objects, passing the Configuration object to the latter. Then run the `main()` method of the Executor object, which returns the results of the experiment in the first element of a tuple."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"single_proc: [<SimCAD.configuration.Configuration object at 0x104ba30f0>]\n"
]
}
],
"source": [
"from SimCAD.engine import ExecutionMode, ExecutionContext, Executor\n",
"exec_mode = ExecutionMode()\n",
"exec_context = ExecutionContext(exec_mode.single_proc)\n",
"executor = Executor(exec_context, [config]) # Pass the configuration object inside an array\n",
"raw_result, tensor = executor.main() # The `main()` method returns a tuple; its first elements contains the raw results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Analyzing the results\n",
"We can now convert the raw results into a DataFrame for analysis"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"count 5.100000e+01\n",
"mean -3.800038e-17\n",
"std 7.071068e-01\n",
"min -9.980267e-01\n",
"25% -6.845471e-01\n",
"50% 0.000000e+00\n",
"75% 6.845471e-01\n",
"max 9.980267e-01\n",
"Name: signal, dtype: float64"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"import pandas as pd\n",
"from tabulate import tabulate\n",
"df = pd.DataFrame(raw_result)\n",
"df.plot('timestamp', 'signal')\n",
"df['signal'].describe()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Modelling Internal States, Mechanisms and User Behavior\n",
"Let's now suppose we want to design a system with which an agent will interact with the intent of replicating the value of the previously defined `signal` in an internal state. The agent can read the current value of the `signal` and the current value of the internal state. And they can add or subtract any amount from the internal state."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we redefine the `initial_conditions` object in order to add the internal state, which will call `follow`"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# List of all the states in the system and their initial conditions\n",
"# In the current version of SimCAD, `timestamp` is mandatory\n",
"# The `signal` state is the exogenous state that we'll model\n",
"initial_conditions = {\n",
" 'follow': float(0),\n",
" 'signal': float(0),\n",
" 'timestamp': '2018-01-01 00:00:00'\n",
"}\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, define the function that updates the `follow` state. As defined above, all it does is add or subtract an amount from the state."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# Definitions of functions that update internal states\n",
"# These functions must return a tuple containing the name of the state being updated and its new value\n",
"# As with the exogenous state update functions, the `s` argument contains a copy of the current values of all the states\n",
"# The argument `_input` contains a dictionary of inputs passed to the mechanisms by agents interacting with it \n",
"\n",
"# Definition of the function that updates the `follow` state\n",
"def add(step, sL, s, _input):\n",
" y = 'follow'\n",
" x = s['follow'] + _input['value'] # All the state update function does is add to the `follow` state the `value` passed to it\n",
" return (y, x)\n",
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The policies of the agents that interact with the system through `mechanisms` are modelled as `BEHAVIORS`. In this example, we are modelling a simple behavior in which the agent reads the current state of the exogenous `signal` and of the internal state `follow` and compares them. The `return value` of the behavior function will be passed by the SimCAD engine as the `_input` argument of the mechanism"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # \n",
"# Definitions of the Behavioral Models (or Behaviors for short) - functions that convey some information to mechanisms\n",
"# Behaviors must return a dictionary containing whatever information they should pass to the mechanism they relate to\n",
"# As with the state update functions, the `s` argument contains a copy of the current values of all the states\n",
"\n",
"# Definition of the `tracker` behavior\n",
"def tracker(step, sL, s):\n",
" currentSignal = s['signal'] # Read the current state of the exogenous `signal`\n",
" currentFollow = s['follow'] # Read the current state of the internal state `follow`\n",
" diff = currentSignal - currentFollow # Compare the two\n",
" return {'value': diff} # Return the difference between them"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we map mechanisms to states and behaviors. In our example, we define that a mechanism called `simple_mechanism` updates the `follow` state through the `add` function, driven by the `tracker` behavior."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"mechanisms = {\n",
" 'simple_mechanism': { # The name of the mechanism; can be anything\n",
" 'behaviors': { # Dictionary of behavioral models related to this mechanism\n",
" 'behavior_group_1': tracker # The name of the behavior (key), followed by the function that defines it\n",
" },\n",
" 'states': { # Dictionary of states updated by this mechanism\n",
" 'follow': add # The name of the state (key) followed by the function that updates it\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Running the engine\n",
"We can now recreate the Configuration object and rerun the experiment with the expanded configurations"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"single_proc: [<SimCAD.configuration.Configuration object at 0x1080d0978>]\n"
]
}
],
"source": [
"config = Configuration(sim_config=sim_config,\n",
" state_dict=initial_conditions,\n",
" seed=seeds,\n",
" exogenous_states=exogenous_states,\n",
" env_processes=env_processes,\n",
" mechanisms=mechanisms)\n",
"executor = Executor(exec_context, [config]) # Pass the configuration object inside an array\n",
"raw_result, tensor = executor.main() # The `main()` method returns a tuple; its first elements contains the raw results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Analyzing the results\n",
"And again we convert the raw results into a DataFrame for analysis"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>signal</th>\n",
" <th>follow</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>count</th>\n",
" <td>5.100000e+01</td>\n",
" <td>5.100000e+01</td>\n",
" </tr>\n",
" <tr>\n",
" <th>mean</th>\n",
" <td>-3.800038e-17</td>\n",
" <td>-3.755166e-17</td>\n",
" </tr>\n",
" <tr>\n",
" <th>std</th>\n",
" <td>7.071068e-01</td>\n",
" <td>7.071068e-01</td>\n",
" </tr>\n",
" <tr>\n",
" <th>min</th>\n",
" <td>-9.980267e-01</td>\n",
" <td>-9.980267e-01</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25%</th>\n",
" <td>-6.845471e-01</td>\n",
" <td>-6.845471e-01</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50%</th>\n",
" <td>0.000000e+00</td>\n",
" <td>0.000000e+00</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75%</th>\n",
" <td>6.845471e-01</td>\n",
" <td>6.845471e-01</td>\n",
" </tr>\n",
" <tr>\n",
" <th>max</th>\n",
" <td>9.980267e-01</td>\n",
" <td>9.980267e-01</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" signal follow\n",
"count 5.100000e+01 5.100000e+01\n",
"mean -3.800038e-17 -3.755166e-17\n",
"std 7.071068e-01 7.071068e-01\n",
"min -9.980267e-01 -9.980267e-01\n",
"25% -6.845471e-01 -6.845471e-01\n",
"50% 0.000000e+00 0.000000e+00\n",
"75% 6.845471e-01 6.845471e-01\n",
"max 9.980267e-01 9.980267e-01"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"import pandas as pd\n",
"from tabulate import tabulate\n",
"df = pd.DataFrame(raw_result)\n",
"df.plot('timestamp', ['signal','follow'])\n",
"df[['signal','follow']].describe()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}