From f55124fbb0f5da8cbca2c81bdf6828301254ebe1 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 10 Dec 2018 22:54:29 -0500 Subject: [PATCH 01/38] multithreaded mech_step, mech_pipeline in progress --- .gitignore | 1 + SimCAD/configuration/utils/__init__.py | 22 ++++++- .../utils/behaviorAggregation.py | 13 ++-- SimCAD/engine/simulation.py | 65 +++++++++++++++++-- SimCAD/engine/utils.py | 18 +++-- SimCAD/utils/__init__.py | 37 ++++++++++- simulations/sim_test.py | 26 ++++---- simulations/validation/config1.py | 31 +++++++-- 8 files changed, 170 insertions(+), 43 deletions(-) diff --git a/.gitignore b/.gitignore index 9e0a0b6..2728be8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .DS_Store .idea notebooks/.ipynb_checkpoints +notebooks/multithreading.ipynb SimCAD.egg-info __pycache__ Pipfile diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 5364566..9fb3e22 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -2,7 +2,9 @@ from datetime import datetime, timedelta from decimal import Decimal from fn.func import curried import pandas as pd +from pathos.threading import ThreadPool +from SimCAD.utils import groupByKey class TensorFieldReport: def __init__(self, config_proc): @@ -18,6 +20,14 @@ class TensorFieldReport: return df +# def s_update(y, x): +# return lambda step, sL, s, _input: (y, x) +# +# +def state_update(y, x): + return lambda step, sL, s, _input: (y, x) + + def bound_norm_random(rng, low, high): # Add RNG Seed res = rng.normal((high+low)/2,(high-low)/6) @@ -53,9 +63,15 @@ def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = t_delta def exo_update_per_ts(ep): @curried - def ep_decorator(f, y, step, sL, s, _input): + def ep_decorator(fs, y, step, sL, s, _input): + # print(s) if s['mech_step'] + 1 == 1: # inside f body to reduce performance costs - return f(step, sL, s, _input) + if isinstance(fs, list): + pool = ThreadPool(nodes=len(fs)) + fx = pool.map(lambda f: f(step, sL, s, _input), fs) + return groupByKey(fx) + else: + return fs(step, sL, s, _input) 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()} diff --git a/SimCAD/configuration/utils/behaviorAggregation.py b/SimCAD/configuration/utils/behaviorAggregation.py index abde5d6..7b51f8a 100644 --- a/SimCAD/configuration/utils/behaviorAggregation.py +++ b/SimCAD/configuration/utils/behaviorAggregation.py @@ -2,14 +2,15 @@ from fn.op import foldr from fn.func import curried -def get_base_value(datatype): - if datatype is str: +def get_base_value(x): + if isinstance(x, str): return '' - elif datatype is int: + elif isinstance(x, int): return 0 - elif datatype is list: + elif isinstance(x, list): return [] - return 0 + else: + return 0 def behavior_to_dict(v): @@ -33,7 +34,7 @@ def sum_dict_values(): def dict_op(f, d1, d2): def set_base_value(target_dict, source_dict, key): if key not in target_dict: - return get_base_value(type(source_dict[key])) + return get_base_value(source_dict[key]) else: return target_dict[key] diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index a0c5d61..7bcfa43 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -1,7 +1,11 @@ +from pathos.threading import ThreadPool from copy import deepcopy from fn.op import foldr, call +import pprint -from SimCAD.utils import rename +pp = pprint.PrettyPrinter(indent=4) + +from SimCAD.utils import groupByKey, flatten, drop_right from SimCAD.engine.utils import engine_exception @@ -23,23 +27,42 @@ class Executor: return foldr(call, get_col_results(step, sL, s, funcs))(ops) + def xthreaded_env_proc(self, f, s_valx): + if isinstance(s_valx, list): + pool = ThreadPool(nodes=len(s_valx)) # ToDo: Optimize + return pool.map(lambda f: f(s_valx), s_valx) + else: + return f(s_valx) + def apply_env_proc(self, env_processes, state_dict, step): for state in state_dict.keys(): if state in list(env_processes.keys()): env_state = env_processes[state] if (env_state.__name__ == '_curried') or (env_state.__name__ == 'proc_trigger'): # might want to change - state_dict[state] = env_state(step)(state_dict[state]) + state_dict[state] = self.xthreaded_env_proc(env_state(step), state_dict[state]) else: - state_dict[state] = env_state(state_dict[state]) + state_dict[state] = self.xthreaded_env_proc(env_state, state_dict[state]) + def xthreaded_state_update(self, fs, m_step, sL, last_in_obj, _input): + if isinstance(fs, list): + pool = ThreadPool(nodes=len(fs)) # ToDo: Optimize + fx = pool.map(lambda f: f(m_step, sL, last_in_obj, _input), fs) + return groupByKey(fx) + else: + return fs(m_step, sL, last_in_obj, _input) + def mech_step(self, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): last_in_obj = sL[-1] _input = self.state_update_exception(self.get_behavior_input(m_step, sL, last_in_obj, behavior_funcs)) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function - last_in_copy = dict([self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs]) + last_in_copy = dict([ + self.behavior_update_exception( + self.xthreaded_state_update(f, m_step, sL, last_in_obj, _input) + ) for f in state_funcs + ]) for k in last_in_obj: if k not in last_in_copy: @@ -49,11 +72,28 @@ class Executor: # make env proc trigger field agnostic self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) # mutating last_in_copy + # print() + # pp.pprint(last_in_copy) + # exit() + + def set_sys_metrics(m_step, t_step, run): + last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = m_step, t_step, run + + if any(isinstance(x, list) for x in last_in_copy.values()): + last_in_copies = flatten(last_in_copy) + for last_in_copy in last_in_copies: + set_sys_metrics(m_step, t_step, run) + sL.append(last_in_copies) + else: + set_sys_metrics(m_step, t_step, run) + sL.append(last_in_copy) - last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = m_step, t_step, run - sL.append(last_in_copy) del last_in_copy + # print() + # pp.pprint(sL) + # exit() + return sL def mech_pipeline(self, states_list, configs, env_processes, t_step, run): @@ -64,15 +104,28 @@ class Executor: genesis_states = states_list_copy[-1] genesis_states['mech_step'], genesis_states['time_step'] = m_step, t_step states_list = [genesis_states] + # print(genesis_states) m_step += 1 for config in configs: s_conf, b_conf = config[0], config[1] + last_states = states_list[-1] + dropped_right_sL = drop_right(states_list, 1) + print() + # print(states_list) + # if isinstance(last_states, list): + # x = list(map(lambda last_state_dict: states_list.pop().append(last_state_dict), last_states)) + # pp.pprint(states_list) + states_list = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) m_step += 1 t_step += 1 + print() + # print(states_list) + exit() + return states_list # rename pipe diff --git a/SimCAD/engine/utils.py b/SimCAD/engine/utils.py index 947a167..90c8fd9 100644 --- a/SimCAD/engine/utils.py +++ b/SimCAD/engine/utils.py @@ -1,5 +1,7 @@ from datetime import datetime from fn.func import curried +from SimCAD.utils import rename +# from SimCAD.configuration.utils import s_update def datetime_range(start, end, delta, dt_format='%Y-%m-%d %H:%M:%S'): @@ -24,6 +26,8 @@ def retrieve_state(l, offset): return l[last_index(l) + offset + 1] +# exception_function = f(m_step, sL, sL[-2], _input) +# try_function = f(m_step, sL, last_mut_obj, _input) @curried def engine_exception(ErrorType, error_message, exception_function, try_function): try: @@ -33,9 +37,11 @@ def engine_exception(ErrorType, error_message, exception_function, try_function) return exception_function -# def exception_handler(f, m_step, sL, last_mut_obj, _input): -# try: -# return f(m_step, sL, last_mut_obj, _input) -# except KeyError: -# print("Exception") -# return f(m_step, sL, sL[-2], _input) \ No newline at end of file +@curried +def fit_param(param, x): + return x + param + +# fit_param = lambda param: lambda x: x + param + +def sweep(params, sweep_f): + return [rename('sweep', sweep_f(param)) for param in params] diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index 3ee6e50..36b6d84 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -1,3 +1,5 @@ +from collections import defaultdict +from itertools import product # from fn.func import curried def pipe(x): @@ -9,17 +11,46 @@ def print_pipe(x): return x +def flattenDict(l): + def tupalize(k, vs): + l = [] + if isinstance(vs, list): + for v in vs: + l.append((k, v)) + else: + l.append((k, vs)) + return l + + flat_list = [tupalize(k, vs) for k, vs in l.items()] + flat_dict = [dict(items) for items in product(*flat_list)] + return flat_dict + + def flatten(l): - return [item for sublist in l for item in sublist] + if isinstance(l, list): + return [item for sublist in l for item in sublist] + elif isinstance(l, dict): + return flattenDict(l) -def flatmap(f, items): - return list(map(f, items)) +def drop_right(l, n=1): + return l[:len(l)-n] + +# def flatmap(f, items): +# return list(map(f, items)) def key_filter(l, keyname): return [v[keyname] for k, v in l.items()] + +def groupByKey(l): + d = defaultdict(list) + for key, value in l: + d[key].append(value) + return list(dict(d).items()).pop() + + # @curried def rename(new_name, f): f.__name__ = new_name diff --git a/simulations/sim_test.py b/simulations/sim_test.py index 1bbfcdc..161db56 100644 --- a/simulations/sim_test.py +++ b/simulations/sim_test.py @@ -29,16 +29,16 @@ print(tabulate(tensor_field, headers='keys', tablefmt='psql')) print("Output:") print(tabulate(result, headers='keys', tablefmt='psql')) print() - -print("Simulation Execution 2: Pairwise Execution") -print() -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() \ No newline at end of file +# +# print("Simulation Execution 2: Pairwise Execution") +# print() +# 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() \ No newline at end of file diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 7bdd5ac..e9a01c5 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -4,8 +4,9 @@ from datetime import timedelta from SimCAD import configs from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ +from SimCAD.configuration.utils import state_update, exo_update_per_ts, proc_trigger, bound_norm_random, \ ep_time_step +from SimCAD.engine.utils import sweep seed = { 'z': np.random.RandomState(1), @@ -42,6 +43,14 @@ def s2m1(step, sL, s, _input): x = _input['param2'] #+ [Coef2 x 5] return (y, x) +s2m1 = sweep( + params = [Decimal(11.0), Decimal(22.0)], + sweep_f = lambda param: lambda step, sL, s, _input: ( + 's2', + s['s2'] + param + ) +) + def s1m2(step, sL, s, _input): y = 's1' x = _input['param1'] @@ -64,10 +73,20 @@ def s2m3(step, sL, s, _input): proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) +# def es3p1(step, sL, s, _input): +# y = 's3' +# x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) +# return (y, x) + + +es3p1 = sweep( + params = [Decimal(11.0), Decimal(22.0)], + sweep_f = lambda param: lambda step, sL, s, _input: ( + 's3', + s['s3'] + param + ) +) + def es4p2(step, sL, s, _input): y = 's4' @@ -111,7 +130,7 @@ exogenous_states = exo_update_per_ts( # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ env_processes = { - "s3": env_a, + # "s3": env_a, "s4": proc_trigger('2018-10-01 15:16:25', env_b) } From 181b7cf986d210865b4db1a577c5e97c5001f2f6 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 10 Dec 2018 23:47:08 -0500 Subject: [PATCH 02/38] multithreaded mech_pipeline in progress --- SimCAD/engine/simulation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 7bcfa43..c420f62 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -113,11 +113,11 @@ class Executor: dropped_right_sL = drop_right(states_list, 1) print() # print(states_list) - # if isinstance(last_states, list): - # x = list(map(lambda last_state_dict: states_list.pop().append(last_state_dict), last_states)) - # pp.pprint(states_list) + if isinstance(last_states, list): + x = list(map(lambda last_state_dict: dropped_right_sL.append(last_state_dict), last_states)) + print(x) - states_list = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) + # states_list = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) m_step += 1 t_step += 1 From a0266641f708cacc0a87d44638831fa2633bfc2f Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 11 Dec 2018 01:07:23 -0500 Subject: [PATCH 03/38] multithreading mech_pipeline again, block_pipeline later --- SimCAD/engine/simulation.py | 43 +++++++++++++++++++++++-------------- SimCAD/utils/__init__.py | 2 +- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index c420f62..9c41d50 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -1,6 +1,7 @@ from pathos.threading import ThreadPool from copy import deepcopy from fn.op import foldr, call +import numpy as np import pprint pp = pprint.PrettyPrinter(indent=4) @@ -72,9 +73,7 @@ class Executor: # make env proc trigger field agnostic self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) # mutating last_in_copy - # print() - # pp.pprint(last_in_copy) - # exit() + def set_sys_metrics(m_step, t_step, run): last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = m_step, t_step, run @@ -90,12 +89,9 @@ class Executor: del last_in_copy - # print() - # pp.pprint(sL) - # exit() - return sL + def mech_pipeline(self, states_list, configs, env_processes, t_step, run): m_step = 0 states_list_copy = deepcopy(states_list) @@ -110,20 +106,27 @@ class Executor: for config in configs: s_conf, b_conf = config[0], config[1] last_states = states_list[-1] - dropped_right_sL = drop_right(states_list, 1) - print() - # print(states_list) if isinstance(last_states, list): - x = list(map(lambda last_state_dict: dropped_right_sL.append(last_state_dict), last_states)) - print(x) + pool = ThreadPool(nodes=len(last_states)) # ToDo: Optimize + dropped_right_sL = drop_right(states_list, 1) + + def multithreaded_mech_step(mod_states_list): + return self.mech_step(m_step, mod_states_list, s_conf, b_conf, env_processes, t_step, run) + + states_lists = pool.map( + lambda last_state_dict: dropped_right_sL + [last_state_dict], + last_states + ) + print() + pp.pprint(configs) + else: + states_lists = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) + - # states_list = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) m_step += 1 t_step += 1 - print() - # print(states_list) exit() return states_list @@ -132,9 +135,17 @@ class Executor: def block_pipeline(self, states_list, configs, env_processes, time_seq, run): time_seq = [x + 1 for x in time_seq] simulation_list = [states_list] + print(len(configs)) for time_step in time_seq: - pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) + # print(simulation_list) + if len(simulation_list) == 1: + pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) + exit() + # elif np.array(pipe_run[-1]) == 2: + # pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) + # print(pipe_run) _, *pipe_run = pipe_run + # print(pipe_run) simulation_list.append(pipe_run) return simulation_list diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index 36b6d84..05363a1 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -33,7 +33,7 @@ def flatten(l): return flattenDict(l) -def drop_right(l, n=1): +def drop_right(l, n): return l[:len(l)-n] # def flatmap(f, items): From e2752161c3b11a163936bcae2b6338beec58913c Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 11 Dec 2018 10:25:25 -0500 Subject: [PATCH 04/38] misc. --- SimCAD/engine/simulation.py | 20 +- notebooks/jjodesty/multithreading.ipynb | 576 ++++++++++++++++++++++++ 2 files changed, 590 insertions(+), 6 deletions(-) create mode 100644 notebooks/jjodesty/multithreading.ipynb diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 9c41d50..e5bf89c 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -74,19 +74,27 @@ class Executor: # make env proc trigger field agnostic self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) # mutating last_in_copy + print() + print(last_in_copy) + print() - def set_sys_metrics(m_step, t_step, run): - last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = m_step, t_step, run + + def set_sys_metrics(state_dict, m_step, t_step, run): + state_dict["mech_step"], state_dict["time_step"], state_dict['run'] = m_step, t_step, run if any(isinstance(x, list) for x in last_in_copy.values()): last_in_copies = flatten(last_in_copy) for last_in_copy in last_in_copies: - set_sys_metrics(m_step, t_step, run) + set_sys_metrics(last_in_copy, m_step, t_step, run) sL.append(last_in_copies) else: - set_sys_metrics(m_step, t_step, run) + set_sys_metrics(last_in_copy, m_step, t_step, run) sL.append(last_in_copy) + print() + pp.pprint(last_in_copies) + print() + del last_in_copy return sL @@ -118,7 +126,7 @@ class Executor: last_states ) print() - pp.pprint(configs) + # pp.pprint(configs) else: states_lists = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) @@ -135,7 +143,7 @@ class Executor: def block_pipeline(self, states_list, configs, env_processes, time_seq, run): time_seq = [x + 1 for x in time_seq] simulation_list = [states_list] - print(len(configs)) + # print(len(configs)) for time_step in time_seq: # print(simulation_list) if len(simulation_list) == 1: diff --git a/notebooks/jjodesty/multithreading.ipynb b/notebooks/jjodesty/multithreading.ipynb new file mode 100644 index 0000000..c3a41ad --- /dev/null +++ b/notebooks/jjodesty/multithreading.ipynb @@ -0,0 +1,576 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import _thread\n", + "import time\n", + "from fn.func import curried" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function for the thread\n", + "def f(threadName, delay):\n", + " count = 0\n", + " print(count)\n", + " # while count < 5:\n", + " # time.sleep(delay)\n", + " # count += 1\n", + " # print(count)\n", + " \n", + "def pipe(x):\n", + " print(x)\n", + " return x" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "00\n", + "\n" + ] + } + ], + "source": [ + "# Create two threads as follows\n", + "try:\n", + " _thread.start_new_thread( f, (\"Thread-1\", 2, ) )\n", + " _thread.start_new_thread( f, (\"Thread-2\", 4, ) )\n", + "except:\n", + " print (\"Error: unable to start thread\")\n", + "\n", + "while 1:\n", + " pass\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 2]\n", + "('s2', . at 0x1099efae8>)\n", + "('s2', . at 0x1099ef9d8>)\n" + ] + } + ], + "source": [ + "from SimCAD.engine.utils import sweep\n", + "from SimCAD.utils import rename\n", + "from SimCAD.configuration.utils import s_update\n", + "\n", + "# @curried\n", + "def fit_param(param):\n", + " return lambda x: x + param\n", + "\n", + "# xf = lambda param: lambda x: x + param\n", + "\n", + "def sweep(params, y, xf):\n", + " op = [rename('sweep', s_update(y, xf(param))) for param in params]\n", + " print(params)\n", + " # print()\n", + " return op\n", + "\n", + "for f in sweep([1,2], 's2', fit_param):\n", + " print(f(1,2,3,4))\n", + "# sweep([1,2], 's2', xf)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 64, 2187, 65536]\n" + ] + } + ], + "source": [ + "# instantiate and configure the worker pool\n", + "from pathos.threading import ThreadPool\n", + "pool = ThreadPool(nodes=4)\n", + "\n", + "# do a blocking map on the chosen function\n", + "print(pool.map(pow, [1,2,3,4], [5,6,7,8]))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 3)", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m3\u001b[0m\n\u001b[0;31m [for f in fs]\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ], + "output_type": "error" + } + ], + "source": [ + "with Pool(len(configs)) as p:\n", + " results = p.map(lambda t: t[0](t[1], t[2], t[3], t[4], t[5]), l)\n", + " \n", + "\n", + "def state_multithreading(self, fs, m_step, sL, last_in_obj, _input):\n", + " if type(fs) == 'list':\n", + " pool.map(f(m_step, sL, last_in_obj, _input), fs)\n", + " else:\n", + " f(m_step, sL, last_in_obj, _input)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('s2', [11, 23])]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from itertools import groupby\n", + "l = [('s2', 11), ('s2', 23)]\n", + "l.sort(key = lambda i : i[0])\n", + "[(key, [i[1] for i in values]) for key, values in groupby(l, lambda i: i[0])]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def groupByKV(l):\n", + " l.sort(key = lambda i : i[0])\n", + " return [(key, [i[1] for i in values]) for key, values in groupby(l, lambda i: i[0])]" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('s2', [11, 23])]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "groupByKV(l)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 2)", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m collect = lambda tuplist: reduce(lambda acc, (k,v): acc[k].append(v) or acc,tuplist, defaultdict(list))\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ], + "output_type": "error" + } + ], + "source": [ + "from collections import defaultdict \n", + "collect = lambda tuplist: reduce(lambda acc, (k,v): acc[k].append(v) or acc,tuplist, defaultdict(list))" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "d = defaultdict(list)\n", + "for key, value in [('s2', 11), ('s2', 23)]:\n", + " d[key].append(value)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Help on defaultdict object:\n", + "\n", + "class defaultdict(builtins.dict)\n", + " | defaultdict(default_factory[, ...]) --> dict with default factory\n", + " | \n", + " | The default factory is called without arguments to produce\n", + " | a new value when a key is not present, in __getitem__ only.\n", + " | A defaultdict compares equal to a dict with the same items.\n", + " | All remaining arguments are treated the same as if they were\n", + " | passed to the dict constructor, including keyword arguments.\n", + " | \n", + " | Method resolution order:\n", + " | defaultdict\n", + " | builtins.dict\n", + " | builtins.object\n", + " | \n", + " | Methods defined here:\n", + " | \n", + " | __copy__(...)\n", + " | D.copy() -> a shallow copy of D.\n", + " | \n", + " | __getattribute__(self, name, /)\n", + " | Return getattr(self, name).\n", + " | \n", + " | __init__(self, /, *args, **kwargs)\n", + " | Initialize self. See help(type(self)) for accurate signature.\n", + " | \n", + " | __missing__(...)\n", + " | __missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n", + " | if self.default_factory is None: raise KeyError((key,))\n", + " | self[key] = value = self.default_factory()\n", + " | return value\n", + " | \n", + " | __reduce__(...)\n", + " | Return state information for pickling.\n", + " | \n", + " | __repr__(self, /)\n", + " | Return repr(self).\n", + " | \n", + " | copy(...)\n", + " | D.copy() -> a shallow copy of D.\n", + " | \n", + " | ----------------------------------------------------------------------\n", + " | Data descriptors defined here:\n", + " | \n", + " | default_factory\n", + " | Factory for default value called by __missing__().\n", + " | \n", + " | ----------------------------------------------------------------------\n", + " | Methods inherited from builtins.dict:\n", + " | \n", + " | __contains__(self, key, /)\n", + " | True if D has a key k, else False.\n", + " | \n", + " | __delitem__(self, key, /)\n", + " | Delete self[key].\n", + " | \n", + " | __eq__(self, value, /)\n", + " | Return self==value.\n", + " | \n", + " | __ge__(self, value, /)\n", + " | Return self>=value.\n", + " | \n", + " | __getitem__(...)\n", + " | x.__getitem__(y) <==> x[y]\n", + " | \n", + " | __gt__(self, value, /)\n", + " | Return self>value.\n", + " | \n", + " | __iter__(self, /)\n", + " | Implement iter(self).\n", + " | \n", + " | __le__(self, value, /)\n", + " | Return self<=value.\n", + " | \n", + " | __len__(self, /)\n", + " | Return len(self).\n", + " | \n", + " | __lt__(self, value, /)\n", + " | Return self size of D in memory, in bytes\n", + " | \n", + " | clear(...)\n", + " | D.clear() -> None. Remove all items from D.\n", + " | \n", + " | fromkeys(iterable, value=None, /) from builtins.type\n", + " | Returns a new dict with keys from iterable and values equal to value.\n", + " | \n", + " | get(...)\n", + " | D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.\n", + " | \n", + " | items(...)\n", + " | D.items() -> a set-like object providing a view on D's items\n", + " | \n", + " | keys(...)\n", + " | D.keys() -> a set-like object providing a view on D's keys\n", + " | \n", + " | pop(...)\n", + " | D.pop(k[,d]) -> v, remove specified key and return the corresponding value.\n", + " | If key is not found, d is returned if given, otherwise KeyError is raised\n", + " | \n", + " | popitem(...)\n", + " | D.popitem() -> (k, v), remove and return some (key, value) pair as a\n", + " | 2-tuple; but raise KeyError if D is empty.\n", + " | \n", + " | setdefault(...)\n", + " | D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D\n", + " | \n", + " | update(...)\n", + " | D.update([E, ]**F) -> None. Update D from dict/iterable E and F.\n", + " | If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n", + " | If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n", + " | In either case, this is followed by: for k in F: D[k] = F[k]\n", + " | \n", + " | values(...)\n", + " | D.values() -> an object providing a view on D's values\n", + " | \n", + " | ----------------------------------------------------------------------\n", + " | Data and other attributes inherited from builtins.dict:\n", + " | \n", + " | __hash__ = None\n", + "\n" + ] + } + ], + "source": [ + "help(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'s2': [11, 23]}" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dict(d)" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "def groupByKey(l):\n", + " d = defaultdict(list)\n", + " for key, value in l:\n", + " d[key].append(value)\n", + " return list(dict(d).items()).pop()" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('s2', [11, 23])" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "r = groupByKey([('s2', 11), ('s2', 23)])\n", + "r" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# xf = lambda param: 1.0 + param\n", + "# def xf(y, param, s):\n", + "# return s[y] + param\n", + "\n", + "# def fit_param(param):\n", + "# y = 's2'\n", + "# x = 1 + param\n", + "# return lambda step, sL, s, _input: (y, x)\n", + "#\n", + "# def fit_param(param):\n", + "# return lambda step, sL, s, _input: (\n", + "# 's2',\n", + "# s['s2'] + param\n", + "# )\n", + "#\n", + "# s2m1 = sweep(\n", + "# params = [Decimal(11.0), Decimal(22.0)],\n", + "# sweep_f = fit_param\n", + "# )" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "from decimal import Decimal\n", + "from itertools import product\n", + "\n", + "# def \n", + "\n", + "l = {\n", + " 's1': 1, \n", + " 's2': [Decimal('11'), Decimal('22')], \n", + " 's3': [Decimal('12'), Decimal('23')], \n", + " 's4': 10, \n", + " 'timestamp': '2018-10-01 15:16:25', \n", + " 'mech_step': 0, \n", + " 'time_step': 1\n", + "}\n", + "\n", + "def flattenDict(l):\n", + " def tupalize(k, vs):\n", + " l = []\n", + " if isinstance(vs, list):\n", + " for v in vs:\n", + " l.append((k, v))\n", + " else:\n", + " l.append((k, vs))\n", + " return l\n", + "\n", + " flat_list = [tupalize(k, vs) for k, vs in l.items()]\n", + " flat_dict = [dict(items) for items in product(*flat_list)]\n", + " return flat_dict" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'s1': 1,\n", + " 's2': Decimal('11'),\n", + " 's3': Decimal('12'),\n", + " 's4': 10,\n", + " 'timestamp': '2018-10-01 15:16:25',\n", + " 'mech_step': 0,\n", + " 'time_step': 1},\n", + " {'s1': 1,\n", + " 's2': Decimal('11'),\n", + " 's3': Decimal('23'),\n", + " 's4': 10,\n", + " 'timestamp': '2018-10-01 15:16:25',\n", + " 'mech_step': 0,\n", + " 'time_step': 1},\n", + " {'s1': 1,\n", + " 's2': Decimal('22'),\n", + " 's3': Decimal('12'),\n", + " 's4': 10,\n", + " 'timestamp': '2018-10-01 15:16:25',\n", + " 'mech_step': 0,\n", + " 'time_step': 1},\n", + " {'s1': 1,\n", + " 's2': Decimal('22'),\n", + " 's3': Decimal('23'),\n", + " 's4': 10,\n", + " 'timestamp': '2018-10-01 15:16:25',\n", + " 'mech_step': 0,\n", + " 'time_step': 1}]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flattenDict(l)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} From b7f6d284a7543cb891e1ac8d6ed8d99a5bf18e40 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 13 Dec 2018 23:44:35 -0500 Subject: [PATCH 05/38] demonstation --- simulations/validation/config1.py | 35 +++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index e9a01c5..f1bb962 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -1,6 +1,7 @@ from decimal import Decimal import numpy as np from datetime import timedelta +from fn.func import curried from SimCAD import configs from SimCAD.configuration import Configuration @@ -38,18 +39,32 @@ def s1m1(step, sL, s, _input): y = 's1' x = _input['param1'] #+ [Coef1 x 5] return (y, x) + + + +# curry to give sweep_f s2m1 and returning a s2m1 sweep_f(s2m1)(param) +# decorator +param = Decimal(11.0) def s2m1(step, sL, s, _input): y = 's2' - x = _input['param2'] #+ [Coef2 x 5] + x = _input['param2'] + param return (y, x) -s2m1 = sweep( - params = [Decimal(11.0), Decimal(22.0)], - sweep_f = lambda param: lambda step, sL, s, _input: ( - 's2', - s['s2'] + param - ) -) +s2m1_params =[Decimal(11.0), Decimal(22.0)] +@curried +def s2m1(param, step, sL, s, _input): + y = 's2' + x = _input['param2'] + param + return (y, x) + + +# s2m1_sweep = s2m1(param=s2m1_params) + +# +# s2m1_sweep = sweep( +# params = s2m1_params, +# sweep_f = s2m1_sweep +# ) def s1m2(step, sL, s, _input): y = 's1' @@ -87,7 +102,6 @@ es3p1 = sweep( ) ) - def es4p2(step, sL, s, _input): y = 's4' x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) @@ -146,7 +160,6 @@ env_processes = { # need at least 1 behaviour and 1 state function for the 1st mech with behaviors # mechanisms = {} - mechanisms = { "m1": { "behaviors": { @@ -155,7 +168,7 @@ mechanisms = { }, "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value "s1": s1m1, - "s2": s2m1 + "s2": sweep(s2m1_params, s2m1) } }, "m2": { From 40f24f0909cbd42713317de92a85677777cb9c12 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Fri, 14 Dec 2018 00:09:55 -0500 Subject: [PATCH 06/38] added simulation documentation --- Simulation.md | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 Simulation.md diff --git a/Simulation.md b/Simulation.md new file mode 100644 index 0000000..81d1ece --- /dev/null +++ b/Simulation.md @@ -0,0 +1,151 @@ +# SimmCAD Documentation + +## Introduction + +A blockchain is a distributed ledger with economic agents transacting in a network. The state of the network evolves with every new transaction, which can be a result of user behaviors, protocol-defined system mechanisms, or external processes. + +It is not uncommon today for blockchain projects to announce a set of rules for their network and make claims about their system level behvaior. However, the validity of those claims is hardly validated. Furthermore, it is difficult to know the potential system-level impact when the network is considering an upgrade to their system rules and prameters. + +To rigorously and reliably analyze, design, and improve cryptoeconomic networks, we are introducing this Computer Aided Design Engine where we define a cryptoeconomic network with its state and exogneous variables, model transactions as a result of agent behaviors, state mechanisms, and environmental processes. We can then run simulations with different initial states, mechanisms, environmental processes to understand and visualize network behavior under different conditions. + +## State Variables and Transitions + +We now define variables and different transition mechanisms that will be inputs to the simulation engine. + +- ***State variables*** are defined to capture the shape and property of the network, such as a vector or a dictionary that captures all user balances. +- ***Exogenous variables*** are variables that represent external input and signal. They are only affected by environmental processes and are not affected by system mechanisms. Nonetheless, exgoneous variables can be used as an input to a mechanism that impacts state variables. They can be considered as read-only variables to the system. +- ***Behaviors per transition*** model agent behaviors in reaction to state variables and exogenous variables. The resulted user action will become an input to state mechanisms. Note that user behaviors should not directly update value of state variables. +- ***State mechanisms per transition*** are system defined mechanisms that take user actions and other states as inputs and produce updates to the value of state variables. +- ***Exogenous state updates*** specify how exogenous variables evolve with time which can indirectly impact state variables through behavior and state mechanisms. +- ***Environmental processes*** model external changes that directly impact state or exogenous variables at specific timestamps or conditions. + +A state evolves to another state via state transition. Each transition is composed of behavior and state mechanisms as functions of state and exogenous variables. A flow of the state transition is as follows. + +Given some state and exogenous variables of the system at the onset of a state transition, agent behavior takes in these variables as input and return a set of agent actions. This models after agent behavior and reaction to a set of variables. Given these agent actions, state mechanism, as defined by the protocol, takes these actions, state, and exogenous variables as inputs and return a new set of state variables. + +## System Configuration File + +Simulation engine takes in system configuration files, e.g. `config.py`, where all the above variables and mechanisms are defined. The following import statements should be added at the beginning of the configuration files. +```python +from decimal import Decimal +import numpy as np +from datetime import timedelta + +from SimCAD import configs +from SimCAD.configuration import Configuration +from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step +``` + +State variables and their initial values can be defined as follows. Note that `timestamp` is a required field for this iteration of SimCAD for `env_proc` to work. Future iterations will strive to make this more generic and timestamp optional. +```python +genesis_dict = { + 's1': Decimal(0.0), + 's2': Decimal(0.0), + 's3': Decimal(1.0), + 'timestamp': '2018-10-01 15:16:24' +} +``` + +Each potential transition and its state and behavior mechanisms can be defined in the following dictionary object. +```python +transitions = { + "m1": { + "behaviors": { + "b1": b1m1, + "b2": b2m1 + }, + "states": { + "s1": s1m1, + "s2": s2m1 + } + }, + "m2": {...} +} +``` +Every behavior per transition should return a dictionary as actions taken by the agents. They will then be aggregated through addition in this version of SimCAD. Some examples of behaviors per transition are as follows. More flexible and user-defined aggregation functions will be introduced in future iterations but no example is provided at this point. +```python +def b1m1(step, sL, s): + return {'param1': 1} + +def b1m2(step, sL, s): + return {'param1': 'a', 'param2': 2} + +def b1m3(step, sL, s): + return {'param1': ['c'], 'param2': np.array([10, 100])} +``` +State mechanism per transition on the other hand takes in the output of behavior mechanisms (`_input`) and returns a tuple of the name of the variable and the new value for the variable. Some examples of a state mechanism per transition are as follows. Note that each state mechanism is supposed to change one state variable at a time. Changes to multiple state variables should be done in separate mechanisms. +```python +def s1m1(step, sL, s, _input): + y = 's1' + x = _input['param1'] + 1 + return (y, x) + +def s1m2(step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) +``` +Exogenous state update functions, for example `es3p1`, `es4p2` and `es5p2` below, update exogenous variables at every timestamp. Note that every timestamp is consist of all behaviors and state mechanisms in the order defined in `transitions` dictionary. If `exo_update_per_ts` is not used, exogenous state updates will be applied at every mechanism step (`m1`, `m2`, etc). Otherwise, exogenous state updates will only be applied once for every timestamp after all the mechanism steps are executed. +```python +exogenous_states = exo_update_per_ts( + { + "s3": es3p1, + "s4": es4p2, + "timestamp": es5p2 + } +) +``` +To model randomness, we should also define pseudorandom seeds in the configuration as follows. +```python +seed = { + 'z': np.random.RandomState(1), + 'a': np.random.RandomState(2), + 'b': np.random.RandomState(3), + 'c': np.random.RandomState(3) +} +``` +SimCAD currently supports generating random number from a normal distribution through `bound_norm_random` with `min` and `max` values specified. Examples of environmental processes with randomness are as follows. We also define timestamp format with `ts_format` and timestamp changes with `t_delta`. Users can define other distributions to update exogenous variables. +```python +proc_one_coef_A = 0.7 +proc_one_coef_B = 1.3 + +def es3p1(step, sL, s, _input): + y = 's3' + x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +def es4p2(step, sL, s, _input): + y = 's4' + x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + return (y, x) + +ts_format = '%Y-%m-%d %H:%M:%S' +t_delta = timedelta(days=0, minutes=0, seconds=1) +def es5p2(step, sL, s, _input): + y = 'timestamp' + x = ep_time_step(s, s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + return (y, x) +``` +User can also define specific external events such as market shocks at specific timestamps through `env_processes` with `proc_trigger`. An environmental process with no `proc_trigger` will be called at every timestamp. In the example below, it will return the value of `s3` at every timestamp. Logical event triggers, such as a big draw down in exogenous variables, will be supported in a later version of SimCAD. +```python +def env_a(x): + return x +def env_b(x): + return 10 + +env_processes = { + "s3": env_a, + "s4": proc_trigger('2018-10-01 15:16:25', env_b) +} +``` + +Lastly, we set the overall simulation configuration and initialize the `Configuration` class with the following. `T` denotes the time range and `N` refers to the number of simulation runs. Each run will start from the same initial states and run for `T` time range. Every transition is consist of behaviors, state mechanisms, exogenous updates, and potentially environmental processes. All of these happen within one time step in the simulation. +```python +sim_config = { + "N": 2, + "T": range(5) +} + +configs.append(Configuration(sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms)) +``` From 9201f9f20ee62bf0b506898b3c14115a798fe8b7 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Sat, 15 Dec 2018 23:08:47 -0500 Subject: [PATCH 07/38] param-sweep work --- SimCAD/configuration/__init__.py | 10 +- SimCAD/engine/utils.py | 4 +- SimCAD/utils/__init__.py | 27 ++++- simulations/validation/config1.py | 162 ++++++++++++++++++++++-------- 4 files changed, 154 insertions(+), 49 deletions(-) diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index 0af1af7..2e9bc99 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -1,21 +1,23 @@ from functools import reduce from fn.op import foldr import pandas as pd +from fn.func import curried from SimCAD.utils import key_filter from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum +# class ParameterSeep: class Configuration: - def __init__(self, sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms, behavior_ops=[foldr(dict_elemwise_sum())]): + def __init__(self, sim_config=None, state_dict=None, seed=None, env_processes=None, + exogenous_states=None, mechanisms=None, behavior_ops=[foldr(dict_elemwise_sum())]): self.sim_config = sim_config self.state_dict = state_dict self.seed = seed - self.exogenous_states = exogenous_states self.env_processes = env_processes - self.behavior_ops = behavior_ops + self.exogenous_states = exogenous_states self.mechanisms = mechanisms - + self.behavior_ops = behavior_ops class Identity: def __init__(self, behavior_id={'identity': 0}): diff --git a/SimCAD/engine/utils.py b/SimCAD/engine/utils.py index 90c8fd9..8bb4218 100644 --- a/SimCAD/engine/utils.py +++ b/SimCAD/engine/utils.py @@ -43,5 +43,5 @@ def fit_param(param, x): # fit_param = lambda param: lambda x: x + param -def sweep(params, sweep_f): - return [rename('sweep', sweep_f(param)) for param in params] +def sweep(params, sweep_f, f_name='sweep'): + return [rename(f_name+"_"+str(i), sweep_f(param)) for param, i in zip(params, range(len(params)))] diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index 05363a1..d96cb23 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -2,6 +2,7 @@ from collections import defaultdict from itertools import product # from fn.func import curried + def pipe(x): return x @@ -33,9 +34,33 @@ def flatten(l): return flattenDict(l) +def flatMap(f, collection): + return flatten(list(map(f, collection))) + + +def dict_filter(dictionary, condition): + return dict([(k, v) for k, v in dictionary.items() if condition(v)]) + + +def contains_type(_collection, type): + return any(isinstance(x, type) for x in _collection) + + def drop_right(l, n): return l[:len(l)-n] + +def mech_sweep_filter(mechanisms): + mech_states_dict = dict([(k, v['states']) for k, v in mechanisms.items()]) + return dict([ + (k, dict_filter(v, lambda v: isinstance(v, list))) for k, v in mech_states_dict.items() + if contains_type(list(v.values()), list) + ]) + + +def state_sweep_filter(raw_exogenous_states): + return dict([(k, v) for k, v in raw_exogenous_states.items() if isinstance(v, list)]) + # def flatmap(f, items): # return list(map(f, items)) @@ -55,7 +80,7 @@ def groupByKey(l): def rename(new_name, f): f.__name__ = new_name return f -# + # def rename(newname): # def decorator(f): # f.__name__ = newname diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index f1bb962..aae710d 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -2,13 +2,17 @@ from decimal import Decimal import numpy as np from datetime import timedelta from fn.func import curried - +import pprint +from copy import deepcopy from SimCAD import configs +from SimCAD.utils import flatMap, mech_sweep_filter, state_sweep_filter from SimCAD.configuration import Configuration from SimCAD.configuration.utils import state_update, exo_update_per_ts, proc_trigger, bound_norm_random, \ ep_time_step from SimCAD.engine.utils import sweep +pp = pprint.PrettyPrinter(indent=4) + seed = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), @@ -41,14 +45,12 @@ def s1m1(step, sL, s, _input): return (y, x) - -# curry to give sweep_f s2m1 and returning a s2m1 sweep_f(s2m1)(param) # decorator -param = Decimal(11.0) -def s2m1(step, sL, s, _input): - y = 's2' - x = _input['param2'] + param - return (y, x) +# param = Decimal(11.0) +# def s2m1(step, sL, s, _input): +# y = 's2' +# x = _input['param2'] + param +# return (y, x) s2m1_params =[Decimal(11.0), Decimal(22.0)] @curried @@ -57,15 +59,6 @@ def s2m1(param, step, sL, s, _input): x = _input['param2'] + param return (y, x) - -# s2m1_sweep = s2m1(param=s2m1_params) - -# -# s2m1_sweep = sweep( -# params = s2m1_params, -# sweep_f = s2m1_sweep -# ) - def s1m2(step, sL, s, _input): y = 's1' x = _input['param1'] @@ -94,13 +87,20 @@ proc_one_coef_B = 1.3 # return (y, x) -es3p1 = sweep( - params = [Decimal(11.0), Decimal(22.0)], - sweep_f = lambda param: lambda step, sL, s, _input: ( - 's3', - s['s3'] + param - ) -) +# es3p1 = sweep( +# params = [Decimal(11.0), Decimal(22.0)], +# sweep_f = lambda param: lambda step, sL, s, _input: ( +# 's3', +# s['s3'] + param +# ) +# ) + +es3p1_params =[Decimal(11.0), Decimal(22.0)] +@curried +def es3p1(param, step, sL, s, _input): + y = 's3' + x = s['s3'] + param + return (y, x) def es4p2(step, sL, s, _input): y = 's4' @@ -116,8 +116,10 @@ def es5p2(step, sL, s, _input): # Environment States -def env_a(x): - return 5 +env_a_params = [Decimal(1), Decimal(2)] +@curried +def env_a(param, x): + return x + param def env_b(x): return 10 # def what_ever(x): @@ -133,18 +135,17 @@ genesis_states = { } # remove `exo_update_per_ts` to update every ts -exogenous_states = exo_update_per_ts( - { - "s3": es3p1, +raw_exogenous_states = { + "s3": sweep(es3p1_params, es3p1), "s4": es4p2, "timestamp": es5p2 - } -) +} +exogenous_states = exo_update_per_ts(raw_exogenous_states) # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ env_processes = { - # "s3": env_a, + "s3": sweep(env_a_params, env_a, 'env_a'), "s4": proc_trigger('2018-10-01 15:16:25', env_b) } @@ -198,13 +199,90 @@ sim_config = { "T": range(5) } -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) -) \ No newline at end of file +# configs.append( +# Configuration( +# sim_config=sim_config, +# state_dict=genesis_states, +# seed=seed, +# env_processes=env_processes, +# exogenous_states=exogenous_states, +# mechanisms=mechanisms +# ) +# ) + + +# filtered_exo_states = raw_exo_sweep_filter(raw_exogenous_states) +# pp.pprint(filtered_exo_states) +# print() + + +@curried +def sweep_mechs(in_config): + configs = [] + filtered_mech_states = mech_sweep_filter(in_config.mechanisms) + if len(filtered_mech_states) > 0: + for mech, state_dict in filtered_mech_states.items(): + for state, state_funcs in state_dict.items(): + for f in state_funcs: + config: Configuration = deepcopy(in_config) + exploded_mechs = deepcopy(mechanisms) + exploded_mechs[mech]['states'][state] = f + config.mechanisms = exploded_mechs + configs.append(config) + del config, exploded_mechs + else: + configs = [in_config] + + return configs + + +@curried +def sweep_states(state_type, states, in_config): + configs = [] + filtered_states = state_sweep_filter(states) + if len(filtered_states) > 0: + for state, state_funcs in filtered_states.items(): + for f in state_funcs: + config: Configuration = deepcopy(in_config) + exploded_states = deepcopy(states) + exploded_states[state] = f + if state_type == 'exogenous': + config.exogenous_states = exploded_states + elif state_type == 'environmental': + config.env_processes = exploded_states + configs.append(config) + del config, exploded_states + else: + configs = [in_config] + + return configs + + +c = Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + env_processes=env_processes, + exogenous_states=exogenous_states, + mechanisms=mechanisms +) + + +l = flatMap( + sweep_states('environmental', env_processes), + flatMap( + sweep_states('exogenous', raw_exogenous_states), + sweep_mechs(c) + ) +) + +for g in l: + print() + print('Configuration') + print() + pp.pprint(g.env_processes) + print() + pp.pprint(g.exogenous_states) + print() + pp.pprint(g.mechanisms) + print() \ No newline at end of file From 2bb378fbf209e4bc0cd53f47d048e6b02bc4db41 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Sun, 16 Dec 2018 00:47:42 -0500 Subject: [PATCH 08/38] param-sweep: cadillac pt. 1 --- SimCAD/configuration/__init__.py | 2 +- SimCAD/configuration/utils/__init__.py | 54 +++++++++++++++- SimCAD/utils/__init__.py | 15 ----- simulations/validation/config1.py | 86 +++++++------------------- 4 files changed, 78 insertions(+), 79 deletions(-) diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index 2e9bc99..5b508af 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -8,7 +8,7 @@ from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum # class ParameterSeep: -class Configuration: +class Configuration(object): def __init__(self, sim_config=None, state_dict=None, seed=None, env_processes=None, exogenous_states=None, mechanisms=None, behavior_ops=[foldr(dict_elemwise_sum())]): self.sim_config = sim_config diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 9fb3e22..cae4a2a 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -1,10 +1,11 @@ from datetime import datetime, timedelta from decimal import Decimal +from copy import deepcopy from fn.func import curried import pandas as pd from pathos.threading import ThreadPool -from SimCAD.utils import groupByKey +from SimCAD.utils import groupByKey, dict_filter, contains_type class TensorFieldReport: def __init__(self, config_proc): @@ -75,3 +76,54 @@ def exo_update_per_ts(ep): else: return (y, s[y]) return {es: ep_decorator(f, es) for es, f in ep.items()} + + +def mech_sweep_filter(mech_field, mechanisms): + mech_dict = dict([(k, v[mech_field]) for k, v in mechanisms.items()]) + return dict([ + (k, dict_filter(v, lambda v: isinstance(v, list))) for k, v in mech_dict.items() + if contains_type(list(v.values()), list) + ]) + + +def state_sweep_filter(raw_exogenous_states): + return dict([(k, v) for k, v in raw_exogenous_states.items() if isinstance(v, list)]) + +@curried +def sweep_mechs(_type, in_config): + configs = [] + filtered_mech_states = mech_sweep_filter(_type, in_config.mechanisms) + if len(filtered_mech_states) > 0: + for mech, state_dict in filtered_mech_states.items(): + for state, state_funcs in state_dict.items(): + for f in state_funcs: + config = deepcopy(in_config) + config.mechanisms[mech][_type][state] = f + configs.append(config) + del config + else: + configs = [in_config] + + return configs + + +@curried +def sweep_states(state_type, states, in_config): + configs = [] + filtered_states = state_sweep_filter(states) + if len(filtered_states) > 0: + for state, state_funcs in filtered_states.items(): + for f in state_funcs: + config = deepcopy(in_config) + exploded_states = deepcopy(states) + exploded_states[state] = f + if state_type == 'exogenous': + config.exogenous_states = exploded_states + elif state_type == 'environmental': + config.env_processes = exploded_states + configs.append(config) + del config, exploded_states + else: + configs = [in_config] + + return configs \ No newline at end of file diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index d96cb23..2609263 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -50,21 +50,6 @@ def drop_right(l, n): return l[:len(l)-n] -def mech_sweep_filter(mechanisms): - mech_states_dict = dict([(k, v['states']) for k, v in mechanisms.items()]) - return dict([ - (k, dict_filter(v, lambda v: isinstance(v, list))) for k, v in mech_states_dict.items() - if contains_type(list(v.values()), list) - ]) - - -def state_sweep_filter(raw_exogenous_states): - return dict([(k, v) for k, v in raw_exogenous_states.items() if isinstance(v, list)]) - -# def flatmap(f, items): -# return list(map(f, items)) - - def key_filter(l, keyname): return [v[keyname] for k, v in l.items()] diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index aae710d..805475c 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,16 +3,17 @@ import numpy as np from datetime import timedelta from fn.func import curried import pprint -from copy import deepcopy from SimCAD import configs -from SimCAD.utils import flatMap, mech_sweep_filter, state_sweep_filter +from SimCAD.utils import flatMap from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import state_update, exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step +from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ + ep_time_step, sweep_states, sweep_mechs from SimCAD.engine.utils import sweep pp = pprint.PrettyPrinter(indent=4) +beta =[Decimal(1), Decimal(2)] + seed = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), @@ -27,8 +28,11 @@ def b1m1(step, sL, s): def b2m1(step, sL, s): return {'param2': 4} -def b1m2(step, sL, s): - return {'param1': 'a', 'param2': 2} + +@curried +def b1m2(param, step, sL, s): + return {'param1': 'a', 'param2': param} + def b2m2(step, sL, s): return {'param1': 'b', 'param2': 4} @@ -52,7 +56,6 @@ def s1m1(step, sL, s, _input): # x = _input['param2'] + param # return (y, x) -s2m1_params =[Decimal(11.0), Decimal(22.0)] @curried def s2m1(param, step, sL, s, _input): y = 's2' @@ -95,7 +98,7 @@ proc_one_coef_B = 1.3 # ) # ) -es3p1_params =[Decimal(11.0), Decimal(22.0)] + @curried def es3p1(param, step, sL, s, _input): y = 's3' @@ -116,7 +119,6 @@ def es5p2(step, sL, s, _input): # Environment States -env_a_params = [Decimal(1), Decimal(2)] @curried def env_a(param, x): return x + param @@ -136,7 +138,7 @@ genesis_states = { # remove `exo_update_per_ts` to update every ts raw_exogenous_states = { - "s3": sweep(es3p1_params, es3p1), + "s3": sweep(beta, es3p1), "s4": es4p2, "timestamp": es5p2 } @@ -145,7 +147,7 @@ exogenous_states = exo_update_per_ts(raw_exogenous_states) # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ env_processes = { - "s3": sweep(env_a_params, env_a, 'env_a'), + "s3": sweep(beta, env_a, 'env_a'), "s4": proc_trigger('2018-10-01 15:16:25', env_b) } @@ -169,12 +171,12 @@ mechanisms = { }, "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value "s1": s1m1, - "s2": sweep(s2m1_params, s2m1) + "s2": sweep(beta, s2m1) } }, "m2": { "behaviors": { - "b1": b1m2, + "b1": sweep(beta, b1m2), "b2": b2m2 }, "states": { @@ -211,53 +213,6 @@ sim_config = { # ) -# filtered_exo_states = raw_exo_sweep_filter(raw_exogenous_states) -# pp.pprint(filtered_exo_states) -# print() - - -@curried -def sweep_mechs(in_config): - configs = [] - filtered_mech_states = mech_sweep_filter(in_config.mechanisms) - if len(filtered_mech_states) > 0: - for mech, state_dict in filtered_mech_states.items(): - for state, state_funcs in state_dict.items(): - for f in state_funcs: - config: Configuration = deepcopy(in_config) - exploded_mechs = deepcopy(mechanisms) - exploded_mechs[mech]['states'][state] = f - config.mechanisms = exploded_mechs - configs.append(config) - del config, exploded_mechs - else: - configs = [in_config] - - return configs - - -@curried -def sweep_states(state_type, states, in_config): - configs = [] - filtered_states = state_sweep_filter(states) - if len(filtered_states) > 0: - for state, state_funcs in filtered_states.items(): - for f in state_funcs: - config: Configuration = deepcopy(in_config) - exploded_states = deepcopy(states) - exploded_states[state] = f - if state_type == 'exogenous': - config.exogenous_states = exploded_states - elif state_type == 'environmental': - config.env_processes = exploded_states - configs.append(config) - del config, exploded_states - else: - configs = [in_config] - - return configs - - c = Configuration( sim_config=sim_config, state_dict=genesis_states, @@ -270,12 +225,19 @@ c = Configuration( l = flatMap( sweep_states('environmental', env_processes), + flatMap( + sweep_states('exogenous', raw_exogenous_states), flatMap( - sweep_states('exogenous', raw_exogenous_states), - sweep_mechs(c) + sweep_mechs('states'), + sweep_mechs('behaviors', c) ) + ) ) + +print() +print(len(l)) +print() for g in l: print() print('Configuration') From 4f9e320109749903e2a817b3483c44b45a77c89d Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Sun, 16 Dec 2018 10:26:52 -0500 Subject: [PATCH 09/38] refactored --- SimCAD/configuration/utils/__init__.py | 15 +++- simulations/validation/config1.py | 102 +++++++++---------------- 2 files changed, 51 insertions(+), 66 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index cae4a2a..94b4c37 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -6,6 +6,7 @@ import pandas as pd from pathos.threading import ThreadPool from SimCAD.utils import groupByKey, dict_filter, contains_type +from SimCAD.utils import flatMap class TensorFieldReport: def __init__(self, config_proc): @@ -126,4 +127,16 @@ def sweep_states(state_type, states, in_config): else: configs = [in_config] - return configs \ No newline at end of file + return configs + +def param_sweep(config, raw_exogenous_states): + return flatMap( + sweep_states('environmental', config.env_processes), + flatMap( + sweep_states('exogenous', raw_exogenous_states), + flatMap( + sweep_mechs('states'), + sweep_mechs('behaviors', config) + ) + ) + ) \ No newline at end of file diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 805475c..4578dbf 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -7,7 +7,7 @@ from SimCAD import configs from SimCAD.utils import flatMap from SimCAD.configuration import Configuration from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step, sweep_states, sweep_mechs + ep_time_step, param_sweep from SimCAD.engine.utils import sweep pp = pprint.PrettyPrinter(indent=4) @@ -28,16 +28,19 @@ def b1m1(step, sL, s): def b2m1(step, sL, s): return {'param2': 4} +# @curried +# def b1m2(param, step, sL, s): +# return {'param1': 'a', 'param2': param} -@curried -def b1m2(param, step, sL, s): - return {'param1': 'a', 'param2': param} +def b1m2(step, sL, s): + return {'param1': 'a', 'param2': 2} def b2m2(step, sL, s): return {'param1': 'b', 'param2': 4} def b1m3(step, sL, s): return {'param1': ['c'], 'param2': np.array([10, 100])} + def b2m3(step, sL, s): return {'param1': ['d'], 'param2': np.array([20, 200])} @@ -49,19 +52,18 @@ def s1m1(step, sL, s, _input): return (y, x) -# decorator -# param = Decimal(11.0) -# def s2m1(step, sL, s, _input): -# y = 's2' -# x = _input['param2'] + param -# return (y, x) - -@curried -def s2m1(param, step, sL, s, _input): +param = Decimal(11.0) +def s2m1(step, sL, s, _input): y = 's2' x = _input['param2'] + param return (y, x) +# @curried +# def s2m1(param, step, sL, s, _input): +# y = 's2' +# x = _input['param2'] + param +# return (y, x) + def s1m2(step, sL, s, _input): y = 's1' x = _input['param1'] @@ -84,27 +86,17 @@ def s2m3(step, sL, s, _input): proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -# def es3p1(step, sL, s, _input): -# y = 's3' -# x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) -# return (y, x) - - -# es3p1 = sweep( -# params = [Decimal(11.0), Decimal(22.0)], -# sweep_f = lambda param: lambda step, sL, s, _input: ( -# 's3', -# s['s3'] + param -# ) -# ) - - -@curried -def es3p1(param, step, sL, s, _input): +def es3p1(step, sL, s, _input): y = 's3' - x = s['s3'] + param + x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) return (y, x) +# @curried +# def es3p1(param, step, sL, s, _input): +# y = 's3' +# x = s['s3'] + param +# return (y, x) + def es4p2(step, sL, s, _input): y = 's4' x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) @@ -119,9 +111,11 @@ def es5p2(step, sL, s, _input): # Environment States -@curried -def env_a(param, x): - return x + param +# @curried +# def env_a(param, x): +# return x + param +def env_a(x): + return x def env_b(x): return 10 # def what_ever(x): @@ -138,7 +132,7 @@ genesis_states = { # remove `exo_update_per_ts` to update every ts raw_exogenous_states = { - "s3": sweep(beta, es3p1), + "s3": es3p1, #sweep(beta, es3p1), "s4": es4p2, "timestamp": es5p2 } @@ -146,9 +140,10 @@ exogenous_states = exo_update_per_ts(raw_exogenous_states) # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ +triggered_env_b = proc_trigger('2018-10-01 15:16:25', env_b) env_processes = { - "s3": sweep(beta, env_a, 'env_a'), - "s4": proc_trigger('2018-10-01 15:16:25', env_b) + "s3": env_a, #sweep(beta, env_a, 'env_a'), + "s4": sweep(beta, triggered_env_b, 'triggered_env_b') } # lambdas @@ -171,12 +166,12 @@ mechanisms = { }, "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value "s1": s1m1, - "s2": sweep(beta, s2m1) + "s2": s2m1 #sweep(beta, s2m1) } }, "m2": { "behaviors": { - "b1": sweep(beta, b1m2), + "b1": b1m2, #sweep(beta, b1m2), "b2": b2m2 }, "states": { @@ -201,18 +196,6 @@ sim_config = { "T": range(5) } -# configs.append( -# Configuration( -# sim_config=sim_config, -# state_dict=genesis_states, -# seed=seed, -# env_processes=env_processes, -# exogenous_states=exogenous_states, -# mechanisms=mechanisms -# ) -# ) - - c = Configuration( sim_config=sim_config, state_dict=genesis_states, @@ -222,23 +205,12 @@ c = Configuration( mechanisms=mechanisms ) - -l = flatMap( - sweep_states('environmental', env_processes), - flatMap( - sweep_states('exogenous', raw_exogenous_states), - flatMap( - sweep_mechs('states'), - sweep_mechs('behaviors', c) - ) - ) -) - +configs = configs + param_sweep(c, raw_exogenous_states) print() -print(len(l)) +print(len(configs)) print() -for g in l: +for g in configs: print() print('Configuration') print() From 1b52a4bebf6816e25eee15ed74104518ec54fc89 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 7 Jan 2019 17:40:09 -0500 Subject: [PATCH 10/38] 50% done --- SimCAD/engine/simulation.py | 95 +++------------- simulations/sim_test.py | 8 +- simulations/validation/config1.py | 178 ++++++++++++++++++++---------- 3 files changed, 139 insertions(+), 142 deletions(-) diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index e5bf89c..8144e6a 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -1,12 +1,7 @@ -from pathos.threading import ThreadPool from copy import deepcopy from fn.op import foldr, call -import numpy as np -import pprint -pp = pprint.PrettyPrinter(indent=4) - -from SimCAD.utils import groupByKey, flatten, drop_right +from SimCAD.utils import rename from SimCAD.engine.utils import engine_exception @@ -28,42 +23,27 @@ class Executor: return foldr(call, get_col_results(step, sL, s, funcs))(ops) - def xthreaded_env_proc(self, f, s_valx): - if isinstance(s_valx, list): - pool = ThreadPool(nodes=len(s_valx)) # ToDo: Optimize - return pool.map(lambda f: f(s_valx), s_valx) - else: - return f(s_valx) - def apply_env_proc(self, env_processes, state_dict, step): for state in state_dict.keys(): if state in list(env_processes.keys()): env_state = env_processes[state] if (env_state.__name__ == '_curried') or (env_state.__name__ == 'proc_trigger'): # might want to change - state_dict[state] = self.xthreaded_env_proc(env_state(step), state_dict[state]) + state_dict[state] = env_state(step)(state_dict[state]) else: - state_dict[state] = self.xthreaded_env_proc(env_state, state_dict[state]) + state_dict[state] = env_state(state_dict[state]) - def xthreaded_state_update(self, fs, m_step, sL, last_in_obj, _input): - if isinstance(fs, list): - pool = ThreadPool(nodes=len(fs)) # ToDo: Optimize - fx = pool.map(lambda f: f(m_step, sL, last_in_obj, _input), fs) - return groupByKey(fx) - else: - return fs(m_step, sL, last_in_obj, _input) - def mech_step(self, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): last_in_obj = sL[-1] _input = self.state_update_exception(self.get_behavior_input(m_step, sL, last_in_obj, behavior_funcs)) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function - last_in_copy = dict([ - self.behavior_update_exception( - self.xthreaded_state_update(f, m_step, sL, last_in_obj, _input) - ) for f in state_funcs - ]) + # last_in_copy = dict([self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs]) + + for f in state_funcs: + print(f(1,2,3,4)) + exit() for k in last_in_obj: if k not in last_in_copy: @@ -74,32 +54,12 @@ class Executor: # make env proc trigger field agnostic self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) # mutating last_in_copy - print() - print(last_in_copy) - print() - - - def set_sys_metrics(state_dict, m_step, t_step, run): - state_dict["mech_step"], state_dict["time_step"], state_dict['run'] = m_step, t_step, run - - if any(isinstance(x, list) for x in last_in_copy.values()): - last_in_copies = flatten(last_in_copy) - for last_in_copy in last_in_copies: - set_sys_metrics(last_in_copy, m_step, t_step, run) - sL.append(last_in_copies) - else: - set_sys_metrics(last_in_copy, m_step, t_step, run) - sL.append(last_in_copy) - - print() - pp.pprint(last_in_copies) - print() - + last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = m_step, t_step, run + sL.append(last_in_copy) del last_in_copy return sL - def mech_pipeline(self, states_list, configs, env_processes, t_step, run): m_step = 0 states_list_copy = deepcopy(states_list) @@ -108,57 +68,30 @@ class Executor: genesis_states = states_list_copy[-1] genesis_states['mech_step'], genesis_states['time_step'] = m_step, t_step states_list = [genesis_states] - # print(genesis_states) m_step += 1 for config in configs: s_conf, b_conf = config[0], config[1] - last_states = states_list[-1] - if isinstance(last_states, list): - pool = ThreadPool(nodes=len(last_states)) # ToDo: Optimize - dropped_right_sL = drop_right(states_list, 1) - - def multithreaded_mech_step(mod_states_list): - return self.mech_step(m_step, mod_states_list, s_conf, b_conf, env_processes, t_step, run) - - states_lists = pool.map( - lambda last_state_dict: dropped_right_sL + [last_state_dict], - last_states - ) - print() - # pp.pprint(configs) - else: - states_lists = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) - - + states_list = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) m_step += 1 t_step += 1 - exit() - return states_list - # rename pipe + # ToDo: Rename Run Pipeline def block_pipeline(self, states_list, configs, env_processes, time_seq, run): time_seq = [x + 1 for x in time_seq] simulation_list = [states_list] # print(len(configs)) for time_step in time_seq: - # print(simulation_list) - if len(simulation_list) == 1: - pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) - exit() - # elif np.array(pipe_run[-1]) == 2: - # pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) - # print(pipe_run) + pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) _, *pipe_run = pipe_run - # print(pipe_run) simulation_list.append(pipe_run) return simulation_list - # Del _ / head + # ToDo: Muiltithreaded Runs def simulation(self, states_list, configs, env_processes, time_seq, runs): pipe_run = [] for run in range(runs): diff --git a/simulations/sim_test.py b/simulations/sim_test.py index 161db56..3d982b2 100644 --- a/simulations/sim_test.py +++ b/simulations/sim_test.py @@ -3,7 +3,7 @@ from tabulate import tabulate # The following imports NEED to be in the exact same order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from simulations.validation import config1, config2 +from simulations.validation import config1 #, config2 # from simulations.validation import base_config1, base_config2 # from simulations.barlin import config4 # from simulations.zx import config_zx @@ -15,7 +15,7 @@ from SimCAD import configs exec_mode = ExecutionMode() -print("Simulation Execution 1") +print("Simulation Execution 1: Config 1") print() first_config = [configs[0]] # from config1 single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) @@ -29,9 +29,9 @@ print(tabulate(tensor_field, headers='keys', tablefmt='psql')) print("Output:") print(tabulate(result, headers='keys', tablefmt='psql')) print() -# + + # print("Simulation Execution 2: Pairwise Execution") -# print() # 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(): diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 4578dbf..aa5d52f 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,8 +3,9 @@ import numpy as np from datetime import timedelta from fn.func import curried import pprint +from copy import deepcopy from SimCAD import configs -from SimCAD.utils import flatMap +from SimCAD.utils import flatMap, rename from SimCAD.configuration import Configuration from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ ep_time_step, param_sweep @@ -12,6 +13,7 @@ from SimCAD.engine.utils import sweep pp = pprint.PrettyPrinter(indent=4) +# ToDo: handle single param sweep beta =[Decimal(1), Decimal(2)] seed = { @@ -28,12 +30,12 @@ def b1m1(step, sL, s): def b2m1(step, sL, s): return {'param2': 4} -# @curried -# def b1m2(param, step, sL, s): -# return {'param1': 'a', 'param2': param} - -def b1m2(step, sL, s): - return {'param1': 'a', 'param2': 2} +@curried +def b1m2(param, step, sL, s): + return {'param1': 'a', 'param2': param} +# +# def b1m2(step, sL, s): +# return {'param1': 'a', 'param2': 2} def b2m2(step, sL, s): return {'param1': 'b', 'param2': 4} @@ -52,18 +54,18 @@ def s1m1(step, sL, s, _input): return (y, x) -param = Decimal(11.0) -def s2m1(step, sL, s, _input): - y = 's2' - x = _input['param2'] + param - return (y, x) - -# @curried -# def s2m1(param, step, sL, s, _input): +# param = Decimal(11.0) +# def s2m1(step, sL, s, _input): # y = 's2' # x = _input['param2'] + param # return (y, x) +@curried +def s2m1(param, step, sL, s, _input): + y = 's2' + x = _input['param2'] + param + return (y, x) + def s1m2(step, sL, s, _input): y = 's1' x = _input['param1'] @@ -85,18 +87,18 @@ def s2m3(step, sL, s, _input): # Exogenous States proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 - -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -# @curried -# def es3p1(param, step, sL, s, _input): +# +# def es3p1(step, sL, s, _input): # y = 's3' -# x = s['s3'] + param +# x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) # return (y, x) +@curried +def es3p1(param, step, sL, s, _input): + y = 's3' + x = s['s3'] + param + return (y, x) + def es4p2(step, sL, s, _input): y = 's4' x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) @@ -137,27 +139,25 @@ raw_exogenous_states = { "timestamp": es5p2 } exogenous_states = exo_update_per_ts(raw_exogenous_states) +exogenous_states['s3'] = rename('parameterized', es3p1) # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ triggered_env_b = proc_trigger('2018-10-01 15:16:25', env_b) env_processes = { "s3": env_a, #sweep(beta, env_a, 'env_a'), - "s4": sweep(beta, triggered_env_b, 'triggered_env_b') + "s4": rename('parameterized', triggered_env_b) #sweep(beta, triggered_env_b) } -# lambdas -# genesis Sites should always be there -# [1, 2] -# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] - -# [1, 2] = {'b1': ['a'], 'b2', [1]} = -# behavior_ops = [ behavior_to_dict, print_fwd, sum_dict_values ] -# behavior_ops = [foldr(dict_elemwise_sum())] -# behavior_ops = [foldr(lambda a, b: a + b)] +# ToDo: The number of values enteren 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 # need at least 1 behaviour and 1 state function for the 1st mech with behaviors # mechanisms = {} + + mechanisms = { "m1": { "behaviors": { @@ -166,12 +166,12 @@ mechanisms = { }, "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value "s1": s1m1, - "s2": s2m1 #sweep(beta, s2m1) + "s2": rename('parameterized', s2m1) #s2m1(1) #sweep(beta, s2m1) } }, "m2": { "behaviors": { - "b1": b1m2, #sweep(beta, b1m2), + "b1": rename('parameterized', b1m2), #b1m2(1) #sweep(beta, b1m2), "b2": b2m2 }, "states": { @@ -196,27 +196,91 @@ sim_config = { "T": range(5) } -c = Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - env_processes=env_processes, - exogenous_states=exogenous_states, - mechanisms=mechanisms +# # print(rename('new', b2m2).__name__) +# +def parameterize_mechanism(mechanisms, param): + new_mechanisms = deepcopy(mechanisms) + for mech, update_types in new_mechanisms.items(): + for update_type, fkv in update_types.items(): + for sk, vf in fkv.items(): + if vf.__name__ == 'parameterized': + print(vf.__name__) + new_mechanisms[mech][update_type][sk] = vf(param) + + del mechanisms + return new_mechanisms + +def parameterize_states(states_dict, param): + new_states_dict = deepcopy(states_dict) + for sk, vf in new_states_dict.items(): + if vf.__name__ == 'parameterized': + print(vf.__name__) + new_states_dict[sk] = vf(param) + + del states_dict + return new_states_dict + +# parameterize_mechanism(mechanisms, beta) +@curried +def s2m1(param, a, b, c, d): + y = a + x = b, + c + d + param + return (y, x) + +# print(s2m1(1)(1)) +pp.pprint(parameterize_mechanism(mechanisms, 1)) +# pp.pprint(parameterize_states(raw_exogenous_states, 1)) +# pp.pprint(parameterize_states(env_processes, 1)) + + +configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=parameterize_mechanism(mechanisms, 1) + ) ) -configs = configs + param_sweep(c, raw_exogenous_states) +# def sweep_config(config, params): +# new_config = deepcopy(config) +# configs = [] +# for param in params: +# new_config.mechanisms = parameterize_mechanism(config.mechanisms, param) +# # new_config.raw_exogenous_states = parameterize_states(config.exogenous_states, param) +# # new_config.env_processes = parameterize_states(config.env_processes, param) +# configs.append(new_config) +# del config +# return configs -print() -print(len(configs)) -print() -for g in configs: - print() - print('Configuration') - print() - pp.pprint(g.env_processes) - print() - pp.pprint(g.exogenous_states) - print() - pp.pprint(g.mechanisms) - print() \ No newline at end of file + +# print(sweep_config(c, beta)) +# +# for config in sweep_config(c, beta): +# configs.append(config) + +# for config in param_sweep(c, raw_exogenous_states): +# configs.append(config) + + + +# # configs = configs + +# # +# print() +# print(len(configs)) +# print() + + + +# for g in configs: +# print() +# print('Configuration') +# print() +# pp.pprint(g.env_processes) +# print() +# pp.pprint(g.exogenous_states) +# print() +# pp.pprint(g.mechanisms) +# print() \ No newline at end of file From cd729bf0a13785509443b75554961ad7293cb62f Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 28 Jan 2019 16:27:16 -0500 Subject: [PATCH 11/38] ongoing --- simulations/validation/config1.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 6f62b36..5b3f31a 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -202,21 +202,30 @@ def mech_sweep(mechanisms): for mech, update_types in new_mechanisms.items(): for update_type, fkv in update_types.items(): for sk, vfs in fkv.items(): + id_sweep_lists = [] if isinstance(vfs, list): for vf in vfs: - sweep_lists.append((sk,vf)) + id_sweep_lists.append({mech: {update_type: {sk: vf}}}) + if len(id_sweep_lists) != 0: + sweep_lists.append(id_sweep_lists) zipped_sweep_lists = [] it = iter(sweep_lists) the_len = len(next(it)) if all(len(l) == the_len for l in it): - zipped_sweep_lists = list(zip(*sweep_lists)) + zipped_sweep_lists = list(map(lambda x: list(x), list(zip(*sweep_lists)))) else: raise ValueError('not all lists have same length!') - return sweep_lists + pp.pprint(zipped_sweep_lists) + print() -pp.pprint(mech_sweep(mechanisms)) + return list(map(lambda x: list(map(lambda y: list(y.keys()).pop(), x)), zipped_sweep_lists)) + + +print(mech_sweep(mechanisms)) +print() +pp.pprint(mechanisms) sim_config = { "N": 2, From 9e277d3cf0c7abe0b0e7b00c88b6f92d3b46b981 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 30 Jan 2019 15:04:56 -0500 Subject: [PATCH 12/38] pivot --- SimCAD/configuration/utils/__init__.py | 60 +++++++- SimCAD/engine/simulation.py | 13 +- SimCAD/engine/utils.py | 3 +- Simulation.md | 2 +- requirements.txt | 1 + simulations/example_run.py | 2 +- simulations/validation/config1.py | 189 ++++++++++++++++--------- 7 files changed, 195 insertions(+), 75 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 5bccdc8..ff1bade 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -3,11 +3,17 @@ from decimal import Decimal from copy import deepcopy from fn.func import curried import pandas as pd -from pathos.threading import ThreadPool +from SimCAD.utils import rename from SimCAD.utils import groupByKey, dict_filter, contains_type from SimCAD.utils import flatMap +from funcy import curry + +import pprint + +pp = pprint.PrettyPrinter(indent=4) + class TensorFieldReport: def __init__(self, config_proc): self.config_proc = config_proc @@ -130,9 +136,61 @@ def exo_update_per_ts(ep): return f(step, sL, s, _input) else: return (y, s[y]) + return {es: ep_decorator(f, es) for es, f in ep.items()} +def sweep(params, sweep_f): + return [rename("sweep_"+sweep_f.__name__+"_"+str(i), curry(sweep_f)(param)) for param, i in zip(params, range(len(params)))] + + +def parameterize_mechanism(mechanisms): + sweep_lists = [] + new_mechanisms = deepcopy(mechanisms) + for mech, update_types in new_mechanisms.items(): + for update_type, fkv in update_types.items(): + for sk, vfs in fkv.items(): + id_sweep_lists = [] + if isinstance(vfs, list): + for vf in vfs: + id_sweep_lists.append({mech: {update_type: {sk: vf}}}) + if len(id_sweep_lists) != 0: + sweep_lists.append(id_sweep_lists) + + zipped_sweep_lists = [] + it = iter(sweep_lists) + the_len = len(next(it)) + if all(len(l) == the_len for l in it): + zipped_sweep_lists = list(map(lambda x: list(x), list(zip(*sweep_lists)))) + else: + raise ValueError('lists have different lengths!') + + if len(sweep_lists) == 0: + return [mechanisms] + + mechanisms_configs = [] + for f_list in zipped_sweep_lists: + mechanisms_copy = deepcopy(mechanisms) + for f_dict in f_list: + updates = list(f_dict.values()).pop() + functs = list(updates.values()).pop() + + mech = list(f_dict.keys()).pop() + update_type = list(updates.keys()).pop() + sk = list(functs.keys()).pop() + vf = list(functs.values()).pop() + mechanisms_copy[mech][update_type][sk] = vf + mechanisms_configs.append(mechanisms_copy) + del mechanisms_copy + + # pp.pprint(sweep_lists) + # print() + # pp.pprint(zipped_sweep_lists) + # print() + + return mechanisms_configs + + # def ep_decorator(f, y, step, sL, s, _input): # if s['mech_step'] + 1 == 1: # return f(step, sL, s, _input) diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 201de1a..39278c6 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -35,8 +35,17 @@ class Executor: # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function # last_in_copy = dict([self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs]) - last_in_copy = [self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs] - print(last_in_copy) + # last_in_copy = [self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs] + + for f in state_funcs: + print(f.__name__ + " " + str(f)) + if f.__name__[0:5] == 'sweep': + self.behavior_update_exception(f(m_step)(sL)(last_in_obj)(_input)) + else: + self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) + # print(f(m_step, sL, last_in_obj, _input)) + + print(last_in_obj) exit() # # for f in state_funcs: diff --git a/SimCAD/engine/utils.py b/SimCAD/engine/utils.py index 8bb4218..d89d900 100644 --- a/SimCAD/engine/utils.py +++ b/SimCAD/engine/utils.py @@ -43,5 +43,4 @@ def fit_param(param, x): # fit_param = lambda param: lambda x: x + param -def sweep(params, sweep_f, f_name='sweep'): - return [rename(f_name+"_"+str(i), sweep_f(param)) for param, i in zip(params, range(len(params)))] + diff --git a/Simulation.md b/Simulation.md index 81d1ece..cd314df 100644 --- a/Simulation.md +++ b/Simulation.md @@ -1,4 +1,4 @@ -# SimmCAD Documentation +# SimCAD Documentation ## Introduction diff --git a/requirements.txt b/requirements.txt index 47937eb..0418284 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ wheel +pandas pathos fn tabulate \ No newline at end of file diff --git a/simulations/example_run.py b/simulations/example_run.py index e6a00a6..d41d8da 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -3,7 +3,7 @@ from tabulate import tabulate # The following imports NEED to be in the exact order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from simulations.validation import config1, config2 +from simulations.validation import config1 #, config2 from SimCAD import configs exec_mode = ExecutionMode() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 5b3f31a..dc4a421 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,18 +3,42 @@ import numpy as np from datetime import timedelta from fn.func import curried import pprint -from copy import deepcopy from SimCAD import configs from SimCAD.utils import flatMap, rename from SimCAD.configuration import Configuration from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step, param_sweep -from SimCAD.engine.utils import sweep + ep_time_step, parameterize_mechanism, sweep #parameterize_states + +from copy import deepcopy pp = pprint.PrettyPrinter(indent=4) # ToDo: handle single param sweep -beta =[Decimal(1), Decimal(2)] +beta = [Decimal(1), Decimal(2)] + +# ------------- +var_a = [1,2,3] +var_b = [1,2,3] + + +# Internal States per Mechanism +def s1m1(assumed, step, sL, s, _input): + y = 's1' + x = _input['param1'] + 1 + assumed + # example = [_input['param1'], 1, assumed].reduceLeft(_ + _) + return (y, x) + +def s2m1(assumed, step, sL, s, _input): + y = 's2' + x = _input['param2'] + assumed + return (y, x) + +def s1m3(assumed, step, sL, s, _input): + y = 's1' + x = _input['param1'] + return (y, x) + +# ------------- seed = { @@ -31,7 +55,7 @@ def b1m1(step, sL, s): def b2m1(step, sL, s): return {'param2': 4} -@curried +# @curried def b1m2(param, step, sL, s): return {'param1': 'a', 'param2': param} # @@ -61,7 +85,7 @@ def s1m1(step, sL, s, _input): # x = _input['param2'] + param # return (y, x) -@curried +# @curried def s2m1(param, step, sL, s, _input): y = 's2' x = _input['param2'] + param @@ -95,15 +119,15 @@ proc_one_coef_B = 1.3 # x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) # return (y, x) -@curried +# @curried def es3p1(param, step, sL, s, _input): y = 's3' x = s['s3'] + param return (y, x) -def es4p2(step, sL, s, _input): +def es4p2(param, step, sL, s, _input): y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + param return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' @@ -135,15 +159,56 @@ genesis_states = { 'timestamp': '2018-10-01 15:16:24' } +# print(sweep(beta, es3p1)) +# print() + # remove `exo_update_per_ts` to update every ts raw_exogenous_states = { - "s3": es3p1, #sweep(beta, es3p1), - "s4": es4p2, + "s3": sweep(beta, es3p1), #es3p1, #sweep(beta, es3p1), + "s4": sweep(beta, es4p2), "timestamp": es5p2 } exogenous_states = exo_update_per_ts(raw_exogenous_states) -exogenous_states['s3'] = rename('parameterized', es3p1) +# pp.pprint(raw_exogenous_states) +# print() + +def parameterize_states(states_dict): + sweep_lists = [] + new_states_dict = deepcopy(states_dict) + for sk, vfs in new_states_dict.items(): + print({sk: vfs}) + print() + id_sweep_lists = [] + if isinstance(vfs, list): + for vf in vfs: + id_sweep_lists.append({sk: vf}) + if len(id_sweep_lists) != 0: + sweep_lists.append(id_sweep_lists) + + zipped_sweep_lists = [] + it = iter(sweep_lists) + the_len = len(next(it)) + same_len_ind = all(len(l) == the_len for l in it) + count_ind = len(sweep_lists) >= 2 + if same_len_ind == True and count_ind == True: + zipped_sweep_lists = list(map(lambda x: list(x), list(zip(*sweep_lists)))) + elif same_len_ind == False or count_ind == False: + zipped_sweep_lists = sweep_lists + else: + raise ValueError('lists have different lengths!') + + pp.pprint(sweep_lists) + print() + pp.pprint(zipped_sweep_lists) + print() + + # return zipped_sweep_lists + +# pp.pprint(parameterize_states(raw_exogenous_states)) +# print() +# exogenous_states['s3'] = rename('parameterized', es3p1) + # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ @@ -151,7 +216,7 @@ triggered_env_b = proc_trigger('2018-10-01 15:16:25', env_b) env_processes = { "s3": env_a, #sweep(beta, env_a, 'env_a'), - "s4": rename('parameterized', triggered_env_b) #sweep(beta, triggered_env_b) + "s4": triggered_env_b #rename('parameterized', triggered_env_b) #sweep(beta, triggered_env_b) } # ToDo: The number of values enteren in sweep should be the # of config objs created, @@ -196,72 +261,60 @@ mechanisms = { } } -def mech_sweep(mechanisms): - sweep_lists = [] - new_mechanisms = deepcopy(mechanisms) - for mech, update_types in new_mechanisms.items(): - for update_type, fkv in update_types.items(): - for sk, vfs in fkv.items(): - id_sweep_lists = [] - if isinstance(vfs, list): - for vf in vfs: - id_sweep_lists.append({mech: {update_type: {sk: vf}}}) - if len(id_sweep_lists) != 0: - sweep_lists.append(id_sweep_lists) - - zipped_sweep_lists = [] - it = iter(sweep_lists) - the_len = len(next(it)) - if all(len(l) == the_len for l in it): - zipped_sweep_lists = list(map(lambda x: list(x), list(zip(*sweep_lists)))) - else: - raise ValueError('not all lists have same length!') - - pp.pprint(zipped_sweep_lists) - print() - - return list(map(lambda x: list(map(lambda y: list(y.keys()).pop(), x)), zipped_sweep_lists)) -print(mech_sweep(mechanisms)) +# list(map(lambda x: list(map(lambda y: list(y.keys()).pop(), x)), zipped_sweep_lists)) +pp.pprint(parameterize_mechanism(mechanisms)) print() -pp.pprint(mechanisms) +# pp.pprint(mechanisms) sim_config = { "N": 2, "T": range(5) } +# for mech_configs in parameterize_mechanism(mechanisms): +# configs.append( +# Configuration( +# sim_config=sim_config, +# state_dict=genesis_states, +# seed=seed, +# exogenous_states=exogenous_states, +# env_processes=env_processes, +# mechanisms=mech_configs +# ) +# ) + # # print(rename('new', b2m2).__name__) # -def parameterize_mechanism(mechanisms, param): - new_mechanisms = deepcopy(mechanisms) - for mech, update_types in new_mechanisms.items(): - for update_type, fkv in update_types.items(): - for sk, vf in fkv.items(): - if vf.__name__ == 'parameterized': - # print(vf.__name__) - new_mechanisms[mech][update_type][sk] = vf(param) - - del mechanisms - return new_mechanisms - -def parameterize_states(states_dict, param): - new_states_dict = deepcopy(states_dict) - for sk, vf in new_states_dict.items(): - if vf.__name__ == 'parameterized': - print(vf.__name__) - new_states_dict[sk] = vf(param) - - del states_dict - return new_states_dict - -# parameterize_mechanism(mechanisms, beta) -@curried -def s2m1(param, a, b, c, d): - y = a - x = b, + c + d + param - return (y, x) +# def parameterize_mechanism(mechanisms, param): +# new_mechanisms = deepcopy(mechanisms) +# for mech, update_types in new_mechanisms.items(): +# for update_type, fkv in update_types.items(): +# for sk, vf in fkv.items(): +# if vf.__name__ == 'parameterized': +# # print(vf.__name__) +# new_mechanisms[mech][update_type][sk] = vf(param) +# +# del mechanisms +# return new_mechanisms +# +# def parameterize_states(states_dict, param): +# new_states_dict = deepcopy(states_dict) +# for sk, vf in new_states_dict.items(): +# if vf.__name__ == 'parameterized': +# print(vf.__name__) +# new_states_dict[sk] = vf(param) +# +# del states_dict +# return new_states_dict +# +# # parameterize_mechanism(mechanisms, beta) +# @curried +# def s2m1(param, a, b, c, d): +# y = a +# x = b, + c + d + param +# return (y, x) # print(s2m1(1)(1)) # pp.pprint(mechanisms) From a9c97467aef0e28c9a62a46d77fe0effb4c772f1 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 30 Jan 2019 16:04:51 -0500 Subject: [PATCH 13/38] pivot2 --- simulations/validation/config1.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index dc4a421..a20189c 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -22,10 +22,13 @@ var_b = [1,2,3] # Internal States per Mechanism -def s1m1(assumed, step, sL, s, _input): +def s1m1(step, sL, s, _input): + # __assumed__ = var_a + # __handler__ = f y = 's1' - x = _input['param1'] + 1 + assumed + x = _input['param1'] + 1 + var_a # example = [_input['param1'], 1, assumed].reduceLeft(_ + _) + return (y, x) def s2m1(assumed, step, sL, s, _input): @@ -33,11 +36,14 @@ def s2m1(assumed, step, sL, s, _input): x = _input['param2'] + assumed return (y, x) -def s1m3(assumed, step, sL, s, _input): +def s1m3(unused_wildcard, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) + +middleware(beta, [s1m1, s2m2, b1m3, . . . ]) + # ------------- From 5729ffc0edd5964a90cf495acef6d94d2dab6cbc Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 31 Jan 2019 09:27:54 -0500 Subject: [PATCH 14/38] param-sweep-multi-proc --- SimCAD/configuration/utils/__init__.py | 93 +++++++++++++------- SimCAD/engine/simulation.py | 42 +++++---- simulations/validation/config1.py | 114 +++++++++---------------- 3 files changed, 132 insertions(+), 117 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index ff1bade..4a6cba6 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -143,11 +143,71 @@ def exo_update_per_ts(ep): def sweep(params, sweep_f): return [rename("sweep_"+sweep_f.__name__+"_"+str(i), curry(sweep_f)(param)) for param, i in zip(params, range(len(params)))] +def zip_sweep_functions(sweep_lists): + zipped_sweep_lists = [] + it = iter(sweep_lists) + the_len = len(next(it)) + same_len_ind = all(len(l) == the_len for l in it) + count_ind = len(sweep_lists) >= 2 + if same_len_ind == True and count_ind == True: + return list(map(lambda x: list(x), list(zip(*sweep_lists)))) + elif same_len_ind == False or count_ind == False: + return sweep_lists + else: + raise ValueError('lists have different lengths!') + + +def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind = 'mechs'): + configs = [] + for f_lists in zipped_sweep_lists: + new_states_dict = deepcopy(states_dict) + for f_dict in f_lists: + if state_type_ind == 'mechs': + updates = list(f_dict.values()).pop() + functs = list(updates.values()).pop() + + mech = list(f_dict.keys()).pop() + update_type = list(updates.keys()).pop() + sk = list(functs.keys()).pop() + vf = list(functs.values()).pop() + + new_states_dict[mech][update_type][sk] = vf + elif state_type_ind == 'exo_proc': + sk = list(f_dict.keys()).pop() + vf = list(f_dict.values()).pop() + + new_states_dict[sk] = vf + else: + raise ValueError("Incorrect \'state_type_ind\'") + + configs.append(new_states_dict) + del new_states_dict + + return configs + + +def parameterize_states(exo_states): + sweep_lists = [] + for sk, vfs in exo_states.items(): + id_sweep_lists = [] + if isinstance(vfs, list): + for vf in vfs: + id_sweep_lists.append({sk: vf}) + if len(id_sweep_lists) != 0: + sweep_lists.append(id_sweep_lists) + + if len(sweep_lists) == 0: + return [exo_states] + + zipped_sweep_lists = zip_sweep_functions(sweep_lists) + states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") + + return states_configs + def parameterize_mechanism(mechanisms): sweep_lists = [] - new_mechanisms = deepcopy(mechanisms) - for mech, update_types in new_mechanisms.items(): + for mech, update_types in mechanisms.items(): for update_type, fkv in update_types.items(): for sk, vfs in fkv.items(): id_sweep_lists = [] @@ -157,36 +217,11 @@ def parameterize_mechanism(mechanisms): if len(id_sweep_lists) != 0: sweep_lists.append(id_sweep_lists) - zipped_sweep_lists = [] - it = iter(sweep_lists) - the_len = len(next(it)) - if all(len(l) == the_len for l in it): - zipped_sweep_lists = list(map(lambda x: list(x), list(zip(*sweep_lists)))) - else: - raise ValueError('lists have different lengths!') - if len(sweep_lists) == 0: return [mechanisms] - mechanisms_configs = [] - for f_list in zipped_sweep_lists: - mechanisms_copy = deepcopy(mechanisms) - for f_dict in f_list: - updates = list(f_dict.values()).pop() - functs = list(updates.values()).pop() - - mech = list(f_dict.keys()).pop() - update_type = list(updates.keys()).pop() - sk = list(functs.keys()).pop() - vf = list(functs.values()).pop() - mechanisms_copy[mech][update_type][sk] = vf - mechanisms_configs.append(mechanisms_copy) - del mechanisms_copy - - # pp.pprint(sweep_lists) - # print() - # pp.pprint(zipped_sweep_lists) - # print() + zipped_sweep_lists = zip_sweep_functions(sweep_lists) + mechanisms_configs = create_sweep_config_list(zipped_sweep_lists, mechanisms, "mechs") return mechanisms_configs diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 39278c6..992ac66 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -11,14 +11,31 @@ class Executor: self.state_update_exception = state_update_exception self.behavior_update_exception = behavior_update_exception + + def curry_pot(self, f, *argv): + sweep_ind = f.__name__[0:5] == 'sweep' + arg_len = len(argv) + if sweep_ind == True and arg_len == 4: + return f(argv[0])(argv[1])(argv[2])(argv[3]) + elif sweep_ind == False and arg_len == 4: + return f(argv[0], argv[1], argv[2], argv[3]) + elif sweep_ind == True and arg_len == 3: + return f(argv[0])(argv[1])(argv[2]) + elif sweep_ind == False and arg_len == 3: + return f(argv[0], argv[1], argv[2]) + else: + raise TypeError('curry_pot() needs 3 or 4 positional arguments') + + def get_behavior_input(self, step, sL, s, funcs): ops = self.behavior_ops[::-1] def get_col_results(step, sL, s, funcs): - return list(map(lambda f: f(step, sL, s), funcs)) + return list(map(lambda f: self.curry_pot(f, step, sL, s), funcs)) return foldr(call, get_col_results(step, sL, s, funcs))(ops) + def apply_env_proc(self, env_processes, state_dict, step): for state in state_dict.keys(): if state in list(env_processes.keys()): @@ -28,29 +45,22 @@ class Executor: else: state_dict[state] = env_state(state_dict[state]) + def mech_step(self, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): last_in_obj = sL[-1] _input = self.state_update_exception(self.get_behavior_input(m_step, sL, last_in_obj, behavior_funcs)) + # print(_input) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function - # last_in_copy = dict([self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs]) # last_in_copy = [self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs] + last_in_copy = dict( + [ + self.behavior_update_exception(self.curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs + ] + ) + # print(last_in_copy) - for f in state_funcs: - print(f.__name__ + " " + str(f)) - if f.__name__[0:5] == 'sweep': - self.behavior_update_exception(f(m_step)(sL)(last_in_obj)(_input)) - else: - self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) - # print(f(m_step, sL, last_in_obj, _input)) - - print(last_in_obj) - exit() - # - # for f in state_funcs: - # print(f(1,2,3,4)) - # exit() for k in last_in_obj: if k not in last_in_copy: diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index a20189c..267f2fb 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -7,7 +7,7 @@ from SimCAD import configs from SimCAD.utils import flatMap, rename from SimCAD.configuration import Configuration from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step, parameterize_mechanism, sweep #parameterize_states + ep_time_step, parameterize_mechanism, parameterize_states, sweep #parameterize_states from copy import deepcopy @@ -16,35 +16,35 @@ pp = pprint.PrettyPrinter(indent=4) # ToDo: handle single param sweep beta = [Decimal(1), Decimal(2)] -# ------------- -var_a = [1,2,3] -var_b = [1,2,3] - - -# Internal States per Mechanism -def s1m1(step, sL, s, _input): - # __assumed__ = var_a - # __handler__ = f - y = 's1' - x = _input['param1'] + 1 + var_a - # example = [_input['param1'], 1, assumed].reduceLeft(_ + _) - - return (y, x) - -def s2m1(assumed, step, sL, s, _input): - y = 's2' - x = _input['param2'] + assumed - return (y, x) - -def s1m3(unused_wildcard, step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) - - -middleware(beta, [s1m1, s2m2, b1m3, . . . ]) - -# ------------- +# # ------------- +# var_a = [1,2,3] +# var_b = [1,2,3] +# +# +# # Internal States per Mechanism +# def s1m1(step, sL, s, _input): +# # __assumed__ = var_a +# # __handler__ = f +# y = 's1' +# x = _input['param1'] + 1 + var_a +# # example = [_input['param1'], 1, assumed].reduceLeft(_ + _) +# +# return (y, x) +# +# def s2m1(assumed, step, sL, s, _input): +# y = 's2' +# x = _input['param2'] + assumed +# return (y, x) +# +# def s1m3(unused_wildcard, step, sL, s, _input): +# y = 's1' +# x = _input['param1'] +# return (y, x) +# +# +# middleware(beta, [s1m1, s2m2, b1m3, . . . ]) +# +# # ------------- seed = { @@ -179,37 +179,7 @@ exogenous_states = exo_update_per_ts(raw_exogenous_states) # pp.pprint(raw_exogenous_states) # print() -def parameterize_states(states_dict): - sweep_lists = [] - new_states_dict = deepcopy(states_dict) - for sk, vfs in new_states_dict.items(): - print({sk: vfs}) - print() - id_sweep_lists = [] - if isinstance(vfs, list): - for vf in vfs: - id_sweep_lists.append({sk: vf}) - if len(id_sweep_lists) != 0: - sweep_lists.append(id_sweep_lists) - zipped_sweep_lists = [] - it = iter(sweep_lists) - the_len = len(next(it)) - same_len_ind = all(len(l) == the_len for l in it) - count_ind = len(sweep_lists) >= 2 - if same_len_ind == True and count_ind == True: - zipped_sweep_lists = list(map(lambda x: list(x), list(zip(*sweep_lists)))) - elif same_len_ind == False or count_ind == False: - zipped_sweep_lists = sweep_lists - else: - raise ValueError('lists have different lengths!') - - pp.pprint(sweep_lists) - print() - pp.pprint(zipped_sweep_lists) - print() - - # return zipped_sweep_lists # pp.pprint(parameterize_states(raw_exogenous_states)) # print() @@ -270,8 +240,8 @@ mechanisms = { # list(map(lambda x: list(map(lambda y: list(y.keys()).pop(), x)), zipped_sweep_lists)) -pp.pprint(parameterize_mechanism(mechanisms)) -print() +# pp.pprint(parameterize_mechanism(mechanisms)) +# print() # pp.pprint(mechanisms) sim_config = { @@ -280,16 +250,16 @@ sim_config = { } # for mech_configs in parameterize_mechanism(mechanisms): -# configs.append( -# Configuration( -# sim_config=sim_config, -# state_dict=genesis_states, -# seed=seed, -# exogenous_states=exogenous_states, -# env_processes=env_processes, -# mechanisms=mech_configs -# ) -# ) +configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=parameterize_states(raw_exogenous_states)[1], + env_processes=env_processes, + mechanisms=parameterize_mechanism(mechanisms)[1] + ) +) # # print(rename('new', b2m2).__name__) # From eaf9cf21ff37bce483eb48a5f0db8b1606c1ca7a Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Fri, 1 Feb 2019 12:42:42 -0500 Subject: [PATCH 15/38] Not producing multiple dicts --- SimCAD/configuration/utils/__init__.py | 28 ++-- SimCAD/engine/simulation.py | 27 +-- SimCAD/utils/__init__.py | 19 ++- simulations/example_run.py | 48 +++--- simulations/validation/config1.py | 222 ++++--------------------- 5 files changed, 86 insertions(+), 258 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 4a6cba6..b9f820f 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -5,8 +5,8 @@ from fn.func import curried import pandas as pd from SimCAD.utils import rename -from SimCAD.utils import groupByKey, dict_filter, contains_type -from SimCAD.utils import flatMap +from SimCAD.utils import dict_filter, contains_type, curry_pot + from funcy import curry @@ -116,24 +116,11 @@ def sweep_states(state_type, states, in_config): return configs -def param_sweep(config, raw_exogenous_states): - return flatMap( - sweep_states('environmental', config.env_processes), - flatMap( - sweep_states('exogenous', raw_exogenous_states), - flatMap( - sweep_mechs('states'), - sweep_mechs('behaviors', config) - ) - ) - ) - - def exo_update_per_ts(ep): @curried def ep_decorator(f, y, step, sL, s, _input): if s['mech_step'] + 1 == 1: - return f(step, sL, s, _input) + return curry_pot(f, step, sL, s, _input) else: return (y, s[y]) @@ -143,6 +130,7 @@ def exo_update_per_ts(ep): def sweep(params, sweep_f): return [rename("sweep_"+sweep_f.__name__+"_"+str(i), curry(sweep_f)(param)) for param, i in zip(params, range(len(params)))] + def zip_sweep_functions(sweep_lists): zipped_sweep_lists = [] it = iter(sweep_lists) @@ -157,7 +145,8 @@ def zip_sweep_functions(sweep_lists): raise ValueError('lists have different lengths!') -def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind = 'mechs'): +# ToDo: Not producing multiple dicts +def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='mechs'): configs = [] for f_lists in zipped_sweep_lists: new_states_dict = deepcopy(states_dict) @@ -187,6 +176,8 @@ def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind = ' def parameterize_states(exo_states): + pp.pprint(exo_states) + print() sweep_lists = [] for sk, vfs in exo_states.items(): id_sweep_lists = [] @@ -199,6 +190,9 @@ def parameterize_states(exo_states): if len(sweep_lists) == 0: return [exo_states] + pp.pprint(sweep_lists) + print() + zipped_sweep_lists = zip_sweep_functions(sweep_lists) states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 992ac66..3724a76 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -1,5 +1,6 @@ from copy import deepcopy from fn.op import foldr, call +from SimCAD.utils import curry_pot from SimCAD.engine.utils import engine_exception id_exception = engine_exception(KeyError, KeyError, None) @@ -11,31 +12,14 @@ class Executor: self.state_update_exception = state_update_exception self.behavior_update_exception = behavior_update_exception - - def curry_pot(self, f, *argv): - sweep_ind = f.__name__[0:5] == 'sweep' - arg_len = len(argv) - if sweep_ind == True and arg_len == 4: - return f(argv[0])(argv[1])(argv[2])(argv[3]) - elif sweep_ind == False and arg_len == 4: - return f(argv[0], argv[1], argv[2], argv[3]) - elif sweep_ind == True and arg_len == 3: - return f(argv[0])(argv[1])(argv[2]) - elif sweep_ind == False and arg_len == 3: - return f(argv[0], argv[1], argv[2]) - else: - raise TypeError('curry_pot() needs 3 or 4 positional arguments') - - def get_behavior_input(self, step, sL, s, funcs): ops = self.behavior_ops[::-1] def get_col_results(step, sL, s, funcs): - return list(map(lambda f: self.curry_pot(f, step, sL, s), funcs)) + return list(map(lambda f: curry_pot(f, step, sL, s), funcs)) return foldr(call, get_col_results(step, sL, s, funcs))(ops) - def apply_env_proc(self, env_processes, state_dict, step): for state in state_dict.keys(): if state in list(env_processes.keys()): @@ -45,7 +29,6 @@ class Executor: else: state_dict[state] = env_state(state_dict[state]) - def mech_step(self, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): last_in_obj = sL[-1] @@ -53,14 +36,11 @@ class Executor: # print(_input) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function - # last_in_copy = [self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_funcs] last_in_copy = dict( [ - self.behavior_update_exception(self.curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs + self.behavior_update_exception(curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs ] ) - # print(last_in_copy) - for k in last_in_obj: if k not in last_in_copy: @@ -97,7 +77,6 @@ class Executor: def block_pipeline(self, states_list, configs, env_processes, time_seq, run): time_seq = [x + 1 for x in time_seq] simulation_list = [states_list] - # print(len(configs)) for time_step in time_seq: pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) _, *pipe_run = pipe_run diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index af0ad03..ade0424 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -1,6 +1,5 @@ from collections import defaultdict from itertools import product -# from fn.func import curried def pipe(x): @@ -47,14 +46,13 @@ def contains_type(_collection, type): def drop_right(l, n): - return l[:len(l)-n] + return l[:len(l) - n] def key_filter(l, keyname): return [v[keyname] for k, v in l.items()] - def groupByKey(l): d = defaultdict(list) for key, value in l: @@ -67,6 +65,21 @@ def rename(new_name, f): f.__name__ = new_name return f + +def curry_pot(f, *argv): + sweep_ind = f.__name__[0:5] == 'sweep' + arg_len = len(argv) + if sweep_ind is True and arg_len == 4: + return f(argv[0])(argv[1])(argv[2])(argv[3]) + elif sweep_ind is False and arg_len == 4: + return f(argv[0], argv[1], argv[2], argv[3]) + elif sweep_ind is True and arg_len == 3: + return f(argv[0])(argv[1])(argv[2]) + elif sweep_ind is False and arg_len == 3: + return f(argv[0], argv[1], argv[2]) + else: + raise TypeError('curry_pot() needs 3 or 4 positional arguments') + # def rename(newname): # def decorator(f): # f.__name__ = newname diff --git a/simulations/example_run.py b/simulations/example_run.py index d41d8da..e80c2de 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -8,28 +8,28 @@ from SimCAD 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: Pairwise 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: Pairwise 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() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 267f2fb..cab014c 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -1,52 +1,18 @@ from decimal import Decimal import numpy as np from datetime import timedelta -from fn.func import curried import pprint + from SimCAD import configs -from SimCAD.utils import flatMap, rename from SimCAD.configuration import Configuration from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step, parameterize_mechanism, parameterize_states, sweep #parameterize_states - -from copy import deepcopy + ep_time_step, parameterize_mechanism, parameterize_states, sweep pp = pprint.PrettyPrinter(indent=4) # ToDo: handle single param sweep beta = [Decimal(1), Decimal(2)] -# # ------------- -# var_a = [1,2,3] -# var_b = [1,2,3] -# -# -# # Internal States per Mechanism -# def s1m1(step, sL, s, _input): -# # __assumed__ = var_a -# # __handler__ = f -# y = 's1' -# x = _input['param1'] + 1 + var_a -# # example = [_input['param1'], 1, assumed].reduceLeft(_ + _) -# -# return (y, x) -# -# def s2m1(assumed, step, sL, s, _input): -# y = 's2' -# x = _input['param2'] + assumed -# return (y, x) -# -# def s1m3(unused_wildcard, step, sL, s, _input): -# y = 's1' -# x = _input['param1'] -# return (y, x) -# -# -# middleware(beta, [s1m1, s2m2, b1m3, . . . ]) -# -# # ------------- - - seed = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), @@ -60,46 +26,35 @@ def b1m1(step, sL, s): return {'param1': 1} def b2m1(step, sL, s): return {'param2': 4} - # @curried def b1m2(param, step, sL, s): return {'param1': 'a', 'param2': param} -# -# def b1m2(step, sL, s): -# return {'param1': 'a', 'param2': 2} def b2m2(step, sL, s): - return {'param1': 'b', 'param2': 4} + return {'param1': 'b', 'param2': 0} def b1m3(step, sL, s): - return {'param1': ['c'], 'param2': np.array([10, 100])} + return {'param1': np.array([10, 100])} def b2m3(step, sL, s): - return {'param1': ['d'], 'param2': np.array([20, 200])} + return {'param1': np.array([20, 200])} # Internal States per Mechanism def s1m1(step, sL, s, _input): y = 's1' - x = _input['param1'] + x = 0 return (y, x) - -# param = Decimal(11.0) -# def s2m1(step, sL, s, _input): -# y = 's2' -# x = _input['param2'] + param -# return (y, x) - # @curried def s2m1(param, step, sL, s, _input): y = 's2' - x = _input['param2'] + param + x = param return (y, x) def s1m2(step, sL, s, _input): y = 's1' - x = _input['param1'] + x = _input['param2'] return (y, x) def s2m2(step, sL, s, _input): y = 's2' @@ -108,22 +63,17 @@ def s2m2(step, sL, s, _input): def s1m3(step, sL, s, _input): y = 's1' - x = _input['param1'] + x = 0 return (y, x) def s2m3(step, sL, s, _input): y = 's2' - x = _input['param2'] + x = 0 return (y, x) # Exogenous States proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -# -# def es3p1(step, sL, s, _input): -# y = 's3' -# x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) -# return (y, x) # @curried def es3p1(param, step, sL, s, _input): @@ -146,14 +96,10 @@ def es5p2(step, sL, s, _input): # Environment States # @curried -# def env_a(param, x): -# return x + param -def env_a(x): - return x +def env_a(param, x): + return x + param def env_b(x): return 10 -# def what_ever(x): -# return x + 1 # Genesis States @@ -165,9 +111,6 @@ genesis_states = { 'timestamp': '2018-10-01 15:16:24' } -# print(sweep(beta, es3p1)) -# print() - # remove `exo_update_per_ts` to update every ts raw_exogenous_states = { @@ -175,25 +118,22 @@ raw_exogenous_states = { "s4": sweep(beta, es4p2), "timestamp": es5p2 } -exogenous_states = exo_update_per_ts(raw_exogenous_states) -# pp.pprint(raw_exogenous_states) -# print() - - - -# pp.pprint(parameterize_states(raw_exogenous_states)) -# print() -# exogenous_states['s3'] = rename('parameterized', es3p1) +# exogenous_states_list = list(map(exo_update_per_ts, parameterize_states(raw_exogenous_states))) # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ triggered_env_b = proc_trigger('2018-10-01 15:16:25', env_b) + env_processes = { - "s3": env_a, #sweep(beta, env_a, 'env_a'), + "s3": 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 enteren in sweep should be the # of config objs created, # not dependent on the # of times the sweep is applied @@ -212,12 +152,12 @@ mechanisms = { }, "states": { "s1": s1m1, - "s2": sweep(beta, s2m1) #rename('parameterized', s2m1) #s2m1(1) #sweep(beta, s2m1) + "s2": sweep(beta, s2m1) #s2m1(1) #sweep(beta, s2m1) } }, "m2": { "behaviors": { - "b1": sweep(beta, b1m2), #rename('parameterized', b1m2), #b1m2(1) #sweep(beta, b1m2), + "b1": sweep(beta, b1m2), #b1m2(1) #sweep(beta, b1m2), "b2": b2m2 }, "states": { @@ -236,119 +176,21 @@ mechanisms = { } } } - - - -# list(map(lambda x: list(map(lambda y: list(y.keys()).pop(), x)), zipped_sweep_lists)) -# pp.pprint(parameterize_mechanism(mechanisms)) -# print() -# pp.pprint(mechanisms) +parameterized_mechanism = parameterize_mechanism(mechanisms) sim_config = { "N": 2, "T": range(5) } -# for mech_configs in parameterize_mechanism(mechanisms): -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=parameterize_states(raw_exogenous_states)[1], - env_processes=env_processes, - mechanisms=parameterize_mechanism(mechanisms)[1] +for mechanisms, env_processes, exogenous_states in zip(parameterized_mechanism, parameterized_env_processes, exogenous_states_list): + configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, #parameterize_states(raw_exogenous_states)[1], + env_processes=env_processes, + mechanisms=mechanisms #parameterize_mechanism(mechanisms)[1] + ) ) -) - -# # print(rename('new', b2m2).__name__) -# -# def parameterize_mechanism(mechanisms, param): -# new_mechanisms = deepcopy(mechanisms) -# for mech, update_types in new_mechanisms.items(): -# for update_type, fkv in update_types.items(): -# for sk, vf in fkv.items(): -# if vf.__name__ == 'parameterized': -# # print(vf.__name__) -# new_mechanisms[mech][update_type][sk] = vf(param) -# -# del mechanisms -# return new_mechanisms -# -# def parameterize_states(states_dict, param): -# new_states_dict = deepcopy(states_dict) -# for sk, vf in new_states_dict.items(): -# if vf.__name__ == 'parameterized': -# print(vf.__name__) -# new_states_dict[sk] = vf(param) -# -# del states_dict -# return new_states_dict -# -# # parameterize_mechanism(mechanisms, beta) -# @curried -# def s2m1(param, a, b, c, d): -# y = a -# x = b, + c + d + param -# return (y, x) - -# print(s2m1(1)(1)) -# pp.pprint(mechanisms) -# pp.pprint(parameterize_mechanism(mechanisms, 1)) -# print(sweep(beta, s2m1)) - -# pp.pprint(parameterize_states(raw_exogenous_states, 1)) -# pp.pprint(parameterize_states(env_processes, 1)) - - -# configs.append( -# Configuration( -# sim_config=sim_config, -# state_dict=genesis_states, -# seed=seed, -# exogenous_states=exogenous_states, -# env_processes=env_processes, -# mechanisms=parameterize_mechanism(mechanisms, 1) -# ) -# ) - -# def sweep_config(config, params): -# new_config = deepcopy(config) -# configs = [] -# for param in params: -# new_config.mechanisms = parameterize_mechanism(config.mechanisms, param) -# # new_config.raw_exogenous_states = parameterize_states(config.exogenous_states, param) -# # new_config.env_processes = parameterize_states(config.env_processes, param) -# configs.append(new_config) -# del config -# return configs - - -# print(sweep_config(c, beta)) -# -# for config in sweep_config(c, beta): -# configs.append(config) - -# for config in param_sweep(c, raw_exogenous_states): -# configs.append(config) - - - -# # configs = configs + -# # -# print() -# print(len(configs)) -# print() - - - -# for g in configs: -# print() -# print('Configuration') -# print() -# pp.pprint(g.env_processes) -# print() -# pp.pprint(g.exogenous_states) -# print() -# pp.pprint(g.mechanisms) -# print() From 3719ead0b172ddc34a8ed135a9290d74f4a57cd7 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Fri, 1 Feb 2019 12:43:42 -0500 Subject: [PATCH 16/38] env-proc sweep: Not producing multiple dicts --- SimCAD/configuration/utils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index b9f820f..d09598f 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -145,7 +145,7 @@ def zip_sweep_functions(sweep_lists): raise ValueError('lists have different lengths!') -# ToDo: Not producing multiple dicts +# ToDo: Not producing multiple dicts. def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='mechs'): configs = [] for f_lists in zipped_sweep_lists: From 20a8bd302674acecf8fcd6f4a196c86fe3e20d6e Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 4 Feb 2019 16:40:06 -0500 Subject: [PATCH 17/38] middleware --- SimCAD/configuration/utils/__init__.py | 8 +-- SimCAD/engine/simulation.py | 1 + SimCAD/engine/utils.py | 2 - SimCAD/utils/__init__.py | 15 ++++- simulations/validation/config1.py | 93 ++++++++++++++++++++++---- 5 files changed, 100 insertions(+), 19 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index d09598f..9c9e238 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -176,8 +176,8 @@ def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='me def parameterize_states(exo_states): - pp.pprint(exo_states) - print() + # pp.pprint(exo_states) + # print() sweep_lists = [] for sk, vfs in exo_states.items(): id_sweep_lists = [] @@ -190,8 +190,8 @@ def parameterize_states(exo_states): if len(sweep_lists) == 0: return [exo_states] - pp.pprint(sweep_lists) - print() + # pp.pprint(sweep_lists) + # print() zipped_sweep_lists = zip_sweep_functions(sweep_lists) states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 3724a76..025a94f 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -18,6 +18,7 @@ class Executor: def get_col_results(step, sL, s, funcs): return list(map(lambda f: curry_pot(f, step, sL, s), funcs)) + print(get_col_results(step, sL, s, funcs)) return foldr(call, get_col_results(step, sL, s, funcs))(ops) def apply_env_proc(self, env_processes, state_dict, step): diff --git a/SimCAD/engine/utils.py b/SimCAD/engine/utils.py index d89d900..be4ddfb 100644 --- a/SimCAD/engine/utils.py +++ b/SimCAD/engine/utils.py @@ -42,5 +42,3 @@ def fit_param(param, x): return x + param # fit_param = lambda param: lambda x: x + param - - diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index ade0424..dc1d61e 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -65,7 +65,6 @@ def rename(new_name, f): f.__name__ = new_name return f - def curry_pot(f, *argv): sweep_ind = f.__name__[0:5] == 'sweep' arg_len = len(argv) @@ -80,6 +79,20 @@ def curry_pot(f, *argv): else: raise TypeError('curry_pot() needs 3 or 4 positional arguments') +# def curry_pot(f, *argv): +# sweep_ind = f.__name__[0:5] == 'sweep' +# arg_len = len(argv) +# if sweep_ind is True and arg_len == 4: +# return f(argv[0])(argv[1])(argv[2])(argv[3]) +# elif sweep_ind is False and arg_len == 4: +# return f(argv[0])(argv[1])(argv[2])(argv[3]) +# elif sweep_ind is True and arg_len == 3: +# return f(argv[0])(argv[1])(argv[2]) +# elif sweep_ind is False and arg_len == 3: +# return f(argv[0])(argv[1])(argv[2]) +# else: +# raise TypeError('curry_pot() needs 3 or 4 positional arguments') + # def rename(newname): # def decorator(f): # f.__name__ = newname diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index cab014c..5907f1b 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -24,8 +24,10 @@ seed = { # Behaviors per Mechanism def b1m1(step, sL, s): return {'param1': 1} + def b2m1(step, sL, s): return {'param2': 4} + # @curried def b1m2(param, step, sL, s): return {'param1': 'a', 'param2': param} @@ -65,6 +67,7 @@ def s1m3(step, sL, s, _input): y = 's1' x = 0 return (y, x) + def s2m3(step, sL, s, _input): y = 's2' x = 0 @@ -96,8 +99,10 @@ def es5p2(step, sL, s, _input): # Environment States # @curried -def env_a(param, x): - return x + param +# def env_a(param, x): +# return x + param +def env_a(x): + return x def env_b(x): return 10 @@ -118,7 +123,7 @@ raw_exogenous_states = { "s4": sweep(beta, es4p2), "timestamp": es5p2 } -# exogenous_states_list = list(map(exo_update_per_ts, parameterize_states(raw_exogenous_states))) +exogenous_states_list = list(map(exo_update_per_ts, parameterize_states(raw_exogenous_states))) # ToDo: make env proc trigger field agnostic @@ -127,13 +132,13 @@ triggered_env_b = proc_trigger('2018-10-01 15:16:25', env_b) env_processes = { - "s3": sweep(beta, env_a), + "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() +# parameterized_env_processes = parameterize_states(env_processes) +# +# pp.pprint(parameterized_env_processes) +# exit() # ToDo: The number of values enteren in sweep should be the # of config objs created, # not dependent on the # of times the sweep is applied @@ -143,8 +148,9 @@ exit() # need at least 1 behaviour and 1 state function for the 1st mech with behaviors # mechanisms = {} +#middleware(beta, [(m1, states, s2, s2m1), (m2, behaviors, b1, b1m2)], mechanisms) -mechanisms = { +mechanisms_test = { "m1": { "behaviors": { "b1": b1m1, @@ -152,12 +158,12 @@ mechanisms = { }, "states": { "s1": s1m1, - "s2": sweep(beta, s2m1) #s2m1(1) #sweep(beta, s2m1) + "s2": "sweep" } }, "m2": { "behaviors": { - "b1": sweep(beta, b1m2), #b1m2(1) #sweep(beta, b1m2), + "b1": "sweep", "b2": b2m2 }, "states": { @@ -176,14 +182,77 @@ mechanisms = { } } } + +from copy import deepcopy +from funcy import curry + + +def sweep_identifier(sweep_list, sweep_id_list, mechanisms): + new_mechanisms = deepcopy(mechanisms) + for x in sweep_id_list: + mech, update_type, update, f = x[0], x[1], x[2], x[3] + current_f = new_mechanisms[x[0]][x[1]][x[2]] + if current_f is 'sweep': + new_mechanisms[x[0]][x[1]][x[2]] = sweep(sweep_list, x[3]) + + # for mech, update_types in new_mechanisms.items(): + # for update_type, fkv in update_types.items(): + # for sk, current_f in fkv.items(): + # if current_f != 'sweep' and isinstance(current_f, list) == False: + # new_mechanisms[mech][update_type][sk] = curry(f)(0) + + del mechanisms + return new_mechanisms + + +sweep_id_list = [('m1', 'states', 's2', s2m1), ('m2', 'behaviors', 'b1', b1m2)] +# pp.pprint(sweep_identifier(beta, sweep_id_list, mechanisms_test)) + + +mechanisms = sweep_identifier(beta, sweep_id_list, mechanisms_test) + +# mechanisms = { +# "m1": { +# "behaviors": { +# "b1": b1m1, +# "b2": b2m1 +# }, +# "states": { +# "s1": s1m1, +# "s2": sweep(beta, s2m1) #s2m1(1) #sweep(beta, s2m1) +# } +# }, +# "m2": { +# "behaviors": { +# "b1": sweep(beta, b1m2), #b1m2(1) #sweep(beta, b1m2), +# "b2": b2m2 +# }, +# "states": { +# "s1": s1m2, +# "s2": s2m2 +# } +# }, +# "m3": { +# "behaviors": { +# "b1": b1m3, +# "b2": b2m3 +# }, +# "states": { +# "s1": s1m3, +# "s2": s2m3 +# } +# } +# } parameterized_mechanism = parameterize_mechanism(mechanisms) +pp.pprint(parameterized_mechanism) +# exit() sim_config = { "N": 2, "T": range(5) } -for mechanisms, env_processes, exogenous_states in zip(parameterized_mechanism, parameterized_env_processes, exogenous_states_list): +for mechanisms, exogenous_states in zip(parameterized_mechanism, exogenous_states_list): configs.append( Configuration( sim_config=sim_config, From 17362884dc991c0fcf86e766ab6b69a2717739ac Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Mon, 4 Feb 2019 20:13:28 -0500 Subject: [PATCH 18/38] middleware pt 2 --- .../utils/behaviorAggregation.py | 3 + SimCAD/engine/simulation.py | 2 +- SimCAD/utils/__init__.py | 1 + simulations/validation/config1.py | 117 ++++++++---------- 4 files changed, 57 insertions(+), 66 deletions(-) diff --git a/SimCAD/configuration/utils/behaviorAggregation.py b/SimCAD/configuration/utils/behaviorAggregation.py index a16f5e1..fea80a0 100644 --- a/SimCAD/configuration/utils/behaviorAggregation.py +++ b/SimCAD/configuration/utils/behaviorAggregation.py @@ -37,6 +37,9 @@ def dict_op(f, d1, d2): else: return target_dict[key] + # print(d1) + # print(d2) + # print() key_set = set(list(d1.keys()) + list(d2.keys())) return {k: f(set_base_value(d1, d2, k), set_base_value(d2, d1, k)) for k in key_set} diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 025a94f..e03fd61 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -18,7 +18,7 @@ class Executor: def get_col_results(step, sL, s, funcs): return list(map(lambda f: curry_pot(f, step, sL, s), funcs)) - print(get_col_results(step, sL, s, funcs)) + # print(get_col_results(step, sL, s, funcs)) return foldr(call, get_col_results(step, sL, s, funcs))(ops) def apply_env_proc(self, env_processes, state_dict, step): diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index dc1d61e..0258e9e 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -65,6 +65,7 @@ def rename(new_name, f): f.__name__ = new_name return f + def curry_pot(f, *argv): sweep_ind = f.__name__[0:5] == 'sweep' arg_len = len(argv) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 5907f1b..ef5ef55 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -7,6 +7,9 @@ from SimCAD import configs from SimCAD.configuration import Configuration from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ ep_time_step, parameterize_mechanism, parameterize_states, sweep +from SimCAD.utils import rename + +from fn.func import curried pp = pprint.PrettyPrinter(indent=4) @@ -22,28 +25,30 @@ seed = { # Behaviors per Mechanism -def b1m1(step, sL, s): +# @curried +def b1m1(param, step, sL, s): return {'param1': 1} - -def b2m1(step, sL, s): +# @curried +def b2m1(param, step, sL, s): return {'param2': 4} # @curried def b1m2(param, step, sL, s): return {'param1': 'a', 'param2': param} - -def b2m2(step, sL, s): +# @curried +def b2m2(param, step, sL, s): return {'param1': 'b', 'param2': 0} - -def b1m3(step, sL, s): +# @curried +def b1m3(param, step, sL, s): return {'param1': np.array([10, 100])} - -def b2m3(step, sL, s): +# @curried +def b2m3(param, step, sL, s): return {'param1': np.array([20, 200])} # Internal States per Mechanism -def s1m1(step, sL, s, _input): +# @curried +def s1m1(param, step, sL, s, _input): y = 's1' x = 0 return (y, x) @@ -53,22 +58,23 @@ def s2m1(param, step, sL, s, _input): y = 's2' x = param return (y, x) - -def s1m2(step, sL, s, _input): +# @curried +def s1m2(param, step, sL, s, _input): y = 's1' x = _input['param2'] return (y, x) -def s2m2(step, sL, s, _input): +# @curried +def s2m2(param, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) - -def s1m3(step, sL, s, _input): +# @curried +def s1m3(param, step, sL, s, _input): y = 's1' x = 0 return (y, x) - -def s2m3(step, sL, s, _input): +# @curried +def s2m3(param, step, sL, s, _input): y = 's2' x = 0 return (y, x) @@ -83,7 +89,7 @@ def es3p1(param, step, sL, s, _input): y = 's3' x = s['s3'] + param return (y, x) - +# @curried def es4p2(param, step, sL, s, _input): y = 's4' x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + param @@ -91,7 +97,8 @@ def es4p2(param, step, sL, s, _input): ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): +# @curried +def es5p2(param, step, sL, s, _input): y = 'timestamp' x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -153,44 +160,44 @@ env_processes = { mechanisms_test = { "m1": { "behaviors": { - "b1": b1m1, - "b2": b2m1 + "b1": b1m1,#(0), + "b2": b2m1#(0) }, "states": { - "s1": s1m1, + "s1": s1m1,#(0), "s2": "sweep" } }, "m2": { "behaviors": { "b1": "sweep", - "b2": b2m2 + "b2": b2m2,#(0) }, "states": { - "s1": s1m2, - "s2": s2m2 + "s1": s1m2,#(0), + "s2": s2m2#(0) } }, "m3": { "behaviors": { - "b1": b1m3, - "b2": b2m3 + "b1": b1m3,#(0), + "b2": b2m3,#(0) }, "states": { - "s1": s1m3, - "s2": s2m3 + "s1": s1m3,#(0), + "s2": s2m3#(0) } } } from copy import deepcopy from funcy import curry +from inspect import getfullargspec def sweep_identifier(sweep_list, sweep_id_list, mechanisms): new_mechanisms = deepcopy(mechanisms) for x in sweep_id_list: - mech, update_type, update, f = x[0], x[1], x[2], x[3] current_f = new_mechanisms[x[0]][x[1]][x[2]] if current_f is 'sweep': new_mechanisms[x[0]][x[1]][x[2]] = sweep(sweep_list, x[3]) @@ -198,8 +205,20 @@ def sweep_identifier(sweep_list, sweep_id_list, mechanisms): # for mech, update_types in new_mechanisms.items(): # for update_type, fkv in update_types.items(): # for sk, current_f in fkv.items(): - # if current_f != 'sweep' and isinstance(current_f, list) == False: - # new_mechanisms[mech][update_type][sk] = curry(f)(0) + # if current_f != 'sweep' and isinstance(current_f, list) is False: + # # new_mechanisms[mech][update_type][sk] = rename("unsweeped", current_f(0)) + # curried_f = curry(current_f) + # + # def uncurried_beh_func(a, b, c): + # return curried_f(0)(a)(b)(c) + # + # def uncurried_state_func(a, b, c, d): + # return curried_f(0)(a)(b)(c)(d) + # + # if update_type == 'behaviors': + # new_mechanisms[mech][update_type][sk] = uncurried_beh_func + # elif update_type == 'states': + # new_mechanisms[mech][update_type][sk] = uncurried_state_func del mechanisms return new_mechanisms @@ -207,42 +226,10 @@ def sweep_identifier(sweep_list, sweep_id_list, mechanisms): sweep_id_list = [('m1', 'states', 's2', s2m1), ('m2', 'behaviors', 'b1', b1m2)] # pp.pprint(sweep_identifier(beta, sweep_id_list, mechanisms_test)) - +# exit() mechanisms = sweep_identifier(beta, sweep_id_list, mechanisms_test) -# mechanisms = { -# "m1": { -# "behaviors": { -# "b1": b1m1, -# "b2": b2m1 -# }, -# "states": { -# "s1": s1m1, -# "s2": sweep(beta, s2m1) #s2m1(1) #sweep(beta, s2m1) -# } -# }, -# "m2": { -# "behaviors": { -# "b1": sweep(beta, b1m2), #b1m2(1) #sweep(beta, b1m2), -# "b2": b2m2 -# }, -# "states": { -# "s1": s1m2, -# "s2": s2m2 -# } -# }, -# "m3": { -# "behaviors": { -# "b1": b1m3, -# "b2": b2m3 -# }, -# "states": { -# "s1": s1m3, -# "s2": s2m3 -# } -# } -# } parameterized_mechanism = parameterize_mechanism(mechanisms) pp.pprint(parameterized_mechanism) # exit() From f9b3b1ea18f5db91d8d6caf2bc9fde1308d11dc4 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 5 Feb 2019 11:48:57 -0500 Subject: [PATCH 19/38] middleware middleground --- Simulation.md | 2 +- simulations/example_run.py | 48 +++++++++++++++---------------- simulations/validation/config1.py | 22 +++++++------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Simulation.md b/Simulation.md index cd314df..a6e1347 100644 --- a/Simulation.md +++ b/Simulation.md @@ -4,7 +4,7 @@ A blockchain is a distributed ledger with economic agents transacting in a network. The state of the network evolves with every new transaction, which can be a result of user behaviors, protocol-defined system mechanisms, or external processes. -It is not uncommon today for blockchain projects to announce a set of rules for their network and make claims about their system level behvaior. However, the validity of those claims is hardly validated. Furthermore, it is difficult to know the potential system-level impact when the network is considering an upgrade to their system rules and prameters. +It is not uncommon today for blockchain projects to announce a set of rules for their network and make claims about their system level behavior. However, the validity of those claims is hardly validated. Furthermore, it is difficult to know the potential system-level impact when the network is considering an upgrade to their system rules and parameters. To rigorously and reliably analyze, design, and improve cryptoeconomic networks, we are introducing this Computer Aided Design Engine where we define a cryptoeconomic network with its state and exogneous variables, model transactions as a result of agent behaviors, state mechanisms, and environmental processes. We can then run simulations with different initial states, mechanisms, environmental processes to understand and visualize network behavior under different conditions. diff --git a/simulations/example_run.py b/simulations/example_run.py index e80c2de..d41d8da 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -8,28 +8,28 @@ from SimCAD 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: Pairwise 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: Pairwise 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() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index ef5ef55..14084fb 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -26,29 +26,29 @@ seed = { # Behaviors per Mechanism # @curried -def b1m1(param, step, sL, s): +def b1m1(step, sL, s): return {'param1': 1} # @curried -def b2m1(param, step, sL, s): +def b2m1(step, sL, s): return {'param2': 4} # @curried def b1m2(param, step, sL, s): return {'param1': 'a', 'param2': param} # @curried -def b2m2(param, step, sL, s): +def b2m2(step, sL, s): return {'param1': 'b', 'param2': 0} # @curried -def b1m3(param, step, sL, s): +def b1m3(step, sL, s): return {'param1': np.array([10, 100])} # @curried -def b2m3(param, step, sL, s): +def b2m3(step, sL, s): return {'param1': np.array([20, 200])} # Internal States per Mechanism # @curried -def s1m1(param, step, sL, s, _input): +def s1m1(step, sL, s, _input): y = 's1' x = 0 return (y, x) @@ -59,22 +59,22 @@ def s2m1(param, step, sL, s, _input): x = param return (y, x) # @curried -def s1m2(param, step, sL, s, _input): +def s1m2(step, sL, s, _input): y = 's1' x = _input['param2'] return (y, x) # @curried -def s2m2(param, step, sL, s, _input): +def s2m2(step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) # @curried -def s1m3(param, step, sL, s, _input): +def s1m3(step, sL, s, _input): y = 's1' x = 0 return (y, x) # @curried -def s2m3(param, step, sL, s, _input): +def s2m3(step, sL, s, _input): y = 's2' x = 0 return (y, x) @@ -98,7 +98,7 @@ def es4p2(param, step, sL, s, _input): ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) # @curried -def es5p2(param, step, sL, s, _input): +def es5p2(step, sL, s, _input): y = 'timestamp' x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) From 6b4ed2dfce9fe8c6c928d0e5e1abc4ced45f0eb5 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 5 Feb 2019 11:51:32 -0500 Subject: [PATCH 20/38] fixed import --- simulations/example_run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulations/example_run.py b/simulations/example_run.py index 3a18378..e50cddd 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -3,7 +3,7 @@ from tabulate import tabulate # The following imports NEED to be in the exact order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from validation import config1, config2 +from simulations.validation import config1, config2 from SimCAD import configs exec_mode = ExecutionMode() From c58f2d65a6f3e5ab8873f6784bdc14060773528a Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 5 Feb 2019 20:00:39 -0500 Subject: [PATCH 21/38] middle ground pt. 3 --- SimCAD/configuration/utils/__init__.py | 104 +------------ SimCAD/configuration/utils/parameterSweep.py | 148 +++++++++++++++++++ simulations/example_run.py | 48 +++--- simulations/validation/config1.py | 123 +++++++-------- 4 files changed, 224 insertions(+), 199 deletions(-) create mode 100644 SimCAD/configuration/utils/parameterSweep.py diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 9c9e238..3ad5b97 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -3,11 +3,12 @@ from decimal import Decimal from copy import deepcopy from fn.func import curried import pandas as pd +import inspect + from SimCAD.utils import rename from SimCAD.utils import dict_filter, contains_type, curry_pot - from funcy import curry import pprint @@ -125,104 +126,3 @@ def exo_update_per_ts(ep): return (y, s[y]) return {es: ep_decorator(f, es) for es, f in ep.items()} - - -def sweep(params, sweep_f): - return [rename("sweep_"+sweep_f.__name__+"_"+str(i), curry(sweep_f)(param)) for param, i in zip(params, range(len(params)))] - - -def zip_sweep_functions(sweep_lists): - zipped_sweep_lists = [] - it = iter(sweep_lists) - the_len = len(next(it)) - same_len_ind = all(len(l) == the_len for l in it) - count_ind = len(sweep_lists) >= 2 - if same_len_ind == True and count_ind == True: - return list(map(lambda x: list(x), list(zip(*sweep_lists)))) - elif same_len_ind == False or count_ind == False: - return sweep_lists - else: - raise ValueError('lists have different lengths!') - - -# ToDo: Not producing multiple dicts. -def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='mechs'): - configs = [] - for f_lists in zipped_sweep_lists: - new_states_dict = deepcopy(states_dict) - for f_dict in f_lists: - if state_type_ind == 'mechs': - updates = list(f_dict.values()).pop() - functs = list(updates.values()).pop() - - mech = list(f_dict.keys()).pop() - update_type = list(updates.keys()).pop() - sk = list(functs.keys()).pop() - vf = list(functs.values()).pop() - - new_states_dict[mech][update_type][sk] = vf - elif state_type_ind == 'exo_proc': - sk = list(f_dict.keys()).pop() - vf = list(f_dict.values()).pop() - - new_states_dict[sk] = vf - else: - raise ValueError("Incorrect \'state_type_ind\'") - - configs.append(new_states_dict) - del new_states_dict - - return configs - - -def parameterize_states(exo_states): - # pp.pprint(exo_states) - # print() - sweep_lists = [] - for sk, vfs in exo_states.items(): - id_sweep_lists = [] - if isinstance(vfs, list): - for vf in vfs: - id_sweep_lists.append({sk: vf}) - if len(id_sweep_lists) != 0: - sweep_lists.append(id_sweep_lists) - - if len(sweep_lists) == 0: - return [exo_states] - - # pp.pprint(sweep_lists) - # print() - - zipped_sweep_lists = zip_sweep_functions(sweep_lists) - states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") - - return states_configs - - -def parameterize_mechanism(mechanisms): - sweep_lists = [] - for mech, update_types in mechanisms.items(): - for update_type, fkv in update_types.items(): - for sk, vfs in fkv.items(): - id_sweep_lists = [] - if isinstance(vfs, list): - for vf in vfs: - id_sweep_lists.append({mech: {update_type: {sk: vf}}}) - if len(id_sweep_lists) != 0: - sweep_lists.append(id_sweep_lists) - - if len(sweep_lists) == 0: - return [mechanisms] - - zipped_sweep_lists = zip_sweep_functions(sweep_lists) - mechanisms_configs = create_sweep_config_list(zipped_sweep_lists, mechanisms, "mechs") - - return mechanisms_configs - - -# def ep_decorator(f, y, step, sL, s, _input): -# if s['mech_step'] + 1 == 1: -# return f(step, sL, s, _input) -# else: -# return (y, s[y]) -# return {es: ep_decorator(f, es) for es, f in ep.items()} diff --git a/SimCAD/configuration/utils/parameterSweep.py b/SimCAD/configuration/utils/parameterSweep.py new file mode 100644 index 0000000..e0467b2 --- /dev/null +++ b/SimCAD/configuration/utils/parameterSweep.py @@ -0,0 +1,148 @@ +import inspect +from copy import deepcopy +from funcy import curry + +from SimCAD.utils import rename +from SimCAD.configuration.utils import exo_update_per_ts + + +class ParamSweep: + def __init__(self, sweep_list, mechs=None, raw_exogenous_states=None): + self.sweep_list = sweep_list + self.mechs = mechs + self.raw_exogenous_states = raw_exogenous_states + + def mechanisms(self): + swept_mechanisms = mech_sweep_identifier(self.sweep_list, self.mechs) + return parameterize_mechanism(swept_mechanisms) + + def exogenous_states(self): + swept_raw_exogenous_states = exo_sweep_identifier(self.sweep_list, self.raw_exogenous_states) + return parameterize_states(swept_raw_exogenous_states) + + +def sweep(params, sweep_f): + return [ + rename("sweep_"+sweep_f.__name__+"_"+str(i), curry(sweep_f)(param)) + for param, i in zip(params, range(len(params))) + ] + + +def mech_sweep_identifier(sweep_list, mechanisms): + new_mechanisms = deepcopy(mechanisms) + for mech, update_types in new_mechanisms.items(): + for update_type, fkv in update_types.items(): + for sk, current_f in fkv.items(): + current_f_arg_len = len(inspect.getfullargspec(current_f).args) + if update_type == 'behaviors' and current_f_arg_len == 4: + new_mechanisms[mech][update_type][sk] = sweep(sweep_list, current_f) + elif update_type == 'states' and current_f_arg_len == 5: + new_mechanisms[mech][update_type][sk] = sweep(sweep_list, current_f) + + del mechanisms + return new_mechanisms + + +def exo_sweep_identifier(sweep_list, exo_states): + new_exo_states = deepcopy(exo_states) + for sk, current_f in exo_states.items(): + current_f_arg_len = len(inspect.getfullargspec(current_f).args) + if current_f_arg_len == 5: + new_exo_states[sk] = sweep(sweep_list, current_f) + + del exo_states + return new_exo_states + + +def zip_sweep_functions(sweep_lists): + zipped_sweep_lists = [] + it = iter(sweep_lists) + the_len = len(next(it)) + same_len_ind = all(len(l) == the_len for l in it) + count_ind = len(sweep_lists) >= 2 + if same_len_ind is True and count_ind is True: + return list(map(lambda x: list(x), list(zip(*sweep_lists)))) + elif same_len_ind is False or count_ind is False: + return sweep_lists + else: + raise ValueError('lists have different lengths!') + + +# ToDo: Not producing multiple dicts. +def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='mechs'): + configs = [] + for f_lists in zipped_sweep_lists: + new_states_dict = deepcopy(states_dict) + for f_dict in f_lists: + if state_type_ind == 'mechs': + updates = list(f_dict.values()).pop() + functs = list(updates.values()).pop() + + mech = list(f_dict.keys()).pop() + update_type = list(updates.keys()).pop() + sk = list(functs.keys()).pop() + vf = list(functs.values()).pop() + + new_states_dict[mech][update_type][sk] = vf + elif state_type_ind == 'exo_proc': + sk = list(f_dict.keys()).pop() + vf = list(f_dict.values()).pop() + + new_states_dict[sk] = vf + else: + raise ValueError("Incorrect \'state_type_ind\'") + + configs.append(new_states_dict) + del new_states_dict + + return configs + + +def parameterize_states(exo_states, exo_update=exo_update_per_ts): + # pp.pprint(exo_states) + # print() + sweep_lists = [] + for sk, vfs in exo_states.items(): + id_sweep_lists = [] + if isinstance(vfs, list): + for vf in vfs: + id_sweep_lists.append({sk: vf}) + if len(id_sweep_lists) != 0: + sweep_lists.append(id_sweep_lists) + + sweep_lists_len = len(sweep_lists) + if sweep_lists_len != 0: + zipped_sweep_lists = zip_sweep_functions(sweep_lists) + states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") + # pp.pprint(sweep_lists) + # print() + if exo_update == exo_update_per_ts: + return list(map(exo_update_per_ts, states_configs)) + elif exo_update != exo_update_per_ts: + return states_configs + + elif sweep_lists_len == 0 and exo_update == exo_update_per_ts: + return list(map(exo_update_per_ts, [exo_states])) + elif sweep_lists_len == 0 and exo_update != exo_update_per_ts: + return [exo_states] + + +def parameterize_mechanism(mechanisms): + sweep_lists = [] + for mech, update_types in mechanisms.items(): + for update_type, fkv in update_types.items(): + for sk, vfs in fkv.items(): + id_sweep_lists = [] + if isinstance(vfs, list): + for vf in vfs: + id_sweep_lists.append({mech: {update_type: {sk: vf}}}) + if len(id_sweep_lists) != 0: + sweep_lists.append(id_sweep_lists) + + if len(sweep_lists) == 0: + return [mechanisms] + + zipped_sweep_lists = zip_sweep_functions(sweep_lists) + mechanisms_configs = create_sweep_config_list(zipped_sweep_lists, mechanisms, "mechs") + + return mechanisms_configs diff --git a/simulations/example_run.py b/simulations/example_run.py index d41d8da..1109322 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -8,28 +8,28 @@ from SimCAD 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: Pairwise 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() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 14084fb..abb1211 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -5,11 +5,10 @@ import pprint from SimCAD import configs from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step, parameterize_mechanism, parameterize_states, sweep -from SimCAD.utils import rename +from SimCAD.configuration.utils import proc_trigger, bound_norm_random, \ + ep_time_step +from SimCAD.configuration.utils.parameterSweep import ParamSweep -from fn.func import curried pp = pprint.PrettyPrinter(indent=4) @@ -33,8 +32,8 @@ def b2m1(step, sL, s): return {'param2': 4} # @curried -def b1m2(param, step, sL, s): - return {'param1': 'a', 'param2': param} +def b1m2(_beta, step, sL, s): + return {'param1': 'a', 'param2': _beta} # @curried def b2m2(step, sL, s): return {'param1': 'b', 'param2': 0} @@ -54,10 +53,16 @@ def s1m1(step, sL, s, _input): return (y, x) # @curried -def s2m1(param, step, sL, s, _input): +def s2m1(sweep_param, step, sL, s, _input): y = 's2' - x = param + x = sweep_param return (y, x) +# +# def s2m1(step, sL, s, _input): +# y = 's2' +# x = 0 +# return (y, x) + # @curried def s1m2(step, sL, s, _input): y = 's1' @@ -126,11 +131,10 @@ genesis_states = { # remove `exo_update_per_ts` to update every ts raw_exogenous_states = { - "s3": sweep(beta, es3p1), #es3p1, #sweep(beta, es3p1), - "s4": sweep(beta, es4p2), + "s3": es3p1, #es3p1, #sweep(beta, es3p1), + "s4": es4p2, "timestamp": es5p2 } -exogenous_states_list = list(map(exo_update_per_ts, parameterize_states(raw_exogenous_states))) # ToDo: make env proc trigger field agnostic @@ -147,7 +151,7 @@ env_processes = { # pp.pprint(parameterized_env_processes) # exit() -# ToDo: The number of values enteren in sweep should be the # of config objs created, +# 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 @@ -155,98 +159,71 @@ env_processes = { # need at least 1 behaviour and 1 state function for the 1st mech with behaviors # mechanisms = {} -#middleware(beta, [(m1, states, s2, s2m1), (m2, behaviors, b1, b1m2)], mechanisms) - -mechanisms_test = { +mechanisms = { "m1": { "behaviors": { - "b1": b1m1,#(0), - "b2": b2m1#(0) + "b1": b1m1, + "b2": b2m1 }, "states": { - "s1": s1m1,#(0), - "s2": "sweep" + "s1": s1m1, + "s2": s2m1 } }, "m2": { "behaviors": { - "b1": "sweep", - "b2": b2m2,#(0) + "b1": b1m2, + "b2": b2m2, }, "states": { - "s1": s1m2,#(0), - "s2": s2m2#(0) + "s1": s1m2, + "s2": s2m2 } }, "m3": { "behaviors": { - "b1": b1m3,#(0), - "b2": b2m3,#(0) + "b1": b1m3, + "b2": b2m3, }, "states": { - "s1": s1m3,#(0), - "s2": s2m3#(0) + "s1": s1m3, + "s2": s2m3 } } } -from copy import deepcopy -from funcy import curry -from inspect import getfullargspec - - -def sweep_identifier(sweep_list, sweep_id_list, mechanisms): - new_mechanisms = deepcopy(mechanisms) - for x in sweep_id_list: - current_f = new_mechanisms[x[0]][x[1]][x[2]] - if current_f is 'sweep': - new_mechanisms[x[0]][x[1]][x[2]] = sweep(sweep_list, x[3]) - - # for mech, update_types in new_mechanisms.items(): - # for update_type, fkv in update_types.items(): - # for sk, current_f in fkv.items(): - # if current_f != 'sweep' and isinstance(current_f, list) is False: - # # new_mechanisms[mech][update_type][sk] = rename("unsweeped", current_f(0)) - # curried_f = curry(current_f) - # - # def uncurried_beh_func(a, b, c): - # return curried_f(0)(a)(b)(c) - # - # def uncurried_state_func(a, b, c, d): - # return curried_f(0)(a)(b)(c)(d) - # - # if update_type == 'behaviors': - # new_mechanisms[mech][update_type][sk] = uncurried_beh_func - # elif update_type == 'states': - # new_mechanisms[mech][update_type][sk] = uncurried_state_func - - del mechanisms - return new_mechanisms - - -sweep_id_list = [('m1', 'states', 's2', s2m1), ('m2', 'behaviors', 'b1', b1m2)] -# pp.pprint(sweep_identifier(beta, sweep_id_list, mechanisms_test)) -# exit() - -mechanisms = sweep_identifier(beta, sweep_id_list, mechanisms_test) - -parameterized_mechanism = parameterize_mechanism(mechanisms) -pp.pprint(parameterized_mechanism) -# exit() +# ToDo: inspect **** +# ToDo: code block regenerator abstracted from user: input config module with params as convention, output it not as convention, +# ToDo: make ParamSweep a part of sim_config sim_config = { "N": 2, "T": range(5) + # beta } -for mechanisms, exogenous_states in zip(parameterized_mechanism, exogenous_states_list): +# beta = [1,2] +# Test +# def(beta, a, b, c): +# return a + b + beta + beta + +# ToDo: and/or, or not working +# ToDo: Abstract ParamSweep away from user +param_sweep = ParamSweep( + sweep_list=beta, + mechs=mechanisms, + raw_exogenous_states=raw_exogenous_states +) + +# ToDo: Make loop standard by returning single elems from ParamSweep if sweep not specified +for mechanisms, exogenous_states in zip(param_sweep.mechanisms(), param_sweep.exogenous_states()): configs.append( Configuration( sim_config=sim_config, state_dict=genesis_states, seed=seed, - exogenous_states=exogenous_states, #parameterize_states(raw_exogenous_states)[1], + exogenous_states=exogenous_states, env_processes=env_processes, - mechanisms=mechanisms #parameterize_mechanism(mechanisms)[1] + mechanisms=mechanisms ) ) From 2d752176eb15cee3c67359e067b58a88b726e2f6 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 6 Feb 2019 20:37:10 -0500 Subject: [PATCH 22/38] middleware working --- SimCAD/__init__.py | 2 +- SimCAD/configuration/__init__.py | 27 ++++++- SimCAD/configuration/utils/__init__.py | 16 ++-- .../utils/behaviorAggregation.py | 3 - SimCAD/configuration/utils/parameterSweep.py | 26 +++--- SimCAD/engine/simulation.py | 1 + SimCAD/engine/utils.py | 2 - simulations/example_run.py | 3 +- simulations/validation/config1.py | 81 +++++-------------- 9 files changed, 64 insertions(+), 97 deletions(-) diff --git a/SimCAD/__init__.py b/SimCAD/__init__.py index 0b7fa28..b4234cb 100644 --- a/SimCAD/__init__.py +++ b/SimCAD/__init__.py @@ -1,2 +1,2 @@ name = "SimCAD" -configs = [] +configs = [] \ No newline at end of file diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index d166df3..ab9f5fd 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -1,12 +1,13 @@ from functools import reduce from fn.op import foldr import pandas as pd -from fn.func import curried + +from SimCAD import configs +from SimCAD.configuration.utils.parameterSweep import ParamSweep from SimCAD.utils import key_filter from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum -# class ParameterSeep: class Configuration(object): def __init__(self, sim_config=None, state_dict=None, seed=None, env_processes=None, @@ -19,6 +20,28 @@ class Configuration(object): self.mechanisms = mechanisms self.behavior_ops = behavior_ops + +def append_configs(sim_config, genesis_states, seed, raw_exogenous_states, env_processes, mechanisms, _exo_update_per_ts=True): + param_sweep = ParamSweep( + sweep_list=sim_config['M'], + mechs=mechanisms, + raw_exogenous_states=raw_exogenous_states, + _exo_update_per_ts=_exo_update_per_ts + ) + + for mechanisms, exogenous_states in zip(param_sweep.mechanisms(), param_sweep.exogenous_states()): + configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms + ) + ) + + class Identity: def __init__(self, behavior_id={'identity': 0}): self.beh_id_return_val = behavior_id diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 3ad5b97..c119190 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -3,17 +3,11 @@ from decimal import Decimal from copy import deepcopy from fn.func import curried import pandas as pd -import inspect - -from SimCAD.utils import rename from SimCAD.utils import dict_filter, contains_type, curry_pot -from funcy import curry - -import pprint - -pp = pprint.PrettyPrinter(indent=4) +# import pprint +# pp = pprint.PrettyPrinter(indent=4) class TensorFieldReport: def __init__(self, config_proc): @@ -37,8 +31,8 @@ def state_update(y, x): def bound_norm_random(rng, low, high): - res = rng.normal((high+low)/2,(high-low)/6) - if (reshigh): + res = rng.normal((high+low)/2, (high-low)/6) + if res < low or res > high: res = bound_norm_random(rng, low, high) return Decimal(res) @@ -123,6 +117,6 @@ def exo_update_per_ts(ep): if s['mech_step'] + 1 == 1: return curry_pot(f, step, sL, s, _input) else: - return (y, s[y]) + return y, s[y] return {es: ep_decorator(f, es) for es, f in ep.items()} diff --git a/SimCAD/configuration/utils/behaviorAggregation.py b/SimCAD/configuration/utils/behaviorAggregation.py index fea80a0..a16f5e1 100644 --- a/SimCAD/configuration/utils/behaviorAggregation.py +++ b/SimCAD/configuration/utils/behaviorAggregation.py @@ -37,9 +37,6 @@ def dict_op(f, d1, d2): else: return target_dict[key] - # print(d1) - # print(d2) - # print() key_set = set(list(d1.keys()) + list(d2.keys())) return {k: f(set_base_value(d1, d2, k), set_base_value(d2, d1, k)) for k in key_set} diff --git a/SimCAD/configuration/utils/parameterSweep.py b/SimCAD/configuration/utils/parameterSweep.py index e0467b2..1c9815f 100644 --- a/SimCAD/configuration/utils/parameterSweep.py +++ b/SimCAD/configuration/utils/parameterSweep.py @@ -7,10 +7,11 @@ from SimCAD.configuration.utils import exo_update_per_ts class ParamSweep: - def __init__(self, sweep_list, mechs=None, raw_exogenous_states=None): + def __init__(self, sweep_list, mechs=None, raw_exogenous_states=None, _exo_update_per_ts=True): self.sweep_list = sweep_list self.mechs = mechs self.raw_exogenous_states = raw_exogenous_states + self._exo_update_per_ts = _exo_update_per_ts def mechanisms(self): swept_mechanisms = mech_sweep_identifier(self.sweep_list, self.mechs) @@ -18,7 +19,7 @@ class ParamSweep: def exogenous_states(self): swept_raw_exogenous_states = exo_sweep_identifier(self.sweep_list, self.raw_exogenous_states) - return parameterize_states(swept_raw_exogenous_states) + return parameterize_states(swept_raw_exogenous_states, self._exo_update_per_ts) def sweep(params, sweep_f): @@ -98,9 +99,7 @@ def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='me return configs -def parameterize_states(exo_states, exo_update=exo_update_per_ts): - # pp.pprint(exo_states) - # print() +def parameterize_states(exo_states, _exo_update_per_ts): sweep_lists = [] for sk, vfs in exo_states.items(): id_sweep_lists = [] @@ -110,21 +109,16 @@ def parameterize_states(exo_states, exo_update=exo_update_per_ts): if len(id_sweep_lists) != 0: sweep_lists.append(id_sweep_lists) + def comp_exo_update(states_configs): + return [exo_update_per_ts(x) if _exo_update_per_ts is True else x for x in states_configs] + sweep_lists_len = len(sweep_lists) if sweep_lists_len != 0: zipped_sweep_lists = zip_sweep_functions(sweep_lists) states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") - # pp.pprint(sweep_lists) - # print() - if exo_update == exo_update_per_ts: - return list(map(exo_update_per_ts, states_configs)) - elif exo_update != exo_update_per_ts: - return states_configs - - elif sweep_lists_len == 0 and exo_update == exo_update_per_ts: - return list(map(exo_update_per_ts, [exo_states])) - elif sweep_lists_len == 0 and exo_update != exo_update_per_ts: - return [exo_states] + return comp_exo_update(states_configs) + elif sweep_lists_len == 0: + return comp_exo_update([exo_states]) def parameterize_mechanism(mechanisms): diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index e03fd61..0d8de63 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -1,5 +1,6 @@ from copy import deepcopy from fn.op import foldr, call + from SimCAD.utils import curry_pot from SimCAD.engine.utils import engine_exception diff --git a/SimCAD/engine/utils.py b/SimCAD/engine/utils.py index be4ddfb..2e569b8 100644 --- a/SimCAD/engine/utils.py +++ b/SimCAD/engine/utils.py @@ -1,7 +1,5 @@ from datetime import datetime from fn.func import curried -from SimCAD.utils import rename -# from SimCAD.configuration.utils import s_update def datetime_range(start, end, delta, dt_format='%Y-%m-%d %H:%M:%S'): diff --git a/simulations/example_run.py b/simulations/example_run.py index 1109322..f017646 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -1,9 +1,10 @@ import pandas as pd from tabulate import tabulate - +from importlib import reload # The following imports NEED to be in the exact order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor from simulations.validation import config1 #, config2 + from SimCAD import configs exec_mode = ExecutionMode() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index abb1211..ad7630d 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,18 +3,11 @@ import numpy as np from datetime import timedelta import pprint -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import proc_trigger, bound_norm_random, \ - ep_time_step -from SimCAD.configuration.utils.parameterSweep import ParamSweep - +from SimCAD.configuration import append_configs, Configuration +from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, exo_update_per_ts pp = pprint.PrettyPrinter(indent=4) -# ToDo: handle single param sweep -beta = [Decimal(1), Decimal(2)] - seed = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), @@ -24,17 +17,15 @@ seed = { # Behaviors per Mechanism -# @curried def b1m1(step, sL, s): return {'param1': 1} -# @curried + def b2m1(step, sL, s): return {'param2': 4} -# @curried def b1m2(_beta, step, sL, s): return {'param1': 'a', 'param2': _beta} -# @curried + def b2m2(step, sL, s): return {'param1': 'b', 'param2': 0} # @curried @@ -44,7 +35,6 @@ def b1m3(step, sL, s): def b2m3(step, sL, s): return {'param1': np.array([20, 200])} - # Internal States per Mechanism # @curried def s1m1(step, sL, s, _input): @@ -52,33 +42,26 @@ def s1m1(step, sL, s, _input): x = 0 return (y, x) -# @curried def s2m1(sweep_param, step, sL, s, _input): y = 's2' x = sweep_param return (y, x) -# -# def s2m1(step, sL, s, _input): -# y = 's2' -# x = 0 -# return (y, x) -# @curried def s1m2(step, sL, s, _input): y = 's1' x = _input['param2'] return (y, x) -# @curried + def s2m2(step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) -# @curried + def s1m3(step, sL, s, _input): y = 's1' x = 0 return (y, x) -# @curried + def s2m3(step, sL, s, _input): y = 's2' x = 0 @@ -89,20 +72,19 @@ def s2m3(step, sL, s, _input): proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -# @curried + def es3p1(param, step, sL, s, _input): y = 's3' - x = s['s3'] + param + x = param return (y, x) # @curried def es4p2(param, step, sL, s, _input): y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + param + x = param return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) -# @curried def es5p2(step, sL, s, _input): y = 'timestamp' x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) @@ -156,9 +138,6 @@ env_processes = { # sweep exo_state func and point to exo-state in every other funtion # param sweep on genesis states -# need at least 1 behaviour and 1 state function for the 1st mech with behaviors -# mechanisms = {} - mechanisms = { "m1": { "behaviors": { @@ -192,38 +171,18 @@ mechanisms = { } } -# ToDo: inspect **** -# ToDo: code block regenerator abstracted from user: input config module with params as convention, output it not as convention, - -# ToDo: make ParamSweep a part of sim_config sim_config = { "N": 2, - "T": range(5) - # beta + "T": range(5), + "M": [Decimal(1), Decimal(2), Decimal(3)] } -# beta = [1,2] -# Test -# def(beta, a, b, c): -# return a + b + beta + beta - -# ToDo: and/or, or not working -# ToDo: Abstract ParamSweep away from user -param_sweep = ParamSweep( - sweep_list=beta, - mechs=mechanisms, - raw_exogenous_states=raw_exogenous_states +append_configs( + sim_config=sim_config, + genesis_states=genesis_states, + seed=seed, + raw_exogenous_states=raw_exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms, + _exo_update_per_ts=True #Default ) - -# ToDo: Make loop standard by returning single elems from ParamSweep if sweep not specified -for mechanisms, exogenous_states in zip(param_sweep.mechanisms(), param_sweep.exogenous_states()): - configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) - ) From 45f8fffe833203e4b16095b960358436443b5af1 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Fri, 8 Feb 2019 13:14:10 -0500 Subject: [PATCH 23/38] funct middleware --- simulations/validation/config1.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index ad7630d..2464b47 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,7 +3,7 @@ import numpy as np from datetime import timedelta import pprint -from SimCAD.configuration import append_configs, Configuration +from SimCAD.configuration import append_configs from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, exo_update_per_ts pp = pprint.PrettyPrinter(indent=4) @@ -15,6 +15,9 @@ seed = { 'c': np.random.RandomState(3) } +# beta = 1 + +#middleware(f1,f2,f3,f4) # Behaviors per Mechanism def b1m1(step, sL, s): @@ -174,7 +177,7 @@ mechanisms = { sim_config = { "N": 2, "T": range(5), - "M": [Decimal(1), Decimal(2), Decimal(3)] + "M": [Decimal(1), Decimal(2), Decimal(3)] # dict read from dict } append_configs( From cccb491f2c875776e8d15d83ad5e35c32c301798 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Tue, 12 Feb 2019 21:13:08 -0500 Subject: [PATCH 24/38] temp parama sweep --- SimCAD/engine/simulation.py | 4 ++-- simulations/validation/config1.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 0d8de63..7c1f5bc 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -34,13 +34,13 @@ class Executor: def mech_step(self, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): last_in_obj = sL[-1] - _input = self.state_update_exception(self.get_behavior_input(m_step, sL, last_in_obj, behavior_funcs)) + _input = self.behavior_update_exception(self.get_behavior_input(m_step, sL, last_in_obj, behavior_funcs)) # print(_input) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function last_in_copy = dict( [ - self.behavior_update_exception(curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs + self.state_update_exception(curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs ] ) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 2464b47..9ad579c 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -17,7 +17,7 @@ seed = { # beta = 1 -#middleware(f1,f2,f3,f4) +# middleware(f1,f2,f3,f4) # Behaviors per Mechanism def b1m1(step, sL, s): @@ -165,7 +165,7 @@ mechanisms = { "m3": { "behaviors": { "b1": b1m3, - "b2": b2m3, + "b2": b2m3 }, "states": { "s1": s1m3, @@ -188,4 +188,4 @@ append_configs( env_processes=env_processes, mechanisms=mechanisms, _exo_update_per_ts=True #Default -) +) \ No newline at end of file From ddc67531bd43e24a7b8951aa72ed7b789044d6d6 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 13 Feb 2019 00:38:15 -0500 Subject: [PATCH 25/38] param sweep full spec working --- SimCAD/configuration/__init__.py | 27 +++++-- SimCAD/configuration/utils/__init__.py | 6 +- SimCAD/engine/__init__.py | 19 ++--- SimCAD/engine/simulation.py | 30 ++++--- SimCAD/utils/__init__.py | 27 +++++++ simulations/validation/config1.py | 106 +++++++++++++++++-------- 6 files changed, 150 insertions(+), 65 deletions(-) diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index ab9f5fd..248c9b0 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -7,6 +7,8 @@ from SimCAD.configuration.utils.parameterSweep import ParamSweep from SimCAD.utils import key_filter from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum +from SimCAD.configuration.utils import exo_update_per_ts + class Configuration(object): @@ -22,14 +24,25 @@ class Configuration(object): def append_configs(sim_config, genesis_states, seed, raw_exogenous_states, env_processes, mechanisms, _exo_update_per_ts=True): - param_sweep = ParamSweep( - sweep_list=sim_config['M'], - mechs=mechanisms, - raw_exogenous_states=raw_exogenous_states, - _exo_update_per_ts=_exo_update_per_ts - ) + if 'M' in sim_config.keys(): + + for mechanisms, exogenous_states in sim_config['M']: + configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms + ) + ) + else: + if _exo_update_per_ts is True: + exogenous_states = exo_update_per_ts(raw_exogenous_states) + else: + exogenous_states = raw_exogenous_states - for mechanisms, exogenous_states in zip(param_sweep.mechanisms(), param_sweep.exogenous_states()): configs.append( Configuration( sim_config=sim_config, diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index c119190..c21f57c 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -4,7 +4,7 @@ from copy import deepcopy from fn.func import curried import pandas as pd -from SimCAD.utils import dict_filter, contains_type, curry_pot +from SimCAD.utils import dict_filter, contains_type, flatten_tabulated_dict, tabulate_dict, curry_pot # import pprint # pp = pprint.PrettyPrinter(indent=4) @@ -120,3 +120,7 @@ def exo_update_per_ts(ep): return y, s[y] return {es: ep_decorator(f, es) for es, f in ep.items()} + + +def process_variables(d): + return flatten_tabulated_dict(tabulate_dict(d)) \ No newline at end of file diff --git a/SimCAD/engine/__init__.py b/SimCAD/engine/__init__.py index 66a0773..3a31be6 100644 --- a/SimCAD/engine/__init__.py +++ b/SimCAD/engine/__init__.py @@ -16,16 +16,16 @@ class ExecutionContext: self.name = context self.method = None - def single_proc_exec(simulation_execs, states_lists, configs_structs, env_processes_list, Ts, Ns): + def single_proc_exec(simulation_execs, var_dict, states_lists, configs_structs, env_processes_list, Ts, Ns): l = [simulation_execs, states_lists, configs_structs, env_processes_list, Ts, Ns] simulation, states_list, config, env_processes, T, N = list(map(lambda x: x.pop(), l)) - result = simulation(states_list, config, env_processes, T, N) + result = simulation(var_dict, states_list, config, env_processes, T, N) return flatten(result) - def parallelize_simulations(fs, states_list, configs, env_processes, Ts, Ns): - l = list(zip(fs, states_list, configs, env_processes, Ts, Ns)) + 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)) with Pool(len(configs)) as p: - results = p.map(lambda t: t[0](t[1], t[2], t[3], t[4], t[5]), l) + results = p.map(lambda t: t[0](t[1], t[2], t[3], t[4], t[5], t[6]), l) return results if context == 'single_proc': @@ -47,10 +47,11 @@ class Executor: create_tensor_field = TensorFieldReport(config_proc).create_tensor_field print(self.exec_context+": "+str(self.configs)) - states_lists, Ts, Ns, eps, configs_structs, env_processes_list, mechanisms, simulation_execs = \ - [], [], [], [], [], [], [], [] + var_dict_list, states_lists, Ts, Ns, eps, configs_structs, env_processes_list, mechanisms, simulation_execs = \ + [], [], [], [], [], [], [], [], [] config_idx = 0 for x in self.configs: + var_dict_list.append(x.sim_config['M']) states_lists.append([x.state_dict]) Ts.append(x.sim_config['T']) Ns.append(x.sim_config['N']) @@ -64,11 +65,11 @@ class Executor: if self.exec_context == ExecutionMode.single_proc: tensor_field = create_tensor_field(mechanisms.pop(), eps.pop()) - result = self.exec_method(simulation_execs, states_lists, configs_structs, env_processes_list, Ts, Ns) + result = self.exec_method(simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, Ns) return result, tensor_field elif self.exec_context == ExecutionMode.multi_proc: if len(self.configs) > 1: - simulations = self.exec_method(simulation_execs, states_lists, configs_structs, env_processes_list, Ts, Ns) + simulations = self.exec_method(simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, Ns) results = [] for result, mechanism, ep in list(zip(simulations, mechanisms, eps)): results.append((flatten(result), create_tensor_field(mechanism, ep))) diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 7c1f5bc..ed3dc06 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -4,6 +4,8 @@ from fn.op import foldr, call from SimCAD.utils import curry_pot from SimCAD.engine.utils import engine_exception +import pprint as pp + id_exception = engine_exception(KeyError, KeyError, None) @@ -13,14 +15,15 @@ class Executor: self.state_update_exception = state_update_exception self.behavior_update_exception = behavior_update_exception - def get_behavior_input(self, step, sL, s, funcs): + def get_behavior_input(self, var_dict, step, sL, s, funcs): ops = self.behavior_ops[::-1] - def get_col_results(step, sL, s, funcs): - return list(map(lambda f: curry_pot(f, step, sL, s), funcs)) + def get_col_results(var_dict, step, sL, s, funcs): + # return list(map(lambda f: curry_pot(f, step, sL, s), funcs)) + return list(map(lambda f: f(var_dict, step, sL, s), funcs)) # print(get_col_results(step, sL, s, funcs)) - return foldr(call, get_col_results(step, sL, s, funcs))(ops) + return foldr(call, get_col_results(var_dict, step, sL, s, funcs))(ops) def apply_env_proc(self, env_processes, state_dict, step): for state in state_dict.keys(): @@ -31,16 +34,17 @@ class Executor: else: state_dict[state] = env_state(state_dict[state]) - def mech_step(self, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): + def mech_step(self, var_dict, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): last_in_obj = sL[-1] - _input = self.behavior_update_exception(self.get_behavior_input(m_step, sL, last_in_obj, behavior_funcs)) + _input = self.behavior_update_exception(self.get_behavior_input(var_dict, m_step, sL, last_in_obj, behavior_funcs)) # print(_input) # ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function last_in_copy = dict( [ - self.state_update_exception(curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs + # self.state_update_exception(curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs + self.state_update_exception(f(var_dict, m_step, sL, last_in_obj, _input)) for f in state_funcs ] ) @@ -58,7 +62,7 @@ class Executor: return sL - def mech_pipeline(self, states_list, configs, env_processes, t_step, run): + def mech_pipeline(self, var_dict, states_list, configs, env_processes, t_step, run): m_step = 0 states_list_copy = deepcopy(states_list) genesis_states = states_list_copy[-1] @@ -68,7 +72,7 @@ class Executor: m_step += 1 for config in configs: s_conf, b_conf = config[0], config[1] - states_list = self.mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step, run) + states_list = self.mech_step(var_dict, m_step, states_list, s_conf, b_conf, env_processes, t_step, run) m_step += 1 t_step += 1 @@ -76,11 +80,11 @@ class Executor: return states_list # ToDo: Rename Run Pipeline - def block_pipeline(self, states_list, configs, env_processes, time_seq, run): + def block_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] for time_step in time_seq: - pipe_run = self.mech_pipeline(simulation_list[-1], configs, env_processes, time_step, run) + pipe_run = self.mech_pipeline(var_dict, simulation_list[-1], configs, env_processes, time_step, run) _, *pipe_run = pipe_run simulation_list.append(pipe_run) @@ -88,12 +92,12 @@ class Executor: # ToDo: Muiltithreaded Runs - def simulation(self, states_list, configs, env_processes, time_seq, runs): + def simulation(self, var_dict, states_list, configs, env_processes, time_seq, runs): pipe_run = [] for run in range(runs): run += 1 states_list_copy = deepcopy(states_list) - head, *tail = self.block_pipeline(states_list_copy, configs, env_processes, time_seq, run) + head, *tail = self.block_pipeline(var_dict, states_list_copy, configs, env_processes, time_seq, run) genesis = head.pop() genesis['mech_step'], genesis['time_step'], genesis['run'] = 0, 0, run first_timestep_per_run = [genesis] + tail.pop(0) diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index 0258e9e..495d09e 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -41,6 +41,33 @@ 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): + return len(max(g.values(), key=len)) + + +def tabulate_dict(d): + max_len = get_max_dict_val_len(d) + _d = {} + for k, vl in d.items(): + if len(vl) != max_len: + _d[k] = vl + list([vl[-1]] * (max_len-1)) + else: + _d[k] = vl + + return _d + + +def flatten_tabulated_dict(d): + max_len = get_max_dict_val_len(d) + dl = [{} for i in range(max_len)] + + for k, vl in d.items(): + for v, i in zip(vl, list(range(len(vl)))): + dl[i][k] = v + + return dl + + def contains_type(_collection, type): return any(isinstance(x, type) for x in _collection) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 9ad579c..b67d04e 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,8 +3,9 @@ import numpy as np from datetime import timedelta import pprint -from SimCAD.configuration import append_configs -from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step, exo_update_per_ts +from SimCAD import configs +from SimCAD.configuration import Configuration +from SimCAD.configuration.utils import proc_trigger, ep_time_step, process_variables, exo_update_per_ts pp = pprint.PrettyPrinter(indent=4) @@ -15,57 +16,66 @@ seed = { 'c': np.random.RandomState(3) } + +g = { + 'alpha': [1], + 'beta': [2, 5], + 'gamma': [3, 4], + 'omega': [7] +} + + # beta = 1 # middleware(f1,f2,f3,f4) # Behaviors per Mechanism -def b1m1(step, sL, s): +def b1m1(_g, step, sL, s): return {'param1': 1} -def b2m1(step, sL, s): +def b2m1(_g, step, sL, s): return {'param2': 4} -def b1m2(_beta, step, sL, s): - return {'param1': 'a', 'param2': _beta} +def b1m2(_g, step, sL, s): + return {'param1': 'a', 'param2': _g['beta']} -def b2m2(step, sL, s): +def b2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 0} # @curried -def b1m3(step, sL, s): +def b1m3(_g, step, sL, s): return {'param1': np.array([10, 100])} # @curried -def b2m3(step, sL, s): +def b2m3(_g, step, sL, s): return {'param1': np.array([20, 200])} # Internal States per Mechanism # @curried -def s1m1(step, sL, s, _input): +def s1m1(_g, step, sL, s, _input): y = 's1' x = 0 return (y, x) -def s2m1(sweep_param, step, sL, s, _input): +def s2m1(_g, step, sL, s, _input): y = 's2' - x = sweep_param + x = _g['beta'] return (y, x) -def s1m2(step, sL, s, _input): +def s1m2(_g, step, sL, s, _input): y = 's1' x = _input['param2'] return (y, x) -def s2m2(step, sL, s, _input): +def s2m2(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) -def s1m3(step, sL, s, _input): +def s1m3(_g, step, sL, s, _input): y = 's1' x = 0 return (y, x) -def s2m3(step, sL, s, _input): +def s2m3(_g, step, sL, s, _input): y = 's2' x = 0 return (y, x) @@ -76,19 +86,19 @@ proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -def es3p1(param, step, sL, s, _input): +def es3p1(_g, step, sL, s, _input): y = 's3' - x = param + x = _g['gamma'] return (y, x) # @curried -def es4p2(param, step, sL, s, _input): +def es4p2(_g, step, sL, s, _input): y = 's4' - x = param + x = _g['gamma'] return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): +def es5p2(_g, step, sL, s, _input): y = 'timestamp' x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -174,18 +184,44 @@ mechanisms = { } } -sim_config = { - "N": 2, - "T": range(5), - "M": [Decimal(1), Decimal(2), Decimal(3)] # dict read from dict -} -append_configs( - sim_config=sim_config, - genesis_states=genesis_states, - seed=seed, - raw_exogenous_states=raw_exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms, - _exo_update_per_ts=True #Default -) \ No newline at end of file +# process_variables(g) +def gen_sim_configs(N, T, Ms): + return [ + { + "N": 2, + "T": range(5), + "M": M + } + for M in process_variables(Ms) + ] + + +sim_configs = gen_sim_configs( + N=2, + T=range(5), + Ms=g +) + + +for sim_config in sim_configs: + configs.append( + Configuration( + sim_config=sim_config, + state_dict=genesis_states, + seed=seed, + exogenous_states=raw_exogenous_states, # exo_update_per_ts + env_processes=env_processes, + mechanisms=mechanisms + ) + ) + +# append_configs( +# sim_config=sim_config, +# genesis_states=genesis_states, +# seed=seed, +# raw_exogenous_states=raw_exogenous_states, +# env_processes=env_processes, +# mechanisms=mechanisms, +# _exo_update_per_ts=True #Default +# ) \ No newline at end of file From 522d6dd34307cd6ddfc380c15f4c945c19791567 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 13 Feb 2019 08:16:58 -0500 Subject: [PATCH 26/38] param sweep full spec working pre-release --- SimCAD/configuration/__init__.py | 24 ++- SimCAD/configuration/utils/__init__.py | 6 +- SimCAD/configuration/utils/parameterSweep.py | 20 ++- SimCAD/engine/__init__.py | 6 +- simulations/validation/base_config1.py | 171 ------------------ simulations/validation/base_config2.py | 180 ------------------- simulations/validation/config1.py | 71 +++----- simulations/validation/config_1.py | 178 ------------------ simulations/validation/config_2.py | 180 ------------------- 9 files changed, 56 insertions(+), 780 deletions(-) delete mode 100644 simulations/validation/base_config1.py delete mode 100644 simulations/validation/base_config2.py delete mode 100644 simulations/validation/config_1.py delete mode 100644 simulations/validation/config_2.py diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index 248c9b0..bd5e063 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -10,7 +10,6 @@ from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum from SimCAD.configuration.utils import exo_update_per_ts - class Configuration(object): def __init__(self, sim_config=None, state_dict=None, seed=None, env_processes=None, exogenous_states=None, mechanisms=None, behavior_ops=[foldr(dict_elemwise_sum())]): @@ -23,30 +22,29 @@ class Configuration(object): self.behavior_ops = behavior_ops -def append_configs(sim_config, genesis_states, seed, raw_exogenous_states, env_processes, mechanisms, _exo_update_per_ts=True): - if 'M' in sim_config.keys(): +def append_configs(sim_configs, state_dict, seed, raw_exogenous_states, env_processes, mechanisms, _exo_update_per_ts=True): + if _exo_update_per_ts is True: + exogenous_states = exo_update_per_ts(raw_exogenous_states) + else: + exogenous_states = raw_exogenous_states - for mechanisms, exogenous_states in sim_config['M']: + if isinstance(sim_configs, list): + for sim_config in sim_configs: configs.append( Configuration( sim_config=sim_config, - state_dict=genesis_states, + state_dict=state_dict, seed=seed, exogenous_states=exogenous_states, env_processes=env_processes, mechanisms=mechanisms ) ) - else: - if _exo_update_per_ts is True: - exogenous_states = exo_update_per_ts(raw_exogenous_states) - else: - exogenous_states = raw_exogenous_states - + elif isinstance(sim_configs, dict): configs.append( Configuration( - sim_config=sim_config, - state_dict=genesis_states, + sim_config=sim_configs, + state_dict=state_dict, seed=seed, exogenous_states=exogenous_states, env_processes=env_processes, diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index c21f57c..68b68ab 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -113,14 +113,12 @@ def sweep_states(state_type, states, in_config): def exo_update_per_ts(ep): @curried - def ep_decorator(f, y, step, sL, s, _input): + def ep_decorator(f, y, var_dict, step, sL, s, _input): if s['mech_step'] + 1 == 1: - return curry_pot(f, step, sL, s, _input) + return f(var_dict, step, sL, s, _input) # curry_pot else: return y, s[y] return {es: ep_decorator(f, es) for es, f in ep.items()} -def process_variables(d): - return flatten_tabulated_dict(tabulate_dict(d)) \ No newline at end of file diff --git a/SimCAD/configuration/utils/parameterSweep.py b/SimCAD/configuration/utils/parameterSweep.py index 1c9815f..3801b5f 100644 --- a/SimCAD/configuration/utils/parameterSweep.py +++ b/SimCAD/configuration/utils/parameterSweep.py @@ -2,10 +2,28 @@ import inspect from copy import deepcopy from funcy import curry -from SimCAD.utils import rename +from SimCAD.utils import rename, flatten_tabulated_dict, tabulate_dict from SimCAD.configuration.utils import exo_update_per_ts +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: + return d + + class ParamSweep: def __init__(self, sweep_list, mechs=None, raw_exogenous_states=None, _exo_update_per_ts=True): self.sweep_list = sweep_list diff --git a/SimCAD/engine/__init__.py b/SimCAD/engine/__init__.py index 3a31be6..5c05c1b 100644 --- a/SimCAD/engine/__init__.py +++ b/SimCAD/engine/__init__.py @@ -51,10 +51,12 @@ class Executor: [], [], [], [], [], [], [], [], [] config_idx = 0 for x in self.configs: - var_dict_list.append(x.sim_config['M']) - states_lists.append([x.state_dict]) + Ts.append(x.sim_config['T']) Ns.append(x.sim_config['N']) + var_dict_list.append(x.sim_config['M']) + + states_lists.append([x.state_dict]) eps.append(list(x.exogenous_states.values())) configs_structs.append(config_proc.generate_config(x.state_dict, x.mechanisms, eps[config_idx])) env_processes_list.append(x.env_processes) diff --git a/simulations/validation/base_config1.py b/simulations/validation/base_config1.py deleted file mode 100644 index 3bf83ba..0000000 --- a/simulations/validation/base_config1.py +++ /dev/null @@ -1,171 +0,0 @@ -from decimal import Decimal -import numpy as np -from datetime import timedelta - -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step - -seed = { - 'z': np.random.RandomState(1), - 'a': np.random.RandomState(2), - 'b': np.random.RandomState(3), - 'c': np.random.RandomState(3) -} - -# Behaviors per Mechanism -# Different return types per mechanism ?? *** No *** -def b1m1(step, sL, s): - return {'param1': 1} -def b2m1(step, sL, s): - return {'param1': 1} - -def b1m2(step, sL, s): - return {'param1': 1, 'param2': 2} -def b2m2(step, sL, s): - return {'param1': 1, 'param2': 4} - -def b1m3(step, sL, s): - return {'param1': 1, 'param2': np.array([10, 100])} -def b2m3(step, sL, s): - return {'param1': 1, 'param2': np.array([20, 200])} - -# deff not more than 2 -# Internal States per Mechanism -def s1m1(step, sL, s, _input): - y = 's1' - x = s['s1'] + _input['param1'] - return (y, x) -def s2m1(step, sL, s, _input): - y = 's2' - x = s['s2'] + _input['param1'] - return (y, x) - -def s1m2(step, sL, s, _input): - y = 's1' - x = s['s1'] + _input['param1'] - return (y, x) -def s2m2(step, sL, s, _input): - y = 's2' - x = s['s2'] + _input['param1'] - return (y, x) - -def s1m3(step, sL, s, _input): - y = 's1' - x = s['s1'] + _input['param1'] - return (y, x) -def s2m3(step, sL, s, _input): - y = 's2' - x = s['s2'] + _input['param1'] - return (y, x) - -# Exogenous States -proc_one_coef_A = 0.7 -proc_one_coef_B = 1.3 - -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -def es4p2(step, sL, s, _input): - y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -ts_format = '%Y-%m-%d %H:%M:%S' -t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) - return (y, x) - - -# Environment States -def env_a(x): - return 10 -def env_b(x): - return 10 -# def what_ever(x): -# return x + 1 - -# Genesis States -genesis_states = { - 's1': Decimal(0.0), - 's2': Decimal(0.0), - 's3': Decimal(1.0), - 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' -} - -# remove `exo_update_per_ts` to update every ts -exogenous_states = exo_update_per_ts( - { - "s3": es3p1, - "s4": es4p2, - "timestamp": es5p2 - } -) - -# make env proc trigger field agnostic - -# ToDo: Bug - Can't use environments without proc_trigger. TypeError: 'int' object is not callable -# "/Users/jjodesty/Projects/DiffyQ-SimCAD/SimCAD/engine/simulation.py" -env_processes = { - # "s3": env_a, - # "s4": env_b - "s3": proc_trigger('2018-10-01 15:16:25', env_a), - "s4": proc_trigger('2018-10-01 15:16:25', env_b) -} - -# need at least 1 behaviour and 1 state function for the 1st mech with behaviors -# mechanisms = {} -mechanisms = { - "m1": { - "behaviors": { - "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, - "b2": b2m1 - }, - "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value - "s1": s1m1, - "s2": s2m1 - } - }, - "m2": { - "behaviors": { - "b1": b1m2, - "b2": b2m2 - }, - "states": { - "s1": s1m2, - "s2": s2m2 - } - }, - "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 - }, - "states": { - "s1": s1m3, - "s2": s2m3 - } - } -} - -sim_config = { - "N": 2, - "T": range(5) -} - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) -) \ No newline at end of file diff --git a/simulations/validation/base_config2.py b/simulations/validation/base_config2.py deleted file mode 100644 index 6b9469e..0000000 --- a/simulations/validation/base_config2.py +++ /dev/null @@ -1,180 +0,0 @@ -from decimal import Decimal -import numpy as np -from datetime import timedelta - -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step - - -seed = { - 'z': np.random.RandomState(1), - 'a': np.random.RandomState(2), - 'b': np.random.RandomState(3), - 'c': np.random.RandomState(3) -} - -# Behaviors per Mechanism -# Different return types per mechanism ?? *** No *** -def b1m1(step, sL, s): - return {'param1': 1} -def b2m1(step, sL, s): - return {'param2': 4} - -def b1m2(step, sL, s): - return {'param1': 'a', 'param2': 2} -def b2m2(step, sL, s): - return {'param1': 'b', 'param2': 4} - - -def b1m3(step, sL, s): - return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(step, sL, s): - return {'param1': ['d'], 'param2': np.array([20, 200])} - - -# Internal States per Mechanism -def s1m1(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m1(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m2(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m2(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m3(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m3(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -# Exogenous States -proc_one_coef_A = 0.7 -proc_one_coef_B = 1.3 - -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -def es4p2(step, sL, s, _input): - y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -ts_format = '%Y-%m-%d %H:%M:%S' -t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) - return (y, x) - - -# Environment States -def env_a(x): - return 10 -def env_b(x): - return 10 -# def what_ever(x): -# return x + 1 - -# Genesis States -genesis_states = { - 's1': Decimal(0.0), - 's2': Decimal(0.0), - 's3': Decimal(1.0), - 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' -} - -# remove `exo_update_per_ts` to update every ts -# why `exo_update_per_ts` here instead of `env_processes` -exogenous_states = exo_update_per_ts( - { - "s3": es3p1, - "s4": es4p2, - "timestamp": es5p2 - } -) - -# make env proc trigger field agnostic -env_processes = { - "s3": proc_trigger('2018-10-01 15:16:25', env_a), - "s4": proc_trigger('2018-10-01 15:16:25', env_b) -} - -# lambdas -# genesis Sites should always be there -# [1, 2] -# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] - - -# [1, 2] = {'b1': ['a'], 'b2', [1]} = -# behavior_ops = [behavior_to_dict, print_fwd, sum_dict_values] -# behavior_ops = [foldr(dict_elemwise_sum())] -# behavior_ops = [] - -# need at least 1 behaviour and 1 state function for the 1st mech with behaviors -# mechanisms = {} -mechanisms = { - "m1": { - "behaviors": { - "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, - # "b2": b2m1 - }, - "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value - "s1": s1m1, - # "s2": s2m1 - } - }, - "m2": { - "behaviors": { - "b1": b1m2, - # "b2": b2m2 - }, - "states": { - "s1": s1m2, - # "s2": s2m2 - } - }, - "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 - }, - "states": { - "s1": s1m3, - "s2": s2m3 - } - } -} - -sim_config = { - "N": 2, - "T": range(5) -} - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) -) \ No newline at end of file diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index b67d04e..e2d1880 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -3,9 +3,9 @@ import numpy as np from datetime import timedelta import pprint -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import proc_trigger, ep_time_step, process_variables, exo_update_per_ts +from SimCAD.configuration import append_configs +from SimCAD.configuration.utils import proc_trigger, ep_time_step +from SimCAD.configuration.utils.parameterSweep import config_sim pp = pprint.PrettyPrinter(indent=4) @@ -24,11 +24,6 @@ g = { 'omega': [7] } - -# beta = 1 - -# middleware(f1,f2,f3,f4) - # Behaviors per Mechanism def b1m1(_g, step, sL, s): return {'param1': 1} @@ -41,15 +36,14 @@ def b1m2(_g, step, sL, s): def b2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 0} -# @curried + def b1m3(_g, step, sL, s): return {'param1': np.array([10, 100])} -# @curried + def b2m3(_g, step, sL, s): return {'param1': np.array([20, 200])} # Internal States per Mechanism -# @curried def s1m1(_g, step, sL, s, _input): y = 's1' x = 0 @@ -126,7 +120,7 @@ genesis_states = { # remove `exo_update_per_ts` to update every ts raw_exogenous_states = { - "s3": es3p1, #es3p1, #sweep(beta, es3p1), + "s3": es3p1, "s4": es4p2, "timestamp": es5p2 } @@ -135,8 +129,6 @@ raw_exogenous_states = { # ToDo: make env proc trigger field agnostic # ToDo: input json into function renaming __name__ triggered_env_b = proc_trigger('2018-10-01 15:16:25', 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) @@ -185,43 +177,20 @@ mechanisms = { } -# process_variables(g) -def gen_sim_configs(N, T, Ms): - return [ - { - "N": 2, - "T": range(5), - "M": M - } - for M in process_variables(Ms) - ] - - -sim_configs = gen_sim_configs( - N=2, - T=range(5), - Ms=g +sim_config = config_sim( + { + "N": 2, + "T": range(5), + "M": g + } ) -for sim_config in sim_configs: - configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=raw_exogenous_states, # exo_update_per_ts - env_processes=env_processes, - mechanisms=mechanisms - ) - ) - -# append_configs( -# sim_config=sim_config, -# genesis_states=genesis_states, -# seed=seed, -# raw_exogenous_states=raw_exogenous_states, -# env_processes=env_processes, -# mechanisms=mechanisms, -# _exo_update_per_ts=True #Default -# ) \ No newline at end of file +append_configs( + sim_configs=sim_config, + state_dict=genesis_states, + seed=seed, + raw_exogenous_states=raw_exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms +) \ No newline at end of file diff --git a/simulations/validation/config_1.py b/simulations/validation/config_1.py deleted file mode 100644 index 7bdd5ac..0000000 --- a/simulations/validation/config_1.py +++ /dev/null @@ -1,178 +0,0 @@ -from decimal import Decimal -import numpy as np -from datetime import timedelta - -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step - -seed = { - 'z': np.random.RandomState(1), - 'a': np.random.RandomState(2), - 'b': np.random.RandomState(3), - 'c': np.random.RandomState(3) -} - -# Behaviors per Mechanism -# Different return types per mechanism ?? *** No *** -def b1m1(step, sL, s): - return {'param1': 1} -def b2m1(step, sL, s): - return {'param2': 4} - -def b1m2(step, sL, s): - return {'param1': 'a', 'param2': 2} -def b2m2(step, sL, s): - return {'param1': 'b', 'param2': 4} - -def b1m3(step, sL, s): - return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(step, sL, s): - return {'param1': ['d'], 'param2': np.array([20, 200])} - -# deff not more than 2 -# Internal States per Mechanism -def s1m1(step, sL, s, _input): - y = 's1' - x = _input['param1'] #+ [Coef1 x 5] - return (y, x) -def s2m1(step, sL, s, _input): - y = 's2' - x = _input['param2'] #+ [Coef2 x 5] - return (y, x) - -def s1m2(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m2(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m3(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m3(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -# Exogenous States -proc_one_coef_A = 0.7 -proc_one_coef_B = 1.3 - -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -def es4p2(step, sL, s, _input): - y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -ts_format = '%Y-%m-%d %H:%M:%S' -t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) - return (y, x) - - -# Environment States -def env_a(x): - return 5 -def env_b(x): - return 10 -# def what_ever(x): -# return x + 1 - -# Genesis States -genesis_states = { - 's1': Decimal(0.0), - 's2': Decimal(0.0), - 's3': Decimal(1.0), - 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' -} - -# remove `exo_update_per_ts` to update every ts -exogenous_states = exo_update_per_ts( - { - "s3": es3p1, - "s4": es4p2, - "timestamp": es5p2 - } -) - -# ToDo: make env proc trigger field agnostic -# ToDo: input json into function renaming __name__ -env_processes = { - "s3": env_a, - "s4": proc_trigger('2018-10-01 15:16:25', env_b) -} - -# lambdas -# genesis Sites should always be there -# [1, 2] -# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] - -# [1, 2] = {'b1': ['a'], 'b2', [1]} = -# behavior_ops = [ behavior_to_dict, print_fwd, sum_dict_values ] -# behavior_ops = [foldr(dict_elemwise_sum())] -# behavior_ops = [foldr(lambda a, b: a + b)] - -# need at least 1 behaviour and 1 state function for the 1st mech with behaviors -# mechanisms = {} - -mechanisms = { - "m1": { - "behaviors": { - "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, - "b2": b2m1 - }, - "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value - "s1": s1m1, - "s2": s2m1 - } - }, - "m2": { - "behaviors": { - "b1": b1m2, - "b2": b2m2 - }, - "states": { - "s1": s1m2, - "s2": s2m2 - } - }, - "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 - }, - "states": { - "s1": s1m3, - "s2": s2m3 - } - } -} - -sim_config = { - "N": 2, - "T": range(5) -} - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) -) \ No newline at end of file diff --git a/simulations/validation/config_2.py b/simulations/validation/config_2.py deleted file mode 100644 index 6b9469e..0000000 --- a/simulations/validation/config_2.py +++ /dev/null @@ -1,180 +0,0 @@ -from decimal import Decimal -import numpy as np -from datetime import timedelta - -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step - - -seed = { - 'z': np.random.RandomState(1), - 'a': np.random.RandomState(2), - 'b': np.random.RandomState(3), - 'c': np.random.RandomState(3) -} - -# Behaviors per Mechanism -# Different return types per mechanism ?? *** No *** -def b1m1(step, sL, s): - return {'param1': 1} -def b2m1(step, sL, s): - return {'param2': 4} - -def b1m2(step, sL, s): - return {'param1': 'a', 'param2': 2} -def b2m2(step, sL, s): - return {'param1': 'b', 'param2': 4} - - -def b1m3(step, sL, s): - return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(step, sL, s): - return {'param1': ['d'], 'param2': np.array([20, 200])} - - -# Internal States per Mechanism -def s1m1(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m1(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m2(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m2(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m3(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m3(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -# Exogenous States -proc_one_coef_A = 0.7 -proc_one_coef_B = 1.3 - -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -def es4p2(step, sL, s, _input): - y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -ts_format = '%Y-%m-%d %H:%M:%S' -t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) - return (y, x) - - -# Environment States -def env_a(x): - return 10 -def env_b(x): - return 10 -# def what_ever(x): -# return x + 1 - -# Genesis States -genesis_states = { - 's1': Decimal(0.0), - 's2': Decimal(0.0), - 's3': Decimal(1.0), - 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' -} - -# remove `exo_update_per_ts` to update every ts -# why `exo_update_per_ts` here instead of `env_processes` -exogenous_states = exo_update_per_ts( - { - "s3": es3p1, - "s4": es4p2, - "timestamp": es5p2 - } -) - -# make env proc trigger field agnostic -env_processes = { - "s3": proc_trigger('2018-10-01 15:16:25', env_a), - "s4": proc_trigger('2018-10-01 15:16:25', env_b) -} - -# lambdas -# genesis Sites should always be there -# [1, 2] -# behavior_ops = [ foldr(_ + _), lambda x: x + 0 ] - - -# [1, 2] = {'b1': ['a'], 'b2', [1]} = -# behavior_ops = [behavior_to_dict, print_fwd, sum_dict_values] -# behavior_ops = [foldr(dict_elemwise_sum())] -# behavior_ops = [] - -# need at least 1 behaviour and 1 state function for the 1st mech with behaviors -# mechanisms = {} -mechanisms = { - "m1": { - "behaviors": { - "b1": b1m1, # lambda step, sL, s: s['s1'] + 1, - # "b2": b2m1 - }, - "states": { # exclude only. TypeError: reduce() of empty sequence with no initial value - "s1": s1m1, - # "s2": s2m1 - } - }, - "m2": { - "behaviors": { - "b1": b1m2, - # "b2": b2m2 - }, - "states": { - "s1": s1m2, - # "s2": s2m2 - } - }, - "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 - }, - "states": { - "s1": s1m3, - "s2": s2m3 - } - } -} - -sim_config = { - "N": 2, - "T": range(5) -} - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) -) \ No newline at end of file From 368fcaa13dcde7186771843ccbfb065f34da5e75 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 13 Feb 2019 08:18:33 -0500 Subject: [PATCH 27/38] param sweep full spec working pre-release --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 289fd4b..825c846 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ SimCAD is written in Python 3. **1. Install Dependencies:** ```bash -pip install -r requirements.txt +pip3 install -r requirements.txt python3 setup.py sdist bdist_wheel -pip install dist/SimCAD-0.1-py3-none-any.whl +pip3 install dist/SimCAD-0.1-py3-none-any.whl ``` **2. Configure Simulation:** From e78bfa3c8a2c44ef130fbdce090908f8bbf6663a Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 13 Feb 2019 16:04:31 -0500 Subject: [PATCH 28/38] param sweep full spec: identity handling --- SimCAD/configuration/__init__.py | 8 +- SimCAD/configuration/utils/parameterSweep.py | 141 ------------------- 2 files changed, 4 insertions(+), 145 deletions(-) diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index bd5e063..ac79325 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -3,7 +3,7 @@ from fn.op import foldr import pandas as pd from SimCAD import configs -from SimCAD.configuration.utils.parameterSweep import ParamSweep +# from SimCAD.configuration.utils.parameterSweep import ParamSweep from SimCAD.utils import key_filter from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum @@ -57,17 +57,17 @@ class Identity: def __init__(self, behavior_id={'identity': 0}): self.beh_id_return_val = behavior_id - def b_identity(self, step, sL, s): + def b_identity(self, var_dict, step, sL, s): return self.beh_id_return_val def behavior_identity(self, k): return self.b_identity - def no_state_identity(self, step, sL, s, _input): + def no_state_identity(self, var_dict, step, sL, s, _input): return None def state_identity(self, k): - return lambda step, sL, s, _input: (k, s[k]) + return lambda var_dict, step, sL, s, _input: (k, s[k]) def apply_identity_funcs(self, identity, df, cols): def fillna_with_id_func(identity, df, col): diff --git a/SimCAD/configuration/utils/parameterSweep.py b/SimCAD/configuration/utils/parameterSweep.py index 3801b5f..eececd5 100644 --- a/SimCAD/configuration/utils/parameterSweep.py +++ b/SimCAD/configuration/utils/parameterSweep.py @@ -1,9 +1,4 @@ -import inspect -from copy import deepcopy -from funcy import curry - from SimCAD.utils import rename, flatten_tabulated_dict, tabulate_dict -from SimCAD.configuration.utils import exo_update_per_ts def process_variables(d): @@ -22,139 +17,3 @@ def config_sim(d): ] else: return d - - -class ParamSweep: - def __init__(self, sweep_list, mechs=None, raw_exogenous_states=None, _exo_update_per_ts=True): - self.sweep_list = sweep_list - self.mechs = mechs - self.raw_exogenous_states = raw_exogenous_states - self._exo_update_per_ts = _exo_update_per_ts - - def mechanisms(self): - swept_mechanisms = mech_sweep_identifier(self.sweep_list, self.mechs) - return parameterize_mechanism(swept_mechanisms) - - def exogenous_states(self): - swept_raw_exogenous_states = exo_sweep_identifier(self.sweep_list, self.raw_exogenous_states) - return parameterize_states(swept_raw_exogenous_states, self._exo_update_per_ts) - - -def sweep(params, sweep_f): - return [ - rename("sweep_"+sweep_f.__name__+"_"+str(i), curry(sweep_f)(param)) - for param, i in zip(params, range(len(params))) - ] - - -def mech_sweep_identifier(sweep_list, mechanisms): - new_mechanisms = deepcopy(mechanisms) - for mech, update_types in new_mechanisms.items(): - for update_type, fkv in update_types.items(): - for sk, current_f in fkv.items(): - current_f_arg_len = len(inspect.getfullargspec(current_f).args) - if update_type == 'behaviors' and current_f_arg_len == 4: - new_mechanisms[mech][update_type][sk] = sweep(sweep_list, current_f) - elif update_type == 'states' and current_f_arg_len == 5: - new_mechanisms[mech][update_type][sk] = sweep(sweep_list, current_f) - - del mechanisms - return new_mechanisms - - -def exo_sweep_identifier(sweep_list, exo_states): - new_exo_states = deepcopy(exo_states) - for sk, current_f in exo_states.items(): - current_f_arg_len = len(inspect.getfullargspec(current_f).args) - if current_f_arg_len == 5: - new_exo_states[sk] = sweep(sweep_list, current_f) - - del exo_states - return new_exo_states - - -def zip_sweep_functions(sweep_lists): - zipped_sweep_lists = [] - it = iter(sweep_lists) - the_len = len(next(it)) - same_len_ind = all(len(l) == the_len for l in it) - count_ind = len(sweep_lists) >= 2 - if same_len_ind is True and count_ind is True: - return list(map(lambda x: list(x), list(zip(*sweep_lists)))) - elif same_len_ind is False or count_ind is False: - return sweep_lists - else: - raise ValueError('lists have different lengths!') - - -# ToDo: Not producing multiple dicts. -def create_sweep_config_list(zipped_sweep_lists, states_dict, state_type_ind='mechs'): - configs = [] - for f_lists in zipped_sweep_lists: - new_states_dict = deepcopy(states_dict) - for f_dict in f_lists: - if state_type_ind == 'mechs': - updates = list(f_dict.values()).pop() - functs = list(updates.values()).pop() - - mech = list(f_dict.keys()).pop() - update_type = list(updates.keys()).pop() - sk = list(functs.keys()).pop() - vf = list(functs.values()).pop() - - new_states_dict[mech][update_type][sk] = vf - elif state_type_ind == 'exo_proc': - sk = list(f_dict.keys()).pop() - vf = list(f_dict.values()).pop() - - new_states_dict[sk] = vf - else: - raise ValueError("Incorrect \'state_type_ind\'") - - configs.append(new_states_dict) - del new_states_dict - - return configs - - -def parameterize_states(exo_states, _exo_update_per_ts): - sweep_lists = [] - for sk, vfs in exo_states.items(): - id_sweep_lists = [] - if isinstance(vfs, list): - for vf in vfs: - id_sweep_lists.append({sk: vf}) - if len(id_sweep_lists) != 0: - sweep_lists.append(id_sweep_lists) - - def comp_exo_update(states_configs): - return [exo_update_per_ts(x) if _exo_update_per_ts is True else x for x in states_configs] - - sweep_lists_len = len(sweep_lists) - if sweep_lists_len != 0: - zipped_sweep_lists = zip_sweep_functions(sweep_lists) - states_configs = create_sweep_config_list(zipped_sweep_lists, exo_states, "exo_proc") - return comp_exo_update(states_configs) - elif sweep_lists_len == 0: - return comp_exo_update([exo_states]) - - -def parameterize_mechanism(mechanisms): - sweep_lists = [] - for mech, update_types in mechanisms.items(): - for update_type, fkv in update_types.items(): - for sk, vfs in fkv.items(): - id_sweep_lists = [] - if isinstance(vfs, list): - for vf in vfs: - id_sweep_lists.append({mech: {update_type: {sk: vf}}}) - if len(id_sweep_lists) != 0: - sweep_lists.append(id_sweep_lists) - - if len(sweep_lists) == 0: - return [mechanisms] - - zipped_sweep_lists = zip_sweep_functions(sweep_lists) - mechanisms_configs = create_sweep_config_list(zipped_sweep_lists, mechanisms, "mechs") - - return mechanisms_configs From e73113754fa2710f1bb131c96275fbced6ab1e6b Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Wed, 13 Feb 2019 16:50:04 -0500 Subject: [PATCH 29/38] misc --- SimCAD/configuration/__init__.py | 2 -- SimCAD/configuration/utils/__init__.py | 8 +++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index ac79325..018a4d7 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -3,8 +3,6 @@ from fn.op import foldr import pandas as pd from SimCAD import configs -# from SimCAD.configuration.utils.parameterSweep import ParamSweep - from SimCAD.utils import key_filter from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum from SimCAD.configuration.utils import exo_update_per_ts diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 68b68ab..797d0da 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -4,10 +4,8 @@ from copy import deepcopy from fn.func import curried import pandas as pd -from SimCAD.utils import dict_filter, contains_type, flatten_tabulated_dict, tabulate_dict, curry_pot +from SimCAD.utils import dict_filter, contains_type -# import pprint -# pp = pprint.PrettyPrinter(indent=4) class TensorFieldReport: def __init__(self, config_proc): @@ -45,14 +43,14 @@ def proc_trigger(trigger_step, update_f, step): return lambda x: x -t_delta = timedelta(days=0, minutes=0, seconds=30) +step_t_delta = timedelta(days=0, minutes=0, seconds=30) def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = t_delta): dt = datetime.strptime(dt_str, dt_format) t = dt + _timedelta return t.strftime(dt_format) -t_delta = timedelta(days=0, minutes=0, seconds=1) +ep_t_delta = timedelta(days=0, minutes=0, seconds=1) def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = t_delta): if s['mech_step'] == 0: return time_step(dt_str, fromat_str, _timedelta) From 20d7d620b7f2f12db6492e91bb3074b165784cae Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 09:30:33 -0500 Subject: [PATCH 30/38] misc --- SimCAD/configuration/utils/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 797d0da..f5334d5 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -44,14 +44,14 @@ def proc_trigger(trigger_step, update_f, step): step_t_delta = timedelta(days=0, minutes=0, seconds=30) -def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = t_delta): +def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = step_t_delta): dt = datetime.strptime(dt_str, dt_format) t = dt + _timedelta return t.strftime(dt_format) ep_t_delta = timedelta(days=0, minutes=0, seconds=1) -def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = t_delta): +def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = ep_t_delta): if s['mech_step'] == 0: return time_step(dt_str, fromat_str, _timedelta) else: @@ -118,5 +118,3 @@ def exo_update_per_ts(ep): return y, s[y] return {es: ep_decorator(f, es) for es, f in ep.items()} - - From df4b7ce747e65f867ae03c11a86f735fce552802 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 09:33:10 -0500 Subject: [PATCH 31/38] rename config: sweep_config --- simulations/example_run.py | 3 +- simulations/validation/config2.py | 171 ------------------ .../{config1.py => sweep_config.py} | 0 3 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 simulations/validation/config2.py rename simulations/validation/{config1.py => sweep_config.py} (100%) diff --git a/simulations/example_run.py b/simulations/example_run.py index f017646..fa1292f 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -1,9 +1,8 @@ import pandas as pd from tabulate import tabulate -from importlib import reload # The following imports NEED to be in the exact order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from simulations.validation import config1 #, config2 +from simulations.validation import sweep_config from SimCAD import configs diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py deleted file mode 100644 index 703dace..0000000 --- a/simulations/validation/config2.py +++ /dev/null @@ -1,171 +0,0 @@ -from decimal import Decimal -import numpy as np -from datetime import timedelta - -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step - - -seed = { - 'z': np.random.RandomState(1), - 'a': np.random.RandomState(2), - 'b': np.random.RandomState(3), - 'c': np.random.RandomState(3) -} - - -# Behaviors per Mechanism -def b1m1(step, sL, s): - return {'param1': 1} -def b2m1(step, sL, s): - return {'param2': 4} - -def b1m2(step, sL, s): - return {'param1': 'a', 'param2': 2} -def b2m2(step, sL, s): - return {'param1': 'b', 'param2': 4} - -def b1m3(step, sL, s): - return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(step, sL, s): - return {'param1': ['d'], 'param2': np.array([20, 200])} - - -# Internal States per Mechanism -def s1m1(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m1(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m2(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m2(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - -def s1m3(step, sL, s, _input): - y = 's1' - x = _input['param1'] - return (y, x) -def s2m3(step, sL, s, _input): - y = 's2' - x = _input['param2'] - return (y, x) - - -# Exogenous States -proc_one_coef_A = 0.7 -proc_one_coef_B = 1.3 - -def es3p1(step, sL, s, _input): - y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -def es4p2(step, sL, s, _input): - y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) - return (y, x) - -ts_format = '%Y-%m-%d %H:%M:%S' -t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) - return (y, x) - - -# Environment States -def env_a(x): - return 10 -def env_b(x): - return 10 -# def what_ever(x): -# return x + 1 - - -# Genesis States -genesis_states = { - 's1': Decimal(0.0), - 's2': Decimal(0.0), - 's3': Decimal(1.0), - 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' -} - - -# remove `exo_update_per_ts` to update every ts -exogenous_states = exo_update_per_ts( - { - "s3": es3p1, - "s4": es4p2, - "timestamp": es5p2 - } -) - - -env_processes = { - "s3": proc_trigger('2018-10-01 15:16:25', env_a), - "s4": proc_trigger('2018-10-01 15:16:25', env_b) -} - - -mechanisms = { - "m1": { - "behaviors": { - "b1": b1m1, - # "b2": b2m1 - }, - "states": { - "s1": s1m1, - # "s2": s2m1 - } - }, - "m2": { - "behaviors": { - "b1": b1m2, - # "b2": b2m2 - }, - "states": { - "s1": s1m2, - # "s2": s2m2 - } - }, - "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 - }, - "states": { - "s1": s1m3, - "s2": s2m3 - } - } -} - - -sim_config = { - "N": 2, - "T": range(5) -} - - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) -) diff --git a/simulations/validation/config1.py b/simulations/validation/sweep_config.py similarity index 100% rename from simulations/validation/config1.py rename to simulations/validation/sweep_config.py From 11d7ba7cf148dd837e55d3fcd485ee8fad0c7130 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 10:17:28 -0500 Subject: [PATCH 32/38] restore test --- simulations/validation/config1.py | 2 +- simulations/validation/config2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index a016842..8b1d28a 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -1,6 +1,6 @@ from decimal import Decimal import numpy as np -from datetime import timedelta +from datetime import timedelta # from SimCAD import configs from SimCAD.configuration import Configuration diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py index 703dace..829b7a8 100644 --- a/simulations/validation/config2.py +++ b/simulations/validation/config2.py @@ -1,6 +1,6 @@ from decimal import Decimal import numpy as np -from datetime import timedelta +from datetime import timedelta # from SimCAD import configs from SimCAD.configuration import Configuration From 8d56cf2939885b1ef1fe53c15acee5523f10e51e Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 10:18:31 -0500 Subject: [PATCH 33/38] restore test2 --- simulations/validation/config1.py | 2 +- simulations/validation/config2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index 8b1d28a..a016842 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -1,6 +1,6 @@ from decimal import Decimal import numpy as np -from datetime import timedelta # +from datetime import timedelta from SimCAD import configs from SimCAD.configuration import Configuration diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py index 829b7a8..703dace 100644 --- a/simulations/validation/config2.py +++ b/simulations/validation/config2.py @@ -1,6 +1,6 @@ from decimal import Decimal import numpy as np -from datetime import timedelta # +from datetime import timedelta from SimCAD import configs from SimCAD.configuration import Configuration From ed2f31cffc7012e63a3c81fb08a0f80fd26d52d3 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 10:29:45 -0500 Subject: [PATCH 34/38] merge heaven: working --- SimCAD/configuration/utils/parameterSweep.py | 1 + SimCAD/engine/__init__.py | 1 - simulations/example_run.py | 2 +- simulations/validation/config1.py | 74 +++++++++---------- simulations/validation/config2.py | 75 +++++++++----------- 5 files changed, 72 insertions(+), 81 deletions(-) diff --git a/SimCAD/configuration/utils/parameterSweep.py b/SimCAD/configuration/utils/parameterSweep.py index 1260da0..7d5024c 100644 --- a/SimCAD/configuration/utils/parameterSweep.py +++ b/SimCAD/configuration/utils/parameterSweep.py @@ -16,4 +16,5 @@ def config_sim(d): for M in process_variables(d["M"]) ] else: + d["M"] = [{}] return d diff --git a/SimCAD/engine/__init__.py b/SimCAD/engine/__init__.py index 5c05c1b..33fb8ef 100644 --- a/SimCAD/engine/__init__.py +++ b/SimCAD/engine/__init__.py @@ -55,7 +55,6 @@ class Executor: Ts.append(x.sim_config['T']) Ns.append(x.sim_config['N']) var_dict_list.append(x.sim_config['M']) - states_lists.append([x.state_dict]) eps.append(list(x.exogenous_states.values())) configs_structs.append(config_proc.generate_config(x.state_dict, x.mechanisms, eps[config_idx])) diff --git a/simulations/example_run.py b/simulations/example_run.py index cf2bba9..8b265aa 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -2,7 +2,7 @@ import pandas as pd from tabulate import tabulate # The following imports NEED to be in the exact order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from simulations.validation import sweep_config +from simulations.validation import config1, config2 # sweep_config from SimCAD import configs exec_mode = ExecutionMode() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index a016842..f1bfe70 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -2,10 +2,9 @@ from decimal import Decimal import numpy as np from datetime import timedelta -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step +from SimCAD.configuration import append_configs +from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step +from SimCAD.configuration.utils.parameterSweep import config_sim seed = { @@ -17,46 +16,46 @@ seed = { # Behaviors per Mechanism -def b1m1(step, sL, s): +def b1m1(_g, step, sL, s): return {'param1': 1} -def b2m1(step, sL, s): +def b2m1(_g, step, sL, s): return {'param2': 4} -def b1m2(step, sL, s): +def b1m2(_g, step, sL, s): return {'param1': 'a', 'param2': 2} -def b2m2(step, sL, s): +def b2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 4} -def b1m3(step, sL, s): +def b1m3(_g, step, sL, s): return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(step, sL, s): +def b2m3(_g, step, sL, s): return {'param1': ['d'], 'param2': np.array([20, 200])} # Internal States per Mechanism -def s1m1(step, sL, s, _input): +def s1m1(_g, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) -def s2m1(step, sL, s, _input): +def s2m1(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) -def s1m2(step, sL, s, _input): +def s1m2(_g, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) -def s2m2(step, sL, s, _input): +def s2m2(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) -def s1m3(step, sL, s, _input): +def s1m3(_g, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) -def s2m3(step, sL, s, _input): +def s2m3(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) @@ -66,19 +65,19 @@ def s2m3(step, sL, s, _input): proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -def es3p1(step, sL, s, _input): +def es3p1(_g, step, sL, s, _input): y = 's3' x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) return (y, x) -def es4p2(step, sL, s, _input): +def es4p2(_g, step, sL, s, _input): y = 's4' x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): +def es5p2(_g, step, sL, s, _input): y = 'timestamp' x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -103,14 +102,11 @@ genesis_states = { } -# remove `exo_update_per_ts` to update every ts -exogenous_states = exo_update_per_ts( - { +raw_exogenous_states = { "s3": es3p1, "s4": es4p2, "timestamp": es5p2 - } -) +} env_processes = { @@ -153,19 +149,19 @@ mechanisms = { } -sim_config = { - "N": 2, - "T": range(5) -} - - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) +sim_config = config_sim( + { + "N": 2, + "T": range(5), + } +) + + +append_configs( + sim_configs=sim_config, + state_dict=genesis_states, + seed=seed, + raw_exogenous_states=raw_exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms ) diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py index 703dace..98705e6 100644 --- a/simulations/validation/config2.py +++ b/simulations/validation/config2.py @@ -2,11 +2,9 @@ from decimal import Decimal import numpy as np from datetime import timedelta -from SimCAD import configs -from SimCAD.configuration import Configuration -from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ - ep_time_step - +from SimCAD.configuration import append_configs +from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step +from SimCAD.configuration.utils.parameterSweep import config_sim seed = { 'z': np.random.RandomState(1), @@ -17,46 +15,46 @@ seed = { # Behaviors per Mechanism -def b1m1(step, sL, s): +def b1m1(_g, step, sL, s): return {'param1': 1} -def b2m1(step, sL, s): +def b2m1(_g, step, sL, s): return {'param2': 4} -def b1m2(step, sL, s): +def b1m2(_g, step, sL, s): return {'param1': 'a', 'param2': 2} -def b2m2(step, sL, s): +def b2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 4} -def b1m3(step, sL, s): +def b1m3(_g, step, sL, s): return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(step, sL, s): +def b2m3(_g, step, sL, s): return {'param1': ['d'], 'param2': np.array([20, 200])} # Internal States per Mechanism -def s1m1(step, sL, s, _input): +def s1m1(_g, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) -def s2m1(step, sL, s, _input): +def s2m1(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) -def s1m2(step, sL, s, _input): +def s1m2(_g, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) -def s2m2(step, sL, s, _input): +def s2m2(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) -def s1m3(step, sL, s, _input): +def s1m3(_g, step, sL, s, _input): y = 's1' x = _input['param1'] return (y, x) -def s2m3(step, sL, s, _input): +def s2m3(_g, step, sL, s, _input): y = 's2' x = _input['param2'] return (y, x) @@ -66,19 +64,19 @@ def s2m3(step, sL, s, _input): proc_one_coef_A = 0.7 proc_one_coef_B = 1.3 -def es3p1(step, sL, s, _input): +def es3p1(_g, step, sL, s, _input): y = 's3' x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) return (y, x) -def es4p2(step, sL, s, _input): +def es4p2(_g, step, sL, s, _input): y = 's4' x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) -def es5p2(step, sL, s, _input): +def es5p2(_g, step, sL, s, _input): y = 'timestamp' x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -103,14 +101,11 @@ genesis_states = { } -# remove `exo_update_per_ts` to update every ts -exogenous_states = exo_update_per_ts( - { +raw_exogenous_states = { "s3": es3p1, "s4": es4p2, "timestamp": es5p2 - } -) +} env_processes = { @@ -153,19 +148,19 @@ mechanisms = { } -sim_config = { - "N": 2, - "T": range(5) -} - - -configs.append( - Configuration( - sim_config=sim_config, - state_dict=genesis_states, - seed=seed, - exogenous_states=exogenous_states, - env_processes=env_processes, - mechanisms=mechanisms - ) +sim_config = config_sim( + { + "N": 2, + "T": range(5), + } +) + + +append_configs( + sim_configs=sim_config, + state_dict=genesis_states, + seed=seed, + raw_exogenous_states=raw_exogenous_states, + env_processes=env_processes, + mechanisms=mechanisms ) From 06367f0573a098e6692c8cb07c17668fb426d132 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 10:34:05 -0500 Subject: [PATCH 35/38] backwards merge --- simulations/example_run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simulations/example_run.py b/simulations/example_run.py index 8b265aa..b179e49 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -2,7 +2,7 @@ import pandas as pd from tabulate import tabulate # The following imports NEED to be in the exact order from SimCAD.engine import ExecutionMode, ExecutionContext, Executor -from simulations.validation import config1, config2 # sweep_config +from simulations.validation import sweep_config, config1, config2 from SimCAD import configs exec_mode = ExecutionMode() From 76fb4525083c64a7ab4f39324b1f0c2072f759fd Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 15:27:51 -0500 Subject: [PATCH 36/38] renaming --- SimCAD/configuration/__init__.py | 72 +++++++++---------- SimCAD/configuration/utils/__init__.py | 38 +++++----- ...iorAggregation.py => policyAggregation.py} | 2 +- SimCAD/engine/__init__.py | 16 ++--- SimCAD/engine/simulation.py | 59 ++++++++------- SimCAD/engine/utils.py | 4 +- SimCAD/utils/__init__.py | 9 ++- simulations/validation/config1.py | 46 ++++++------ simulations/validation/config2.py | 46 ++++++------ simulations/validation/sweep_config.py | 42 +++++------ 10 files changed, 170 insertions(+), 164 deletions(-) rename SimCAD/configuration/utils/{behaviorAggregation.py => policyAggregation.py} (97%) diff --git a/SimCAD/configuration/__init__.py b/SimCAD/configuration/__init__.py index 018a4d7..1440b54 100644 --- a/SimCAD/configuration/__init__.py +++ b/SimCAD/configuration/__init__.py @@ -4,23 +4,23 @@ import pandas as pd from SimCAD import configs from SimCAD.utils import key_filter -from SimCAD.configuration.utils.behaviorAggregation import dict_elemwise_sum +from SimCAD.configuration.utils.policyAggregation import dict_elemwise_sum from SimCAD.configuration.utils import exo_update_per_ts class Configuration(object): - def __init__(self, sim_config=None, state_dict=None, seed=None, env_processes=None, - exogenous_states=None, mechanisms=None, behavior_ops=[foldr(dict_elemwise_sum())]): + def __init__(self, sim_config=None, initial_state=None, seeds=None, env_processes=None, + exogenous_states=None, partial_state_updates=None, policy_ops=[foldr(dict_elemwise_sum())]): self.sim_config = sim_config - self.state_dict = state_dict - self.seed = seed + self.initial_state = initial_state + self.seeds = seeds self.env_processes = env_processes self.exogenous_states = exogenous_states - self.mechanisms = mechanisms - self.behavior_ops = behavior_ops + self.partial_state_updates = partial_state_updates + self.policy_ops = policy_ops -def append_configs(sim_configs, state_dict, seed, raw_exogenous_states, env_processes, mechanisms, _exo_update_per_ts=True): +def append_configs(sim_configs, initial_state, seeds, raw_exogenous_states, env_processes, partial_state_updates, _exo_update_per_ts=True): if _exo_update_per_ts is True: exogenous_states = exo_update_per_ts(raw_exogenous_states) else: @@ -31,41 +31,41 @@ def append_configs(sim_configs, state_dict, seed, raw_exogenous_states, env_proc configs.append( Configuration( sim_config=sim_config, - state_dict=state_dict, - seed=seed, + initial_state=initial_state, + seeds=seeds, exogenous_states=exogenous_states, env_processes=env_processes, - mechanisms=mechanisms + partial_state_updates=partial_state_updates ) ) elif isinstance(sim_configs, dict): configs.append( Configuration( sim_config=sim_configs, - state_dict=state_dict, - seed=seed, + initial_state=initial_state, + seeds=seeds, exogenous_states=exogenous_states, env_processes=env_processes, - mechanisms=mechanisms + partial_state_updates=partial_state_updates ) ) class Identity: - def __init__(self, behavior_id={'identity': 0}): - self.beh_id_return_val = behavior_id + def __init__(self, policy_id={'identity': 0}): + self.beh_id_return_val = policy_id - def b_identity(self, var_dict, step, sL, s): + def p_identity(self, var_dict, sub_step, sL, s): return self.beh_id_return_val - def behavior_identity(self, k): - return self.b_identity + def policy_identity(self, k): + return self.p_identity - def no_state_identity(self, var_dict, step, sL, s, _input): + def no_state_identity(self, var_dict, sub_step, sL, s, _input): return None def state_identity(self, k): - return lambda var_dict, step, sL, s, _input: (k, s[k]) + return lambda var_dict, sub_step, sL, s, _input: (k, s[k]) def apply_identity_funcs(self, identity, df, cols): def fillna_with_id_func(identity, df, col): @@ -77,34 +77,34 @@ class Identity: class Processor: def __init__(self, id=Identity()): self.id = id - self.b_identity = id.b_identity - self.behavior_identity = id.behavior_identity + self.p_identity = id.p_identity + self.policy_identity = id.policy_identity self.no_state_identity = id.no_state_identity self.state_identity = id.state_identity self.apply_identity_funcs = id.apply_identity_funcs - def create_matrix_field(self, mechanisms, key): + def create_matrix_field(self, partial_state_updates, key): if key == 'states': identity = self.state_identity - elif key == 'behaviors': - identity = self.behavior_identity - df = pd.DataFrame(key_filter(mechanisms, key)) + elif key == 'policies': + identity = self.policy_identity + df = pd.DataFrame(key_filter(partial_state_updates, key)) col_list = self.apply_identity_funcs(identity, df, list(df.columns)) if len(col_list) != 0: return reduce((lambda x, y: pd.concat([x, y], axis=1)), col_list) else: return pd.DataFrame({'empty': []}) - def generate_config(self, state_dict, mechanisms, exo_proc): + def generate_config(self, initial_state, partial_state_updates, exo_proc): def no_update_handler(bdf, sdf): if (bdf.empty == False) and (sdf.empty == True): bdf_values = bdf.values.tolist() - sdf_values = [[self.no_state_identity] * len(bdf_values) for m in range(len(mechanisms))] + sdf_values = [[self.no_state_identity] * len(bdf_values) for m in range(len(partial_state_updates))] return sdf_values, bdf_values elif (bdf.empty == True) and (sdf.empty == False): sdf_values = sdf.values.tolist() - bdf_values = [[self.b_identity] * len(sdf_values) for m in range(len(mechanisms))] + bdf_values = [[self.b_identity] * len(sdf_values) for m in range(len(partial_state_updates))] return sdf_values, bdf_values else: sdf_values = sdf.values.tolist() @@ -113,19 +113,19 @@ class Processor: def only_ep_handler(state_dict): sdf_functions = [ - lambda step, sL, s, _input: (k, v) for k, v in zip(state_dict.keys(), state_dict.values()) + lambda sub_step, sL, s, _input: (k, v) for k, v in zip(state_dict.keys(), state_dict.values()) ] sdf_values = [sdf_functions] - bdf_values = [[self.b_identity] * len(sdf_values)] + bdf_values = [[self.p_identity] * len(sdf_values)] return sdf_values, bdf_values - if len(mechanisms) != 0: - bdf = self.create_matrix_field(mechanisms, 'behaviors') - sdf = self.create_matrix_field(mechanisms, 'states') + if len(partial_state_updates) != 0: + bdf = self.create_matrix_field(partial_state_updates, 'policies') + sdf = self.create_matrix_field(partial_state_updates, 'states') sdf_values, bdf_values = no_update_handler(bdf, sdf) zipped_list = list(zip(sdf_values, bdf_values)) else: - sdf_values, bdf_values = only_ep_handler(state_dict) + sdf_values, bdf_values = only_ep_handler(initial_state) zipped_list = list(zip(sdf_values, bdf_values)) return list(map(lambda x: (x[0] + exo_proc, x[1]), zipped_list)) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index f5334d5..814efcf 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -11,8 +11,8 @@ class TensorFieldReport: def __init__(self, config_proc): self.config_proc = config_proc - def create_tensor_field(self, mechanisms, exo_proc, keys=['behaviors', 'states']): - dfs = [self.config_proc.create_matrix_field(mechanisms, k) for k in keys] + def create_tensor_field(self, partial_state_updates, exo_proc, keys=['policies', 'states']): + dfs = [self.config_proc.create_matrix_field(partial_state_updates, k) for k in keys] df = pd.concat(dfs, axis=1) for es, i in zip(exo_proc, range(len(exo_proc))): df['es' + str(i + 1)] = es @@ -25,7 +25,7 @@ class TensorFieldReport: # # def state_update(y, x): - return lambda step, sL, s, _input: (y, x) + return lambda sub_step, sL, s, _input: (y, x) def bound_norm_random(rng, low, high): @@ -36,15 +36,15 @@ def bound_norm_random(rng, low, high): @curried -def proc_trigger(trigger_step, update_f, step): - if step == trigger_step: +def proc_trigger(trigger_time, update_f, time): + if time == trigger_time: return update_f else: return lambda x: x -step_t_delta = timedelta(days=0, minutes=0, seconds=30) -def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = step_t_delta): +tstep_delta = timedelta(days=0, minutes=0, seconds=30) +def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = tstep_delta): dt = datetime.strptime(dt_str, dt_format) t = dt + _timedelta return t.strftime(dt_format) @@ -57,11 +57,11 @@ def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = ep_t_de else: return dt_str - -def mech_sweep_filter(mech_field, mechanisms): - mech_dict = dict([(k, v[mech_field]) for k, v in mechanisms.items()]) +# mech_sweep_filter +def partial_state_sweep_filter(state_field, partial_state_updates): + partial_state_dict = dict([(k, v[state_field]) for k, v in partial_state_updates.items()]) return dict([ - (k, dict_filter(v, lambda v: isinstance(v, list))) for k, v in mech_dict.items() + (k, dict_filter(v, lambda v: isinstance(v, list))) for k, v in partial_state_dict.items() if contains_type(list(v.values()), list) ]) @@ -69,16 +69,18 @@ def mech_sweep_filter(mech_field, mechanisms): def state_sweep_filter(raw_exogenous_states): return dict([(k, v) for k, v in raw_exogenous_states.items() if isinstance(v, list)]) +# sweep_mech_states @curried -def sweep_mechs(_type, in_config): +def sweep_partial_states(_type, in_config): configs = [] - filtered_mech_states = mech_sweep_filter(_type, in_config.mechanisms) - if len(filtered_mech_states) > 0: - for mech, state_dict in filtered_mech_states.items(): + # filtered_mech_states + filtered_partial_states = partial_state_sweep_filter(_type, in_config.partial_state_updates) + if len(filtered_partial_states) > 0: + for partial_state, state_dict in filtered_partial_states.items(): for state, state_funcs in state_dict.items(): for f in state_funcs: config = deepcopy(in_config) - config.mechanisms[mech][_type][state] = f + config.partial_state_updates[partial_state][_type][state] = f configs.append(config) del config else: @@ -111,9 +113,9 @@ def sweep_states(state_type, states, in_config): def exo_update_per_ts(ep): @curried - def ep_decorator(f, y, var_dict, step, sL, s, _input): + def ep_decorator(f, y, var_dict, sub_step, sL, s, _input): if s['mech_step'] + 1 == 1: - return f(var_dict, step, sL, s, _input) # curry_pot + return f(var_dict, sub_step, sL, s, _input) else: return y, s[y] diff --git a/SimCAD/configuration/utils/behaviorAggregation.py b/SimCAD/configuration/utils/policyAggregation.py similarity index 97% rename from SimCAD/configuration/utils/behaviorAggregation.py rename to SimCAD/configuration/utils/policyAggregation.py index a16f5e1..eac845d 100644 --- a/SimCAD/configuration/utils/behaviorAggregation.py +++ b/SimCAD/configuration/utils/policyAggregation.py @@ -13,7 +13,7 @@ def get_base_value(x): return 0 -def behavior_to_dict(v): +def policy_to_dict(v): return dict(list(zip(map(lambda n: 'b' + str(n + 1), list(range(len(v)))), v))) diff --git a/SimCAD/engine/__init__.py b/SimCAD/engine/__init__.py index 33fb8ef..139d126 100644 --- a/SimCAD/engine/__init__.py +++ b/SimCAD/engine/__init__.py @@ -47,7 +47,7 @@ class Executor: create_tensor_field = TensorFieldReport(config_proc).create_tensor_field print(self.exec_context+": "+str(self.configs)) - var_dict_list, states_lists, Ts, Ns, eps, configs_structs, env_processes_list, mechanisms, simulation_execs = \ + var_dict_list, states_lists, Ts, Ns, eps, configs_structs, env_processes_list, partial_state_updates, simulation_execs = \ [], [], [], [], [], [], [], [], [] config_idx = 0 for x in self.configs: @@ -55,24 +55,24 @@ class Executor: Ts.append(x.sim_config['T']) Ns.append(x.sim_config['N']) var_dict_list.append(x.sim_config['M']) - states_lists.append([x.state_dict]) + states_lists.append([x.initial_state]) eps.append(list(x.exogenous_states.values())) - configs_structs.append(config_proc.generate_config(x.state_dict, x.mechanisms, eps[config_idx])) + configs_structs.append(config_proc.generate_config(x.initial_state, x.partial_state_updates, eps[config_idx])) env_processes_list.append(x.env_processes) - mechanisms.append(x.mechanisms) - simulation_execs.append(SimExecutor(x.behavior_ops).simulation) + partial_state_updates.append(x.partial_state_updates) + simulation_execs.append(SimExecutor(x.policy_ops).simulation) config_idx += 1 if self.exec_context == ExecutionMode.single_proc: - tensor_field = create_tensor_field(mechanisms.pop(), eps.pop()) + tensor_field = create_tensor_field(partial_state_updates.pop(), eps.pop()) result = self.exec_method(simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, Ns) return result, tensor_field elif self.exec_context == ExecutionMode.multi_proc: if len(self.configs) > 1: simulations = self.exec_method(simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, Ns) results = [] - for result, mechanism, ep in list(zip(simulations, mechanisms, eps)): - results.append((flatten(result), create_tensor_field(mechanism, ep))) + for result, partial_state_updates, ep in list(zip(simulations, partial_state_updates, eps)): + results.append((flatten(result), create_tensor_field(partial_state_updates, ep))) return results diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 759e7ce..288af7e 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -7,41 +7,39 @@ id_exception = engine_exception(KeyError, KeyError, None) class Executor: - def __init__(self, behavior_ops, behavior_update_exception=id_exception, state_update_exception=id_exception): - self.behavior_ops = behavior_ops + 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.behavior_update_exception = behavior_update_exception + self.policy_update_exception = policy_update_exception # behavior_update_exception - def get_behavior_input(self, var_dict, step, sL, s, funcs): - ops = self.behavior_ops[::-1] + # 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, step, sL, s, funcs): - # return list(map(lambda f: curry_pot(f, step, sL, s), funcs)) - return list(map(lambda f: f(var_dict, step, sL, s), funcs)) + def get_col_results(var_dict, sub_step, sL, s, funcs): + return list(map(lambda f: f(var_dict, sub_step, sL, s), funcs)) - # print(get_col_results(step, sL, s, funcs)) - return foldr(call, get_col_results(var_dict, step, sL, s, funcs))(ops) + return foldr(call, get_col_results(var_dict, sub_step, sL, s, funcs))(ops) - def apply_env_proc(self, env_processes, state_dict, step): + def apply_env_proc(self, env_processes, state_dict, sub_step): for state in state_dict.keys(): if state in list(env_processes.keys()): env_state = env_processes[state] if (env_state.__name__ == '_curried') or (env_state.__name__ == 'proc_trigger'): - state_dict[state] = env_state(step)(state_dict[state]) + state_dict[state] = env_state(sub_step)(state_dict[state]) else: state_dict[state] = env_state(state_dict[state]) - def mech_step(self, var_dict, m_step, sL, state_funcs, behavior_funcs, env_processes, t_step, run): + # 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] - _input = self.behavior_update_exception(self.get_behavior_input(var_dict, m_step, sL, last_in_obj, behavior_funcs)) - # print(_input) + _input = 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( [ - # self.state_update_exception(curry_pot(f, m_step, sL, last_in_obj, _input)) for f in state_funcs - self.state_update_exception(f(var_dict, m_step, sL, last_in_obj, _input)) for f in state_funcs + self.state_update_exception(f(var_dict, sub_step, sL, last_in_obj, _input)) for f in state_funcs ] ) @@ -53,48 +51,47 @@ class Executor: self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) - last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = m_step, t_step, run + last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = sub_step, time_step, run sL.append(last_in_copy) del last_in_copy return sL - def mech_pipeline(self, var_dict, states_list, configs, env_processes, t_step, run): - m_step = 0 + # mech_pipeline + def state_update_pipeline(self, var_dict, states_list, configs, env_processes, time_step, run): + sub_step = 0 states_list_copy = deepcopy(states_list) genesis_states = states_list_copy[-1] - genesis_states['mech_step'], genesis_states['time_step'] = m_step, t_step + genesis_states['mech_step'], genesis_states['time_step'] = sub_step, time_step states_list = [genesis_states] - m_step += 1 + sub_step += 1 for config in configs: - s_conf, b_conf = config[0], config[1] - states_list = self.mech_step(var_dict, m_step, states_list, s_conf, b_conf, env_processes, t_step, run) - m_step += 1 + 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) + sub_step += 1 - t_step += 1 + time_step += 1 return states_list - # ToDo: Rename Run Pipeline - def block_pipeline(self, var_dict, states_list, configs, env_processes, time_seq, run): + 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] for time_step in time_seq: - pipe_run = self.mech_pipeline(var_dict, simulation_list[-1], configs, env_processes, time_step, run) + pipe_run = 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 = [] for run in range(runs): run += 1 states_list_copy = deepcopy(states_list) - head, *tail = self.block_pipeline(var_dict, states_list_copy, configs, env_processes, time_seq, run) + head, *tail = self.run_pipeline(var_dict, states_list_copy, configs, env_processes, time_seq, run) genesis = head.pop() genesis['mech_step'], genesis['time_step'], genesis['run'] = 0, 0, run first_timestep_per_run = [genesis] + tail.pop(0) diff --git a/SimCAD/engine/utils.py b/SimCAD/engine/utils.py index 2e569b8..c0f3a76 100644 --- a/SimCAD/engine/utils.py +++ b/SimCAD/engine/utils.py @@ -24,8 +24,8 @@ def retrieve_state(l, offset): return l[last_index(l) + offset + 1] -# exception_function = f(m_step, sL, sL[-2], _input) -# try_function = f(m_step, sL, last_mut_obj, _input) +# exception_function = f(sub_step, sL, sL[-2], _input) +# try_function = f(sub_step, sL, last_mut_obj, _input) @curried def engine_exception(ErrorType, error_message, exception_function, try_function): try: diff --git a/SimCAD/utils/__init__.py b/SimCAD/utils/__init__.py index 495d09e..b29ba08 100644 --- a/SimCAD/utils/__init__.py +++ b/SimCAD/utils/__init__.py @@ -1,6 +1,6 @@ from collections import defaultdict from itertools import product - +import warnings def pipe(x): return x @@ -77,6 +77,13 @@ def drop_right(l, n): def key_filter(l, keyname): + if (type(l) == list): + return [v[keyname] for v in l] + # Keeping support to dictionaries for backwards compatibility + # Should be removed in the future + warnings.warn( + "The use of a dictionary to describe Partial State Update Blocks will be deprecated. Use a list instead.", + FutureWarning) return [v[keyname] for k, v in l.items()] diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index f1bfe70..ce74604 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -7,7 +7,7 @@ from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_ from SimCAD.configuration.utils.parameterSweep import config_sim -seed = { +seeds = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), 'b': np.random.RandomState(3), @@ -15,20 +15,20 @@ seed = { } -# Behaviors per Mechanism -def b1m1(_g, step, sL, s): +# Policies per Mechanism +def p1m1(_g, step, sL, s): return {'param1': 1} -def b2m1(_g, step, sL, s): +def p2m1(_g, step, sL, s): return {'param2': 4} -def b1m2(_g, step, sL, s): +def p1m2(_g, step, sL, s): return {'param1': 'a', 'param2': 2} -def b2m2(_g, step, sL, s): +def p2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 4} -def b1m3(_g, step, sL, s): +def p1m3(_g, step, sL, s): return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(_g, step, sL, s): +def p2m3(_g, step, sL, s): return {'param1': ['d'], 'param2': np.array([20, 200])} @@ -67,12 +67,12 @@ proc_one_coef_B = 1.3 def es3p1(_g, step, sL, s, _input): y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + x = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B) return (y, x) def es4p2(_g, step, sL, s, _input): y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + x = s['s4'] * bound_norm_random(seeds['b'], proc_one_coef_A, proc_one_coef_B) return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' @@ -115,11 +115,11 @@ env_processes = { } -mechanisms = { +partial_state_update_block = { "m1": { - "behaviors": { - "b1": b1m1, - "b2": b2m1 + "policies": { + "b1": p1m1, + "b2": p2m1 }, "states": { "s1": s1m1, @@ -127,9 +127,9 @@ mechanisms = { } }, "m2": { - "behaviors": { - "b1": b1m2, - "b2": b2m2 + "policies": { + "b1": p1m2, + "b2": p2m2 }, "states": { "s1": s1m2, @@ -137,9 +137,9 @@ mechanisms = { } }, "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 + "policies": { + "b1": p1m3, + "b2": p2m3 }, "states": { "s1": s1m3, @@ -159,9 +159,9 @@ sim_config = config_sim( append_configs( sim_configs=sim_config, - state_dict=genesis_states, - seed=seed, + initial_state=genesis_states, + seeds=seeds, raw_exogenous_states=raw_exogenous_states, env_processes=env_processes, - mechanisms=mechanisms + partial_state_updates=partial_state_update_block ) diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py index 98705e6..987e8c0 100644 --- a/simulations/validation/config2.py +++ b/simulations/validation/config2.py @@ -6,7 +6,7 @@ from SimCAD.configuration import append_configs from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step from SimCAD.configuration.utils.parameterSweep import config_sim -seed = { +seeds = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), 'b': np.random.RandomState(3), @@ -14,20 +14,20 @@ seed = { } -# Behaviors per Mechanism -def b1m1(_g, step, sL, s): +# Policies per Mechanism +def p1m1(_g, step, sL, s): return {'param1': 1} -def b2m1(_g, step, sL, s): +def p2m1(_g, step, sL, s): return {'param2': 4} -def b1m2(_g, step, sL, s): +def p1m2(_g, step, sL, s): return {'param1': 'a', 'param2': 2} -def b2m2(_g, step, sL, s): +def p2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 4} -def b1m3(_g, step, sL, s): +def p1m3(_g, step, sL, s): return {'param1': ['c'], 'param2': np.array([10, 100])} -def b2m3(_g, step, sL, s): +def p2m3(_g, step, sL, s): return {'param1': ['d'], 'param2': np.array([20, 200])} @@ -66,12 +66,12 @@ proc_one_coef_B = 1.3 def es3p1(_g, step, sL, s, _input): y = 's3' - x = s['s3'] * bound_norm_random(seed['a'], proc_one_coef_A, proc_one_coef_B) + x = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B) return (y, x) def es4p2(_g, step, sL, s, _input): y = 's4' - x = s['s4'] * bound_norm_random(seed['b'], proc_one_coef_A, proc_one_coef_B) + x = s['s4'] * bound_norm_random(seeds['b'], proc_one_coef_A, proc_one_coef_B) return (y, x) ts_format = '%Y-%m-%d %H:%M:%S' @@ -114,11 +114,11 @@ env_processes = { } -mechanisms = { +partial_state_update_block = { "m1": { - "behaviors": { - "b1": b1m1, - # "b2": b2m1 + "policies": { + "b1": p1m1, + # "b2": p2m1 }, "states": { "s1": s1m1, @@ -126,9 +126,9 @@ mechanisms = { } }, "m2": { - "behaviors": { - "b1": b1m2, - # "b2": b2m2 + "policies": { + "b1": p1m2, + # "b2": p2m2 }, "states": { "s1": s1m2, @@ -136,9 +136,9 @@ mechanisms = { } }, "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 + "policies": { + "b1": p1m3, + "b2": p2m3 }, "states": { "s1": s1m3, @@ -158,9 +158,9 @@ sim_config = config_sim( append_configs( sim_configs=sim_config, - state_dict=genesis_states, - seed=seed, + initial_state=genesis_states, + seeds=seeds, raw_exogenous_states=raw_exogenous_states, env_processes=env_processes, - mechanisms=mechanisms + partial_state_updates=partial_state_update_block ) diff --git a/simulations/validation/sweep_config.py b/simulations/validation/sweep_config.py index e2d1880..c93a703 100644 --- a/simulations/validation/sweep_config.py +++ b/simulations/validation/sweep_config.py @@ -9,7 +9,7 @@ from SimCAD.configuration.utils.parameterSweep import config_sim pp = pprint.PrettyPrinter(indent=4) -seed = { +seeds = { 'z': np.random.RandomState(1), 'a': np.random.RandomState(2), 'b': np.random.RandomState(3), @@ -24,23 +24,23 @@ g = { 'omega': [7] } -# Behaviors per Mechanism -def b1m1(_g, step, sL, s): +# Policies per Mechanism +def p1m1(_g, step, sL, s): return {'param1': 1} -def b2m1(_g, step, sL, s): +def p2m1(_g, step, sL, s): return {'param2': 4} -def b1m2(_g, step, sL, s): +def p1m2(_g, step, sL, s): return {'param1': 'a', 'param2': _g['beta']} -def b2m2(_g, step, sL, s): +def p2m2(_g, step, sL, s): return {'param1': 'b', 'param2': 0} -def b1m3(_g, step, sL, s): +def p1m3(_g, step, sL, s): return {'param1': np.array([10, 100])} -def b2m3(_g, step, sL, s): +def p2m3(_g, step, sL, s): return {'param1': np.array([20, 200])} # Internal States per Mechanism @@ -143,11 +143,11 @@ env_processes = { # sweep exo_state func and point to exo-state in every other funtion # param sweep on genesis states -mechanisms = { +partial_state_update_block = { "m1": { - "behaviors": { - "b1": b1m1, - "b2": b2m1 + "policies": { + "b1": p1m1, + "b2": p2m1 }, "states": { "s1": s1m1, @@ -155,9 +155,9 @@ mechanisms = { } }, "m2": { - "behaviors": { - "b1": b1m2, - "b2": b2m2, + "policies": { + "b1": p1m2, + "b2": p2m2, }, "states": { "s1": s1m2, @@ -165,9 +165,9 @@ mechanisms = { } }, "m3": { - "behaviors": { - "b1": b1m3, - "b2": b2m3 + "policies": { + "b1": p1m3, + "b2": p2m3 }, "states": { "s1": s1m3, @@ -188,9 +188,9 @@ sim_config = config_sim( append_configs( sim_configs=sim_config, - state_dict=genesis_states, - seed=seed, + initial_state=genesis_states, + seeds=seeds, raw_exogenous_states=raw_exogenous_states, env_processes=env_processes, - mechanisms=mechanisms + partial_state_updates=partial_state_update_block ) \ No newline at end of file From fcda21d513286ab0efb7e1e9158568a4b0dd0281 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 15:38:57 -0500 Subject: [PATCH 37/38] renaming --- SimCAD/configuration/utils/__init__.py | 4 ++-- SimCAD/engine/simulation.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SimCAD/configuration/utils/__init__.py b/SimCAD/configuration/utils/__init__.py index 814efcf..ab5113d 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/SimCAD/configuration/utils/__init__.py @@ -52,7 +52,7 @@ def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = tstep_delta): ep_t_delta = timedelta(days=0, minutes=0, seconds=1) def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = ep_t_delta): - if s['mech_step'] == 0: + if s['sub_step'] == 0: return time_step(dt_str, fromat_str, _timedelta) else: return dt_str @@ -114,7 +114,7 @@ def sweep_states(state_type, states, in_config): def exo_update_per_ts(ep): @curried def ep_decorator(f, y, var_dict, sub_step, sL, s, _input): - if s['mech_step'] + 1 == 1: + if s['sub_step'] + 1 == 1: return f(var_dict, sub_step, sL, s, _input) else: return y, s[y] diff --git a/SimCAD/engine/simulation.py b/SimCAD/engine/simulation.py index 288af7e..4d855b1 100644 --- a/SimCAD/engine/simulation.py +++ b/SimCAD/engine/simulation.py @@ -51,7 +51,7 @@ class Executor: self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) - last_in_copy["mech_step"], last_in_copy["time_step"], last_in_copy['run'] = sub_step, time_step, run + last_in_copy["sub_step"], last_in_copy["time_step"], last_in_copy['run'] = sub_step, time_step, run sL.append(last_in_copy) del last_in_copy @@ -62,7 +62,7 @@ class Executor: sub_step = 0 states_list_copy = deepcopy(states_list) genesis_states = states_list_copy[-1] - genesis_states['mech_step'], genesis_states['time_step'] = sub_step, time_step + genesis_states['sub_step'], genesis_states['time_step'] = sub_step, time_step states_list = [genesis_states] sub_step += 1 @@ -93,7 +93,7 @@ class Executor: states_list_copy = deepcopy(states_list) head, *tail = self.run_pipeline(var_dict, states_list_copy, configs, env_processes, time_seq, run) genesis = head.pop() - genesis['mech_step'], genesis['time_step'], genesis['run'] = 0, 0, run + genesis['sub_step'], genesis['time_step'], genesis['run'] = 0, 0, run first_timestep_per_run = [genesis] + tail.pop(0) pipe_run += [first_timestep_per_run] + tail del states_list_copy From 50e4a38df7e1fbbf9073559baf71a80eeadac5a3 Mon Sep 17 00:00:00 2001 From: "Joshua E. Jodesty" Date: Thu, 14 Feb 2019 20:05:46 -0500 Subject: [PATCH 38/38] rename hell --- .gitignore | 2 ++ README.md | 2 +- SimCAD/__init__.py | 2 -- cadCAD/__init__.py | 2 ++ {SimCAD => cadCAD}/configuration/__init__.py | 12 ++++++------ .../configuration/utils/__init__.py | 2 +- .../configuration/utils/parameterSweep.py | 2 +- .../configuration/utils/policyAggregation.py | 0 {SimCAD => cadCAD}/engine/__init__.py | 8 ++++---- {SimCAD => cadCAD}/engine/simulation.py | 4 ++-- {SimCAD => cadCAD}/engine/utils.py | 0 {SimCAD => cadCAD}/utils/__init__.py | 0 dist/SimCAD-0.1-py3-none-any.whl | Bin 7445 -> 0 bytes dist/cadCAD-0.1-py3-none-any.whl | Bin 0 -> 9794 bytes setup.py | 10 +++++----- simulations/example_run.py | 4 ++-- simulations/validation/config1.py | 14 +++++++------- simulations/validation/config2.py | 14 +++++++------- simulations/validation/sweep_config.py | 14 +++++++------- 19 files changed, 47 insertions(+), 45 deletions(-) delete mode 100644 SimCAD/__init__.py create mode 100644 cadCAD/__init__.py rename {SimCAD => cadCAD}/configuration/__init__.py (92%) rename {SimCAD => cadCAD}/configuration/utils/__init__.py (98%) rename {SimCAD => cadCAD}/configuration/utils/parameterSweep.py (84%) rename {SimCAD => cadCAD}/configuration/utils/policyAggregation.py (100%) rename {SimCAD => cadCAD}/engine/__init__.py (94%) rename {SimCAD => cadCAD}/engine/simulation.py (97%) rename {SimCAD => cadCAD}/engine/utils.py (100%) rename {SimCAD => cadCAD}/utils/__init__.py (100%) delete mode 100644 dist/SimCAD-0.1-py3-none-any.whl create mode 100644 dist/cadCAD-0.1-py3-none-any.whl diff --git a/.gitignore b/.gitignore index b70d197..27a58c5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ results *.csv *.txt simulations/.ipynb_checkpoints +dist/*.gz +cadCAD.egg-info build SimCAD.egg-info \ No newline at end of file diff --git a/README.md b/README.md index 825c846..b591f72 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ SimCAD is written in Python 3. ```bash pip3 install -r requirements.txt python3 setup.py sdist bdist_wheel -pip3 install dist/SimCAD-0.1-py3-none-any.whl +pip3 install dist/cadCAD-0.1-py3-none-any.whl ``` **2. Configure Simulation:** diff --git a/SimCAD/__init__.py b/SimCAD/__init__.py deleted file mode 100644 index b4234cb..0000000 --- a/SimCAD/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -name = "SimCAD" -configs = [] \ No newline at end of file diff --git a/cadCAD/__init__.py b/cadCAD/__init__.py new file mode 100644 index 0000000..ce0b0f9 --- /dev/null +++ b/cadCAD/__init__.py @@ -0,0 +1,2 @@ +name = "cadCAD" +configs = [] \ No newline at end of file diff --git a/SimCAD/configuration/__init__.py b/cadCAD/configuration/__init__.py similarity index 92% rename from SimCAD/configuration/__init__.py rename to cadCAD/configuration/__init__.py index 1440b54..277ffce 100644 --- a/SimCAD/configuration/__init__.py +++ b/cadCAD/configuration/__init__.py @@ -2,15 +2,15 @@ from functools import reduce from fn.op import foldr import pandas as pd -from SimCAD import configs -from SimCAD.utils import key_filter -from SimCAD.configuration.utils.policyAggregation import dict_elemwise_sum -from SimCAD.configuration.utils import exo_update_per_ts +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 class Configuration(object): - def __init__(self, sim_config=None, initial_state=None, seeds=None, env_processes=None, - exogenous_states=None, partial_state_updates=None, policy_ops=[foldr(dict_elemwise_sum())]): + def __init__(self, sim_config={}, initial_state={}, seeds={}, env_processes={}, + exogenous_states={}, partial_state_updates={}, policy_ops=[foldr(dict_elemwise_sum())], **kwargs): self.sim_config = sim_config self.initial_state = initial_state self.seeds = seeds diff --git a/SimCAD/configuration/utils/__init__.py b/cadCAD/configuration/utils/__init__.py similarity index 98% rename from SimCAD/configuration/utils/__init__.py rename to cadCAD/configuration/utils/__init__.py index ab5113d..084f7ae 100644 --- a/SimCAD/configuration/utils/__init__.py +++ b/cadCAD/configuration/utils/__init__.py @@ -4,7 +4,7 @@ from copy import deepcopy from fn.func import curried import pandas as pd -from SimCAD.utils import dict_filter, contains_type +from cadCAD.utils import dict_filter, contains_type class TensorFieldReport: diff --git a/SimCAD/configuration/utils/parameterSweep.py b/cadCAD/configuration/utils/parameterSweep.py similarity index 84% rename from SimCAD/configuration/utils/parameterSweep.py rename to cadCAD/configuration/utils/parameterSweep.py index 7d5024c..9e5d6ab 100644 --- a/SimCAD/configuration/utils/parameterSweep.py +++ b/cadCAD/configuration/utils/parameterSweep.py @@ -1,4 +1,4 @@ -from SimCAD.utils import flatten_tabulated_dict, tabulate_dict +from cadCAD.utils import flatten_tabulated_dict, tabulate_dict def process_variables(d): diff --git a/SimCAD/configuration/utils/policyAggregation.py b/cadCAD/configuration/utils/policyAggregation.py similarity index 100% rename from SimCAD/configuration/utils/policyAggregation.py rename to cadCAD/configuration/utils/policyAggregation.py diff --git a/SimCAD/engine/__init__.py b/cadCAD/engine/__init__.py similarity index 94% rename from SimCAD/engine/__init__.py rename to cadCAD/engine/__init__.py index 139d126..5a1d4ad 100644 --- a/SimCAD/engine/__init__.py +++ b/cadCAD/engine/__init__.py @@ -1,9 +1,9 @@ from pathos.multiprocessing import ProcessingPool as Pool -from SimCAD.utils import flatten -from SimCAD.configuration import Processor -from SimCAD.configuration.utils import TensorFieldReport -from SimCAD.engine.simulation import Executor as SimExecutor +from cadCAD.utils import flatten +from cadCAD.configuration import Processor +from cadCAD.configuration.utils import TensorFieldReport +from cadCAD.engine.simulation import Executor as SimExecutor class ExecutionMode: diff --git a/SimCAD/engine/simulation.py b/cadCAD/engine/simulation.py similarity index 97% rename from SimCAD/engine/simulation.py rename to cadCAD/engine/simulation.py index 4d855b1..9e3a153 100644 --- a/SimCAD/engine/simulation.py +++ b/cadCAD/engine/simulation.py @@ -1,7 +1,7 @@ from copy import deepcopy from fn.op import foldr, call -from SimCAD.engine.utils import engine_exception +from cadCAD.engine.utils import engine_exception id_exception = engine_exception(KeyError, KeyError, None) @@ -49,7 +49,7 @@ class Executor: del last_in_obj - self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestamp']) + self.apply_env_proc(env_processes, last_in_copy, last_in_copy['timestep']) # not time_step last_in_copy["sub_step"], last_in_copy["time_step"], last_in_copy['run'] = sub_step, time_step, run sL.append(last_in_copy) diff --git a/SimCAD/engine/utils.py b/cadCAD/engine/utils.py similarity index 100% rename from SimCAD/engine/utils.py rename to cadCAD/engine/utils.py diff --git a/SimCAD/utils/__init__.py b/cadCAD/utils/__init__.py similarity index 100% rename from SimCAD/utils/__init__.py rename to cadCAD/utils/__init__.py diff --git a/dist/SimCAD-0.1-py3-none-any.whl b/dist/SimCAD-0.1-py3-none-any.whl deleted file mode 100644 index d6a18cf3b4ece9d96dc8275acf765fab7dcc56cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7445 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 literal 0 HcmV?d00001 diff --git a/setup.py b/setup.py index 619744d..ab1c80c 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -long_description = "SimCAD is a differential games based simulation software package for research, validation, and \ +long_description = "cadCAD is a differential games based simulation software package for research, validation, and \ Computer Aided Design of economic systems. An economic system is treated as a state based model and defined through \ a set of endogenous and exogenous state variables which are updated through mechanisms and environmental processes, \ respectively. Behavioral models, which may be deterministic or stochastic, provide the evolution of the system \ @@ -10,14 +10,14 @@ long_description = "SimCAD is a differential games based simulation software pac processes to understand and visualize network behavior under various conditions. Support for A/B testing policies, \ monte carlo analysis and other common numerical methods is provided." -setup(name='SimCAD', +setup(name='cadCAD', version='0.1', - description="SimCAD: a differential games based simulation software package for research, validation, and \ + description="cadCAD: a differential games based simulation software package for research, validation, and \ Computer Aided Design of economic systems", long_description = long_description, - url='https://github.com/BlockScience/DiffyQ-SimCAD', + url='https://github.com/BlockScience/DiffyQ-cadCAD', author='Joshua E. Jodesty', author_email='joshua@block.science', # license='LICENSE', - packages=find_packages() #['SimCAD'] + packages=find_packages() ) diff --git a/simulations/example_run.py b/simulations/example_run.py index b179e49..3c80d44 100644 --- a/simulations/example_run.py +++ b/simulations/example_run.py @@ -1,9 +1,9 @@ import pandas as pd from tabulate import tabulate # The following imports NEED to be in the exact order -from SimCAD.engine import ExecutionMode, ExecutionContext, Executor +from cadCAD.engine import ExecutionMode, ExecutionContext, Executor from simulations.validation import sweep_config, config1, config2 -from SimCAD import configs +from cadCAD import configs exec_mode = ExecutionMode() diff --git a/simulations/validation/config1.py b/simulations/validation/config1.py index ce74604..4539208 100644 --- a/simulations/validation/config1.py +++ b/simulations/validation/config1.py @@ -2,9 +2,9 @@ from decimal import Decimal import numpy as np from datetime import timedelta -from SimCAD.configuration import append_configs -from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step -from SimCAD.configuration.utils.parameterSweep import config_sim +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 seeds = { @@ -78,8 +78,8 @@ def es4p2(_g, step, sL, s, _input): ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) def es5p2(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + y = 'timestep' + x = ep_time_step(s, dt_str=s['timestep'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -98,14 +98,14 @@ genesis_states = { 's2': Decimal(0.0), 's3': Decimal(1.0), 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' + 'timestep': '2018-10-01 15:16:24' } raw_exogenous_states = { "s3": es3p1, "s4": es4p2, - "timestamp": es5p2 + "timestep": es5p2 } diff --git a/simulations/validation/config2.py b/simulations/validation/config2.py index 987e8c0..5925c6c 100644 --- a/simulations/validation/config2.py +++ b/simulations/validation/config2.py @@ -2,9 +2,9 @@ from decimal import Decimal import numpy as np from datetime import timedelta -from SimCAD.configuration import append_configs -from SimCAD.configuration.utils import proc_trigger, bound_norm_random, ep_time_step -from SimCAD.configuration.utils.parameterSweep import config_sim +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 seeds = { 'z': np.random.RandomState(1), @@ -77,8 +77,8 @@ def es4p2(_g, step, sL, s, _input): ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) def es5p2(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + y = 'timestep' + x = ep_time_step(s, dt_str=s['timestep'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -97,14 +97,14 @@ genesis_states = { 's2': Decimal(0.0), 's3': Decimal(1.0), 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' + 'timestep': '2018-10-01 15:16:24' } raw_exogenous_states = { "s3": es3p1, "s4": es4p2, - "timestamp": es5p2 + "timestep": es5p2 } diff --git a/simulations/validation/sweep_config.py b/simulations/validation/sweep_config.py index c93a703..f23e4ba 100644 --- a/simulations/validation/sweep_config.py +++ b/simulations/validation/sweep_config.py @@ -3,9 +3,9 @@ import numpy as np from datetime import timedelta import pprint -from SimCAD.configuration import append_configs -from SimCAD.configuration.utils import proc_trigger, ep_time_step -from SimCAD.configuration.utils.parameterSweep import config_sim +from cadCAD.configuration import append_configs +from cadCAD.configuration.utils import proc_trigger, ep_time_step +from cadCAD.configuration.utils.parameterSweep import config_sim pp = pprint.PrettyPrinter(indent=4) @@ -93,8 +93,8 @@ def es4p2(_g, step, sL, s, _input): ts_format = '%Y-%m-%d %H:%M:%S' t_delta = timedelta(days=0, minutes=0, seconds=1) def es5p2(_g, step, sL, s, _input): - y = 'timestamp' - x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta) + y = 'timestep' + x = ep_time_step(s, dt_str=s['timestep'], fromat_str=ts_format, _timedelta=t_delta) return (y, x) @@ -114,7 +114,7 @@ genesis_states = { 's2': Decimal(0.0), 's3': Decimal(1.0), 's4': Decimal(1.0), - 'timestamp': '2018-10-01 15:16:24' + 'timestep': '2018-10-01 15:16:24' } @@ -122,7 +122,7 @@ genesis_states = { raw_exogenous_states = { "s3": es3p1, "s4": es4p2, - "timestamp": es5p2 + "timestep": es5p2 }