merge hell

This commit is contained in:
Joshua E. Jodesty 2019-02-14 10:16:24 -05:00
commit 2989dc2554
20 changed files with 1092 additions and 777 deletions

3
.gitignore vendored
View File

@ -1,6 +1,9 @@
.idea
.ipynb_checkpoints
.DS_Store
.idea
notebooks
SimCAD.egg-info
__pycache__
Pipfile
Pipfile.lock

View File

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

View File

@ -2,36 +2,70 @@ 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.behaviorAggregation import dict_elemwise_sum
from SimCAD.configuration.utils import exo_update_per_ts
class Configuration:
def __init__(self, sim_config, state_dict, seed, exogenous_states, env_processes, mechanisms, behavior_ops=[foldr(dict_elemwise_sum())]):
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
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
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
if isinstance(sim_configs, list):
for sim_config in sim_configs:
configs.append(
Configuration(
sim_config=sim_config,
state_dict=state_dict,
seed=seed,
exogenous_states=exogenous_states,
env_processes=env_processes,
mechanisms=mechanisms
)
)
elif isinstance(sim_configs, dict):
configs.append(
Configuration(
sim_config=sim_configs,
state_dict=state_dict,
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
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):

View File

@ -1,8 +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 SimCAD.utils import dict_filter, contains_type
class TensorFieldReport:
def __init__(self, config_proc):
@ -17,9 +20,17 @@ 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):
res = rng.normal((high+low)/2, (high-low)/6)
if (res<low or res>high):
if res < low or res > high:
res = bound_norm_random(rng, low, high)
return Decimal(res)
@ -32,26 +43,78 @@ def proc_trigger(trigger_step, update_f, step):
return lambda x: x
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):
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):
dt = datetime.strptime(dt_str, dt_format)
t = dt + _timedelta
return t.strftime(dt_format)
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):
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:
return time_step(dt_str, fromat_str, _timedelta)
else:
return dt_str
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
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 f(step, sL, s, _input)
return f(var_dict, step, sL, s, _input) # curry_pot
else:
return (y, s[y])
return y, s[y]
return {es: ep_decorator(f, es) for es, f in ep.items()}

View File

@ -2,13 +2,14 @@ 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 []
else:
return 0
@ -32,7 +33,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]

View File

@ -0,0 +1,19 @@
from SimCAD.utils import flatten_tabulated_dict, tabulate_dict
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

View File

@ -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,13 +47,16 @@ 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:
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)
@ -64,11 +67,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)))

View File

@ -1,5 +1,6 @@
from copy import deepcopy
from fn.op import foldr, call
from SimCAD.engine.utils import engine_exception
id_exception = engine_exception(KeyError, KeyError, None)
@ -11,13 +12,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: 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))
return foldr(call, get_col_results(step, sL, s, funcs))(ops)
# print(get_col_results(step, sL, s, funcs))
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():
@ -28,12 +31,19 @@ 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.state_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)
last_in_copy = dict([self.behavior_update_exception(f(m_step, sL, last_in_obj, _input)) for f in state_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
]
)
for k in last_in_obj:
if k not in last_in_copy:
@ -49,7 +59,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]
@ -59,29 +69,32 @@ 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
return states_list
def block_pipeline(self, states_list, configs, env_processes, time_seq, run):
# ToDo: Rename Run Pipeline
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)
return simulation_list
def simulation(self, states_list, configs, env_processes, time_seq, runs):
# 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(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)

View File

@ -24,6 +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)
@curried
def engine_exception(ErrorType, error_message, exception_function, try_function):
try:
@ -31,3 +33,10 @@ def engine_exception(ErrorType, error_message, exception_function, try_function)
except ErrorType:
print(error_message)
return exception_function
@curried
def fit_param(param, x):
return x + param
# fit_param = lambda param: lambda x: x + param

View File

