fefactored env_process
This commit is contained in:
parent
1c89d28ab5
commit
2de989db0a
|
|
@ -1,4 +1,4 @@
|
||||||
.idea
|
jupyter notebook.idea
|
||||||
.ipynb_checkpoints
|
.ipynb_checkpoints
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.idea
|
.idea
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class Configuration(object):
|
||||||
|
|
||||||
sanitize_config(self)
|
sanitize_config(self)
|
||||||
|
|
||||||
|
# ToDo: Remove Seeds
|
||||||
def append_configs(sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={},
|
def append_configs(sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={},
|
||||||
partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True) -> None:
|
partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True) -> None:
|
||||||
if _exo_update_per_ts is True:
|
if _exo_update_per_ts is True:
|
||||||
|
|
|
||||||
|
|
@ -134,20 +134,43 @@ def trigger_condition(s, conditions, cond_opp):
|
||||||
condition_bools = [s[field] in precondition_values for field, precondition_values in conditions.items()]
|
condition_bools = [s[field] in precondition_values for field, precondition_values in conditions.items()]
|
||||||
return reduce(cond_opp, condition_bools)
|
return reduce(cond_opp, condition_bools)
|
||||||
|
|
||||||
def apply_state_condition(conditions, cond_opp, y, f, _g, step, sL, s, _input):
|
def apply_state_condition(pre_conditions, cond_opp, y, f, _g, step, sL, s, _input):
|
||||||
if trigger_condition(s, conditions, cond_opp):
|
if trigger_condition(s, pre_conditions, cond_opp):
|
||||||
return f(_g, step, sL, s, _input)
|
return f(_g, step, sL, s, _input)
|
||||||
else:
|
else:
|
||||||
return y, s[y]
|
return y, s[y]
|
||||||
|
|
||||||
def proc_trigger(y, f, conditions, cond_op):
|
def var_trigger(y, f, pre_conditions, cond_op):
|
||||||
return lambda _g, step, sL, s, _input: apply_state_condition(conditions, cond_op, y, f, _g, step, sL, s, _input)
|
return lambda _g, step, sL, s, _input: apply_state_condition(pre_conditions, cond_op, y, f, _g, step, sL, s, _input)
|
||||||
|
|
||||||
|
|
||||||
def timestep_trigger(end_substep, y, f):
|
def var_substep_trigger(substeps):
|
||||||
conditions = {'substep': [0, end_substep]}
|
def trigger(end_substep, y, f):
|
||||||
cond_opp = lambda a, b: a and b
|
pre_conditions = {'substep': substeps}
|
||||||
return proc_trigger(y, f, conditions, cond_opp)
|
cond_opp = lambda a, b: a and b
|
||||||
|
return var_trigger(y, f, pre_conditions, cond_opp)
|
||||||
|
return lambda y, f: curry(trigger)(substeps)(y)(f)
|
||||||
|
|
||||||
|
|
||||||
|
def env_trigger(end_substep):
|
||||||
|
def trigger(end_substep, trigger_field, trigger_vals, funct_list):
|
||||||
|
def env_update(state_dict, target_value):
|
||||||
|
state_dict_copy = deepcopy(state_dict)
|
||||||
|
# Use supstep to simulate current sysMetrics
|
||||||
|
if state_dict_copy['substep'] == end_substep:
|
||||||
|
state_dict_copy['timestep'] = state_dict_copy['timestep'] + 1
|
||||||
|
|
||||||
|
if state_dict_copy[trigger_field] in trigger_vals:
|
||||||
|
for g in funct_list:
|
||||||
|
target_value = g(target_value)
|
||||||
|
|
||||||
|
del state_dict_copy
|
||||||
|
return target_value
|
||||||
|
|
||||||
|
return env_update
|
||||||
|
|
||||||
|
return lambda trigger_field, trigger_vals, funct_list: \
|
||||||
|
curry(trigger)(end_substep)(trigger_field)(trigger_vals)(funct_list)
|
||||||
|
|
||||||
# trigger = curry(_trigger)
|
# trigger = curry(_trigger)
|
||||||
# print(timestep_trigger)
|
# print(timestep_trigger)
|
||||||
|
|
@ -157,19 +180,15 @@ def timestep_trigger(end_substep, y, f):
|
||||||
def config_sim(d):
|
def config_sim(d):
|
||||||
def process_variables(d):
|
def process_variables(d):
|
||||||
return flatten_tabulated_dict(tabulate_dict(d))
|
return flatten_tabulated_dict(tabulate_dict(d))
|
||||||
|
|
||||||
if "M" in d:
|
if "M" in d:
|
||||||
return [
|
return [{"N": d["N"], "T": d["T"], "M": M} for M in process_variables(d["M"])]
|
||||||
{
|
|
||||||
"N": d["N"],
|
|
||||||
"T": d["T"],
|
|
||||||
"M": M
|
|
||||||
}
|
|
||||||
for M in process_variables(d["M"])
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
d["M"] = [{}]
|
d["M"] = [{}]
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def psub_list(psu_block, psu_steps):
|
||||||
|
return [psu_block[psu] for psu in psu_steps]
|
||||||
|
|
||||||
def psub(policies, state_updates):
|
def psub(policies, state_updates):
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ class udcView(object):
|
||||||
}
|
}
|
||||||
members['methods'] = [k for k, v in self.__dict__.items() if str(type(v)) == "<class 'method'>"]
|
members['methods'] = [k for k, v in self.__dict__.items() if str(type(v)) == "<class 'method'>"]
|
||||||
members.update(variables)
|
members.update(variables)
|
||||||
return f"{members}"
|
return f"{members}" #[1:-1]
|
||||||
|
|
||||||
|
|
||||||
class udcBroker(object):
|
class udcBroker(object):
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from typing import Any, Callable, Dict, List, Tuple
|
||||||
from pathos.pools import ThreadPool as TPool
|
from pathos.pools import ThreadPool as TPool
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
from funcy import compose
|
||||||
|
|
||||||
from cadCAD.engine.utils import engine_exception
|
from cadCAD.engine.utils import engine_exception
|
||||||
from cadCAD.utils import flatten
|
from cadCAD.utils import flatten
|
||||||
|
|
@ -72,19 +73,48 @@ class Executor:
|
||||||
# return {k: reduce(f1, val_list) for k, val_list in new_dict.items()}
|
# return {k: reduce(f1, val_list) for k, val_list in new_dict.items()}
|
||||||
# return foldr(call, col_results)(ops)
|
# return foldr(call, col_results)(ops)
|
||||||
|
|
||||||
|
# def apply_env_proc(
|
||||||
|
# self,
|
||||||
|
# env_processes: Dict[str, Callable],
|
||||||
|
# state_dict: Dict[str, Any],
|
||||||
|
# time_step: int
|
||||||
|
# ) -> Dict[str, Any]:
|
||||||
|
# for state in state_dict.keys():
|
||||||
|
# if state in list(env_processes.keys()):
|
||||||
|
# env_state: Callable = env_processes[state]
|
||||||
|
# if (env_state.__name__ == '_curried') or (env_state.__name__ == 'proc_trigger'):
|
||||||
|
# state_dict[state] = env_state(sub_step)(state_dict[state])
|
||||||
|
# else:
|
||||||
|
# state_dict[state] = env_state(state_dict[state])
|
||||||
|
#
|
||||||
|
# return state_dict
|
||||||
|
|
||||||
def apply_env_proc(
|
def apply_env_proc(
|
||||||
self,
|
self,
|
||||||
env_processes: Dict[str, Callable],
|
env_processes: Dict[str, Callable],
|
||||||
state_dict: Dict[str, Any],
|
state_dict: Dict[str, Any],
|
||||||
sub_step: int
|
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
for state in state_dict.keys():
|
|
||||||
if state in list(env_processes.keys()):
|
def env_composition(target_field, state_dict, target_value):
|
||||||
env_state: Callable = env_processes[state]
|
function_type = type(lambda x: x)
|
||||||
if (env_state.__name__ == '_curried') or (env_state.__name__ == 'proc_trigger'):
|
env_update = env_processes[target_field]
|
||||||
state_dict[state] = env_state(sub_step)(state_dict[state])
|
if isinstance(env_update, list):
|
||||||
else:
|
target_value = compose(*env_update[::-1])(target_value)
|
||||||
state_dict[state] = env_state(state_dict[state])
|
elif isinstance(env_update, function_type):
|
||||||
|
target_value = env_update(state_dict, target_value)
|
||||||
|
else:
|
||||||
|
target_value = env_update
|
||||||
|
|
||||||
|
return target_value
|
||||||
|
|
||||||
|
filtered_state_dict = {k: v for k, v in state_dict.items() if k in env_processes.keys()}
|
||||||
|
env_proc_dict = {
|
||||||
|
target_field: env_composition(target_field, state_dict, target_value)
|
||||||
|
for target_field, target_value in filtered_state_dict.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v in env_proc_dict.items():
|
||||||
|
state_dict[k] = v
|
||||||
|
|
||||||
return state_dict
|
return state_dict
|
||||||
|
|
||||||
|
|
@ -137,7 +167,10 @@ class Executor:
|
||||||
|
|
||||||
last_in_copy: Dict[str, Any] = transfer_missing_fields(last_in_obj, dict(generate_record(state_funcs)))
|
last_in_copy: Dict[str, Any] = transfer_missing_fields(last_in_obj, dict(generate_record(state_funcs)))
|
||||||
# ToDo: Remove
|
# ToDo: Remove
|
||||||
last_in_copy: Dict[str, Any] = self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestep'])
|
# last_in_copy: Dict[str, Any] = self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestep'])
|
||||||
|
last_in_copy: Dict[str, Any] = self.apply_env_proc(env_processes, last_in_copy)
|
||||||
|
|
||||||
|
|
||||||
# ToDo: make 'substep' & 'timestep' reserve fields
|
# ToDo: make 'substep' & 'timestep' reserve fields
|
||||||
last_in_copy['substep'], last_in_copy['timestep'], last_in_copy['run'] = sub_step, time_step, run
|
last_in_copy['substep'], last_in_copy['timestep'], last_in_copy['run'] = sub_step, time_step, run
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
from fn.func import curried
|
||||||
|
|
||||||
from cadCAD.configuration.utils import ep_time_step, time_step
|
from cadCAD.configuration.utils import ep_time_step, time_step
|
||||||
from funcy import curry
|
from funcy import curry
|
||||||
|
import pprint as pp
|
||||||
# from fn import _
|
# from fn import _
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
|
||||||
|
|
@ -25,7 +30,7 @@ def update_timestamp(y, timedelta, format):
|
||||||
def apply(f, y: str, incr_by: int):
|
def apply(f, y: str, incr_by: int):
|
||||||
return lambda _g, step, sL, s, _input: (y, curry(f)(s[y])(incr_by))
|
return lambda _g, step, sL, s, _input: (y, curry(f)(s[y])(incr_by))
|
||||||
|
|
||||||
def add(y: str, incr_by: int):
|
def add(y: str, incr_by):
|
||||||
return apply(lambda a, b: a + b, y, incr_by)
|
return apply(lambda a, b: a + b, y, incr_by)
|
||||||
|
|
||||||
def increment_state_by_int(y: str, incr_by: int):
|
def increment_state_by_int(y: str, incr_by: int):
|
||||||
|
|
@ -85,15 +90,22 @@ def time_model(y, substeps, time_delta, ts_format='%Y-%m-%d %H:%M:%S'):
|
||||||
# multi_cond_opp = lambda a, b: a and b
|
# multi_cond_opp = lambda a, b: a and b
|
||||||
# return proc_trigger2(y, f, multi_conditions, multi_cond_opp)
|
# return proc_trigger2(y, f, multi_conditions, multi_cond_opp)
|
||||||
|
|
||||||
|
#
|
||||||
|
# @curried
|
||||||
|
|
||||||
|
|
||||||
def env_trigger(trigger_field, trigger_val, input, funct_list):
|
|
||||||
y, x = input
|
# print(env_trigger(3).__module__)
|
||||||
if trigger_field == trigger_val:
|
# pp.pprint(dir(env_trigger))
|
||||||
i = 0
|
|
||||||
for g in funct_list:
|
|
||||||
x = g(x)
|
|
||||||
return y, x
|
# @curried
|
||||||
|
# def env_proc_trigger(trigger_time, update_f, time):
|
||||||
|
# if time == trigger_time:
|
||||||
|
# return update_f
|
||||||
|
# else:
|
||||||
|
# return lambda x: x
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -3,3 +3,4 @@ wheel
|
||||||
pathos
|
pathos
|
||||||
fn
|
fn
|
||||||
tabulate
|
tabulate
|
||||||
|
funcy
|
||||||
|
|
@ -16,7 +16,6 @@ run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||||
raw_result, tensor_field = run.main()
|
raw_result, tensor_field = run.main()
|
||||||
result = pd.DataFrame(raw_result)
|
result = pd.DataFrame(raw_result)
|
||||||
def delSH(d):
|
def delSH(d):
|
||||||
print(d)
|
|
||||||
if 'sh' in d.keys():
|
if 'sh' in d.keys():
|
||||||
del d['sh']
|
del d['sh']
|
||||||
return d
|
return d
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ import pandas as pd
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
# The following imports NEED to be in the exact order
|
# The following imports NEED to be in the exact order
|
||||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||||
from simulations.validation import new_sweep_config
|
# from simulations.validation import new_sweep_config
|
||||||
|
from simulations.regression_tests import sweep_config
|
||||||
from cadCAD import configs
|
from cadCAD import configs
|
||||||
|
|
||||||
exec_mode = ExecutionMode()
|
exec_mode = ExecutionMode()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from funcy import compose
|
||||||
import pprint
|
import pprint
|
||||||
|
|
||||||
from cadCAD.configuration import append_configs
|
from cadCAD.configuration import append_configs
|
||||||
from cadCAD.configuration.utils import proc_trigger, ep_time_step, config_sim
|
from cadCAD.configuration.utils import proc_trigger, env_trigger, var_substep_trigger, config_sim, env_proc_trigger, \
|
||||||
|
time_step, psub_list
|
||||||
|
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
|
|
@ -25,74 +27,95 @@ g: Dict[str, List[int]] = {
|
||||||
'omega': [7]
|
'omega': [7]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
psu_steps = ['m1', 'm2', 'm3']
|
||||||
|
system_substeps = len(psu_steps)
|
||||||
|
var_timestep_trigger = var_substep_trigger(system_substeps)
|
||||||
|
env_timestep_trigger = env_trigger(system_substeps)
|
||||||
|
env_process = {}
|
||||||
|
psu_block = {k: {"policies": {}, "variables": {}} for k in psu_steps}
|
||||||
|
|
||||||
|
# ['s1', 's2', 's3', 's4']
|
||||||
# Policies per Mechanism
|
# Policies per Mechanism
|
||||||
def p1m1(_g, step, sL, s):
|
def p1m1(_g, step, sL, s):
|
||||||
return {'param1': 1}
|
return {'param1': 1}
|
||||||
|
psu_block['m1']['policies']['p1'] = p1m1
|
||||||
|
|
||||||
def p2m1(_g, step, sL, s):
|
def p2m1(_g, step, sL, s):
|
||||||
return {'param2': 4}
|
return {'param2': 4}
|
||||||
|
psu_block['m1']['policies']['p2'] = p2m1
|
||||||
|
|
||||||
def p1m2(_g, step, sL, s):
|
def p1m2(_g, step, sL, s):
|
||||||
return {'param1': 'a', 'param2': _g['beta']}
|
return {'param1': 'a', 'param2': _g['beta']}
|
||||||
|
psu_block['m2']['policies']['p1'] = p1m2
|
||||||
|
|
||||||
def p2m2(_g, step, sL, s):
|
def p2m2(_g, step, sL, s):
|
||||||
return {'param1': 'b', 'param2': 0}
|
return {'param1': 'b', 'param2': 0}
|
||||||
|
psu_block['m2']['policies']['p2'] = p2m2
|
||||||
|
|
||||||
def p1m3(_g, step, sL, s):
|
def p1m3(_g, step, sL, s):
|
||||||
return {'param1': np.array([10, 100])}
|
return {'param1': np.array([10, 100])}
|
||||||
|
psu_block['m3']['policies']['p1'] = p1m3
|
||||||
|
|
||||||
def p2m3(_g, step, sL, s):
|
def p2m3(_g, step, sL, s):
|
||||||
return {'param1': np.array([20, 200])}
|
return {'param1': np.array([20, 200])}
|
||||||
|
psu_block['m3']['policies']['p2'] = p2m3
|
||||||
|
|
||||||
|
|
||||||
# Internal States per Mechanism
|
# Internal States per Mechanism
|
||||||
def s1m1(_g, step, sL, s, _input):
|
def s1m1(_g, step, sL, s, _input):
|
||||||
return 's1', 0
|
return 's1', 0
|
||||||
|
psu_block['m1']["variables"]['s1'] = s1m1
|
||||||
|
|
||||||
def s2m1(_g, step, sL, s, _input):
|
def s2m1(_g, step, sL, s, _input):
|
||||||
return 's2', _g['beta']
|
return 's2', _g['beta']
|
||||||
|
psu_block['m1']["variables"]['s2'] = s2m1
|
||||||
|
|
||||||
def s1m2(_g, step, sL, s, _input):
|
def s1m2(_g, step, sL, s, _input):
|
||||||
return 's1', _input['param2']
|
return 's1', _input['param2']
|
||||||
|
psu_block['m2']["variables"]['s1'] = s1m2
|
||||||
|
|
||||||
def s2m2(_g, step, sL, s, _input):
|
def s2m2(_g, step, sL, s, _input):
|
||||||
return 's2', _input['param2']
|
return 's2', _input['param2']
|
||||||
|
psu_block['m2']["variables"]['s2'] = s2m2
|
||||||
|
|
||||||
def s1m3(_g, step, sL, s, _input):
|
def s1m3(_g, step, sL, s, _input):
|
||||||
return 's1', 0
|
return 's1', 0
|
||||||
|
psu_block['m3']["variables"]['s1'] = s1m3
|
||||||
|
|
||||||
def s2m3(_g, step, sL, s, _input):
|
def s2m3(_g, step, sL, s, _input):
|
||||||
return 's2', 0
|
return 's2', 0
|
||||||
|
psu_block['m3']["variables"]['s2'] = s2m3
|
||||||
|
|
||||||
|
|
||||||
# Exogenous States
|
# Exogenous States
|
||||||
|
def update_timestamp(_g, step, sL, s, _input):
|
||||||
|
y = 'timestamp'
|
||||||
|
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||||
|
for m in ['m1','m2','m3']:
|
||||||
|
# psu_block[m]["variables"]['timestamp'] = update_timestamp
|
||||||
|
psu_block[m]["variables"]['timestamp'] = var_timestep_trigger(y='timestamp', f=update_timestamp)
|
||||||
|
# psu_block[m]["variables"]['timestamp'] = proc_trigger(
|
||||||
|
# y='timestamp', f=update_timestamp, pre_conditions={'substep': [0, system_substeps]}, cond_op=lambda a, b: a and b
|
||||||
|
# )
|
||||||
|
|
||||||
proc_one_coef_A = 0.7
|
proc_one_coef_A = 0.7
|
||||||
proc_one_coef_B = 1.3
|
|
||||||
|
|
||||||
|
|
||||||
def es3p1(_g, step, sL, s, _input):
|
def es3p1(_g, step, sL, s, _input):
|
||||||
return 's3', _g['gamma']
|
return 's3', s['s3']
|
||||||
# @curried
|
# use `timestep_trigger` to update every ts
|
||||||
|
for m in ['m1','m2','m3']:
|
||||||
|
psu_block[m]["variables"]['s3'] = var_timestep_trigger(y='s3', f=es3p1)
|
||||||
|
|
||||||
|
proc_one_coef_B = 1.3
|
||||||
def es4p2(_g, step, sL, s, _input):
|
def es4p2(_g, step, sL, s, _input):
|
||||||
return 's4', _g['gamma']
|
return 's4', s['s4'] #+ 4 #g['gamma'] + proc_one_coef_B
|
||||||
|
for m in ['m1','m2','m3']:
|
||||||
ts_format = '%Y-%m-%d %H:%M:%S'
|
psu_block[m]["variables"]['s4'] = var_timestep_trigger(y='s4', f=es4p2)
|
||||||
t_delta = timedelta(days=0, minutes=0, seconds=1)
|
|
||||||
def es5p2(_g, step, sL, s, _input):
|
|
||||||
y = 'timestep'
|
|
||||||
x = ep_time_step(s, dt_str=s['timestep'], fromat_str=ts_format, _timedelta=t_delta)
|
|
||||||
return (y, x)
|
|
||||||
|
|
||||||
|
|
||||||
# Environment States
|
# ToDo: The number of values entered in sweep should be the # of config objs created,
|
||||||
# @curried
|
# not dependent on the # of times the sweep is applied
|
||||||
# def env_a(param, x):
|
# sweep exo_state func and point to exo-state in every other funtion
|
||||||
# return x + param
|
# param sweep on genesis states
|
||||||
def env_a(x):
|
|
||||||
return x
|
|
||||||
def env_b(x):
|
|
||||||
return 10
|
|
||||||
|
|
||||||
|
|
||||||
# Genesis States
|
# Genesis States
|
||||||
genesis_states = {
|
genesis_states = {
|
||||||
|
|
@ -100,83 +123,37 @@ genesis_states = {
|
||||||
's2': Decimal(0.0),
|
's2': Decimal(0.0),
|
||||||
's3': Decimal(1.0),
|
's3': Decimal(1.0),
|
||||||
's4': Decimal(1.0),
|
's4': Decimal(1.0),
|
||||||
# 'timestep': '2018-10-01 15:16:24'
|
'timestamp': '2018-10-01 15:16:24'
|
||||||
}
|
}
|
||||||
|
# Environment Process
|
||||||
|
# ToDo: Validate - make env proc trigger field agnostic
|
||||||
|
env_process["s3"] = [lambda x: x + 1, lambda x: x + 1]
|
||||||
|
env_process["s4"] = env_timestep_trigger(trigger_field='timestep', trigger_vals=[5], funct_list=[lambda x: 1, lambda x: x + 2])
|
||||||
|
|
||||||
|
|
||||||
# remove `exo_update_per_ts` to update every ts
|
|
||||||
raw_exogenous_states = {
|
|
||||||
"s3": es3p1,
|
|
||||||
"s4": es4p2,
|
|
||||||
# "timestep": es5p2
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ToDo: make env proc trigger field agnostic
|
|
||||||
# ToDo: input json into function renaming __name__
|
|
||||||
triggered_env_b = proc_trigger(1, env_b)
|
|
||||||
env_processes = {
|
|
||||||
"s3": env_a, #sweep(beta, env_a),
|
|
||||||
"s4": triggered_env_b #rename('parameterized', triggered_env_b) #sweep(beta, triggered_env_b)
|
|
||||||
}
|
|
||||||
# parameterized_env_processes = parameterize_states(env_processes)
|
|
||||||
#
|
|
||||||
# pp.pprint(parameterized_env_processes)
|
|
||||||
# exit()
|
|
||||||
|
|
||||||
# ToDo: The number of values entered in sweep should be the # of config objs created,
|
|
||||||
# not dependent on the # of times the sweep is applied
|
|
||||||
# sweep exo_state func and point to exo-state in every other funtion
|
|
||||||
# param sweep on genesis states
|
|
||||||
|
|
||||||
partial_state_update_block = {
|
|
||||||
"m1": {
|
|
||||||
"policies": {
|
|
||||||
"b1": p1m1,
|
|
||||||
"b2": p2m1
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"s1": s1m1,
|
|
||||||
"s2": s2m1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"m2": {
|
|
||||||
"policies": {
|
|
||||||
"b1": p1m2,
|
|
||||||
"b2": p2m2,
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"s1": s1m2,
|
|
||||||
"s2": s2m2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"m3": {
|
|
||||||
"policies": {
|
|
||||||
"b1": p1m3,
|
|
||||||
"b2": p2m3
|
|
||||||
},
|
|
||||||
"variables": {
|
|
||||||
"s1": s1m3,
|
|
||||||
"s2": s2m3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# config_sim Necessary
|
# config_sim Necessary
|
||||||
sim_config = config_sim(
|
sim_config = config_sim(
|
||||||
{
|
{
|
||||||
"N": 2,
|
"N": 2,
|
||||||
"T": range(5),
|
"T": range(5),
|
||||||
"M": g # Optional
|
"M": g, # Optional
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# New Convention
|
# New Convention
|
||||||
|
partial_state_update_blocks = psub_list(psu_block, psu_steps)
|
||||||
append_configs(
|
append_configs(
|
||||||
sim_configs=sim_config,
|
sim_configs=sim_config,
|
||||||
initial_state=genesis_states,
|
initial_state=genesis_states,
|
||||||
seeds=seeds,
|
seeds=seeds,
|
||||||
raw_exogenous_states=raw_exogenous_states,
|
env_processes=env_process,
|
||||||
env_processes=env_processes,
|
partial_state_update_blocks=partial_state_update_blocks
|
||||||
partial_state_update_blocks=partial_state_update_block
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("Policie State Update Block:")
|
||||||
|
pp.pprint(partial_state_update_blocks)
|
||||||
|
print()
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ from functools import reduce
|
||||||
|
|
||||||
from cadCAD.utils import SilentDF #, val_switch
|
from cadCAD.utils import SilentDF #, val_switch
|
||||||
from cadCAD.configuration import append_configs
|
from cadCAD.configuration import append_configs
|
||||||
from cadCAD.configuration.utils import time_step, config_sim, proc_trigger, timestep_trigger, genereate_psubs
|
from cadCAD.configuration.utils import time_step, config_sim, var_trigger, var_substep_trigger, genereate_psubs, \
|
||||||
|
env_trigger, psub_list
|
||||||
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
|
@ -69,32 +70,36 @@ state_dict = {
|
||||||
'timestamp': '2019-01-01 00:00:00'
|
'timestamp': '2019-01-01 00:00:00'
|
||||||
}
|
}
|
||||||
|
|
||||||
policies, state_updates = {}, {}
|
psu_steps = ['m1', 'm2', 'm3']
|
||||||
#
|
system_substeps = len(psu_steps)
|
||||||
# def assign_udo_policy(udo):
|
var_timestep_trigger = var_substep_trigger([0, system_substeps])
|
||||||
# def policy(_g, step, sL, s):
|
env_timestep_trigger = env_trigger(system_substeps)
|
||||||
# s['udo_policies'][udo].updateX()
|
psu_block = {k: {"policies": {}, "variables": {}} for k in psu_steps}
|
||||||
# return {udo: udoPipe(s['udo_policies'][udo])}
|
|
||||||
# return policy
|
|
||||||
# policies_updates = {p: assign_udo_policy(udo) for p, udo in zip(['p1', 'p2'], ['udo_A', 'udo_B'])}
|
|
||||||
|
|
||||||
def udo_policyA(_g, step, sL, s):
|
def udo_policyA(_g, step, sL, s):
|
||||||
s['udo_policies']['udo_A'].updateX()
|
s['udo_policies']['udo_A'].updateX()
|
||||||
return {'udo_A': udoPipe(s['udo_policies']['udo_A'])}
|
return {'udo_A': udoPipe(s['udo_policies']['udo_A'])}
|
||||||
policies['a'] = udo_policyA
|
# policies['a'] = udo_policyA
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]['policies']['a'] = udo_policyA
|
||||||
|
|
||||||
def udo_policyB(_g, step, sL, s):
|
def udo_policyB(_g, step, sL, s):
|
||||||
s['udo_policies']['udo_B'].updateX()
|
s['udo_policies']['udo_B'].updateX()
|
||||||
return {'udo_B': udoPipe(s['udo_policies']['udo_B'])}
|
return {'udo_B': udoPipe(s['udo_policies']['udo_B'])}
|
||||||
policies['b'] = udo_policyB
|
# policies['b'] = udo_policyB
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]['policies']['b'] = udo_policyB
|
||||||
|
|
||||||
|
|
||||||
# policies = {"p1": udo_policyA, "p2": udo_policyB}
|
# policies = {"p1": udo_policyA, "p2": udo_policyB}
|
||||||
# policies = {"A": udo_policyA, "B": udo_policyB}
|
# policies = {"A": udo_policyA, "B": udo_policyB}
|
||||||
|
|
||||||
# def increment_state_by_int(y: str, incr_by: int):
|
def add(y: str, added_val):
|
||||||
# return lambda _g, step, sL, s, _input: (y, s[y] + incr_by)
|
return lambda _g, step, sL, s, _input: (y, s[y] + added_val)
|
||||||
state_updates['increment'] = add('increment', 1)
|
# state_updates['increment'] = add('increment', 1)
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['increment'] = add('increment', 1)
|
||||||
|
|
||||||
|
|
||||||
@curried
|
@curried
|
||||||
def perceive(s, self):
|
def perceive(s, self):
|
||||||
|
|
@ -110,12 +115,15 @@ def state_udo_update(_g, step, sL, s, _input):
|
||||||
s['state_udo'].updateX().perceive(s)
|
s['state_udo'].updateX().perceive(s)
|
||||||
x = udoPipe(s['state_udo'])
|
x = udoPipe(s['state_udo'])
|
||||||
return y, x
|
return y, x
|
||||||
state_updates['state_udo'] = state_udo_update
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['state_udo'] = state_udo_update
|
||||||
|
|
||||||
|
|
||||||
def track(destination, source):
|
def track(destination, source):
|
||||||
return lambda _g, step, sL, s, _input: (destination, s[source].x)
|
return lambda _g, step, sL, s, _input: (destination, s[source].x)
|
||||||
state_updates['state_udo_tracker'] = track('state_udo_tracker', 'state_udo')
|
state_udo_tracker = track('state_udo_tracker', 'state_udo')
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['state_udo_tracker'] = state_udo_tracker
|
||||||
|
|
||||||
|
|
||||||
def track_state_udo_perception(destination, source):
|
def track_state_udo_perception(destination, source):
|
||||||
|
|
@ -125,12 +133,15 @@ def track_state_udo_perception(destination, source):
|
||||||
else:
|
else:
|
||||||
return past_perception
|
return past_perception
|
||||||
return lambda _g, step, sL, s, _input: (destination, id(s[source].perception))
|
return lambda _g, step, sL, s, _input: (destination, id(s[source].perception))
|
||||||
state_updates['state_udo_perception_tracker'] = track_state_udo_perception('state_udo_perception_tracker', 'state_udo')
|
state_udo_perception_tracker = track_state_udo_perception('state_udo_perception_tracker', 'state_udo')
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['state_udo_perception_tracker'] = state_udo_perception_tracker
|
||||||
|
|
||||||
|
|
||||||
def view_udo_policy(_g, step, sL, s, _input):
|
def view_udo_policy(_g, step, sL, s, _input):
|
||||||
return 'udo_policies', _input
|
return 'udo_policies', _input
|
||||||
state_updates['udo_policies'] = view_udo_policy
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['udo_policies'] = view_udo_policy
|
||||||
|
|
||||||
|
|
||||||
def track_udo_policy(destination, source):
|
def track_udo_policy(destination, source):
|
||||||
|
|
@ -140,56 +151,32 @@ def track_udo_policy(destination, source):
|
||||||
else:
|
else:
|
||||||
return v.x
|
return v.x
|
||||||
return lambda _g, step, sL, s, _input: (destination, tuple(val_switch(v) for _, v in s[source].items()))
|
return lambda _g, step, sL, s, _input: (destination, tuple(val_switch(v) for _, v in s[source].items()))
|
||||||
state_updates['udo_policy_tracker'] = track_udo_policy('udo_policy_tracker', 'udo_policies')
|
udo_policy_tracker = track_udo_policy('udo_policy_tracker', 'udo_policies')
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['udo_policy_tracker'] = udo_policy_tracker
|
||||||
|
|
||||||
|
|
||||||
def update_timestamp(_g, step, sL, s, _input):
|
def update_timestamp(_g, step, sL, s, _input):
|
||||||
y = 'timestamp'
|
y = 'timestamp'
|
||||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||||
|
for m in psu_steps:
|
||||||
|
psu_block[m]["variables"]['timestamp'] = var_timestep_trigger(y='timestamp', f=update_timestamp)
|
||||||
|
# psu_block[m]["variables"]['timestamp'] = var_trigger(
|
||||||
|
# y='timestamp', f=update_timestamp,
|
||||||
|
# pre_conditions={'substep': [0, system_substeps]}, cond_op=lambda a, b: a and b
|
||||||
|
# )
|
||||||
|
# psu_block[m]["variables"]['timestamp'] = update_timestamp
|
||||||
|
|
||||||
|
|
||||||
system_substeps = 3
|
|
||||||
# state_updates['timestamp'] = update_timestamp
|
|
||||||
state_updates['timestamp'] = timestep_trigger(end_substep=system_substeps, y='timestamp', f=update_timestamp)
|
|
||||||
# state_updates['timestamp'] = proc_trigger(y='timestamp', f=update_timestamp, conditions={'substep': [0, substeps]}, cond_op=lambda a, b: a and b)
|
|
||||||
|
|
||||||
print()
|
|
||||||
print("State Updates:")
|
|
||||||
pp.pprint(state_updates)
|
|
||||||
print()
|
|
||||||
print("Policies:")
|
|
||||||
pp.pprint(policies)
|
|
||||||
print()
|
|
||||||
|
|
||||||
filter_out = lambda remove_list, state_list: list(filter(lambda state: state not in remove_list, state_list))
|
|
||||||
|
|
||||||
states = list(state_updates.keys())
|
|
||||||
# states_noTS = filter_out(['timestamp'], states)
|
|
||||||
# states_grid = [states,states_noTS,states_noTS]
|
|
||||||
|
|
||||||
# states_grid = [states] * system_substeps #
|
|
||||||
states_grid = [states,states,states]
|
|
||||||
policy_grid = [['a', 'b'], ['a', 'b'], ['a', 'b']]
|
|
||||||
|
|
||||||
|
|
||||||
PSUBS = genereate_psubs(policy_grid, states_grid, policies, state_updates)
|
|
||||||
pp.pprint(PSUBS)
|
|
||||||
# ToDo: Bug without specifying parameters
|
# ToDo: Bug without specifying parameters
|
||||||
|
# New Convention
|
||||||
|
partial_state_update_blocks = psub_list(psu_block, psu_steps)
|
||||||
append_configs(
|
append_configs(
|
||||||
sim_configs=sim_config,
|
sim_configs=sim_config,
|
||||||
initial_state=state_dict,
|
initial_state=state_dict,
|
||||||
seeds={},
|
partial_state_update_blocks=partial_state_update_blocks
|
||||||
raw_exogenous_states={},
|
|
||||||
env_processes={},
|
|
||||||
partial_state_update_blocks=PSUBS,
|
|
||||||
# policy_ops=[lambda a, b: {**a, **b}]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# pp.pprint(partial_state_update_blocks)
|
print()
|
||||||
|
print("State Updates:")
|
||||||
# PSUB = {
|
pp.pprint(partial_state_update_blocks)
|
||||||
# 'policies': policies,
|
print()
|
||||||
# 'states': state_updates
|
|
||||||
# }
|
|
||||||
# partial_state_update_blocks = [PSUB] * substeps
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -5,7 +5,7 @@ from cadCAD.configuration import append_configs
|
||||||
from cadCAD.configuration.utils import time_step, ep_time_step, config_sim
|
from cadCAD.configuration.utils import time_step, ep_time_step, config_sim
|
||||||
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
import pprint as pp
|
||||||
from fn.func import curried
|
from fn.func import curried
|
||||||
|
|
||||||
DF = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv'))
|
DF = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv'))
|
||||||
|
|
@ -161,3 +161,8 @@ append_configs(
|
||||||
partial_state_update_blocks=partial_state_update_blocks,
|
partial_state_update_blocks=partial_state_update_blocks,
|
||||||
# policy_ops=[lambda a, b: {**a, **b}]
|
# policy_ops=[lambda a, b: {**a, **b}]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("State Updates:")
|
||||||
|
pp.pprint(partial_state_update_blocks)
|
||||||
|
print()
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from cadCAD.configuration import append_configs
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
@ -21,11 +22,98 @@ for node in G.nodes:
|
||||||
scale=100
|
scale=100
|
||||||
nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls'))
|
nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls'))
|
||||||
|
|
||||||
initial_conditions = {'balls': balls, 'network': G}
|
def greedy_robot(src_balls, dst_balls):
|
||||||
|
# robot wishes to accumlate balls at its source
|
||||||
|
# takes half of its neighbors balls
|
||||||
|
if src_balls < dst_balls:
|
||||||
|
return -np.floor(dst_balls / 2)
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def fair_robot(src_balls, dst_balls):
|
||||||
|
# robot follows the simple balancing rule
|
||||||
|
return np.sign(src_balls - dst_balls)
|
||||||
|
|
||||||
|
|
||||||
|
def giving_robot(src_balls, dst_balls):
|
||||||
|
# robot wishes to gice away balls one at a time
|
||||||
|
if src_balls > 0:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
robot_strategies = [greedy_robot,fair_robot, giving_robot]
|
||||||
|
|
||||||
|
for node in G.nodes:
|
||||||
|
nstrats = len(robot_strategies)
|
||||||
|
rv = np.random.randint(0,nstrats)
|
||||||
|
G.nodes[node]['strat'] = robot_strategies[rv]
|
||||||
|
|
||||||
|
for e in G.edges:
|
||||||
|
owner_node = e[0]
|
||||||
|
G.edges[e]['strat'] = G.nodes[owner_node]['strat']
|
||||||
|
|
||||||
|
default_policy = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': {}}
|
||||||
|
class robot(object):
|
||||||
|
def __init__(self, graph, balls, internal_policy=default_policy):
|
||||||
|
self.mem_id = str(hex(id(self)))
|
||||||
|
self.internal_policy = internal_policy
|
||||||
|
self.graph = graph
|
||||||
|
self.balls = balls
|
||||||
|
|
||||||
|
|
||||||
|
def robotic_network(self, graph, balls): # move balls
|
||||||
|
self.graph, self.balls = graph, balls
|
||||||
|
delta_balls = {}
|
||||||
|
for e in self.graph.edges:
|
||||||
|
src = e[0]
|
||||||
|
src_balls = self.balls[src]
|
||||||
|
dst = e[1]
|
||||||
|
dst_balls = self.balls[dst]
|
||||||
|
|
||||||
|
# transfer balls according to specific robot strat
|
||||||
|
strat = self.graph.edges[e]['strat']
|
||||||
|
delta_balls[e] = strat(src_balls, dst_balls)
|
||||||
|
|
||||||
|
self.internal_policy = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': delta_balls}
|
||||||
|
return self
|
||||||
|
|
||||||
|
def agent_arrival(self, graph, balls): # add node
|
||||||
|
self.graph, self.balls = graph, balls
|
||||||
|
node = len(self.graph.nodes)
|
||||||
|
edge_list = self.graph.edges
|
||||||
|
|
||||||
|
# choose a m random edges without replacement
|
||||||
|
# new = np.random.choose(edgelist,m)
|
||||||
|
new = [0, 1] # tester
|
||||||
|
|
||||||
|
nodes = [node]
|
||||||
|
edges = [(node, new_node) for new_node in new]
|
||||||
|
|
||||||
|
initial_balls = {node: np.random.randint(1, 25)}
|
||||||
|
|
||||||
|
rv = np.random.randint(0, nstrats)
|
||||||
|
node_strat = {node: robot_strategies[rv]}
|
||||||
|
|
||||||
|
edge_strats = {e: robot_strategies[rv] for e in edges}
|
||||||
|
|
||||||
|
self.internal_policy = {'nodes': nodes,
|
||||||
|
'edges': edges,
|
||||||
|
'quantity': initial_balls,
|
||||||
|
'node_strats': node_strat,
|
||||||
|
'edge_strats': edge_strats,
|
||||||
|
'delta': np.zeros(node + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
robot_udo = UDO(udo=robot(G, balls), masked_members=['obj'])
|
||||||
|
initial_conditions = {'balls': balls, 'network': G, 'robot': robot_udo}
|
||||||
|
|
||||||
|
|
||||||
def update_balls(params, step, sL, s, _input):
|
def update_balls(params, step, sL, s, _input):
|
||||||
delta_balls = _input['delta']
|
delta_balls = _input['robot'].internal_policy['delta']
|
||||||
new_balls = s['balls']
|
new_balls = s['balls']
|
||||||
for e in G.edges:
|
for e in G.edges:
|
||||||
move_ball = delta_balls[e]
|
move_ball = delta_balls[e]
|
||||||
|
|
@ -42,20 +130,20 @@ def update_balls(params, step, sL, s, _input):
|
||||||
|
|
||||||
|
|
||||||
def update_network(params, step, sL, s, _input):
|
def update_network(params, step, sL, s, _input):
|
||||||
new_nodes = _input['nodes']
|
new_nodes = _input['robot'].internal_policy['nodes']
|
||||||
new_edges = _input['edges']
|
new_edges = _input['robot'].internal_policy['edges']
|
||||||
new_balls = _input['quantity']
|
new_balls = _input['robot'].internal_policy['quantity']
|
||||||
|
|
||||||
graph = s['network']
|
graph = s['network']
|
||||||
|
|
||||||
for node in new_nodes:
|
for node in new_nodes:
|
||||||
graph.add_node(node)
|
graph.add_node(node)
|
||||||
graph.nodes[node]['initial_balls'] = new_balls[node]
|
graph.nodes[node]['initial_balls'] = new_balls[node]
|
||||||
graph.nodes[node]['strat'] = _input['node_strats'][node]
|
graph.nodes[node]['strat'] = _input['robot'].internal_policy['node_strats'][node]
|
||||||
|
|
||||||
for edge in new_edges:
|
for edge in new_edges:
|
||||||
graph.add_edge(edge[0], edge[1])
|
graph.add_edge(edge[0], edge[1])
|
||||||
graph.edges[edge]['strat'] = _input['edge_strats'][edge]
|
graph.edges[edge]['strat'] = _input['robot'].internal_policy['edge_strats'][edge]
|
||||||
|
|
||||||
key = 'network'
|
key = 'network'
|
||||||
value = graph
|
value = graph
|
||||||
|
|
@ -63,8 +151,8 @@ def update_network(params, step, sL, s, _input):
|
||||||
|
|
||||||
|
|
||||||
def update_network_balls(params, step, sL, s, _input):
|
def update_network_balls(params, step, sL, s, _input):
|
||||||
new_nodes = _input['nodes']
|
new_nodes = _input['robot'].internal_policy['nodes']
|
||||||
new_balls = _input['quantity']
|
new_balls = _input['robot'].internal_policy['quantity']
|
||||||
balls = np.zeros(len(s['balls']) + len(new_nodes))
|
balls = np.zeros(len(s['balls']) + len(new_nodes))
|
||||||
|
|
||||||
for node in s['network'].nodes:
|
for node in s['network'].nodes:
|
||||||
|
|
@ -79,91 +167,17 @@ def update_network_balls(params, step, sL, s, _input):
|
||||||
return (key, value)
|
return (key, value)
|
||||||
|
|
||||||
|
|
||||||
def greedy_robot(src_balls, dst_balls):
|
|
||||||
# robot wishes to accumlate balls at its source
|
|
||||||
# takes half of its neighbors balls
|
|
||||||
if src_balls < dst_balls:
|
|
||||||
delta = -np.floor(dst_balls / 2)
|
|
||||||
else:
|
|
||||||
delta = 0
|
|
||||||
|
|
||||||
return delta
|
|
||||||
|
|
||||||
|
|
||||||
def fair_robot(src_balls, dst_balls):
|
|
||||||
# robot follows the simple balancing rule
|
|
||||||
delta = np.sign(src_balls - dst_balls)
|
|
||||||
|
|
||||||
return delta
|
|
||||||
|
|
||||||
|
|
||||||
def giving_robot(src_balls, dst_balls):
|
|
||||||
# robot wishes to gice away balls one at a time
|
|
||||||
if src_balls > 0:
|
|
||||||
delta = 1
|
|
||||||
else:
|
|
||||||
delta = 0
|
|
||||||
|
|
||||||
return delta
|
|
||||||
|
|
||||||
robot_strategies = [greedy_robot,fair_robot, giving_robot]
|
|
||||||
|
|
||||||
for node in G.nodes:
|
|
||||||
nstrats = len(robot_strategies)
|
|
||||||
rv = np.random.randint(0,nstrats)
|
|
||||||
G.nodes[node]['strat'] = robot_strategies[rv]
|
|
||||||
|
|
||||||
for e in G.edges:
|
|
||||||
owner_node = e[0]
|
|
||||||
G.edges[e]['strat'] = G.nodes[owner_node]['strat']
|
|
||||||
|
|
||||||
|
|
||||||
def robotic_network(params, step, sL, s):
|
def robotic_network(params, step, sL, s):
|
||||||
graph = s['network']
|
s['robot'].robotic_network(s['network'], s['balls'])
|
||||||
|
return {'robot': udoPipe(s['robot'])}
|
||||||
delta_balls = {}
|
|
||||||
for e in graph.edges:
|
|
||||||
src = e[0]
|
|
||||||
src_balls = s['balls'][src]
|
|
||||||
dst = e[1]
|
|
||||||
dst_balls = s['balls'][dst]
|
|
||||||
|
|
||||||
# transfer balls according to specific robot strat
|
|
||||||
strat = graph.edges[e]['strat']
|
|
||||||
delta_balls[e] = strat(src_balls, dst_balls)
|
|
||||||
|
|
||||||
return_dict = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': delta_balls}
|
|
||||||
|
|
||||||
return (return_dict)
|
|
||||||
|
|
||||||
|
|
||||||
def agent_arrival(params, step, sL, s):
|
def agent_arrival(params, step, sL, s):
|
||||||
node = len(s['network'].nodes)
|
s['robot'].agent_arrival(s['network'], s['balls'])
|
||||||
edge_list = s['network'].edges
|
return {'robot': udoPipe(s['robot'])}
|
||||||
|
|
||||||
# choose a m random edges without replacement
|
|
||||||
# new = np.random.choose(edgelist,m)
|
|
||||||
new = [0, 1] # tester
|
|
||||||
|
|
||||||
nodes = [node]
|
|
||||||
edges = [(node, new_node) for new_node in new]
|
|
||||||
|
|
||||||
initial_balls = {node: np.random.randint(1, 25)}
|
|
||||||
|
|
||||||
rv = np.random.randint(0, nstrats)
|
|
||||||
node_strat = {node: robot_strategies[rv]}
|
|
||||||
|
|
||||||
edge_strats = {e: robot_strategies[rv] for e in edges}
|
|
||||||
|
|
||||||
return_dict = {'nodes': nodes,
|
|
||||||
'edges': edges,
|
|
||||||
'quantity': initial_balls,
|
|
||||||
'node_strats': node_strat,
|
|
||||||
'edge_strats': edge_strats,
|
|
||||||
'delta': np.zeros(node + 1)
|
|
||||||
}
|
|
||||||
return (return_dict)
|
|
||||||
|
|
||||||
|
def get_robot(params, step, sL, s, _input):
|
||||||
|
return 'robot', _input['robot']
|
||||||
|
|
||||||
partial_state_update_blocks = [
|
partial_state_update_blocks = [
|
||||||
{
|
{
|
||||||
|
|
@ -172,7 +186,8 @@ partial_state_update_blocks = [
|
||||||
'p1': robotic_network
|
'p1': robotic_network
|
||||||
},
|
},
|
||||||
'variables': { # The following state variables will be updated simultaneously
|
'variables': { # The following state variables will be updated simultaneously
|
||||||
'balls': update_balls
|
'balls': update_balls,
|
||||||
|
'robot': get_robot
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -183,7 +198,8 @@ partial_state_update_blocks = [
|
||||||
},
|
},
|
||||||
'variables': { # The following state variables will be updated simultaneously
|
'variables': { # The following state variables will be updated simultaneously
|
||||||
'network': update_network,
|
'network': update_network,
|
||||||
'balls': update_network_balls
|
'balls': update_network_balls,
|
||||||
|
'robot': get_robot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -2,7 +2,6 @@ import pandas as pd
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
# The following imports NEED to be in the exact order
|
# The following imports NEED to be in the exact order
|
||||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||||
from simulations.validation import marbles2
|
|
||||||
from cadCAD import configs
|
from cadCAD import configs
|
||||||
|
|
||||||
exec_mode = ExecutionMode()
|
exec_mode = ExecutionMode()
|
||||||
|
|
@ -20,6 +19,7 @@ print("Tensor Field: config1")
|
||||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||||
print("Output:")
|
print("Output:")
|
||||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||||
|
print(result[['network']])
|
||||||
print()
|
print()
|
||||||
|
|
||||||
print(result[['network', 'substep']])
|
print(result[['network', 'substep']])
|
||||||
|
|
@ -2,10 +2,9 @@ import pandas as pd
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
# The following imports NEED to be in the exact order
|
# The following imports NEED to be in the exact order
|
||||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||||
from simulations.validation import udo
|
from simulations.regression_tests import udo_inter_substep_update
|
||||||
from cadCAD import configs
|
from cadCAD import configs
|
||||||
|
|
||||||
|
|
||||||
exec_mode = ExecutionMode()
|
exec_mode = ExecutionMode()
|
||||||
|
|
||||||
print("Simulation Execution: Single Configuration")
|
print("Simulation Execution: Single Configuration")
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||||
from simulations.regression_tests import udo
|
from simulations.regression_tests import udo
|
||||||
from cadCAD import configs
|
from cadCAD import configs
|
||||||
|
|
||||||
|
|
||||||
exec_mode = ExecutionMode()
|
exec_mode = ExecutionMode()
|
||||||
|
|
||||||
print("Simulation Execution: Single Configuration")
|
print("Simulation Execution: Single Configuration")
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
from cadCAD.configuration import append_configs
|
from cadCAD.configuration import append_configs
|
||||||
from cadCAD.configuration.utils import config_sim
|
from cadCAD.configuration.utils import config_sim
|
||||||
|
|
||||||
|
# Policies per Mechanism
|
||||||
|
# def p(_g, substep, sH, s):
|
||||||
|
# return {'last_update_block': sH[-1]}
|
||||||
|
|
||||||
|
# def policies(_g, substep, sH, s, _input):
|
||||||
|
# y = 'policies'
|
||||||
|
# x = _input
|
||||||
|
# return (y, x)
|
||||||
|
|
||||||
|
# policies = {"p1": p, "p2": p}
|
||||||
|
|
||||||
|
|
||||||
# last_partial_state_update_block
|
# last_partial_state_update_block
|
||||||
def last_update_block(_g, substep, sH, s, _input):
|
def last_update_block(_g, substep, sH, s, _input):
|
||||||
return 'sh', sH[-1]
|
return 'sh', sH[-1]
|
||||||
|
|
||||||
|
|
||||||
# Policies per Mechanism
|
|
||||||
def p(_g, substep, sH, s):
|
|
||||||
return {'last_update_block': sH[-1]}
|
|
||||||
|
|
||||||
def add(y, x):
|
def add(y, x):
|
||||||
return lambda _g, substep, sH, s, _input: (y, s[y] + x)
|
return lambda _g, substep, sH, s, _input: (y, s[y] + x)
|
||||||
|
|
||||||
def policies(_g, substep, sH, s, _input):
|
|
||||||
y = 'policies'
|
|
||||||
x = _input
|
|
||||||
return (y, x)
|
|
||||||
|
|
||||||
policies = {"p1": p, "p2": p}
|
|
||||||
|
|
||||||
genesis_states = {
|
genesis_states = {
|
||||||
's': 0,
|
's': 0,
|
||||||
'sh': [{}], # {[], {}}
|
'sh': [{}], # {[], {}}
|
||||||
|
|
@ -34,7 +34,7 @@ variables = {
|
||||||
|
|
||||||
|
|
||||||
PSUB = {
|
PSUB = {
|
||||||
"policies": policies,
|
"policies": {}, #policies,
|
||||||
"variables": variables
|
"variables": variables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,6 +58,5 @@ append_configs(
|
||||||
seeds={},
|
seeds={},
|
||||||
raw_exogenous_states={},
|
raw_exogenous_states={},
|
||||||
env_processes={},
|
env_processes={},
|
||||||
partial_state_update_blocks=partial_state_update_block,
|
partial_state_update_blocks=partial_state_update_block
|
||||||
policy_ops=[lambda a, b: a + b]
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue