os refactor pt 1
This commit is contained in:
parent
67c46cfe09
commit
747ec36e50
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]],
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
Loading…
Reference in New Issue