Skip to content

Commit

Permalink
Merge branch 'master' of github.com:cadCAD-org/cadCAD
Browse files Browse the repository at this point in the history
  • Loading branch information
danlessa committed Jan 18, 2024
2 parents bcd97bf + 13ad507 commit ba3a14b
Show file tree
Hide file tree
Showing 13 changed files with 380 additions and 239 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/cadcad-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,43 @@ permissions:
contents: read

jobs:
windows-build:
continue-on-error: true

runs-on: windows-latest

strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'

- name: Display Python version
run: python -c "import sys; print(sys.version)"

- name: Install test and build dependencies
run: |
python -m pip install --upgrade pip
python -m pip install jupyter
pip install -r requirements.txt
- name: Build cadCAD
shell: cmd
run: |
python setup.py bdist_wheel
for %%x in ("dist\*.whl") do python -m pip install %%x --force-reinstall
- name: Run tests
run: |
python -m pytest
build:
continue-on-error: true

Expand Down
197 changes: 103 additions & 94 deletions CHANGELOG.md

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
/ ___/ __` / __ / / / /| | / / / /
/ /__/ /_/ / /_/ / /___/ ___ |/ /_/ /
\___/\__,_/\__,_/\____/_/ |_/_____/
by cadCAD ver. 0.5.0
by cadCAD ver. 0.5.1
======================================
Complex Adaptive Dynamics
Complex Adaptive Dynamics
o i e
m d s
p e i
Expand All @@ -15,12 +15,12 @@ by cadCAD ver. 0.5.0
e
r
```
***cadCAD*** is a Python package that assists in the processes of designing, testing and validating complex systems
through simulation, with support for Monte Carlo methods, A/B testing and parameter sweeping.
***cadCAD*** is a Python package that assists in the processes of designing, testing and validating complex systems
through simulation, with support for Monte Carlo methods, A/B testing and parameter sweeping.

# Getting Started

#### Change Log: [ver. 0.5.0](CHANGELOG.md)
#### Change Log: [ver. 0.5.1](CHANGELOG.md)

