# 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 )