From 9d9e33b766a802cc518427749875f0562e2ad6f7 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 26 Feb 2019 11:47:41 -0500 Subject: [PATCH] type annotations: simulation.py --- README.md | 2 +- cadCAD/engine/__init__.py | 4 +- cadCAD/engine/simulation.py | 136 +++++++++++++----- cadCAD/engine/utils.py | 2 +- cadCAD/utils/__init__.py | 10 +- monkeytype.sqlite3 | Bin 0 -> 761856 bytes ...ulti_config run.py => multi_config_run.py} | 0 simulations/validation/config1.py | 2 + simulations/validation/sweep_config.py | 4 +- 9 files changed, 117 insertions(+), 43 deletions(-) create mode 100644 monkeytype.sqlite3 rename simulations/{multi_config run.py => multi_config_run.py} (100%) diff --git a/README.md b/README.md index a067880..0719875 100644 --- a/README.md +++ b/README.md @@ -129,4 +129,4 @@ for raw_result, tensor_field in run2.main(): The above can be run in Jupyter. ```bash jupyter notebook -``` \ No newline at end of file +``` diff --git a/cadCAD/engine/__init__.py b/cadCAD/engine/__init__.py index b0727e8..6ba51e9 100644 --- a/cadCAD/engine/__init__.py +++ b/cadCAD/engine/__init__.py @@ -22,8 +22,8 @@ class ExecutionContext: result = simulation(var_dict, states_list, config, env_processes, T, N) return flatten(result) - def parallelize_simulations(fs, var_dict_list, states_list, configs, env_processes, Ts, Ns): - l = list(zip(fs, var_dict_list, states_list, configs, env_processes, Ts, Ns)) + def parallelize_simulations(simulations, var_dict_list, states_list, configs, env_processes, Ts, Ns): + l = list(zip(simulations, var_dict_list, states_list, configs, env_processes, Ts, Ns)) with Pool(len(configs)) as p: results = p.map(lambda t: t[0](t[1], t[2], t[3], t[4], t[5], t[6]), l) return results diff --git a/cadCAD/engine/simulation.py b/cadCAD/engine/simulation.py index 3881cde..97af73d 100644 --- a/cadCAD/engine/simulation.py +++ b/cadCAD/engine/simulation.py @@ -2,19 +2,38 @@ from copy import deepcopy from fn.op import foldr, call from cadCAD.engine.utils import engine_exception +from typing import Any, Callable, Dict, List, Tuple -id_exception = engine_exception(KeyError, KeyError, None) +id_exception: Callable = engine_exception(KeyError, KeyError, None) + +import pprint as pp class Executor: - def __init__(self, policy_ops, policy_update_exception=id_exception, state_update_exception=id_exception): - self.policy_ops = policy_ops # behavior_ops - self.state_update_exception = state_update_exception - self.policy_update_exception = policy_update_exception # behavior_update_exception + def __init__( + self, + policy_ops: List[Callable], + policy_update_exception: Callable = id_exception, + state_update_exception: Callable = id_exception + ) -> None: + + # behavior_ops + self.policy_ops = policy_ops + self.state_update_exception = state_update_exception + self.policy_update_exception = policy_update_exception + # behavior_update_exception + + # get_behavior_input # sL: State Window + def get_policy_input( + self, + var_dict: Dict[str, List[Any]], + sub_step: int, + sL: List[Dict[str, Any]], + s: Dict[str, Any], + funcs: List[Callable] + ) -> Dict[str, Any]: - # get_behavior_input - def get_policy_input(self, var_dict, sub_step, sL, s, funcs): ops = self.policy_ops[::-1] def get_col_results(var_dict, sub_step, sL, s, funcs): @@ -22,23 +41,39 @@ class Executor: return foldr(call, get_col_results(var_dict, sub_step, sL, s, funcs))(ops) - def apply_env_proc(self, env_processes, state_dict, sub_step): + def apply_env_proc( + self, + env_processes: Dict[str, Callable], + state_dict: Dict[str, Any], + sub_step: int + ) -> None: for state in state_dict.keys(): if state in list(env_processes.keys()): - env_state = env_processes[state] + 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]) + state_dict[state]: Any = env_state(sub_step)(state_dict[state]) else: - state_dict[state] = env_state(state_dict[state]) + state_dict[state]: Any = env_state(state_dict[state]) # mech_step - def partial_state_update(self, var_dict, sub_step, sL, state_funcs, policy_funcs, env_processes, time_step, run): - last_in_obj = sL[-1] + def partial_state_update( + self, + var_dict: Dict[str, List[Any]], + sub_step: int, + sL: Any, + state_funcs: List[Callable], + policy_funcs: List[Callable], + env_processes: Dict[str, Callable], + time_step: int, + run: int + ) -> List[Dict[str, Any]]: - _input = self.policy_update_exception(self.get_policy_input(var_dict, sub_step, sL, last_in_obj, policy_funcs)) + 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 - last_in_copy = dict( + 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 ] @@ -46,58 +81,91 @@ class Executor: for k in last_in_obj: if k not in last_in_copy: - last_in_copy[k] = last_in_obj[k] + last_in_copy[k]: Any = last_in_obj[k] del last_in_obj self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestep']) last_in_copy['substep'], last_in_copy['timestep'], last_in_copy['run'] = sub_step, time_step, run + sL.append(last_in_copy) del last_in_copy return sL - # mech_pipeline - def state_update_pipeline(self, var_dict, states_list, configs, env_processes, time_step, run): + def state_update_pipeline( + self, + var_dict: Dict[str, List[Any]], + states_list: List[Dict[str, Any]], + configs: List[Tuple[List[Callable], List[Callable]]], + env_processes: Dict[str, Callable], + time_step: int, + run: int + ) -> List[Dict[str, Any]]: + sub_step = 0 - states_list_copy = deepcopy(states_list) - genesis_states = states_list_copy[-1] + states_list_copy: List[Dict[str, Any]] = deepcopy(states_list) + genesis_states: Dict[str, Any] = states_list_copy[-1] genesis_states['substep'], genesis_states['timestep'] = sub_step, time_step - states_list = [genesis_states] + states_list: List[Dict[str, Any]] = [genesis_states] sub_step += 1 for config in configs: s_conf, p_conf = config[0], config[1] - states_list = self.partial_state_update(var_dict, sub_step, states_list, s_conf, p_conf, env_processes, time_step, run) + 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 + ) + sub_step += 1 time_step += 1 return states_list - def run_pipeline(self, var_dict, states_list, configs, env_processes, time_seq, run): - time_seq = [x + 1 for x in time_seq] - simulation_list = [states_list] + def run_pipeline( + self, + var_dict: Dict[str, List[Any]], + states_list: List[Dict[str, Any]], + configs: List[Tuple[List[Callable], List[Callable]]], + env_processes: Dict[str, Callable], + time_seq: range, + run: int + ) -> List[List[Dict[str, Any]]]: + + time_seq: List[int] = [x + 1 for x in time_seq] + simulation_list: List[List[Dict[str, Any]]] = [states_list] for time_step in time_seq: - pipe_run = self.state_update_pipeline(var_dict, simulation_list[-1], configs, env_processes, time_step, run) + pipe_run: List[Dict[str, Any]] = self.state_update_pipeline( + var_dict, simulation_list[-1], configs, env_processes, time_step, run + ) _, *pipe_run = pipe_run simulation_list.append(pipe_run) return simulation_list # ToDo: Muiltithreaded Runs - def simulation(self, var_dict, states_list, configs, env_processes, time_seq, runs): - pipe_run = [] + def simulation( + self, + var_dict: Dict[str, List[Any]], + states_list: List[Dict[str, Any]], + configs: List[Tuple[List[Callable], List[Callable]]], + env_processes: Dict[str, Callable], + time_seq: range, + runs: int + ) -> List[List[Dict[str, Any]]]: + + pipe_run: List[List[Dict[str, Any]]] = [] for run in range(runs): run += 1 - states_list_copy = deepcopy(states_list) + states_list_copy: List[Dict[str, Any]] = deepcopy(states_list) head, *tail = self.run_pipeline(var_dict, states_list_copy, configs, env_processes, time_seq, run) - genesis = head.pop() - genesis['substep'], genesis['timestep'], genesis['run'] = 0, 0, run - first_timestep_per_run = [genesis] + tail.pop(0) - pipe_run += [first_timestep_per_run] + tail del states_list_copy - return pipe_run \ No newline at end of file + genesis: Dict[str, Any] = head.pop() + genesis['substep'], genesis['timestep'], genesis['run'] = 0, 0, run + first_timestep_per_run: List[Dict[str, Any]] = [genesis] + tail.pop(0) + pipe_run += [first_timestep_per_run] + tail + + return pipe_run diff --git a/cadCAD/engine/utils.py b/cadCAD/engine/utils.py index 08428cc..c0f3a76 100644 --- a/cadCAD/engine/utils.py +++ b/cadCAD/engine/utils.py @@ -39,4 +39,4 @@ def engine_exception(ErrorType, error_message, exception_function, try_function) def fit_param(param, x): return x + param -# fit_param = lambda param: lambda x: x + param \ No newline at end of file +# fit_param = lambda param: lambda x: x + param diff --git a/cadCAD/utils/__init__.py b/cadCAD/utils/__init__.py index dac15c1..59fc9c8 100644 --- a/cadCAD/utils/__init__.py +++ b/cadCAD/utils/__init__.py @@ -1,6 +1,8 @@ from collections import defaultdict from itertools import product import warnings +from typing import Dict, List + def pipe(x): return x @@ -41,11 +43,11 @@ def dict_filter(dictionary, condition): return dict([(k, v) for k, v in dictionary.items() if condition(v)]) -def get_max_dict_val_len(g): +def get_max_dict_val_len(g: Dict[str, List[int]]) -> int: return len(max(g.values(), key=len)) -def tabulate_dict(d): +def tabulate_dict(d: Dict[str, List[int]]) -> Dict[str, List[int]]: max_len = get_max_dict_val_len(d) _d = {} for k, vl in d.items(): @@ -57,7 +59,7 @@ def tabulate_dict(d): return _d -def flatten_tabulated_dict(d): +def flatten_tabulated_dict(d: Dict[str, List[int]]) -> List[Dict[str, int]]: max_len = get_max_dict_val_len(d) dl = [{} for i in range(max_len)] @@ -133,4 +135,4 @@ def curry_pot(f, *argv): # def decorator(f): # f.__name__ = newname # return f -# return decorator \ No newline at end of file +# return decorator diff --git a/monkeytype.sqlite3 b/monkeytype.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..c8ea7409a5b1f1bff8411e094c63cd9c9f178813 GIT binary patch literal 761856 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 literal 0 HcmV?d00001 diff --git a/simulations/multi_config run.py b/simulations/multi_config_run.py similarity index 100% rename from simulations/multi_config run.py rename to simulations/multi_config_run.py diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 532f6e7..2c26f91 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -21,6 +21,8 @@ def p1m1(_g, step, sL, s): def p2m1(_g, step, sL, s): return {'param2': 4} +# [] + def p1m2(_g, step, sL, s): return {'param1': 'a', 'param2': 2} def p2m2(_g, step, sL, s): diff --git a/simulations/validation/sweep_config.py b/simulations/validation/sweep_config.py index 09ccd6b..2350d95 100644 --- a/simulations/validation/sweep_config.py +++ b/simulations/validation/sweep_config.py @@ -7,6 +7,8 @@ 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 typing import Dict, List + pp = pprint.PrettyPrinter(indent=4) seeds = { @@ -17,7 +19,7 @@ seeds = { } -g = { +g: Dict[str, List[int]] = { 'alpha': [1], 'beta': [2, 5], 'gamma': [3, 4],