middle ground pt. 3

This commit is contained in:
Joshua E. Jodesty 2019-02-05 20:00:39 -05:00
parent f9b3b1ea18
commit c58f2d65a6
4 changed files with 224 additions and 199 deletions

View File

@ -3,11 +3,12 @@ from decimal import Decimal
from copy import deepcopy from copy import deepcopy
from fn.func import curried from fn.func import curried
import pandas as pd import pandas as pd
import inspect
from SimCAD.utils import rename from SimCAD.utils import rename
from SimCAD.utils import dict_filter, contains_type, curry_pot from SimCAD.utils import dict_filter, contains_type, curry_pot
from funcy import curry from funcy import curry
import pprint import pprint
@ -125,104 +126,3 @@ def exo_update_per_ts(ep):
return (y, s[y]) return (y, s[y])
return {es: ep_decorator(f, es) for es, f in ep.items()} 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()}

View File

@ -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

View File

@ -8,28 +8,28 @@ from SimCAD import configs
exec_mode = ExecutionMode() exec_mode = ExecutionMode()
print("Simulation Execution 1") # print("Simulation Execution 1")
print() # print()
first_config = [configs[0]] # from config1 # first_config = [configs[0]] # from config1
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc) # single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
run1 = Executor(exec_context=single_proc_ctx, configs=first_config) # run1 = Executor(exec_context=single_proc_ctx, configs=first_config)
run1_raw_result, tensor_field = run1.main() # run1_raw_result, tensor_field = run1.main()
result = pd.DataFrame(run1_raw_result) # result = pd.DataFrame(run1_raw_result)
print() # print()
print("Tensor Field:") # print("Tensor Field:")
print(tabulate(tensor_field, headers='keys', tablefmt='psql')) # print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
print("Output:") # print("Output:")
print(tabulate(result, headers='keys', tablefmt='psql')) # print(tabulate(result, headers='keys', tablefmt='psql'))
print() # print()
# print("Simulation Execution 2: Pairwise Execution") print("Simulation Execution 2: Concurrent Execution")
# multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc) multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
# run2 = Executor(exec_context=multi_proc_ctx, configs=configs) run2 = Executor(exec_context=multi_proc_ctx, configs=configs)
# for raw_result, tensor_field in run2.main(): for raw_result, tensor_field in run2.main():
# result = pd.DataFrame(raw_result) result = pd.DataFrame(raw_result)
# print() print()
# print("Tensor Field:") print("Tensor Field:")
# print(tabulate(tensor_field, headers='keys', tablefmt='psql')) print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
# print("Output:") print("Output:")
# print(tabulate(result, headers='keys', tablefmt='psql')) print(tabulate(result, headers='keys', tablefmt='psql'))
# print() print()

View File

@ -5,11 +5,10 @@ import pprint
from SimCAD import configs from SimCAD import configs
from SimCAD.configuration import Configuration from SimCAD.configuration import Configuration
from SimCAD.configuration.utils import exo_update_per_ts, proc_trigger, bound_norm_random, \ from SimCAD.configuration.utils import proc_trigger, bound_norm_random, \
ep_time_step, parameterize_mechanism, parameterize_states, sweep ep_time_step
from SimCAD.utils import rename from SimCAD.configuration.utils.parameterSweep import ParamSweep
from fn.func import curried
pp = pprint.PrettyPrinter(indent=4) pp = pprint.PrettyPrinter(indent=4)
@ -33,8 +32,8 @@ def b2m1(step, sL, s):
return {'param2': 4} return {'param2': 4}
# @curried # @curried
def b1m2(param, step, sL, s): def b1m2(_beta, step, sL, s):
return {'param1': 'a', 'param2': param} return {'param1': 'a', 'param2': _beta}
# @curried # @curried
def b2m2(step, sL, s): def b2m2(step, sL, s):
return {'param1': 'b', 'param2': 0} return {'param1': 'b', 'param2': 0}
@ -54,10 +53,16 @@ def s1m1(step, sL, s, _input):
return (y, x) return (y, x)
# @curried # @curried
def s2m1(param, step, sL, s, _input): def s2m1(sweep_param, step, sL, s, _input):
y = 's2' y = 's2'
x = param x = sweep_param
return (y, x) return (y, x)
#
# def s2m1(step, sL, s, _input):
# y = 's2'
# x = 0
# return (y, x)
# @curried # @curried
def s1m2(step, sL, s, _input): def s1m2(step, sL, s, _input):
y = 's1' y = 's1'
@ -126,11 +131,10 @@ genesis_states = {
# remove `exo_update_per_ts` to update every ts # remove `exo_update_per_ts` to update every ts
raw_exogenous_states = { raw_exogenous_states = {
"s3": sweep(beta, es3p1), #es3p1, #sweep(beta, es3p1), "s3": es3p1, #es3p1, #sweep(beta, es3p1),
"s4": sweep(beta, es4p2), "s4": es4p2,
"timestamp": es5p2 "timestamp": es5p2
} }
exogenous_states_list = list(map(exo_update_per_ts, parameterize_states(raw_exogenous_states)))
# ToDo: make env proc trigger field agnostic # ToDo: make env proc trigger field agnostic
@ -147,7 +151,7 @@ env_processes = {
# pp.pprint(parameterized_env_processes) # pp.pprint(parameterized_env_processes)
# exit() # 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 # not dependent on the # of times the sweep is applied
# sweep exo_state func and point to exo-state in every other funtion # sweep exo_state func and point to exo-state in every other funtion
# param sweep on genesis states # 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 # need at least 1 behaviour and 1 state function for the 1st mech with behaviors
# mechanisms = {} # mechanisms = {}
#middleware(beta, [(m1, states, s2, s2m1), (m2, behaviors, b1, b1m2)], mechanisms) mechanisms = {
mechanisms_test = {
"m1": { "m1": {
"behaviors": { "behaviors": {
"b1": b1m1,#(0), "b1": b1m1,
"b2": b2m1#(0) "b2": b2m1
}, },
"states": { "states": {
"s1": s1m1,#(0), "s1": s1m1,
"s2": "sweep" "s2": s2m1
} }
}, },
"m2": { "m2": {
"behaviors": { "behaviors": {
"b1": "sweep", "b1": b1m2,
"b2": b2m2,#(0) "b2": b2m2,
}, },
"states": { "states": {
"s1": s1m2,#(0), "s1": s1m2,
"s2": s2m2#(0) "s2": s2m2
} }
}, },
"m3": { "m3": {
"behaviors": { "behaviors": {
"b1": b1m3,#(0), "b1": b1m3,
"b2": b2m3,#(0) "b2": b2m3,
}, },
"states": { "states": {
"s1": s1m3,#(0), "s1": s1m3,
"s2": s2m3#(0) "s2": s2m3
} }
} }
} }
from copy import deepcopy # ToDo: inspect ****
from funcy import curry # ToDo: code block regenerator abstracted from user: input config module with params as convention, output it not as convention,
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: make ParamSweep a part of sim_config
sim_config = { sim_config = {
"N": 2, "N": 2,
"T": range(5) "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( configs.append(
Configuration( Configuration(
sim_config=sim_config, sim_config=sim_config,
state_dict=genesis_states, state_dict=genesis_states,
seed=seed, seed=seed,
exogenous_states=exogenous_states, #parameterize_states(raw_exogenous_states)[1], exogenous_states=exogenous_states,
env_processes=env_processes, env_processes=env_processes,
mechanisms=mechanisms #parameterize_mechanism(mechanisms)[1] mechanisms=mechanisms
) )
) )