From ac44a7bee8b1ab884c8410422065e8ea8b11d827 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 18 Mar 2019 11:42:37 -0400 Subject: [PATCH] checkpoint --- cadCAD/configuration/utils/__init__.py | 22 ++- cadCAD/configuration/utils/parameterSweep.py | 20 --- cadCAD/engine/simulation.py | 45 ++++- simulations/az_run_a.py | 24 +++ simulations/az_run_b.py | 24 +++ simulations/az_run_udc.py | 24 +++ simulations/az_run_udc_json.py | 24 +++ simulations/validation/config1.py | 3 +- simulations/validation/config2.py | 3 +- simulations/validation/config4.py | 3 +- simulations/validation/config_az.py | 6 +- simulations/validation/config_az_a.py | 113 +++++++++++++ simulations/validation/config_az_b.py | 86 ++++++++++ simulations/validation/config_udc.py | 169 +++++++++++++++++++ simulations/validation/config_udc_json.py | 150 ++++++++++++++++ simulations/validation/sweep_config.py | 11 +- 16 files changed, 687 insertions(+), 40 deletions(-) delete mode 100644 cadCAD/configuration/utils/parameterSweep.py create mode 100644 simulations/az_run_a.py create mode 100644 simulations/az_run_b.py create mode 100644 simulations/az_run_udc.py create mode 100644 simulations/az_run_udc_json.py create mode 100644 simulations/validation/config_az_a.py create mode 100644 simulations/validation/config_az_b.py create mode 100644 simulations/validation/config_udc.py create mode 100644 simulations/validation/config_udc_json.py diff --git a/cadCAD/configuration/utils/__init__.py b/cadCAD/configuration/utils/__init__.py index d0d9aec..ee121ad 100644 --- a/cadCAD/configuration/utils/__init__.py +++ b/cadCAD/configuration/utils/__init__.py @@ -6,7 +6,7 @@ import pandas as pd # Temporary from cadCAD.configuration.utils.depreciationHandler import sanitize_partial_state_updates -from cadCAD.utils import dict_filter, contains_type +from cadCAD.utils import dict_filter, contains_type, flatten_tabulated_dict, tabulate_dict # ToDo: Fix - Returns empty when partial_state_update is missing in Configuration @@ -122,4 +122,22 @@ def exo_update_per_ts(ep): else: return y, s[y] - return {es: ep_decorator(f, es) for es, f in ep.items()} \ No newline at end of file + return {es: ep_decorator(f, es) for es, f in ep.items()} + + +# param sweep enabling middleware +def config_sim(d): + def process_variables(d): + return flatten_tabulated_dict(tabulate_dict(d)) + if "M" in d: + return [ + { + "N": d["N"], + "T": d["T"], + "M": M + } + for M in process_variables(d["M"]) + ] + else: + d["M"] = [{}] + return d \ No newline at end of file diff --git a/cadCAD/configuration/utils/parameterSweep.py b/cadCAD/configuration/utils/parameterSweep.py deleted file mode 100644 index a91e938..0000000 --- a/cadCAD/configuration/utils/parameterSweep.py +++ /dev/null @@ -1,20 +0,0 @@ -from cadCAD.utils import flatten_tabulated_dict, tabulate_dict - - -def process_variables(d): - return flatten_tabulated_dict(tabulate_dict(d)) - - -def config_sim(d): - if "M" in d: - return [ - { - "N": d["N"], - "T": d["T"], - "M": M - } - for M in process_variables(d["M"]) - ] - else: - d["M"] = [{}] - return d \ No newline at end of file diff --git a/cadCAD/engine/simulation.py b/cadCAD/engine/simulation.py index 104e8d2..b55d0bf 100644 --- a/cadCAD/engine/simulation.py +++ b/cadCAD/engine/simulation.py @@ -68,18 +68,47 @@ class Executor: run: int ) -> List[Dict[str, Any]]: - last_in_obj: Dict[str, Any] = sL[-1] + last_in_obj: Dict[str, Any] = deepcopy(sL[-1]) + # last_in_obj: Dict[str, Any] = sL[-1] _input: Dict[str, Any] = self.policy_update_exception(self.get_policy_input(var_dict, sub_step, sL, last_in_obj, policy_funcs)) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function # ToDo: Can be multithreaded ?? + + # ToDo: Create Separate past state paradigm for which users specify the use of identity / past function + # ToDo: UDC / any class must be deepcopy before every update + # vs an assumed update + + # last_class = deepcopy(last_in_obj['classX']) + + # incoming + + # past_attr_dict = {k: v for k, v in last_in_obj.items() if + # hasattr(v, 'past_attr') and k == v.past_attr} + # incoming_attr_dict = {k: deepcopy(v) for k, v in last_in_obj.items() if + # hasattr(v, 'past_attr') and k != v.past_attr} + + # udcs = {k: deepcopy(v) for k, v in last_in_obj.items() if hasattr(v, 'class_id')} + # non_udcs = {k: deepcopy(v) for k, v in last_in_obj.items() if not hasattr(v, 'class_id')} + + + # past_attr_dict = {k: v for k, v in last_in_obj.items() if 'past' in v.keys()} + # incoming_attr_dict = {k: v for k, v in last_in_obj.items() if 'current' in v.keys()} + + # ToDo: Previous Record Cache + # last_in_copy_staging = deepcopy(last_in_obj) + + # past_udc = deepcopy(last_in_obj['classX']['current']) + last_in_copy: Dict[str, Any] = dict( [ self.state_update_exception(f(var_dict, sub_step, sL, last_in_obj, _input)) for f in state_funcs ] ) + # a b c d e f g + for k in last_in_obj: if k not in last_in_copy: last_in_copy[k] = last_in_obj[k] @@ -91,6 +120,16 @@ class Executor: # ToDo: make 'substep' & 'timestep' reserve fields last_in_copy['substep'], last_in_copy['timestep'], last_in_copy['run'] = sub_step, time_step, run + # # ToDo: Handle conditions + # for k_past, _ in past_attr_dict.items(): + # for _, v_current in incoming_attr_dict.items(): + # last_in_copy[k_past] = v_current + + # last_in_copy['pastX'] = last_class + + # last_in_copy['classX']['past'] = past_udc + # last_in_copy['pastX_str'] = past_udc + sL.append(last_in_copy) del last_in_copy @@ -109,10 +148,11 @@ class Executor: sub_step = 0 states_list_copy: List[Dict[str, Any]] = deepcopy(states_list) + # for d1 in states_list: # for d2 in states_list_copy: # d2['classX'] = d1['classX'] - # + # print() # pp.pprint(states_list_copy) # print() @@ -125,6 +165,7 @@ class Executor: sub_step += 1 for config in configs: s_conf, p_conf = config[0], config[1] + # states_list["classX"] = deepcopy(classX) states_list: List[Dict[str, Any]] = self.partial_state_update( var_dict, sub_step, states_list, s_conf, p_conf, env_processes, time_step, run ) diff --git a/simulations/az_run_a.py b/simulations/az_run_a.py new file mode 100644 index 0000000..7fe6f84 --- /dev/null +++ b/simulations/az_run_a.py @@ -0,0 +1,24 @@ +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_az_a +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) +print() +print("Tensor Field: config1") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() \ No newline at end of file diff --git a/simulations/az_run_b.py b/simulations/az_run_b.py new file mode 100644 index 0000000..483677e --- /dev/null +++ b/simulations/az_run_b.py @@ -0,0 +1,24 @@ +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_az_b +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) +print() +print("Tensor Field: config1") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() \ No newline at end of file diff --git a/simulations/az_run_udc.py b/simulations/az_run_udc.py new file mode 100644 index 0000000..0406896 --- /dev/null +++ b/simulations/az_run_udc.py @@ -0,0 +1,24 @@ +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 +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) +print() +print("Tensor Field: config1") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() \ No newline at end of file diff --git a/simulations/az_run_udc_json.py b/simulations/az_run_udc_json.py new file mode 100644 index 0000000..81190e3 --- /dev/null +++ b/simulations/az_run_udc_json.py @@ -0,0 +1,24 @@ +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_json +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) +print() +print("Tensor Field: config1") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() \ No newline at end of file diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 70d1da3..9f0fb64 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,8 +3,7 @@ import numpy as np from datetime import timedelta from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step -from cadCAD.configuration.utils.parameterSweep import config_sim +from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, config_sim seeds = { 'z': np.random.RandomState(1), diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py index 0247c9b..a75b22a 100644 --- a/simulations/validation/config2.py +++ b/simulations/validation/config2.py @@ -3,8 +3,7 @@ import numpy as np from datetime import timedelta from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step -from cadCAD.configuration.utils.parameterSweep import config_sim +from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, config_sim seeds = { 'z': np.random.RandomState(1), diff --git a/simulations/validation/config4.py b/simulations/validation/config4.py index 62f626f..164df26 100644 --- a/simulations/validation/config4.py +++ b/simulations/validation/config4.py @@ -3,8 +3,7 @@ import numpy as np from datetime import timedelta from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step -from cadCAD.configuration.utils.parameterSweep import config_sim +from cadCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, config_sim seeds = { diff --git a/simulations/validation/config_az.py b/simulations/validation/config_az.py index 02ff2f3..746df2d 100644 --- a/simulations/validation/config_az.py +++ b/simulations/validation/config_az.py @@ -1,8 +1,6 @@ -from copy import deepcopy from datetime import timedelta from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import ep_time_step -from cadCAD.configuration.utils.parameterSweep import config_sim +from cadCAD.configuration.utils import ep_time_step, config_sim class MyClass: @@ -60,7 +58,7 @@ partial_state_update_blocks = { 'behaviors': { }, 'states': { - 'timestamp': time_model + 'timestamp': time_model, } }, 'PSUB2': { diff --git a/simulations/validation/config_az_a.py b/simulations/validation/config_az_a.py new file mode 100644 index 0000000..153d883 --- /dev/null +++ b/simulations/validation/config_az_a.py @@ -0,0 +1,113 @@ +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 new file mode 100644 index 0000000..462b40b --- /dev/null +++ b/simulations/validation/config_az_b.py @@ -0,0 +1,86 @@ +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 new file mode 100644 index 0000000..6904766 --- /dev/null +++ b/simulations/validation/config_udc.py @@ -0,0 +1,169 @@ +from datetime import timedelta +from cadCAD.configuration import append_configs +from cadCAD.configuration.utils import ep_time_step, config_sim +from copy import deepcopy + + +# ToDo: Create member for past value +class MyClass: + def __init__(self, past_attr): + self.past_self = 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_self = 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.x #self #old_self #self.x + + def past(self): + return self.past_self + + 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 + +udc = MyClass('pastX') + +# 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, + # '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 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['classX'].x + return (y, x) + +partial_state_update_blocks = { + 'PSUB1': { + 'behaviors': { + }, + 'states': { + 'a': updateA, + 'b': updateB, + 'c': updateC, + 'c2': updateC2, + 'classX': trackClassX, + 'timestamp': time_model, + 'classX_MemID': trackClassX_str, + # 'pastX': updatePastX, + # 'pastX_MemID': updatePastX_str, + 'z': updateZ + } + }, + 'PSUB2': { + 'behaviors': { + }, + 'states': { + 'a': updateA, + 'b': updateB, + 'c': updateC, + 'c2': updateC2, + 'classX': trackClassX, + '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, + '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_udc_json.py b/simulations/validation/config_udc_json.py new file mode 100644 index 0000000..8aa8d85 --- /dev/null +++ b/simulations/validation/config_udc_json.py @@ -0,0 +1,150 @@ +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/sweep_config.py b/simulations/validation/sweep_config.py index 2350d95..40071b6 100644 --- a/simulations/validation/sweep_config.py +++ b/simulations/validation/sweep_config.py @@ -4,8 +4,7 @@ from datetime import timedelta import pprint from cadCAD.configuration import append_configs -from cadCAD.configuration.utils import proc_trigger, ep_time_step -from cadCAD.configuration.utils.parameterSweep import config_sim +from cadCAD.configuration.utils import proc_trigger, ep_time_step, config_sim from typing import Dict, List @@ -18,7 +17,7 @@ seeds = { 'c': np.random.RandomState(3) } - +# Optional g: Dict[str, List[int]] = { 'alpha': [1], 'beta': [2, 5], @@ -178,16 +177,16 @@ partial_state_update_block = { } } - +# config_sim Necessary sim_config = config_sim( { "N": 2, "T": range(5), - "M": g + "M": g # Optional } ) - +# New Convention append_configs( sim_configs=sim_config, initial_state=genesis_states,