From ef9d73a32c4201bbbb8bce6582b398d5e8706c16 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 18 Feb 2019 14:00:39 -0500 Subject: [PATCH] e-courage 2 --- cadCAD/configuration/__init__.py | 78 +++++-------------- cadCAD/configuration/utils/__init__.py | 5 +- .../utils/depreciationHandler.py | 46 +++++++++++ cadCAD/utils/__init__.py | 1 + simulations/example_run.py | 50 ++++++------ 5 files changed, 94 insertions(+), 86 deletions(-) create mode 100644 cadCAD/configuration/utils/depreciationHandler.py diff --git a/cadCAD/configuration/__init__.py b/cadCAD/configuration/__init__.py index c4d7a88..82d13d0 100644 --- a/cadCAD/configuration/__init__.py +++ b/cadCAD/configuration/__init__.py @@ -1,12 +1,13 @@ from functools import reduce from fn.op import foldr import pandas as pd -from copy import deepcopy from cadCAD import configs + from cadCAD.utils import key_filter -from cadCAD.configuration.utils.policyAggregation import dict_elemwise_sum from cadCAD.configuration.utils import exo_update_per_ts +from cadCAD.configuration.utils.policyAggregation import dict_elemwise_sum +from cadCAD.configuration.utils.depreciationHandler import sanitize_partial_state_updates, sanitize_config class Configuration(object): @@ -19,22 +20,10 @@ class Configuration(object): self.exogenous_states = exogenous_states self.partial_state_updates = partial_state_update_blocks self.policy_ops = policy_ops - - # for backwards compatibility, we accept old arguments via **kwargs - # TODO: raise specific deprecation warnings for key == 'state_dict', key == 'seed', key == 'mechanisms' - for key, value in kwargs.items(): - if key == 'state_dict': - self.initial_state = value - elif key == 'seed': - self.seeds = value - elif key == 'mechanisms': - self.partial_state_updates = value - - if self.initial_state == {}: - raise Exception('The initial conditions of the system have not been set') + self.kwargs = kwargs -def append_configs(sim_configs, initial_state, seeds, raw_exogenous_states, env_processes, partial_state_update_blocks, _exo_update_per_ts=True): +def append_configs(sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={}, partial_state_update_blocks={}, _exo_update_per_ts=True): if _exo_update_per_ts is True: exogenous_states = exo_update_per_ts(raw_exogenous_states) else: @@ -42,27 +31,27 @@ def append_configs(sim_configs, initial_state, seeds, raw_exogenous_states, env_ if isinstance(sim_configs, list): for sim_config in sim_configs: - configs.append( - Configuration( - sim_config=sim_config, - initial_state=initial_state, - seeds=seeds, - exogenous_states=exogenous_states, - env_processes=env_processes, - partial_state_update_blocks=partial_state_update_blocks - ) - ) - elif isinstance(sim_configs, dict): - configs.append( - Configuration( - sim_config=sim_configs, + config = Configuration( + sim_config=sim_config, initial_state=initial_state, seeds=seeds, exogenous_states=exogenous_states, env_processes=env_processes, partial_state_update_blocks=partial_state_update_blocks ) + back_compatable_config = sanitize_config(config) + configs.append(back_compatable_config) + elif isinstance(sim_configs, dict): + config = Configuration( + sim_config=sim_configs, + initial_state=initial_state, + seeds=seeds, + exogenous_states=exogenous_states, + env_processes=env_processes, + partial_state_update_blocks=partial_state_update_blocks ) + back_compatable_config = sanitize_config(config) + configs.append(back_compatable_config) class Identity: @@ -134,35 +123,10 @@ class Processor: bdf_values = [[self.p_identity] * len(sdf_values)] return sdf_values, bdf_values - # backwards compatibility - def sanitize_partial_state_updates(partial_state_updates): - new_partial_state_updates = deepcopy(partial_state_updates) - # for backwards compatibility we accept the old keys - # ('behaviors' and 'states') and rename them - def rename_keys(d): - try: - d['policies'] = d.pop('behaviors') - except KeyError: - pass - try: - d['variables'] = d.pop('states') - except KeyError: - pass - - # Also for backwards compatibility, we accept partial state update blocks both as list or dict - # No need for a deprecation warning as it's already raised by cadCAD.utils.key_filter - if (type(new_partial_state_updates)==list): - for v in new_partial_state_updates: - rename_keys(v) - elif (type(new_partial_state_updates)==dict): - for k, v in new_partial_state_updates.items(): - rename_keys(v) - - del partial_state_updates - return new_partial_state_updates - if len(partial_state_updates) != 0: + # backwards compatibility partial_state_updates = sanitize_partial_state_updates(partial_state_updates) + bdf = self.create_matrix_field(partial_state_updates, 'policies') sdf = self.create_matrix_field(partial_state_updates, 'variables') sdf_values, bdf_values = no_update_handler(bdf, sdf) diff --git a/cadCAD/configuration/utils/__init__.py b/cadCAD/configuration/utils/__init__.py index ed17912..2a60d3e 100644 --- a/cadCAD/configuration/utils/__init__.py +++ b/cadCAD/configuration/utils/__init__.py @@ -12,6 +12,7 @@ class TensorFieldReport: def __init__(self, config_proc): self.config_proc = config_proc + # ToDo: backwards compatibility def create_tensor_field(self, partial_state_updates, exo_proc, keys=['policies', 'variables']): dfs = [self.config_proc.create_matrix_field(partial_state_updates, k) for k in keys] df = pd.concat(dfs, axis=1) @@ -21,10 +22,6 @@ class TensorFieldReport: return df -# def s_update(y, x): -# return lambda step, sL, s, _input: (y, x) -# -# def state_update(y, x): return lambda var_dict, sub_step, sL, s, _input: (y, x) diff --git a/cadCAD/configuration/utils/depreciationHandler.py b/cadCAD/configuration/utils/depreciationHandler.py new file mode 100644 index 0000000..148163d --- /dev/null +++ b/cadCAD/configuration/utils/depreciationHandler.py @@ -0,0 +1,46 @@ +from copy import deepcopy + + +def sanitize_config(config): + new_config = deepcopy(config) + # for backwards compatibility, we accept old arguments via **kwargs + # TODO: raise specific deprecation warnings for key == 'state_dict', key == 'seed', key == 'mechanisms' + for key, value in new_config.kwargs.items(): + if key == 'state_dict': + new_config.initial_state = value + elif key == 'seed': + new_config.seeds = value + elif key == 'mechanisms': + new_config.partial_state_updates = value + + if new_config.initial_state == {}: + raise Exception('The initial conditions of the system have not been set') + + del config + return new_config + + +def sanitize_partial_state_updates(partial_state_updates): + new_partial_state_updates = deepcopy(partial_state_updates) + # for backwards compatibility we accept the old keys + # ('behaviors' and 'states') and rename them + def rename_keys(d): + + if 'behaviors' in d: + d['policies'] = d.pop('behaviors') + + if 'states' in d: + d['variables'] = d.pop('states') + + + # Also for backwards compatibility, we accept partial state update blocks both as list or dict + # No need for a deprecation warning as it's already raised by cadCAD.utils.key_filter + if (type(new_partial_state_updates)==list): + for v in new_partial_state_updates: + rename_keys(v) + elif (type(new_partial_state_updates)==dict): + for k, v in new_partial_state_updates.items(): + rename_keys(v) + + del partial_state_updates + return new_partial_state_updates \ No newline at end of file diff --git a/cadCAD/utils/__init__.py b/cadCAD/utils/__init__.py index 0ac3c39..dac15c1 100644 --- a/cadCAD/utils/__init__.py +++ b/cadCAD/utils/__init__.py @@ -76,6 +76,7 @@ def drop_right(l, n): return l[:len(l) - n] # backwards compatibility +# ToDo: Encapsulate in function def key_filter(l, keyname): if (type(l) == list): return [v[keyname] for v in l] diff --git a/simulations/example_run.py b/simulations/example_run.py index 172a622..b0b385e 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -2,33 +2,33 @@ 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 sweep_config, config1, config2, config4 +from simulations.validation import config2 #sweep_config, config1, config2, config4 from cadCAD import configs exec_mode = ExecutionMode() -# print("Simulation Execution 1") -# print() -# first_config = [configs[0]] # from config1 -# single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) -# run1 = Executor(exec_context=single_proc_ctx, configs=first_config) -# run1_raw_result, tensor_field = run1.main() -# result = pd.DataFrame(run1_raw_result) -# print() -# print("Tensor Field:") -# print(tabulate(tensor_field, headers='keys', tablefmt='psql')) -# print("Output:") -# print(tabulate(result, headers='keys', tablefmt='psql')) -# print() +print("Simulation Execution 1") +print() +first_config = [configs[0]] # from config1 +single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) +run1 = Executor(exec_context=single_proc_ctx, configs=first_config) +run1_raw_result, tensor_field = run1.main() +result = pd.DataFrame(run1_raw_result) +print() +print("Tensor Field:") +print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +print("Output:") +print(tabulate(result, headers='keys', tablefmt='psql')) +print() -print("Simulation Execution 2: Concurrent Execution") -multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc) -run2 = Executor(exec_context=multi_proc_ctx, configs=configs) -for raw_result, tensor_field in run2.main(): - result = pd.DataFrame(raw_result) - print() - print("Tensor Field:") - print(tabulate(tensor_field, headers='keys', tablefmt='psql')) - print("Output:") - print(tabulate(result, headers='keys', tablefmt='psql')) - print() +# print("Simulation Execution 2: Concurrent Execution") +# multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc) +# run2 = Executor(exec_context=multi_proc_ctx, configs=configs) +# for raw_result, tensor_field in run2.main(): +# result = pd.DataFrame(raw_result) +# print() +# print("Tensor Field:") +# print(tabulate(tensor_field, headers='keys', tablefmt='psql')) +# print("Output:") +# print(tabulate(result, headers='keys', tablefmt='psql')) +# print()