tutorials from cadCAD-Tutorials repo + fixed links
|
|
@ -34,7 +34,7 @@
|
||||||
"\n",
|
"\n",
|
||||||
"cadCAD is a Python library that assists in the processes of designing, testing and validating complex systems through simulation. At its core, cadCAD is a differential games engine that supports parameter sweeping and Monte Carlo analyses and can be easily integrated with other scientific computing Python modules and data science workflows.\n",
|
"cadCAD is a Python library that assists in the processes of designing, testing and validating complex systems through simulation. At its core, cadCAD is a differential games engine that supports parameter sweeping and Monte Carlo analyses and can be easily integrated with other scientific computing Python modules and data science workflows.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"To learn more about cadCAD, follow our [tutorial series](https://github.com/BlockScience/cadCAD-Tutorials/tree/master/01%20Tutorials)\n",
|
"To learn more about cadCAD, follow our [tutorial series](../../tutorials)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"**Installing cadCAD:**\n",
|
"**Installing cadCAD:**\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
**Robot and Marbles Tutorial Series**
|
||||||
|
|
||||||
|
In this series, we introduce basic concepts of cadCAD and system modelling in general using a simple toy model.
|
||||||
|
[Part 1](robot-marbles-part-1/robot-marbles-part-1.ipynb) - States and State Update Functions
|
||||||
|
[Part 2](robot-marbles-part-2/robot-marbles-part-2.ipynb) - Actions and State Dependent Policies
|
||||||
|
[Part 3](robot-marbles-part-3/robot-marbles-part-3.ipynb) - From Synchronous to Asynchronous Time
|
||||||
|
[Part 4](robot-marbles-part-4/robot-marbles-part-4.ipynb) - Uncertainty and Stochastic Processes
|
||||||
|
[Part 5](robot-marbles-part-5/robot-marbles-part-5.ipynb) - Using class objects as state variables
|
||||||
|
|
||||||
|
Check out the [videos](videos) folder for detailed walkthroughs of each one of the tutorials.
|
||||||
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
(https://youtu.be/uJEiYHRWA9g)
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 1, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def update_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
x = s['box_A'] + add_to_A
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def update_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
add_to_B = 0
|
||||||
|
if (s['box_B'] > s['box_A']):
|
||||||
|
add_to_B = -1
|
||||||
|
elif (s['box_B'] < s['box_A']):
|
||||||
|
add_to_B = 1
|
||||||
|
x = s['box_B'] + add_to_B
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': {
|
||||||
|
},
|
||||||
|
'variables': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': update_A,
|
||||||
|
'box_B': update_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 1, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def update_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
x = s['box_A'] + add_to_A
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def update_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
add_to_B = 0
|
||||||
|
if (s['box_B'] > s['box_A']):
|
||||||
|
add_to_B = -1
|
||||||
|
elif (s['box_B'] < s['box_A']):
|
||||||
|
add_to_B = 1
|
||||||
|
x = s['box_B'] + add_to_B
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 11, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': {
|
||||||
|
},
|
||||||
|
'variables': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': update_A,
|
||||||
|
'box_B': update_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
(https://youtu.be/Y5MzhVRQyzY)
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 1, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
def robot_arm(_g, step, sL, s):
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
return({'add_to_A': add_to_A, 'add_to_B': -add_to_A})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def increment_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
x = s['box_A'] + _input['add_to_A']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def increment_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
x = s['box_B'] + _input['add_to_B']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||||
|
'robot_arm': robot_arm
|
||||||
|
},
|
||||||
|
'states': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': increment_A,
|
||||||
|
'box_B': increment_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 1, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
def robot_arm(_g, step, sL, s):
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
return({'add_to_A': add_to_A, 'add_to_B': -add_to_A})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def increment_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
x = s['box_A'] + _input['add_to_A']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def increment_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
x = s['box_B'] + _input['add_to_B']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||||
|
'robot_arm_1': robot_arm,
|
||||||
|
'robot_arm_2': robot_arm
|
||||||
|
},
|
||||||
|
|
||||||
|
'states': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': increment_A,
|
||||||
|
'box_B': increment_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10),
|
||||||
|
'N': 1
|
||||||
|
})
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
def robot_arm(_g, step, sL, s):
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
return({'add_to_A': add_to_A, 'add_to_B': -add_to_A})
|
||||||
|
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def increment_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
x = s['box_A'] + _input['add_to_A']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def increment_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
x = s['box_B'] + _input['add_to_B']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10,
|
||||||
|
'box_B': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': {
|
||||||
|
'robot_arm': robot_arm
|
||||||
|
},
|
||||||
|
'states': {
|
||||||
|
'box_A': increment_A,
|
||||||
|
'box_B': increment_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
(https://youtu.be/wF539-K0qXs)
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 1, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
def robot_arm(_g, step, sL, s):
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
return({'add_to_A': add_to_A, 'add_to_B': -add_to_A})
|
||||||
|
|
||||||
|
robots_periods = [2,3] # Robot 1 acts once every 2 timesteps; Robot 2 acts once every 3 timesteps
|
||||||
|
|
||||||
|
def get_current_timestep(cur_substep, s):
|
||||||
|
if cur_substep == 1:
|
||||||
|
return s['timestep']+1
|
||||||
|
return s['timestep']
|
||||||
|
|
||||||
|
def robot_arm_1(_g, step, sL, s):
|
||||||
|
_robotId = 1
|
||||||
|
if get_current_timestep(step, s)%robots_periods[_robotId-1]==0: # on timesteps that are multiple of 2, Robot 1 acts
|
||||||
|
return robot_arm(_g, step, sL, s)
|
||||||
|
else:
|
||||||
|
return({'add_to_A': 0, 'add_to_B': 0}) # for all other timesteps, Robot 1 doesn't interfere with the system
|
||||||
|
|
||||||
|
def robot_arm_2(_g, step, sL, s):
|
||||||
|
_robotId = 2
|
||||||
|
if get_current_timestep(step, s)%robots_periods[_robotId-1]==0: # on timesteps that are multiple of 3, Robot 2 acts
|
||||||
|
return robot_arm(_g, step, sL, s)
|
||||||
|
else:
|
||||||
|
return({'add_to_A': 0, 'add_to_B': 0}) # for all other timesteps, Robot 2 doesn't interfere with the system
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def increment_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
x = s['box_A'] + _input['add_to_A']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def increment_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
x = s['box_B'] + _input['add_to_B']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||||
|
'robot_arm_1': robot_arm_1,
|
||||||
|
'robot_arm_2': robot_arm_2
|
||||||
|
},
|
||||||
|
|
||||||
|
'states': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': increment_A,
|
||||||
|
'box_B': increment_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
(https://youtu.be/MLNTqqX47Ew)
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 1, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
def robot_arm(_g, step, sL, s):
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
return({'add_to_A': add_to_A, 'add_to_B': -add_to_A})
|
||||||
|
|
||||||
|
robots_probabilities = [0.5,1/3] # Robot 1 acts with a 50% probability; Robot 2, 33.33%
|
||||||
|
|
||||||
|
def robot_arm_1(_g, step, sL, s):
|
||||||
|
_robotId = 1
|
||||||
|
if np.random.rand()<robots_probabilities[_robotId-1]: # draw a random number between 0 and 1; if it's smaller than the robot's parameter, it acts
|
||||||
|
return robot_arm(_g, step, sL, s)
|
||||||
|
else:
|
||||||
|
return({'add_to_A': 0, 'add_to_B': 0}) # otherwise, the robot doesn't interfere with the system
|
||||||
|
|
||||||
|
def robot_arm_2(_g, step, sL, s):
|
||||||
|
_robotId = 2
|
||||||
|
if np.random.rand()<robots_probabilities[_robotId-1]: # draw a random number between 0 and 1; if it's smaller than the robot's parameter, it acts
|
||||||
|
return robot_arm(_g, step, sL, s)
|
||||||
|
else:
|
||||||
|
return({'add_to_A': 0, 'add_to_B': 0}) # otherwise, the robot doesn't interfere with the system
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def increment_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
x = s['box_A'] + _input['add_to_A']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def increment_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
x = s['box_B'] + _input['add_to_B']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||||
|
'robot_arm_1': robot_arm_1,
|
||||||
|
'robot_arm_2': robot_arm_2
|
||||||
|
},
|
||||||
|
|
||||||
|
'states': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': increment_A,
|
||||||
|
'box_B': increment_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
# import libraries
|
||||||
|
from decimal import Decimal
|
||||||
|
import numpy as np
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import bound_norm_random, ep_time_step, config_sim
|
||||||
|
|
||||||
|
seeds = {
|
||||||
|
# 'z': np.random.RandomState(1),
|
||||||
|
# 'a': np.random.RandomState(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
'T': range(10), #number of discrete iterations in each experiement
|
||||||
|
'N': 50, #number of times the simulation will be run (Monte Carlo runs)
|
||||||
|
#'M': g #parameter sweep dictionary
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# define the time deltas for the discrete increments in the model
|
||||||
|
# ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
# t_delta = timedelta(days=0, minutes=1, seconds=0)
|
||||||
|
# def time_model(_g, step, sL, s, _input):
|
||||||
|
# y = 'time'
|
||||||
|
# x = ep_time_step(s, dt_str=s['time'], fromat_str=ts_format, _timedelta=t_delta)
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# Behaviors
|
||||||
|
def robot_arm(_g, step, sL, s):
|
||||||
|
add_to_A = 0
|
||||||
|
if (s['box_A'] > s['box_B']):
|
||||||
|
add_to_A = -1
|
||||||
|
elif (s['box_A'] < s['box_B']):
|
||||||
|
add_to_A = 1
|
||||||
|
return({'add_to_A': add_to_A, 'add_to_B': -add_to_A})
|
||||||
|
|
||||||
|
robots_probabilities = [0.5,1/3] # Robot 1 acts with a 50% probability; Robot 2, 33.33%
|
||||||
|
|
||||||
|
def robot_arm_1(_g, step, sL, s):
|
||||||
|
_robotId = 1
|
||||||
|
if np.random.rand()<robots_probabilities[_robotId-1]: # draw a random number between 0 and 1; if it's smaller than the robot's parameter, it acts
|
||||||
|
return robot_arm(_g, step, sL, s)
|
||||||
|
else:
|
||||||
|
return({'add_to_A': 0, 'add_to_B': 0}) # otherwise, the robot doesn't interfere with the system
|
||||||
|
|
||||||
|
def robot_arm_2(_g, step, sL, s):
|
||||||
|
_robotId = 2
|
||||||
|
if np.random.rand()<robots_probabilities[_robotId-1]: # draw a random number between 0 and 1; if it's smaller than the robot's parameter, it acts
|
||||||
|
return robot_arm(_g, step, sL, s)
|
||||||
|
else:
|
||||||
|
return({'add_to_A': 0, 'add_to_B': 0}) # otherwise, the robot doesn't interfere with the system
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Mechanisms
|
||||||
|
def increment_A(_g, step, sL, s, _input):
|
||||||
|
y = 'box_A'
|
||||||
|
x = s['box_A'] + _input['add_to_A']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def increment_B(_g, step, sL, s, _input):
|
||||||
|
y = 'box_B'
|
||||||
|
x = s['box_B'] + _input['add_to_B']
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
# Initial States
|
||||||
|
genesis_states = {
|
||||||
|
'box_A': 10, # as per the description of the example, box_A starts out with 10 marbles in it
|
||||||
|
'box_B': 0 # as per the description of the example, box_B starts out empty
|
||||||
|
}
|
||||||
|
|
||||||
|
exogenous_states = {
|
||||||
|
#'time': time_model
|
||||||
|
}
|
||||||
|
|
||||||
|
env_processes = {
|
||||||
|
}
|
||||||
|
|
||||||
|
#build mechanism dictionary to "wire up the circuit"
|
||||||
|
mechanisms = [
|
||||||
|
{
|
||||||
|
'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||||
|
'robot_arm_1': robot_arm_1,
|
||||||
|
'robot_arm_2': robot_arm_2
|
||||||
|
},
|
||||||
|
|
||||||
|
'states': { # The following state variables will be updated simultaneously
|
||||||
|
'box_A': increment_A,
|
||||||
|
'box_B': increment_B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
append_configs(
|
||||||
|
sim_configs=sim_config,
|
||||||
|
initial_state=genesis_states,
|
||||||
|
seeds=seeds,
|
||||||
|
raw_exogenous_states=exogenous_states,
|
||||||
|
env_processes=env_processes,
|
||||||
|
partial_state_update_blocks=mechanisms
|
||||||
|
)
|
||||||
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
|
@ -0,0 +1 @@
|
||||||
|
https://www.youtube.com/watch?v=I0mSQppibLs&feature=youtu.be
|
||||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 21 KiB |