@ -1,3 +1,7 @@
from collections import defaultdict
from itertools import product
def pipe(x):
return x
@ -7,14 +11,118 @@ 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):
if isinstance(l, list):
return [item for sublist in l for item in sublist]
elif isinstance(l, dict):
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 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)
def drop_right(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:
d[key].append(value)
return list(dict(d).items()).pop()
# @curried
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 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,4 +1,4 @@
# SimmCAD Documentation
# SimCAD Documentation
## Introduction

View File

@ -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', <function fit_param.<locals>.<lambda> at 0x1099efae8>)\n",
"('s2', <function fit_param.<locals>.<lambda> 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 (<ipython-input-2-6e999d313015>, line 3)",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-2-6e999d313015>\"\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 (<ipython-input-20-fada0ccd8d2a>, line 2)",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-20-fada0ccd8d2a>\"\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<value.\n",
" | \n",
" | __ne__(self, value, /)\n",
" | Return self!=value.\n",
" | \n",
" | __new__(*args, **kwargs) from builtins.type\n",
" | Create and return a new object. See help(type) for accurate signature.\n",
" | \n",
" | __setitem__(self, key, value, /)\n",
" | Set self[key] to value.\n",
" | \n",
" | __sizeof__(...)\n",
" | D.__sizeof__() -> 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
}

View File

@ -1,4 +1,5 @@
wheel
pandas
pathos
fn
tabulate

View File

@ -1,29 +1,27 @@
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
from simulations.validation import sweep_config
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")
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():

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,196 @@
from decimal import Decimal
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
pp = pprint.PrettyPrinter(indent=4)
seed = {
'z': np.random.RandomState(1),
'a': np.random.RandomState(2),
'b': np.random.RandomState(3),
'c': np.random.RandomState(3)
}
g = {
'alpha': [1],
'beta': [2, 5],
'gamma': [3, 4],
'omega': [7]
}
# Behaviors per Mechanism
def b1m1(_g, step, sL, s):
return {'param1': 1}
def b2m1(_g, step, sL, s):
return {'param2': 4}
def b1m2(_g, step, sL, s):
return {'param1': 'a', 'param2': _g['beta']}
def b2m2(_g, step, sL, s):
return {'param1': 'b', 'param2': 0}
def b1m3(_g, step, sL, s):
return {'param1': np.array([10, 100])}
def b2m3(_g, step, sL, s):
return {'param1': np.array([20, 200])}
# Internal States per Mechanism
def s1m1(_g, step, sL, s, _input):
y = 's1'
x = 0
return (y, x)
def s2m1(_g, step, sL, s, _input):
y = 's2'
x = _g['beta']
return (y, x)
def s1m2(_g, step, sL, s, _input):
y = 's1'
x = _input['param2']
return (y, x)
def s2m2(_g, step, sL, s, _input):
y = 's2'
x = _input['param2']
return (y, x)
def s1m3(_g, step, sL, s, _input):
y = 's1'
x = 0
return (y, x)
def s2m3(_g, step, sL, s, _input):
y = 's2'
x = 0
return (y, x)
# Exogenous States
proc_one_coef_A = 0.7
proc_one_coef_B = 1.3
def es3p1(_g, step, sL, s, _input):
y = 's3'
x = _g['gamma']
return (y, x)
# @curried
def es4p2(_g, step, sL, s, _input):
y = 's4'
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(_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)
# Environment States
# @curried
# def env_a(param, x):
# return x + param
def env_a(x):
return x
def env_b(x):
return 10
# 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
raw_exogenous_states = {
"s3": es3p1,
"s4": es4p2,
"timestamp": es5p2
}
# 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)
}
# parameterized_env_processes = parameterize_states(env_processes)
#
# pp.pprint(parameterized_env_processes)
# exit()
# 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
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 = config_sim(
{
"N": 2,
"T": range(5),
"M": g
}
)
append_configs(
sim_configs=sim_config,
state_dict=genesis_states,
seed=seed,
raw_exogenous_states=raw_exogenous_states,
env_processes=env_processes,
mechanisms=mechanisms
)