os refactor pt 1

This commit is contained in:
Joshua E. Jodesty 2019-08-21 14:27:31 -04:00
parent 67c46cfe09
commit 747ec36e50
10 changed files with 27 additions and 169 deletions

View File

@ -9,8 +9,6 @@ from cadCAD.configuration.utils import exo_update_per_ts
from cadCAD.configuration.utils.policyAggregation import dict_elemwise_sum
from cadCAD.configuration.utils.depreciationHandler import sanitize_partial_state_updates, sanitize_config
# policy_ops=[foldr(dict_elemwise_sum())]
# policy_ops=[reduce, lambda a, b: {**a, **b}]
class Configuration(object):
def __init__(self, sim_config={}, initial_state={}, seeds={}, env_processes={},
@ -28,7 +26,7 @@ class Configuration(object):
sanitize_config(self)
# ToDo: Remove Seeds
def append_configs(sim_configs={}, initial_state={}, seeds={}, raw_exogenous_states={}, env_processes={},
partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b], _exo_update_per_ts: bool = True) -> None:
if _exo_update_per_ts is True:

View File

@ -5,12 +5,10 @@ from fn.func import curried
from funcy import curry
import pandas as pd
# Temporary
from cadCAD.configuration.utils.depreciationHandler import sanitize_partial_state_updates
from cadCAD.utils import dict_filter, contains_type, flatten_tabulated_dict, tabulate_dict
# ToDo: Fix - Returns empty when partial_state_update is missing in Configuration
class TensorFieldReport:
def __init__(self, config_proc):
self.config_proc = config_proc
@ -56,7 +54,6 @@ def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = tstep_delta):
return t.strftime(dt_format)
# ToDo: Inject in first elem of last PSUB from Historical state
ep_t_delta = timedelta(days=0, minutes=0, seconds=1)
def ep_time_step(s_condition, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta = ep_t_delta):
# print(dt_str)
@ -65,7 +62,7 @@ def ep_time_step(s_condition, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', _timedelta
else:
return dt_str
# 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([
@ -77,7 +74,7 @@ def partial_state_sweep_filter(state_field, partial_state_updates):
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_partial_states(_type, in_config):
configs = []
@ -129,16 +126,19 @@ def exo_update_per_ts(ep):
return {es: ep_decorator(f, es) for es, f in ep.items()}
def trigger_condition(s, pre_conditions, cond_opp):
condition_bools = [s[field] in precondition_values for field, precondition_values in pre_conditions.items()]
return reduce(cond_opp, condition_bools)
def apply_state_condition(pre_conditions, cond_opp, y, f, _g, step, sL, s, _input):
if trigger_condition(s, pre_conditions, cond_opp):
return f(_g, step, sL, s, _input)
else:
return y, s[y]
def var_trigger(y, f, pre_conditions, cond_op):
return lambda _g, step, sL, s, _input: apply_state_condition(pre_conditions, cond_op, y, f, _g, step, sL, s, _input)
@ -173,7 +173,6 @@ def env_trigger(end_substep):
curry(trigger)(end_substep)(trigger_field)(trigger_vals)(funct_list)
# param sweep enabling middleware
def config_sim(d):
def process_variables(d):
return flatten_tabulated_dict(tabulate_dict(d))
@ -184,15 +183,18 @@ def config_sim(d):
d["M"] = [{}]
return d
def psub_list(psu_block, psu_steps):
return [psu_block[psu] for psu in psu_steps]
def psub(policies, state_updates):
return {
'policies': policies,
'states': state_updates
}
def genereate_psubs(policy_grid, states_grid, policies, state_updates):
PSUBS = []
for policy_ids, state_list in zip(policy_grid, states_grid):
@ -202,7 +204,7 @@ def genereate_psubs(policy_grid, states_grid, policies, state_updates):
return PSUBS
# ToDo: DO NOT filter sH for every state/policy update. Requires a consumable sH (new sH)
def access_block(state_history, target_field, psu_block_offset, exculsion_list=[]):
exculsion_list += [target_field]
def filter_history(key_list, sH):

View File

@ -2,8 +2,6 @@ from copy import deepcopy
def sanitize_config(config):
# for backwards compatibility, we accept old arguments via **kwargs
# TODO: raise specific deprecation warnings for key == 'state_dict', key == 'seed', key == 'mechanisms'
for key, value in config.kwargs.items():
if key == 'state_dict':
config.initial_state = value
@ -18,8 +16,6 @@ def sanitize_config(config):
def sanitize_partial_state_updates(partial_state_updates):
new_partial_state_updates = deepcopy(partial_state_updates)
# for backwards compatibility we accept the old keys
# ('behaviors' and 'states') and rename them
def rename_keys(d):
if 'behaviors' in d:
d['policies'] = d.pop('behaviors')
@ -28,8 +24,6 @@ def sanitize_partial_state_updates(partial_state_updates):
d['variables'] = d.pop('states')
# Also for backwards compatibility, we accept partial state update blocks both as list or dict
# No need for a deprecation warning as it's already raised by cadCAD.utils.key_filter
if isinstance(new_partial_state_updates, list):
for v in new_partial_state_updates:
rename_keys(v)

View File

@ -1,6 +1,7 @@
from fn.op import foldr
from fn.func import curried
def get_base_value(x):
if isinstance(x, str):
return ''
@ -17,7 +18,7 @@ def policy_to_dict(v):
add = lambda a, b: a + b
# df_union = lambda a, b: ...
@curried
def foldr_dict_vals(f, d):

View File

@ -1,23 +1,22 @@
from collections import namedtuple
from copy import deepcopy
from inspect import getmembers, ismethod
from pandas.core.frame import DataFrame
from cadCAD.utils import SilentDF
def val_switch(v):
if isinstance(v, DataFrame) is True:
return SilentDF(v)
else:
return v
class udcView(object):
def __init__(self, d, masked_members):
self.__dict__ = d
self.masked_members = masked_members
# returns dict to dataframe
def __repr__(self):
members = {}
variables = {
@ -27,17 +26,7 @@ class udcView(object):
members['methods'] = [k for k, v in self.__dict__.items() if str(type(v)) == "<class 'method'>"]
members.update(variables)
return f"{members}" #[1:-1]
# def __repr__(self):
# members = {}
# variables = {
# k: val_switch(v) for k, v in self.__dict__.items()
# if str(type(v)) != "<class 'method'>" and k not in self.masked_members and k == 'x' # and isinstance(v, DataFrame) is not True
# }
#
# members.update(variables)
# return f"{members}" #[1:-1]
return f"{members}"
class udcBroker(object):

View File

@ -93,7 +93,6 @@ class Executor:
final_result = None
if self.exec_context == ExecutionMode.single_proc:
# ToDO: Deprication Handler - "sanitize" in appropriate place
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)
final_result = result, tensor_field

View File

@ -63,9 +63,6 @@ class Executor:
) for k, val_list in new_dict.items()
}
# [f1] = ops
# return {k: reduce(f1, val_list) for k, val_list in new_dict.items()}
# return foldr(call, col_results)(ops)
def apply_env_proc(
self,
@ -98,7 +95,6 @@ class Executor:
return state_dict
# ToDo: Redifined as a function that applies the tensor field to a set og last conditions
# mech_step
def partial_state_update(
self,
@ -119,8 +115,6 @@ class Executor:
)
# ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function
# ToDo: Can be multithreaded ??
def generate_record(state_funcs):
for f in state_funcs:
yield self.state_update_exception(f(sweep_dict, sub_step, sH, last_in_obj, _input))
@ -134,7 +128,6 @@ class Executor:
last_in_copy: Dict[str, Any] = transfer_missing_fields(last_in_obj, dict(generate_record(state_funcs)))
last_in_copy: Dict[str, Any] = self.apply_env_proc(sweep_dict, env_processes, last_in_copy)
# ToDo: make 'substep' & 'timestep' reserve fields
last_in_copy['substep'], last_in_copy['timestep'], last_in_copy['run'] = sub_step, time_step, run
sL.append(last_in_copy)
@ -155,7 +148,6 @@ class Executor:
sub_step = 0
states_list_copy: List[Dict[str, Any]] = deepcopy(simulation_list[-1])
# ToDo: Causes Substep repeats in sL:
genesis_states: Dict[str, Any] = states_list_copy[-1]
if len(states_list_copy) == 1:
@ -167,7 +159,6 @@ class Executor:
del states_list_copy
states_list: List[Dict[str, Any]] = [genesis_states]
# ToDo: Was causing Substep repeats in sL, use for yield
sub_step += 1
for [s_conf, p_conf] in configs: # tensor field
@ -196,7 +187,6 @@ class Executor:
) -> List[List[Dict[str, Any]]]:
time_seq: List[int] = [x + 1 for x in time_seq]
# ToDo: simulation_list should be a Tensor that is generated throughout the Executor
simulation_list: List[List[Dict[str, Any]]] = [states_list]
for time_step in time_seq:
@ -209,8 +199,6 @@ class Executor:
return simulation_list
# ToDo: Below can be recieved from a tensor field
# configs: List[Tuple[List[Callable], List[Callable]]]
def simulation(
self,
sweep_dict: Dict[str, List[Any]],

View File

@ -24,8 +24,6 @@ def retrieve_state(l, offset):
return l[last_index(l) + offset + 1]
# 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:
@ -38,5 +36,3 @@ def engine_exception(ErrorType, error_message, exception_function, try_function)
@curried
def fit_param(param, x):
return x + param
# fit_param = lambda param: lambda x: x + param

View File

@ -11,15 +11,11 @@ class SilentDF(DataFrame):
def __repr__(self):
return str(hex(id(DataFrame))) #"pandas.core.frame.DataFrame"
def append_dict(dict, new_dict):
dict.update(new_dict)
return dict
# def val_switch(v):
# if isinstance(v, DataFrame) is True or isinstance(v, SilentDF) is True:
# return SilentDF(v)
# else:
# return v.x
class IndexCounter:
def __init__(self):
@ -29,8 +25,6 @@ class IndexCounter:
self.i += 1
return self.i
# def compose(*functions):
# return reduce(lambda f, g: lambda x: f(g(x)), functions, lambda x: x)
def compose(*functions):
return reduce(lambda f, g: lambda x: f(g(x)), functions, lambda x: x)
@ -108,8 +102,7 @@ def contains_type(_collection, type):
def drop_right(l, n):
return l[:len(l) - n]
# backwards compatibility
# ToDo: Encapsulate in function
def key_filter(l, keyname):
if (type(l) == list):
return [v[keyname] for v in l]
@ -147,23 +140,3 @@ def curry_pot(f, *argv):
return f(argv[0], argv[1], argv[2])
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
# return f
# return decorator

View File

@ -1,37 +1,46 @@
from funcy import curry
from cadCAD.configuration.utils import ep_time_step, time_step
def increment(y, incr_by):
return lambda _g, step, sL, s, _input: (y, s[y] + incr_by)
def track(y):
return lambda _g, step, sL, s, _input: (y, s[y].x)
def simple_state_update(y, x):
return lambda _g, step, sH, s, _input: (y, x)
def simple_policy_update(y):
return lambda _g, step, sH, s: y
def update_timestamp(y, timedelta, format):
return lambda _g, step, sL, s, _input: (
y,
ep_time_step(s, dt_str=s[y], fromat_str=format, _timedelta=timedelta)
)
def apply(f, y: str, incr_by: int):
return lambda _g, step, sL, s, _input: (y, curry(f)(s[y])(incr_by))
def add(y: str, incr_by):
return apply(lambda a, b: a + b, y, incr_by)
def increment_state_by_int(y: str, incr_by: int):
return lambda _g, step, sL, s, _input: (y, s[y] + incr_by)
def s(y, x):
return lambda _g, step, sH, s, _input: (y, x)
def time_model(y, substeps, time_delta, ts_format='%Y-%m-%d %H:%M:%S'):
def apply_incriment_condition(s):
if s['substep'] == 0 or s['substep'] == substeps:
@ -40,94 +49,3 @@ def time_model(y, substeps, time_delta, ts_format='%Y-%m-%d %H:%M:%S'):
return y, s[y]
return lambda _g, step, sL, s, _input: apply_incriment_condition(s)
# ToDo: Impliment Matrix reduction
#
# [
# {'conditions': [123], 'opp': lambda a, b: a and b},
# {'conditions': [123], 'opp': lambda a, b: a and b}
# ]
# def trigger_condition2(s, conditions, cond_opp):
# # print(conditions)
# condition_bools = [s[field] in precondition_values for field, precondition_values in conditions.items()]
# return reduce(cond_opp, condition_bools)
#
# def trigger_multi_conditions(s, multi_conditions, multi_cond_opp):
# # print([(d['conditions'], d['reduction_opp']) for d in multi_conditions])
# condition_bools = [
# trigger_condition2(s, conditions, opp) for conditions, opp in [
# (d['conditions'], d['reduction_opp']) for d in multi_conditions
# ]
# ]
# return reduce(multi_cond_opp, condition_bools)
#
# def apply_state_condition2(multi_conditions, multi_cond_opp, y, f, _g, step, sL, s, _input):
# if trigger_multi_conditions(s, multi_conditions, multi_cond_opp):
# return f(_g, step, sL, s, _input)
# else:
# return y, s[y]
#
# def proc_trigger2(y, f, multi_conditions, multi_cond_opp):
# return lambda _g, step, sL, s, _input: apply_state_condition2(multi_conditions, multi_cond_opp, y, f, _g, step, sL, s, _input)
#
# def timestep_trigger2(end_substep, y, f):
# multi_conditions = [
# {
# 'condition': {
# 'substep': [0, end_substep]
# },
# 'reduction_opp': lambda a, b: a and b
# }
# ]
# multi_cond_opp = lambda a, b: a and b
# return proc_trigger2(y, f, multi_conditions, multi_cond_opp)
#
# @curried
# print(env_trigger(3).__module__)
# pp.pprint(dir(env_trigger))
# @curried
# def env_proc_trigger(trigger_time, update_f, time):
# if time == trigger_time:
# return update_f
# else:
# return lambda x: x
# def p1m1(_g, step, sL, s):
# return {'param1': 1}
#
# def apply_policy_condition(policies, policy_id, f, conditions, _g, step, sL, s):
# if trigger_condition(s, conditions):
# policies[policy_id] = f(_g, step, sL, s)
# return policies
# else:
# return policies
#
# def proc_trigger2(policies, conditions, policy_id, f):
# return lambda _g, step, sL, s: apply_policy_condition(policies, policy_id, f, conditions,_g, step, sL, s)
# policies_updates = {"p1": udo_policyA, "p2": udo_policyB}
# @curried
# def proc_trigger(trigger_time, update_f, time):
# if time == trigger_time:
# return update_f
# else:
# return lambda x: x
# def repr(_g, step, sL, s, _input):
# y = 'z'
# x = s['state_udo'].__repr__()
# return (y, x)