I’m getting an error I can’t figure out when using sweepable simulation parameters. I’m working off the Robots and Marbles tutorial. Just tried to add a parameter and I’m getting a type error: TypeError: list indices must be integers or slices, not str. So I think when it reads the params input it’s reading it as a list instead of a dict… I’m not getting the same issue for the s dict even though it looks like it’s structured the same way to me. And I don’t see any differences between how I’m defining the parameters and the documentation, but I could very well be missing something. Here’s the code:
indent preformatted text by 4 spaces
initial_conditions = {
'box_A': 20, # 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
}
%%capture
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# We specify the robot arm's logic in a Policy Function
def robot_arm1(params, step, sL, s):
add_to_A2 = 0
if (s['box_A'] > s['box_B']):
add_to_A2 = -1*params['multiplier']
elif (s['box_A'] < s['box_B']):
add_to_A2 = 1
return({'add_to_A': add_to_A2, 'add_to_B': -add_to_A2})
def robot_arm2(params, step, sL, s):
add_to_A2 = 0
if (s['box_A'] > s['box_B']):
add_to_A2 = -1
elif (s['box_A'] < s['box_B']):
add_to_A2 = 1
return({'add_to_A': add_to_A2, 'add_to_B': -add_to_A2})
def changes(params, step, sL, s):
x=step
return({})
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# We make the state update functions less "intelligent",
# ie. they simply add the number of marbles specified in _input
# (which, per the policy function definition, may be negative)
def increment_A(params, step, sL, s, _input):
y = 'box_A'
x = s['box_A'] + _input['add_to_A']
print("_input: ",_input)
return (y, x)
def increment_B(params, step, sL, s, _input):
y = 'box_B'
x = s['box_B'] + _input['add_to_B']
return (y, x)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# In the Partial State Update Blocks,
# the user specifies if state update functions will be run in series or in parallel
# and the policy functions that will be evaluated in that block
partial_state_update_blocks = [
{
'policies': { # The following policy functions will be evaluated and their returns will be passed to the state update functions
'robot_armA': robot_arm1,
'robot_arm': robot_arm2,
'changeThings': changes
},
'states': { # The following state variables will be updated simultaneously
'box_A': increment_A,
'box_B': increment_B
}
}
]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Settings of general simulation parameters, unrelated to the system itself
# T
is a range with the number of discrete units of time the simulation will run for;
# N
is the number of times the simulation will be run (Monte Carlo runs)
# In this example, we’ll run the simulation once (N=1) and its duration will be of 10 timesteps
# We’ll cover the M
key in a future article. For now, let’s leave it empty
simulation_parameters = {
'T': range(10),
'N': 1,
'M': {
'multiplier': [2]
}
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
from cadCAD.configuration import Configuration
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# The configurations above are then packaged into a `Configuration` object
config = Configuration(initial_state=initial_conditions, #dict containing variable names and initial
values
partial_state_update_blocks=partial_state_update_blocks, #dict containing state
update functions
sim_config=simulation_parameters #dict containing simulation parameters
)
%%capture
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
exec_mode = ExecutionMode()
exec_context = ExecutionContext(exec_mode.single_proc)
executor = Executor(exec_context, [config]) # Pass the configuration object inside an array
raw_result, tensor = executor.execute() # The `execute()` method returns a tuple; its first elements
contains the raw results
–TypeError: list indices must be integers or slices, not str