Skip to content

Instantly share code, notes, and snippets.

@markusbkoch
Last active February 27, 2020 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markusbkoch/3abb127ae8444d4be845f0ad688cbd1d to your computer and use it in GitHub Desktop.
Save markusbkoch/3abb127ae8444d4be845f0ad688cbd1d to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"from cadCAD.configuration import append_configs\n",
"from cadCAD.configuration.utils import config_sim\n",
"import networkx as nx\n",
"\n",
"# create a base networkx object\n",
"base_network = nx.DiGraph()\n",
"base_network.add_node('i')\n",
"base_network.add_node('j')\n",
"\n",
"# base genesis state\n",
"genesis = {\n",
" 'network': base_network,\n",
" 'a': 0,\n",
" 'b': 0\n",
"}\n",
"\n",
"# params to be swept\n",
"params = {\n",
" 'node_param_i': [1, 2, 3],\n",
" 'node_param_j': [4, 5, 6],\n",
" 'b': [100, 200, 300],\n",
" 'r': [1, 2, 3]\n",
"}\n",
"\n",
"# mockup state update function for state variable a\n",
"def func_a(params, substep, state_history, prev_state, policy_input):\n",
" key = 'a'\n",
" value = 0\n",
" value += prev_state['network'].nodes['i']['param']\n",
" value += prev_state['network'].nodes['j']['param']\n",
" return (key, value)\n",
"\n",
"# mockup state update function for state variable a\n",
"def func_b(params, substep, state_history, prev_state, policy_input):\n",
" key = 'b'\n",
" value = prev_state['b']*params['r']\n",
" return (key, value)\n",
"\n",
"# partial state update blocks\n",
"psub = [\n",
" {\n",
" 'policies': {\n",
" },\n",
" 'variables': {\n",
" 'a': func_a,\n",
" 'b': func_b,\n",
" }\n",
" }\n",
"]\n",
"\n",
"# create sim_config\n",
"sim_config = config_sim (\n",
" {\n",
" 'N': 2, \n",
" 'T': range(1), # number of timesteps\n",
" 'M': params,\n",
" }\n",
")\n",
"# append configs\n",
"append_configs(\n",
" sim_configs=sim_config,\n",
" initial_state=genesis,\n",
" partial_state_update_blocks=psub\n",
")\n",
"\n",
"from copy import deepcopy\n",
"from cadCAD import configs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"At this point, `configs` contains a list of `Configuration` objects..."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<cadCAD.configuration.Configuration at 0x11aec7fd0>,\n",
" <cadCAD.configuration.Configuration at 0x1117b39d0>,\n",
" <cadCAD.configuration.Configuration at 0x11af6bc90>]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"configs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"...each with its own set of parameters..."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'N': 2,\n",
" 'T': range(0, 1),\n",
" 'M': {'node_param_i': 1, 'node_param_j': 4, 'b': 100, 'r': 1}},\n",
" {'N': 2,\n",
" 'T': range(0, 1),\n",
" 'M': {'node_param_i': 2, 'node_param_j': 5, 'b': 200, 'r': 2}},\n",
" {'N': 2,\n",
" 'T': range(0, 1),\n",
" 'M': {'node_param_i': 3, 'node_param_j': 6, 'b': 300, 'r': 3}}]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[c.sim_config for c in configs]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"...but they all share the same initial state"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"See how all 3 network variables point to the same instance of DiGraph (same address in memory)\n"
]
},
{
"data": {
"text/plain": [
"[{'network': <networkx.classes.digraph.DiGraph at 0x1117b3950>,\n",
" 'a': 0,\n",
" 'b': 0},\n",
" {'network': <networkx.classes.digraph.DiGraph at 0x1117b3950>,\n",
" 'a': 0,\n",
" 'b': 0},\n",
" {'network': <networkx.classes.digraph.DiGraph at 0x1117b3950>,\n",
" 'a': 0,\n",
" 'b': 0}]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(\"See how all 3 network variables point to the same instance of DiGraph (same address in memory)\")\n",
"[c.initial_state for c in configs]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following script updates the `initial_state` of each `Configuration` object so that the value of the state variable `b` is set to the value of the parameter `b` in the parameter dictionary"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'network': <networkx.classes.digraph.DiGraph at 0x1117b35d0>,\n",
" 'a': 0,\n",
" 'b': 100},\n",
" {'network': <networkx.classes.digraph.DiGraph at 0x1117b3690>,\n",
" 'a': 0,\n",
" 'b': 200},\n",
" {'network': <networkx.classes.digraph.DiGraph at 0x1117b3710>,\n",
" 'a': 0,\n",
" 'b': 300}]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"for c in configs: # for each configuration object\n",
" c.initial_state = deepcopy(c.initial_state) # make a deepcopy of the initial state dict (it's shared across configs by default)\n",
" for k in c.initial_state: # for each state variable\n",
" if k in c.sim_config['M']: # if there is a param with the same name in the params dict\n",
" c.initial_state[k] = c.sim_config['M'][k] # assign the param value to the initial value of the state variable\n",
"\n",
"# check result\n",
"[c.initial_state for c in configs]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following script updates the networkx object in the `initial_state` of each `Configuration` object so that they point to their own unique instance of a networkx object, modified according to the `init_network` function we defined above"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"See how each network now points to a different object (different address in memory)\n"
]
},
{
"data": {
"text/plain": [
"[{'network': <networkx.classes.digraph.DiGraph at 0x111706690>,\n",
" 'a': 0,\n",
" 'b': 100},\n",
" {'network': <networkx.classes.digraph.DiGraph at 0x1227ac490>,\n",
" 'a': 0,\n",
" 'b': 200},\n",
" {'network': <networkx.classes.digraph.DiGraph at 0x1228831d0>,\n",
" 'a': 0,\n",
" 'b': 300}]"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# network initializer:\n",
"# given a networkx object and a cadCAD params dictionary, \n",
"# modify attributes of the networkx object\n",
"def init_network(n, params):\n",
" n.nodes['i']['param'] = params['node_param_i']\n",
" n.nodes['j']['param'] = params['node_param_j']\n",
" return n\n",
"\n",
"for c in configs: # for each configuration object\n",
" c.initial_state = deepcopy(c.initial_state) # make a deepcopy of the initial state dict (it's shared across configs by default)\n",
" c.initial_state['network'] = init_network(c.initial_state['network'], c.sim_config['M'])\n",
"\n",
"# check result\n",
"print(\"See how each network now points to a different object (different address in memory)\")\n",
"[c.initial_state for c in configs]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now just run the simulation and look at the results"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"from cadCAD.engine import ExecutionMode, ExecutionContext, Executor\n",
"import pandas as pd\n",
"\n",
"def run(drop_midsteps=True):\n",
" exec_mode = ExecutionMode()\n",
" multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)\n",
" run = Executor(exec_context=multi_proc_ctx, configs=configs)\n",
" results = pd.DataFrame()\n",
" i = 0\n",
" for raw_result, _ in run.execute():\n",
" params = configs[i].sim_config['M']\n",
" result_record = pd.DataFrame.from_records([tuple([i for i in params.values()])], columns=list(params.keys()))\n",
"\n",
" df = pd.DataFrame(raw_result)\n",
" # keep only last substep of each timestep\n",
" if drop_midsteps:\n",
" max_substep = max(df.substep)\n",
" is_droppable = (df.substep!=max_substep)&(df.substep!=0)\n",
" df.drop(df[is_droppable].index, inplace=True)\n",
"\n",
" result_record['dataset'] = [df]\n",
" results = results.append(result_record)\n",
" i += 1\n",
" return results.reset_index()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"experiments = run()"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Experiment 0\n",
"-------------\n",
"Parameters:\n",
" - node_param_i = 1\n",
" - node_param_j = 4\n",
" - b = 100\n",
" - r = 1\n",
"Dataset:\n",
" run timestep a b\n",
"0 1 0 0 100\n",
"1 1 1 5 100\n",
"2 2 0 0 100\n",
"3 2 1 5 100\n",
"=======================================================\n",
"Experiment 1\n",
"-------------\n",
"Parameters:\n",
" - node_param_i = 2\n",
" - node_param_j = 5\n",
" - b = 200\n",
" - r = 2\n",
"Dataset:\n",
" run timestep a b\n",
"0 1 0 0 200\n",
"1 1 1 7 400\n",
"2 2 0 0 200\n",
"3 2 1 7 400\n",
"=======================================================\n",
"Experiment 2\n",
"-------------\n",
"Parameters:\n",
" - node_param_i = 3\n",
" - node_param_j = 6\n",
" - b = 300\n",
" - r = 3\n",
"Dataset:\n",
" run timestep a b\n",
"0 1 0 0 300\n",
"1 1 1 9 900\n",
"2 2 0 0 300\n",
"3 2 1 9 900\n",
"=======================================================\n"
]
}
],
"source": [
"for i,r in experiments.iterrows():\n",
" print(f'Experiment {i}')\n",
" print('-------------')\n",
" print('Parameters:')\n",
" for k in list(params.keys()):\n",
" print(f' - {k} = {r[k]}')\n",
" print('Dataset:')\n",
" print(r.dataset[['run','timestep','a','b']])\n",
" print('=======================================================')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As intended, the initial value of `b` is different for each one of the experiments (same value as defined in the parameters dictionary that we swept).\n",
"\n",
"Also, each one of the experiments was executed based on a different initial `network`, as we can infer from the different values of `a` in each experiment (remember `a` is computed from attributes of the underlying `network`)"
]
}
],
"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.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment