diff --git a/cadCAD/engine/simulation.py b/cadCAD/engine/simulation.py index 0eb8605..f9914d5 100644 --- a/cadCAD/engine/simulation.py +++ b/cadCAD/engine/simulation.py @@ -88,6 +88,7 @@ class Executor: return state_dict + # ToDo: Redifined as a function that applies the tensor field to a set og last conditions # mech_step def partial_state_update( self, @@ -106,7 +107,7 @@ class Executor: last_in_obj: Dict[str, Any] = sL[-1] # last_in_obj: Dict[str, Any] = sH[-1] # print(last_in_obj) - # print(sH[-1]) + print(sH[-1]) _input: Dict[str, Any] = self.policy_update_exception(self.get_policy_input(var_dict, sub_step, sH, last_in_obj, policy_funcs)) @@ -168,7 +169,7 @@ class Executor: # ToDo: Causes Substep repeats in sL, use for yield sub_step += 1 - for [s_conf, p_conf] in configs: + for [s_conf, p_conf] in configs: # tensor field states_list: List[Dict[str, Any]] = self.partial_state_update( var_dict, sub_step, states_list, simulation_list, s_conf, p_conf, env_processes, time_step, run ) @@ -193,6 +194,7 @@ class Executor: ) -> List[List[Dict[str, Any]]]: time_seq: List[int] = [x + 1 for x in time_seq] + # ToDo: simulation_list should be a Tensor that is generated throughout the Executor simulation_list: List[List[Dict[str, Any]]] = [states_list] # print(simulation_list[-1]) @@ -211,6 +213,8 @@ class Executor: return simulation_list + # ToDo: Below can be recieved from a tensor field + # configs: List[Tuple[List[Callable], List[Callable]]] def simulation( self, var_dict: Dict[str, List[Any]], diff --git a/cadCAD/utils/sys_config.py b/cadCAD/utils/sys_config.py index 90d3250..cf45e88 100644 --- a/cadCAD/utils/sys_config.py +++ b/cadCAD/utils/sys_config.py @@ -19,6 +19,12 @@ def update_timestamp(y, timedelta, format): ep_time_step(s, dt_str=s[y], fromat_str=format, _timedelta=timedelta) ) +def add(y, x): + return lambda _g, step, sH, s, _input: (y, s[y] + x) + +def s(y, x): + return lambda _g, step, sH, s, _input: (y, x) + # def repr(_g, step, sL, s, _input): # y = 'z' diff --git a/simulations/external_ds_run.py b/simulations/external_ds_run.py new file mode 100644 index 0000000..0c1f16b --- /dev/null +++ b/simulations/external_ds_run.py @@ -0,0 +1,29 @@ +import pandas as pd +from tabulate import tabulate +# The following imports NEED to be in the exact order +from cadCAD.engine import ExecutionMode, ExecutionContext, Executor +# from simulations.validation import config1_test_pipe +# from simulations.validation import config1 +# from simulations.validation import externalds +from simulations.validation import external_dataset +from cadCAD import configs + +exec_mode = ExecutionMode() + +print("Simulation Execution: Single Configuration") +print() +first_config = configs # only contains config1 +single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) +run = Executor(exec_context=single_proc_ctx, configs=first_config) + +raw_result, tensor_field = run.main() +result = pd.DataFrame(raw_result) +result = pd.concat([result, result['external_data'].apply(pd.Series)], axis=1)[ + ['run', 'substep', 'timestep', 'increment', 'external_data', 'ds1', 'ds2', 'ds3', 'policies'] +] +print() +print("Tensor Field: config1") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() diff --git a/simulations/externalds_run.py b/simulations/externalds_run.py index 569d432..9edcf8c 100644 --- a/simulations/externalds_run.py +++ b/simulations/externalds_run.py @@ -4,7 +4,7 @@ from tabulate import tabulate from cadCAD.engine import ExecutionMode, ExecutionContext, Executor # from simulations.validation import config1_test_pipe # from simulations.validation import config1 -from simulations.validation import externalds +from simulations.validation import write_simulation from cadCAD import configs exec_mode = ExecutionMode() diff --git a/simulations/single_config_run.py b/simulations/single_config_run.py index 081d4e1..9bd4737 100644 --- a/simulations/single_config_run.py +++ b/simulations/single_config_run.py @@ -2,10 +2,11 @@ import pandas as pd from tabulate import tabulate # The following imports NEED to be in the exact order from cadCAD.engine import ExecutionMode, ExecutionContext, Executor -# from simulations.validation import config1_test_pipe +# from simulations.validation import policy_aggregation +from simulations.validation import historical_state_access # from simulations.validation import config1 # from simulations.validation import externalds -from simulations.validation import incr_external_dataset +# from simulations.validation import external_dataset from cadCAD import configs exec_mode = ExecutionMode() diff --git a/simulations/sweep_udc_hack_run.py b/simulations/sweep_udc_hack_run.py deleted file mode 100644 index dd33c16..0000000 --- a/simulations/sweep_udc_hack_run.py +++ /dev/null @@ -1,24 +0,0 @@ -import pandas as pd -from tabulate import tabulate -# The following imports NEED to be in the exact order -from cadCAD.engine import ExecutionMode, ExecutionContext, Executor -from simulations.validation import config_udc_json2 -from cadCAD import configs - -exec_mode = ExecutionMode() - -print("Simulation Execution: Concurrent Execution") -multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc) -run = Executor(exec_context=multi_proc_ctx, configs=configs) - -i = 0 -config_names = ['sweep_config_A', 'sweep_config_B'] -for raw_result, tensor_field in run.main(): - result = pd.DataFrame(raw_result) - print() - print("Tensor Field: " + config_names[i]) - print(tabulate(tensor_field, headers='keys', tablefmt='psql')) - print("Output:") - print(tabulate(result, headers='keys', tablefmt='psql')) - print() - i += 1 diff --git a/simulations/validation/config4.py b/simulations/validation/config4.py index 164df26..8e00129 100644 --- a/simulations/validation/config4.py +++ b/simulations/validation/config4.py @@ -92,8 +92,6 @@ def env_a(x): return 5 def env_b(x): return 10 -# def what_ever(x): -# return x + 1 # Genesis States diff --git a/simulations/validation/config_az.py b/simulations/validation/config_az.py deleted file mode 100644 index 746df2d..0000000 --- a/simulations/validation/config_az.py +++ /dev/null @@ -1,89 +0,0 @@ -from datetime import timedelta -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim - - -class MyClass: - def __init__(self): - self.x = 0 - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - def update(self): - # res = deepcopy(self) - self.x += 1 - # print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self #res - - def __str__(self): - return f"PRINT MyClass: @ {hex(id(self))}: value {self.x}" - -# genesis state -state_dict = { - 'classX': MyClass(), - 'a': 0, - 'b': 0, - 'timestamp': '2019-01-01 00:00:00' -} - - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - - -def updateClassX(_g, step, sL, s, _input): - y = 'classX' - x = s['classX'] - return (y, x) - - -def updateA(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - - -def updateB(_g, step, sL, s, _input): - s['classX'].update() - y = 'b' - x = s['classX'].x - return (y, x) - - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - 'timestamp': time_model, - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - 'classX': updateClassX, - 'a': updateA, - 'b': updateB - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'classX': updateClassX, - 'a': updateA, - 'b': updateB - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_az_a.py b/simulations/validation/config_az_a.py deleted file mode 100644 index 153d883..0000000 --- a/simulations/validation/config_az_a.py +++ /dev/null @@ -1,113 +0,0 @@ -from datetime import timedelta -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim - - -class MyClass: - def __init__(self): - self.x = 0 - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - def update(self): - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self - - def __str__(self): - return f"PRINT MyClass: @ {hex(id(self))}: value {self.x}" - -# a is Correct, and classX's value is Incorrect -# Expected: a == classX's value -# b should be tracking classX's value and a: -# b should be the same value as the previous classX value and the previous a value - -udc = MyClass() -# z = MyClass() -# pointer(z) -# separate thread/process for UCD with async calls to this thread/process - -# genesis state -state_dict = { - 'classX': udc, - 'c_udc': udc, - 'a': 0, - 'b': 0, - 'c': "", - 'd': None, - 'timestamp': '2019-01-01 00:00:00' -} - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - -def updateClassX(_g, step, sL, s, _input): - y = 'classX' - x = s['classX'].update() - return (y, x) - -def updateA(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - -def updateB(_g, step, sL, s, _input): - y = 'b' - x = s['classX'].x - return (y, x) - -def updateC(_g, step, sL, s, _input): - y = 'c' - x = f"PRINT MyClass: @ {hex(id(s['classX']))}: value {s['classX'].x}" - return (y, x) - -def updateD(_g, step, sL, s, _input): - y = 'd' - x = s['classX'] - return (y, x) - - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - 'timestamp': time_model, - 'b': updateB, - 'c': updateC, - # 'd': updateD - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - 'classX': updateClassX, - 'a': updateA, - 'b': updateB, - 'c': updateC, - # 'd': updateD - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'classX': updateClassX, - 'a': updateA, - 'b': updateB, - 'c': updateC, - # 'd': updateD - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_az_b.py b/simulations/validation/config_az_b.py deleted file mode 100644 index 462b40b..0000000 --- a/simulations/validation/config_az_b.py +++ /dev/null @@ -1,86 +0,0 @@ -from copy import deepcopy -from datetime import timedelta -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim - -class MyClass: - def __init__(self): - self.x = 0 - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - def update(self): - res = deepcopy(self) - res.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return res - - def __str__(self): - return f"PRINT MyClass: @ {hex(id(self))}: value {self.x}" - - -# genesis state -state_dict = { - 'classX': MyClass(), - 'a': 0, - 'b': 0, - 'timestamp': '2019-01-01 00:00:00' -} - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - -def updateClassX(_g, step, sL, s, _input): - y = 'classX' - x = s['classX'].update() - return (y, x) - -def updateA(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - -def updateB(_g, step, sL, s, _input): - y = 'b' - # x = s['classX'].x - x = s['a'] - return (y, x) - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - 'timestamp': time_model, - 'b': updateB - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - 'classX': updateClassX, - 'a': updateA, - 'b': updateB - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'classX': updateClassX, - 'a': updateA, - 'b': updateB - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_udc.py b/simulations/validation/config_udc.py deleted file mode 100644 index 5c98b69..0000000 --- a/simulations/validation/config_udc.py +++ /dev/null @@ -1,175 +0,0 @@ -from datetime import timedelta -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim -from copy import deepcopy, copy - - -# ToDo: Create member for past value -class MyClass: - def __init__(self, past_attr): - # self.past = self - self.past_attr = past_attr - self.class_id = None - self.x = 0 - - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - - def update(self): - # self.past = copy(self) - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self.x #self #old_self #self.x - - - def getMemID(self): - return str(hex(id(self))) - - # can be accessed after an update within the same substep and timestep - # ToDo: id sensitive to lineage, rerepresent - def __str__(self): - # return str(self.x) - return f"{hex(id(self))} - {self.x}" - - -# a is Correct, and classX's value is Incorrect -# Expected: a == classX's value -# b should be tracking classX's value and a: -# b should be the same value as the previous classX value and the previous a value -# https://pymotw.com/2/multiprocessing/communication.html -udc = MyClass(0) - -# z = MyClass() -# pointer(z) -# separate thread/process for UCD with async calls to this thread/process - -# genesis state - -# udc_json = {'udc': udc, 'udc-1': udc} -state_dict = { - 'classX': udc, - # 'classX_MemID': udc.getMemID(), - 'pastX': udc, - 'otherX': udc, - # 'pastX_MemID': udc.getMemID(), - 'a': 0, - 'b': udc.x, - 'c': udc.x, - 'c2': udc.x, - 'z': udc.x, - 'timestamp': '2019-01-01 00:00:00' -} - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - -def trackClassX(_g, step, sL, s, _input): - y = 'classX' - x = s['classX'] - return (y, x) - -# def trackClassX_str(_g, step, sL, s, _input): -# y = 'classX_MemID' -# x = s['classX'].getMemID() -# return (y, x) - -def updatePastX(_g, step, sL, s, _input): - y = 'pastX' - x = s['pastX'] - return (y, x) - -def updateOtherX(_g, step, sL, s, _input): - y = 'otherX' - x = s['otherX'] - return (y, x) - -# def updatePastX_str(_g, step, sL, s, _input): -# y = 'pastX_MemID' -# x = s['pastX'].getMemID() -# return (y, x) - -def updateA(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - -def updateB(_g, step, sL, s, _input): - y = 'b' - x = s['classX'].x - return (y, x) - -def updateC(_g, step, sL, s, _input): - y = 'c' - x = s['classX'].update() - return (y, x) - -def updateZ(_g, step, sL, s, _input): - y = 'z' - x = s['classX'].x - return (y, x) - -def updateC2(_g, step, sL, s, _input): - y = 'c2' - x = s['pastX'].x - return (y, x) - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - 'a': updateA, - 'b': updateB, - 'c': updateC, - 'c2': updateC2, - 'classX': trackClassX, - 'otherX': updateOtherX, - 'timestamp': time_model, - 'pastX': updatePastX, - 'z': updateZ - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - 'a': updateA, - 'b': updateB, - 'c': updateC, - 'c2': updateC2, - 'classX': trackClassX, - 'otherX': updateOtherX, - # 'classX_MemID': trackClassX_str, - 'pastX': updatePastX, - # 'pastX_MemID': updatePastX_str, - 'z': updateZ - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'a': updateA, - 'b': updateB, - 'c': updateC, - 'c2': updateC2, - 'classX': trackClassX, - 'otherX': updateOtherX, - # 'classX_MemID': trackClassX_str, - 'pastX': updatePastX, - # 'pastX_MemID': updatePastX_str, - 'z': updateZ - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_udc3.py b/simulations/validation/config_udc3.py deleted file mode 100644 index c4fc321..0000000 --- a/simulations/validation/config_udc3.py +++ /dev/null @@ -1,210 +0,0 @@ -from datetime import timedelta -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim - - -# ToDo: Create member for past value -class MyClassA: - def __init__(self): - self.class_id = None - self.x = 0 - - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - - def update(self): - # self.past = copy(self) - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self.x #self #old_self #self.x - - - def getMemID(self): - return str(hex(id(self))) - - # can be accessed after an update within the same substep and timestep - # ToDo: id sensitive to lineage, rerepresent - def __str__(self): - # return str(self.x) - return f"{hex(id(self))} - {self.x}" - - -class MyClassB: - def __init__(self): - self.class_id = None - self.x = 5 - - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - - def update(self): - # self.past = copy(self) - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self.x #self #old_self #self.x - - - def getMemID(self): - return str(hex(id(self))) - - # can be accessed after an update within the same substep and timestep - # ToDo: id sensitive to lineage, rerepresent - def __str__(self): - # return str(self.x) - return f"{hex(id(self))} - {self.x}" - -# a is Correct, and classX's value is Incorrect -# Expected: a == classX's value -# b should be tracking classX's value and a: -# b should be the same value as the previous classX value and the previous a value -# https://pymotw.com/2/multiprocessing/communication.html -udcA = MyClassA() -udcB = MyClassB() - -# z = MyClass() -# pointer(z) -# separate thread/process for UCD with async calls to this thread/process - -# genesis state - -# udc_json = {'udc': udc, 'udc-1': udc} -state_dict = { - 'ca': 0, - 'cb': udcA.x, - 'cblassX': udcA, - 'cc': udcA.x, - 'cz': udcA.x, - 'da': 5, - 'db': udcB.x, - 'dblassX': udcB, - 'dc': udcB.x, - 'dz': udcB.x, - 'timestamp': '2019-01-01 00:00:00' -} - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - -def CBlassX(_g, step, sL, s, _input): - y = 'cblassX' - # x = s['cblassX'] - x = _g['cblassX'] - return (y, x) - -def DBlassX(_g, step, sL, s, _input): - y = 'dblassX' - # x = s['dblassX'] - x = _g['dblassX'] - return (y, x) - - -def CA(_g, step, sL, s, _input): - y = 'ca' - x = s['ca'] + 1 - return (y, x) - -def DA(_g, step, sL, s, _input): - y = 'da' - x = s['da'] + 1 - return (y, x) - -def CB(_g, step, sL, s, _input): - y = 'cb' - x = _g['cblassX'].x - # x = s['cblassX'].x - return (y, x) - -def DB(_g, step, sL, s, _input): - y = 'db' - x = _g['dblassX'].x - # x = s['dblassX'].x - return (y, x) - -def CC(_g, step, sL, s, _input): - y = 'cc' - # x = s['cblassX'].update() - x = _g['cblassX'].update() - return (y, x) - -def DC(_g, step, sL, s, _input): - # s['dblassX'] = _g['dblassX'].update() - - y = 'dc' - # x = s['dblassX'].update() - x = _g['dblassX'].update() - return (y, x) - -def CZ(_g, step, sL, s, _input): - y = 'cz' - x = _g['cblassX'].x - # x = s['cblassX'].x - return (y, x) - -def DZ(_g, step, sL, s, _input): - y = 'dz' - x = _g['dblassX'].x - # x = s['dblassX'].x - return (y, x) - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - 'ca': CA, - 'cb': CB, - 'cblassX': CBlassX, - 'cc': CC, - 'cz': CZ, - 'da': DA, - 'db': DB, - 'dblassX': DBlassX, - 'dc': DC, - 'dz': DZ, - 'timestamp': time_model, - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - 'ca': CA, - 'cb': CB, - 'cblassX': CBlassX, - 'cc': CC, - 'cz': CZ, - 'da': DA, - 'db': DB, - 'dblassX': DBlassX, - 'dc': DC, - 'dz': DZ, - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'ca': CA, - 'cb': CB, - 'cblassX': CBlassX, - 'cc': CC, - 'cz': CZ, - 'da': DA, - 'db': DB, - 'dblassX': DBlassX, - 'dc': DC, - 'dz': DZ, - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_udc_json.py b/simulations/validation/config_udc_json.py deleted file mode 100644 index 8aa8d85..0000000 --- a/simulations/validation/config_udc_json.py +++ /dev/null @@ -1,150 +0,0 @@ -from datetime import timedelta -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim -import inspect - - -# ToDo: Create member for past value -class MyClass: - def __init__(self, past_attr): - self.past_attr = past_attr - self.x = 0 - - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - def update(self): - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self.x - - def getMemID(self): - return str(hex(id(self))) - - # can be accessed after an update within the same substep and timestep - def __str__(self): - # return str(self.x) - return f"{hex(id(self))} - {self.x}" - - -# a is Correct, and classX's value is Incorrect -# Expected: a == classX's value -# b should be tracking classX's value and a: -# b should be the same value as the previous classX value and the previous a value - -udc = MyClass('pastX') - -# z = MyClass() -# pointer(z) -# separate thread/process for UCD with async calls to this thread/process - -# genesis state -# seperate process -# staging - -udc_json = {'current': udc, 'past': udc} -state_dict = { - 'classX': udc_json, - 'classX_str': udc_json['current'], - # 'pastX': udc, - 'pastX_str': f"{hex(id(udc_json['past']))} - {udc_json['past'].x}", - 'a': 0, - 'b': udc_json['current'].x, - 'c': udc_json['current'].x, - 'timestamp': '2019-01-01 00:00:00' -} - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - -def trackClassX(_g, step, sL, s, _input): - y = 'classX' - x = s['classX'] - return (y, x) - -def trackClassX_str(_g, step, sL, s, _input): - y = 'classX_str' - # x = s['classX']['current'] - x = s['classX_str'] - return (y, x) - -def updatePastX(_g, step, sL, s, _input): - y = 'pastX' - x = s['pastX'] - return (y, x) - -def updatePastX_str(_g, step, sL, s, _input): - y = 'pastX_str' - x = s['classX']['past'] - # x = f"{hex(id(s['classX']['past']))} - {s['classX']['past'].x}" - # x = s['pastX_str'] - return (y, x) - -def updateA(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - -def updateB(_g, step, sL, s, _input): - y = 'b' - x = s['classX']['current'].x - return (y, x) - -def updateC(_g, step, sL, s, _input): - y = 'c' - x = s['classX']['current'].update() - return (y, x) - - - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - 'a': updateA, - 'b': updateB, - 'c': updateC, - 'timestamp': time_model, - 'classX_str': trackClassX_str, - # 'pastX': updatePastX, - 'pastX_str': updatePastX_str - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - 'a': updateA, - 'b': updateB, - 'c': updateC, - 'classX': trackClassX, - 'classX_str': trackClassX_str, - # 'pastX': updatePastX, - 'pastX_str': updatePastX_str, - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'a': updateA, - 'b': updateB, - 'c': updateC, - 'classX': trackClassX, - 'classX_str': trackClassX_str, - # 'pastX': updatePastX, - 'pastX_str': updatePastX_str, - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_udc_json2.py b/simulations/validation/config_udc_json2.py deleted file mode 100644 index 4f9221e..0000000 --- a/simulations/validation/config_udc_json2.py +++ /dev/null @@ -1,239 +0,0 @@ -from copy import deepcopy, copy -from datetime import timedelta -from cadCAD.utils import UDC_Wrapper, objectview -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim -from typing import Dict, List, Any - -from collections import namedtuple - - -# ToDo: Create member for past value -class MyClassA(object): - def __init__(self, x, class_id=None): - self.class_id = class_id - self.x = x - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - def update(self): - # self.past = copy(self) - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self #.x #self #old_self #self.x - - def getMemID(self): - return str(hex(id(self))) - - # can be accessed after an update within the same substep and timestep - # ToDo: id sensitive to lineage, rerepresent - def __str__(self): - # return str(self.x) - return f"{self.__class__.__name__} - {hex(id(self))} - {self.__dict__}" - - -class MyClassB: - def __init__(self, x): - self.class_id = None - self.x = x - - print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}") - - - def update(self): - # self.past = copy(self) - self.x += 1 - print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}") - return self.x #self #old_self #self.x - - - def getMemID(self): - return str(hex(id(self))) - - # can be accessed after an update within the same substep and timestep - # ToDo: id sensitive to lineage, rerepresent - def __str__(self): - # return str(self.x) - return f"{hex(id(self))} - {self.x}" - -# a is Correct, and classX's value is Incorrect -# Expected: a == classX's value -# b should be tracking classX's value and a: -# b should be the same value as the previous classX value and the previous a value -# https://pymotw.com/2/multiprocessing/communication.html -# ccc = MyClassA -# udc = ccc(0) -# print(MyClassA(**udc.__dict__).__dict__) - -g: Dict[str, List[MyClassA]] = {'udc': [MyClassA]} - -# udcB = MyClassB() - -# z = MyClass() -# pointer(z) -# separate thread/process for UCD with async calls to this thread/process - -# genesis state -udc = MyClassA(0) -# namedtuple("Hydra", self.hybrid_members.keys())(*self.hybrid_members.values()) -udc_json = {'current': udc, 'past': udc} -hydra = UDC_Wrapper(udc, udc, current_functions=['update']) -hydra_members = hydra.get_hybrid_members() -# hydra_obj = namedtuple("Hydra", hydra_members.keys())(*hydra_members.values()) -hydra_view = objectview(hydra_members) - - -state_dict = { - 'a': 0, - 'b': 0, - 'i': 0, - 'j': 0, - # 'k': 0, - # "hydra": hydra, - "hydra_members": hydra_members, - # "hydra_obj": hydra_obj, - # 'hydra_view': hydra_view, - 'timestamp': '2019-01-01 00:00:00' -} - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - -def Hydra(_g, step, sL, s, _input): - y = 'hydra' - x = s['hydra'] - return (y, x) - -def HydraMembers(_g, step, sL, s, _input): - y = 'hydra_members' - x = s['hydra_members'] #.get_hybrid_members() - return (y, x) - -def HydraObj(_g, step, sL, s, _input): - y = 'hydra_obj' - # x = s['hydra_obj'] - # v = list(map(lambda x: copy(x), list(s['hydra_members'].values()))) - - # hydra_members = s['hydra_members'] - # def generate_var_deepcopy(hydra_members): - # for k, v in hydra_members.items(): - # if k == 'x': - # yield k, deepcopy(v) - # else: - # yield k, v - # - # hydra_nt = namedtuple("Hydra", s['hydra_members'].keys())(*s['hydra_members'].values()) - # new_hydra = dict(generate_var_deepcopy(hydra_nt)) - - # new_hydra_members = dict(generate_var_deepcopy(hydra_members)) - hm = copy(s['hydra_members']) - x = namedtuple("Hydra", hm.keys())(*hm.values()) - # x = namedtuple("Hydra", new_hydra.keys())(*new_hydra.values()) - - # print(x.x) - return (y, x) - -def HydraView(_g, step, sL, s, _input): - y = 'hydra_view' - # x = objectview(s['hydra_members']) - x = s['hydra_view'].update() - return (y, x) - -def A(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - -def B(_g, step, sL, s, _input): - y = 'b' - x = s['hydra_members']['x'] - # x = s['hydra_view'].x - # x = s['hydra_obj'].x - return (y, x) - -def I(_g, step, sL, s, _input): - y = 'i' - x = s['hydra_members']['update']() - - # Either works - # x = s['hydra_obj'].update() - # x = s['hydra_view'].x - return (y, x) - -def J(_g, step, sL, s, _input): - y = 'j' - x = s['hydra_members']['x'] - # x = s['hydra_members'].x - # x = s['hydra_obj'].x - # x = s['hydra_view'].x - return (y, x) - - -def K(_g, step, sL, s, _input): - y = 'k' - x = s['hydra_obj'].x - # x = s['hydra_view'].x - return (y, x) - - -partial_state_update_blocks = { - 'PSUB1': { - 'behaviors': { - }, - 'states': { - # 'ca': CA, - 'a': A, - 'b': B, - # 'hydra': Hydra, - 'hydra_members': HydraMembers, - # 'hydra_obj': HydraObj, - # 'hydra_view': HydraView, - 'i': I, - 'j': J, - # 'k': K, - 'timestamp': time_model, - } - }, - 'PSUB2': { - 'behaviors': { - }, - 'states': { - # 'ca': CA, - 'a': A, - 'b': B, - # 'hydra': Hydra, - 'hydra_members': HydraMembers, - # 'hydra_obj': HydraObj, - # 'hydra_view': HydraView, - 'i': I, - 'j': J, - # 'k': K, - } - }, - 'PSUB3': { - 'behaviors': { - }, - 'states': { - 'a': A, - 'b': B, - # 'hydra': Hydra, - 'hydra_members': HydraMembers, - # 'hydra_obj': HydraObj, - # 'hydra_view': HydraView, - 'i': I, - 'j': J, - # 'k': K, - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4), - "M": g -}) - -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks) diff --git a/simulations/validation/config_udc_json4.py b/simulations/validation/config_udc_json4.py deleted file mode 100644 index 29dd353..0000000 --- a/simulations/validation/config_udc_json4.py +++ /dev/null @@ -1,146 +0,0 @@ -from datetime import timedelta - -from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim -from cadCAD.configuration.utils.policyAggregation import dict_op, dict_elemwise_sum -from cadCAD.configuration.utils.userDefinedObject import udcBroker, udoPipe, UDO - - -# ToDo: Create member for past value -class MyClass(object): - def __init__(self, x): - self.x = x - - def update(self): - self.x += 1 - return self - - def getMemID(self): - return str(hex(id(self))) - - pass - - -# can be accessed after an update within the same substep and timestep - -hydra_state_view = UDO(MyClass(0)) -udc_view_B = UDO(MyClass(0)) -udc_view_C = UDO(MyClass(0)) - -# g: Dict[str, List[int]] = {'MyClassB'} - -state_dict = { - 'a': 0, 'b': 0, 'j': 0, - 'k': (0, 0), 'q': (0, 0), - 'hydra_state': hydra_state_view, - 'policies': {'hydra_B': udc_view_B, 'hydra_C': udc_view_C}, - 'timestamp': '2019-01-01 00:00:00' -} - -def p1(_g, step, sL, s): - s['policies']['hydra_B'].update() - return {'hydra_B': udoPipe(s['policies']['hydra_B'])} - -def p2(_g, step, sL, s): - s['policies']['hydra_C'].update() - return {'hydra_C': udoPipe(s['policies']['hydra_C'])} - -def policies(_g, step, sL, s, _input): - y = 'policies' - x = _input - return (y, x) - -timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute. -ts_format = '%Y-%m-%d %H:%M:%S' -def time_model(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration) - return (y, x) - - -def HydraMembers(_g, step, sL, s, _input): - y = 'hydra_state' - s['hydra_state'].update() - x = udoPipe(s['hydra_state']) - return (y, x) - -def repr(_g, step, sL, s, _input): - y = 'z' - x = s['hydra_members'].__repr__() - return (y, x) - -def incriment(y, incr_val): - return lambda _g, step, sL, s, _input: (y, s[y] + incr_val) - -def A(_g, step, sL, s, _input): - y = 'a' - x = s['a'] + 1 - return (y, x) - -def hydra_state_tracker(y): - return lambda _g, step, sL, s, _input: (y, s['hydra_state'].x) - - -def hydra_policy_tracker(y): - return lambda _g, step, sL, s, _input: (y, tuple(v.x for k, v in s['policies'].items())) - - -# needs M1&2 need behaviors -partial_state_update_blocks = { - 'PSUB1': { - 'policies': { - "b1": p1, - "b2": p2 - }, - 'states': { - 'a': A, - 'b': hydra_state_tracker('b'), - 'j': hydra_state_tracker('j'), - 'k': hydra_policy_tracker('k'), - 'q': hydra_policy_tracker('q'), - 'hydra_state': HydraMembers, - 'timestamp': time_model, - 'policies': policies - } - }, - 'PSUB2': { - 'policies': { - "b1": p1, - "b2": p2 - }, - 'states': { - 'a': A, - 'b': hydra_state_tracker('b'), - 'j': hydra_state_tracker('j'), - 'k': hydra_policy_tracker('k'), - 'q': hydra_policy_tracker('q'), - 'hydra_state': HydraMembers, - 'policies': policies - } - }, - 'PSUB3': { - 'policies': { - "b1": p1, - "b2": p2 - }, - 'states': { - 'a': A, - 'b': hydra_state_tracker('b'), - 'j': hydra_state_tracker('j'), - 'k': hydra_policy_tracker('k'), - 'q': hydra_policy_tracker('q'), - 'hydra_state': HydraMembers, - 'policies': policies - } - } -} - -sim_config = config_sim({ - "N": 2, - "T": range(4) -}) - -append = lambda a, b: [a, b] -update_dict = lambda a, b: a.update(b) -take_first = lambda a, b: [a, b] -append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks)#, policy_ops=[foldr(dict_op(take_first))]) diff --git a/simulations/validation/incr_external_dataset.py b/simulations/validation/external_dataset.py similarity index 78% rename from simulations/validation/incr_external_dataset.py rename to simulations/validation/external_dataset.py index d503201..cc32338 100644 --- a/simulations/validation/incr_external_dataset.py +++ b/simulations/validation/external_dataset.py @@ -1,18 +1,15 @@ -from datetime import timedelta - from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step, config_sim -# from cadCAD.configuration.utils.policyAggregation import dict_op, dict_elemwise_sum -from cadCAD.configuration.utils.userDefinedObject import udcBroker, udoPipe, UDO +from cadCAD.configuration.utils import config_sim import pandas as pd from cadCAD.utils import SilentDF -df = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/output.csv')) +df = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv')) +external_data = {'ds1': None, 'ds2': None, 'ds3': None} state_dict = { 'increment': 0, - 'external_data': {"ds1": None, "ds2": None, "ds3": None}, - 'policies': {} + 'external_data': external_data, + 'policies': external_data, } def query(s, df): @@ -61,9 +58,11 @@ sim_config = config_sim({ }) append_configs( - sim_config, - state_dict, - {}, {}, {}, - partial_state_update_blocks, + sim_configs=sim_config, + initial_state=state_dict, + # seeds=seeds, + # raw_exogenous_states=raw_exogenous_states, + # env_processes=env_processes, + partial_state_update_blocks=partial_state_update_blocks, policy_ops=[lambda a, b: {**a, **b}] ) diff --git a/simulations/validation/historical_state_access.py b/simulations/validation/historical_state_access.py new file mode 100644 index 0000000..36bc5de --- /dev/null +++ b/simulations/validation/historical_state_access.py @@ -0,0 +1,63 @@ +from cadCAD.configuration import append_configs +from cadCAD.configuration.utils import config_sim + +# last_partial_state_update_block +def last_update_block(_g, step, sH, s, _input): + return 'sh', sH[-1] + + +# Policies per Mechanism +def p(_g, step, sH, s): + return {'last_update_block': sH[-1]} + +def add(y, x): + return lambda _g, step, sH, s, _input: (y, s[y] + x) + +def policies(_g, step, sH, s, _input): + y = 'policies' + x = _input + return (y, x) + +policies = {"p1": p, "p2": p} + +genesis_states = { + 's': 0, + 'sh': {}, # {[], {}} + # 'policies': {}, +} + +variables = { + 's': add('s', 1), + 'sh': last_update_block, + # "policies": policies +} + + +PSUB = { + "policies": policies, + "variables": variables +} + +partial_state_update_block = { + "PSUB1": PSUB, + "PSUB2": PSUB, + "PSUB3": PSUB +} + +sim_config = config_sim( + { + "N": 1, + "T": range(3), + } +) + + +append_configs( + sim_configs=sim_config, + initial_state=genesis_states, + seeds={}, + raw_exogenous_states={}, + env_processes={}, + partial_state_update_blocks=partial_state_update_block, + policy_ops=[lambda a, b: a + b] +) diff --git a/simulations/validation/config1_test_pipe.py b/simulations/validation/policy_aggregation.py similarity index 56% rename from simulations/validation/config1_test_pipe.py rename to simulations/validation/policy_aggregation.py index 5d9e3dd..c7028de 100644 --- a/simulations/validation/config1_test_pipe.py +++ b/simulations/validation/policy_aggregation.py @@ -1,14 +1,8 @@ -from decimal import Decimal -from functools import reduce - import numpy as np -from datetime import timedelta - -from cadCAD.configuration.utils.policyAggregation import get_base_value - from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, config_sim +from cadCAD.configuration.utils import config_sim +# ToDo: Use seeds = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), @@ -23,8 +17,6 @@ def p1m1(_g, step, sL, s): def p2m1(_g, step, sL, s): return {'param2': 2} -# [] - def p1m2(_g, step, sL, s): return {'param1': 2, 'param2': 2} def p2m2(_g, step, sL, s): @@ -35,18 +27,10 @@ def p1m3(_g, step, sL, s): def p2m3(_g, step, sL, s): return {'param1': 1, 'param2': 2, 'param3': 3} -def test_pipeline(_g, step, sL, s): - return {'test': 2, 'param2': 2} - # Internal States per Mechanism -def s(y): - return lambda _g, step, sH, s, _input: (y, s[y] + 1) - -def sH(_g, step, sH, s, _input): - y = 'sh' - x = sH - return (y, x) +def add(y, x): + return lambda _g, step, sH, s, _input: (y, s[y] + x) def policies(_g, step, sH, s, _input): y = 'policies' @@ -58,49 +42,39 @@ genesis_states = { 'policies': {}, 's1': 0, 's2': 0, - # 'sh': [] } raw_exogenous_states = {} env_processes = {} +variables = { + 's1': add('s1', 1), + 's2': add('s2', 1), + "policies": policies +} + partial_state_update_block = { "m1": { "policies": { - "b1": p1m1, - "b2": p2m1 + "p1": p1m1, + "p2": p2m1 }, - "variables": { - 's1': s('s1'), - 's2': s('s2'), - # 'sh': sH, - "policies": policies - } + "variables": variables }, "m2": { "policies": { - "b1": p1m2, - "b2": p2m2 + "p1": p1m2, + "p2": p2m2 }, - "variables": { - 's1': s('s1'), - 's2': s('s2'), - # 'sh': sH, - "policies": policies - } + "variables": variables }, "m3": { "policies": { - "b1": p1m3, - "b2": p2m3 + "p1": p1m3, + "p2": p2m3 }, - "variables": { - 's1': s('s1'), - 's2': s('s2'), - # 'sh': sH, - "policies": policies - } + "variables": variables } } @@ -120,7 +94,7 @@ append_configs( raw_exogenous_states=raw_exogenous_states, env_processes=env_processes, partial_state_update_blocks=partial_state_update_block, - # policy_ops=[lambda a, b: a + b, lambda y: y + 100, lambda y: y + 300] + policy_ops=[lambda a, b: a + b, lambda y: y + 10, lambda y: y + 30] ) diff --git a/simulations/validation/udo.py b/simulations/validation/udo.py index 1f06107..4adb1a5 100644 --- a/simulations/validation/udo.py +++ b/simulations/validation/udo.py @@ -7,7 +7,7 @@ import pandas as pd from fn.func import curried -DF = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/output.csv')) +DF = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv')) class udoExample(object): def __init__(self, x, dataset=None): @@ -153,7 +153,9 @@ sim_config = config_sim({ append_configs( sim_config, state_dict, - {}, {}, {}, + # seeds=seeds, + # raw_exogenous_states=raw_exogenous_states, + # env_processes=env_processes, partial_state_update_blocks, policy_ops=[lambda a, b: {**a, **b}] ) diff --git a/simulations/validation/externalds.py b/simulations/validation/write_simulation.py similarity index 100% rename from simulations/validation/externalds.py rename to simulations/validation/write_simulation.py