[Previous Stable Release (No Longer Supported)](https://github.com/cadCAD-org/cadCAD/tree/b9cc6b2e4af15d6361d60d6ec059246ab8fbf6da)

Expand All @@ -44,10 +44,10 @@ $ source ~/cadcad/bin/activate
$
```

## 1. Installation:
Requires [>= Python 3.6.13](https://www.python.org/downloads/)
## 1. Installation:
Requires [>= Python 3.9.0](https://www.python.org/downloads/)

**Option A:** Install Using **[pip](https://pypi.org/project/cadCAD/)**
**Option A:** Install Using **[pip](https://pypi.org/project/cadCAD/)**
```bash
pip3 install cadCAD
```
Expand Down
2 changes: 1 addition & 1 deletion cadCAD/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from cadCAD.configuration import Experiment

name = "cadCAD"
version = "0.5.0"
version = "0.5.1"
experiment = Experiment()
configs = experiment.configs

Expand Down
2 changes: 1 addition & 1 deletion cadCAD/configuration/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def ep_decorator(f, y, var_dict, sub_step, sL, s, _input, **kwargs):
else:
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()} # type: ignore


def trigger_condition(s, pre_conditions, cond_opp):
Expand Down
46 changes: 39 additions & 7 deletions cadCAD/engine/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from time import time
from typing import Callable, Dict, List, Any, Tuple, Union
from typing import Callable, Dict, List, Any, Tuple, Union, Sequence, Mapping
from tqdm.auto import tqdm

from cadCAD.utils import flatten
Expand Down Expand Up @@ -147,18 +147,50 @@ def get_final_results(simulations: List[StateHistory],
eps,
sessions: List[SessionDict],
remote_threshold: int):

# if list of lists of lists of dicts: do flatten
# if list of dicts: do not flatetn
# else raise error


init: bool = isinstance(simulations, Sequence)
failed_1 = False
failed_2 = False

try:
init: bool = isinstance(simulations, Sequence)
dont_flatten = init & isinstance(simulations[0], Mapping)
do_flatten = not dont_flatten
except:
failed_1 = True
do_flatten = True

try:
do_flatten = init & isinstance(simulations[0], Sequence)
do_flatten &= isinstance(simulations[0][0], Sequence)
do_flatten &= isinstance(simulations[0][0][0], Mapping)
except:
failed_2 = True
do_flatten = False

if failed_1 and failed_2:
raise ValueError('Invalid simulation results (Executor output is not list[dict] or list[list[list[dict]]])')


flat_timesteps, tensor_fields = [], []
for sim_result, psu, ep in tqdm(list(zip(simulations, psus, eps)),
total=len(simulations),
desc='Flattening results'):
flat_timesteps.append(flatten(sim_result))
if do_flatten:
flat_timesteps.append(flatten(sim_result))
tensor_fields.append(create_tensor_field(psu, ep))

if do_flatten:
flat_simulations = flatten(flat_timesteps)
else:
flat_simulations = simulations

flat_simulations = flatten(flat_timesteps)
if config_amt == 1:
return simulations, tensor_fields, sessions
elif config_amt > 1:
return flat_simulations, tensor_fields, sessions
return flat_simulations, tensor_fields, sessions

final_result = None
original_N = len(configs_as_dicts(self.configs))
Expand Down
61 changes: 29 additions & 32 deletions cadCAD/engine/execution.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Callable, Dict, List, Any, Tuple
from typing import Callable, Dict, List, Any, Tuple, Sequence
from pathos.multiprocessing import ProcessPool # type: ignore
from collections import Counter
from cadCAD.types import *
Expand All @@ -11,41 +11,38 @@


def single_proc_exec(
simulation_execs: List[ExecutorFunction],
var_dict_list: List[Parameters],
states_lists: List[StateHistory],
configs_structs: List[StateUpdateBlocks],
env_processes_list: List[EnvProcesses],
Ts: List[TimeSeq],
SimIDs: List[SimulationID],
Ns: List[Run],
ExpIDs: List[int],
SubsetIDs: List[SubsetID],
SubsetWindows: List[SubsetWindow],
configured_n: List[N_Runs],
simulation_execs: Sequence[ExecutorFunction],
var_dict_list: Union[Sequence[Parameters], Parameters],
states_lists: Sequence[StateHistory],
configs_structs: Sequence[StateUpdateBlocks],
env_processes_list: Sequence[EnvProcesses],
Ts: Sequence[TimeSeq],
SimIDs: Sequence[SimulationID],
Ns: Sequence[Run],
ExpIDs: Sequence[int],
SubsetIDs: Sequence[SubsetID],
SubsetWindows: Sequence[SubsetWindow],
configured_n: Sequence[N_Runs],
additional_objs=None
):
) -> List:


# HACK for making it run with N_Runs=1
if type(var_dict_list) == list:
var_dict_list = var_dict_list[0]
if not isinstance(var_dict_list, Sequence):
var_dict_list = list([var_dict_list])

print(f'Execution Mode: single_threaded')
raw_params: List[List] = [
raw_params = (
simulation_execs, states_lists, configs_structs, env_processes_list,
Ts, SimIDs, Ns, SubsetIDs, SubsetWindows
]
simulation_exec, states_list, config, env_processes, T, sim_id, N, subset_id, subset_window = list(
map(lambda x: x.pop(), raw_params)
)
result = simulation_exec(
var_dict_list, states_list, config, env_processes, T, sim_id, N, subset_id, subset_window, configured_n, additional_objs
)
return flatten(result)




Ts, SimIDs, Ns, SubsetIDs, SubsetWindows, var_dict_list)

results: List = []
print(f'Execution Mode: single_threaded')
for raw_param in zip(*raw_params):
simulation_exec, states_list, config, env_processes, T, sim_id, N, subset_id, subset_window, var_dict = raw_param
result = simulation_exec(
var_dict, states_list, config, env_processes, T, sim_id, N, subset_id, subset_window, configured_n, additional_objs
)
results.append(flatten(result))
return flatten(results)

def parallelize_simulations(
simulation_execs: List[ExecutorFunction],
Expand Down
5 changes: 2 additions & 3 deletions cadCAD/engine/simulation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Any, Callable, Dict, List, Tuple
from copy import deepcopy
from types import MappingProxyType
from copy import deepcopy, copy
from functools import reduce
from funcy import curry # type: ignore

Expand Down Expand Up @@ -161,7 +160,7 @@ def partial_state_update(

if type(additional_objs) == dict:
if additional_objs.get('deepcopy_off', False) == True:
last_in_obj = MappingProxyType(sL[-1])
last_in_obj = copy(sL[-1])
if len(additional_objs) == 1:
additional_objs = None
# XXX: drop the additional objects if only used for deepcopy
Expand Down
8 changes: 4 additions & 4 deletions cadCAD/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TypedDict, Callable, Union, Dict, List, Tuple, Iterator
from typing import TypedDict, Callable, Union, Dict, List, Tuple, Iterable
from collections import deque

State = Dict[str, object]
Expand All @@ -20,18 +20,18 @@ class StateUpdateBlock(TypedDict):
StateUpdateBlocks = List[StateUpdateBlock]

class ConfigurationDict(TypedDict):
T: Iterator # Generator for the timestep variable
T: Iterable # Generator for the timestep variable
N: int # Number of MC Runs
M: Union[Parameters, SweepableParameters] # Parameters / List of Parameter to Sweep

TargetValue = object
EnvProcess: Callable[[State, SweepableParameters, TargetValue], TargetValue]
EnvProcesses = Dict[str, Callable]
TimeSeq = Iterator
TimeSeq = Iterable
SimulationID = int
Run = int
SubsetID = int
SubsetWindow = Iterator
SubsetWindow = Iterable
N_Runs = int

ExecutorFunction = Callable[[Parameters, StateHistory, StateUpdateBlocks, EnvProcesses, TimeSeq, SimulationID, Run, SubsetID, SubsetWindow, N_Runs], object]
Expand Down
59 changes: 26 additions & 33 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,38 @@
from setuptools import setup, find_packages
from setuptools import find_packages, setup

short_description = "cadCAD: a differential games based simulation software package for research, validation, and \
Computer Aided Design of economic systems"

long_description = """
cadCAD (complex adaptive systems computer-aided design) is a python based, unified modeling framework for stochastic
dynamical systems and differential games for research, validation, and Computer Aided Design of economic systems created
by BlockScience. It is capable of modeling systems at all levels of abstraction from Agent Based Modeling (ABM) to
System Dynamics (SD), and enabling smooth integration of computational social science simulations with empirical data
cadCAD (complex adaptive systems computer-aided design) is a python based, unified modeling framework for stochastic
dynamical systems and differential games for research, validation, and Computer Aided Design of economic systems created
by BlockScience. It is capable of modeling systems at all levels of abstraction from Agent Based Modeling (ABM) to
System Dynamics (SD), and enabling smooth integration of computational social science simulations with empirical data
science workflows.
An economic system is treated as a state-based model and defined through a set of endogenous and exogenous state
variables which are updated through mechanisms and environmental processes, respectively. Behavioral models, which may
be deterministic or stochastic, provide the evolution of the system within the action space of the mechanisms.
Mathematical formulations of these economic games treat agent utility as derived from the state rather than direct from
an action, creating a rich, dynamic modeling framework. Simulations may be run with a range of initial conditions and
parameters for states, behaviors, mechanisms, and environmental processes to understand and visualize network behavior
under various conditions. Support for A/B testing policies, Monte Carlo analysis, and other common numerical methods is
An economic system is treated as a state-based model and defined through a set of endogenous and exogenous state
variables which are updated through mechanisms and environmental processes, respectively. Behavioral models, which may
be deterministic or stochastic, provide the evolution of the system within the action space of the mechanisms.
Mathematical formulations of these economic games treat agent utility as derived from the state rather than direct from
an action, creating a rich, dynamic modeling framework. Simulations may be run with a range of initial conditions and
parameters for states, behaviors, mechanisms, and environmental processes to understand and visualize network behavior
under various conditions. Support for A/B testing policies, Monte Carlo analysis, and other common numerical methods is
provided.
"""

name = "cadCAD"
version = "0.5.0"
version = "0.5.1"

setup(name=name,
version=version,
description=short_description,
long_description=long_description,
url='https://github.com/cadCAD-org/cadCAD',
author='cadCAD-org Developers',
author_email='[email protected]',
license='LICENSE.txt',
packages=find_packages(),
install_requires=[
"pandas",
"funcy",
"dill",
"pathos",
"numpy",
"pytz",
"six"
],
python_requires='>=3.8.0'
)
setup(
name=name,
version=version,
description=short_description,
long_description=long_description,
url="https://github.com/cadCAD-org/cadCAD",
author="cadCAD-org Developers",
author_email="[email protected]",
license="LICENSE.txt",
packages=find_packages(),
install_requires=["pandas", "funcy", "dill", "pathos", "numpy", "pytz", "six"],
python_requires=">=3.9.0",
)
Loading

0 comments on commit ba3a14b

Please sign in to comment.