Compare commits
8 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
62af34f179 | |
|
|
32367faefe | |
|
|
4afbdffb8d | |
|
|
84c02e18ba | |
|
|
c50e8e8c71 | |
|
|
261f11e301 | |
|
|
05a760f28d | |
|
|
2f069a3a2e |
|
|
@ -1,30 +1,8 @@
|
|||
.idea
|
||||
jupyter notebook
|
||||
.ipynb_checkpoints
|
||||
.ipynb_checkpoints/*
|
||||
.DS_Store
|
||||
.idea
|
||||
.pytest_cache/
|
||||
notebooks
|
||||
*.egg-info
|
||||
__pycache__
|
||||
Pipfile
|
||||
Pipfile.lock
|
||||
results
|
||||
.mypy_cache
|
||||
*.csv
|
||||
simulations/.ipynb_checkpoints
|
||||
simulations/validation/config3.py
|
||||
cadCAD.egg-info
|
||||
|
||||
build
|
||||
cadCAD.egg-info
|
||||
|
||||
testing/example.py
|
||||
testing/example2.py
|
||||
testing/multi_config_test.py
|
||||
testing/udo.py
|
||||
testing/udo_test.py
|
||||
|
||||
Simulation.md
|
||||
|
||||
monkeytype.sqlite3
|
||||
engine/__pycache__
|
||||
engine/.ipynb_checkpoints
|
||||
notebooks/.ipynb_checkpoints
|
||||
ui/__pycache__
|
||||
SimCAD.egg-info
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
29
AUTHORS.txt
29
AUTHORS.txt
|
|
@ -1,29 +0,0 @@
|
|||
Authors
|
||||
=======
|
||||
|
||||
cadCAD was originally implemented by Joshua E. Jodesty and designed by Michael Zargham, Markus B. Koch, and
|
||||
Matthew V. Barlin from 2018 to 2019.
|
||||
|
||||
|
||||
Project Maintainers:
|
||||
- Joshua E. Jodesty <joshua@block.science, joshua.jodesty@gmail.com>
|
||||
- Markus B. Koch <markus@block.science>
|
||||
|
||||
|
||||
Contributors:
|
||||
- Joshua E. Jodesty
|
||||
- Markus B. Koch
|
||||
- Matthew V. Barlin
|
||||
- Michael Zargham
|
||||
- Zixuan Zhang
|
||||
- Charles Rice
|
||||
|
||||
|
||||
We’d also like to thank:
|
||||
- Andrew Clark
|
||||
- Nikhil Jamdade
|
||||
- Nick Hirannet
|
||||
- Jonathan Gabler
|
||||
- Chris Frazier
|
||||
- Harry Goodnight
|
||||
- Charlie Hoppes
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
# Contributing to cadCAD (Draft)
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
The following is a set of guidelines for contributing to cadCAD. These are mostly guidelines, not rules.
|
||||
Use your best judgment, and feel free to propose changes to this document in a pull request.
|
||||
|
||||
### Pull Requests:
|
||||
|
||||
Pull Request (PR) presented as "->".
|
||||
|
||||
General Template:
|
||||
fork/branch -> BlockScience/staging
|
||||
|
||||
Contributing a new feature:
|
||||
fork/feature -> BlockScience/staging
|
||||
|
||||
Contributing to an existing feature:
|
||||
fork/feature -> BlockScience/feature
|
||||
|
||||
Thanks! :heart:
|
||||
21
LICENSE.txt
21
LICENSE.txt
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018-2019 BlockScience
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
[[source]]
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
ipykernel = "*"
|
||||
pandas = "*"
|
||||
jupyter = "*"
|
||||
scipy = "*"
|
||||
matplotlib = "*"
|
||||
seaborn = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[requires]
|
||||
python_version = "3.6"
|
||||
|
|
@ -0,0 +1,550 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "76927ed95e0de5668160ccfcd430fdb91ab2b1597b3e55e14a89fb3855f05757"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.6"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"appnope": {
|
||||
"hashes": [
|
||||
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
|
||||
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
|
||||
],
|
||||
"markers": "sys_platform == 'darwin'",
|
||||
"version": "==0.1.0"
|
||||
},
|
||||
"backcall": {
|
||||
"hashes": [
|
||||
"sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4",
|
||||
"sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2"
|
||||
],
|
||||
"version": "==0.1.0"
|
||||
},
|
||||
"bleach": {
|
||||
"hashes": [
|
||||
"sha256:0ee95f6167129859c5dce9b1ca291ebdb5d8cd7e382ca0e237dfd0dad63f63d8",
|
||||
"sha256:24754b9a7d530bf30ce7cbc805bc6cce785660b4a10ff3a43633728438c105ab"
|
||||
],
|
||||
"version": "==2.1.4"
|
||||
},
|
||||
"cycler": {
|
||||
"hashes": [
|
||||
"sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d",
|
||||
"sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"
|
||||
],
|
||||
"version": "==0.10.0"
|
||||
},
|
||||
"decorator": {
|
||||
"hashes": [
|
||||
"sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82",
|
||||
"sha256:c39efa13fbdeb4506c476c9b3babf6a718da943dab7811c206005a4a956c080c"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
},
|
||||
"defusedxml": {
|
||||
"hashes": [
|
||||
"sha256:24d7f2f94f7f3cb6061acb215685e5125fbcdc40a857eff9de22518820b0a4f4",
|
||||
"sha256:702a91ade2968a82beb0db1e0766a6a273f33d4616a6ce8cde475d8e09853b20"
|
||||
],
|
||||
"version": "==0.5.0"
|
||||
},
|
||||
"entrypoints": {
|
||||
"hashes": [
|
||||
"sha256:10ad569bb245e7e2ba425285b9fa3e8178a0dc92fc53b1e1c553805e15a8825b",
|
||||
"sha256:d2d587dde06f99545fb13a383d2cd336a8ff1f359c5839ce3a64c917d10c029f"
|
||||
],
|
||||
"markers": "python_version >= '2.7'",
|
||||
"version": "==0.2.3"
|
||||
},
|
||||
"html5lib": {
|
||||
"hashes": [
|
||||
"sha256:20b159aa3badc9d5ee8f5c647e5efd02ed2a66ab8d354930bd9ff139fc1dc0a3",
|
||||
"sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736"
|
||||
],
|
||||
"version": "==1.0.1"
|
||||
},
|
||||
"ipykernel": {
|
||||
"hashes": [
|
||||
"sha256:00d88b7e628e4e893359119b894451611214bce09776a3bf8248fe42cb48ada6",
|
||||
"sha256:a706b975376efef98b70e10cd167ab9506cf08a689d689a3c7daf344c15040f6",
|
||||
"sha256:c5a498c70f7765c34f3397cf943b069057f5bef4e0218e4cfbb733e9f38fa5fa"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.9.0"
|
||||
},
|
||||
"ipython": {
|
||||
"hashes": [
|
||||
"sha256:007dcd929c14631f83daff35df0147ea51d1af420da303fd078343878bd5fb62",
|
||||
"sha256:b0f2ef9eada4a68ef63ee10b6dde4f35c840035c50fd24265f8052c98947d5a4"
|
||||
],
|
||||
"markers": "python_version >= '3.3'",
|
||||
"version": "==6.5.0"
|
||||
},
|
||||
"ipython-genutils": {
|
||||
"hashes": [
|
||||
"sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8",
|
||||
"sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"
|
||||
],
|
||||
"version": "==0.2.0"
|
||||
},
|
||||
"ipywidgets": {
|
||||
"hashes": [
|
||||
"sha256:0f2b5cde9f272cb49d52f3f0889fdd1a7ae1e74f37b48dac35a83152780d2b7b",
|
||||
"sha256:a3e224f430163f767047ab9a042fc55adbcab0c24bbe6cf9f306c4f89fdf0ba3"
|
||||
],
|
||||
"version": "==7.4.2"
|
||||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
"sha256:b409ed0f6913a701ed474a614a3bb46e6953639033e31f769ca7581da5bd1ec1",
|
||||
"sha256:c254b135fb39ad76e78d4d8f92765ebc9bf92cbc76f49e97ade1d5f5121e1f6f"
|
||||
],
|
||||
"version": "==0.12.1"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
|
||||
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:000e68abd33c972a5248544925a0cae7d1125f9bf6c58280d37546b946769a08",
|
||||
"sha256:6ff5f3180870836cae40f06fa10419f557208175f13ad7bc26caa77beb1f6e02"
|
||||
],
|
||||
"version": "==2.6.0"
|
||||
},
|
||||
"jupyter": {
|
||||
"hashes": [
|
||||
"sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7",
|
||||
"sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78",
|
||||
"sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.0"
|
||||
},
|
||||
"jupyter-client": {
|
||||
"hashes": [
|
||||
"sha256:27befcf0446b01e29853014d6a902dd101ad7d7f94e2252b1adca17c3466b761",
|
||||
"sha256:59e6d791e22a8002ad0e80b78c6fd6deecab4f9e1b1aa1a22f4213de271b29ea"
|
||||
],
|
||||
"version": "==5.2.3"
|
||||
},
|
||||
"jupyter-console": {
|
||||
"hashes": [
|
||||
"sha256:3f928b817fc82cda95e431eb4c2b5eb21be5c483c2b43f424761a966bb808094",
|
||||
"sha256:545dedd3aaaa355148093c5609f0229aeb121b4852995c2accfa64fe3e0e55cd"
|
||||
],
|
||||
"version": "==5.2.0"
|
||||
},
|
||||
"jupyter-core": {
|
||||
"hashes": [
|
||||
"sha256:927d713ffa616ea11972534411544589976b2493fc7e09ad946e010aa7eb9970",
|
||||
"sha256:ba70754aa680300306c699790128f6fbd8c306ee5927976cbe48adacf240c0b7"
|
||||
],
|
||||
"version": "==4.4.0"
|
||||
},
|
||||
"kiwisolver": {
|
||||
"hashes": [
|
||||
"sha256:0ee4ed8b3ae8f5f712b0aa9ebd2858b5b232f1b9a96b0943dceb34df2a223bc3",
|
||||
"sha256:0f7f532f3c94e99545a29f4c3f05637f4d2713e7fd91b4dd8abfc18340b86cd5",
|
||||
"sha256:1a078f5dd7e99317098f0e0d490257fd0349d79363e8c923d5bb76428f318421",
|
||||
"sha256:1aa0b55a0eb1bd3fa82e704f44fb8f16e26702af1a073cc5030eea399e617b56",
|
||||
"sha256:2874060b91e131ceeff00574b7c2140749c9355817a4ed498e82a4ffa308ecbc",
|
||||
"sha256:379d97783ba8d2934d52221c833407f20ca287b36d949b4bba6c75274bcf6363",
|
||||
"sha256:3b791ddf2aefc56382aadc26ea5b352e86a2921e4e85c31c1f770f527eb06ce4",
|
||||
"sha256:4329008a167fac233e398e8a600d1b91539dc33c5a3eadee84c0d4b04d4494fa",
|
||||
"sha256:45813e0873bbb679334a161b28cb9606d9665e70561fd6caa8863e279b5e464b",
|
||||
"sha256:53a5b27e6b5717bdc0125338a822605084054c80f382051fb945d2c0e6899a20",
|
||||
"sha256:574f24b9805cb1c72d02b9f7749aa0cc0b81aa82571be5201aa1453190390ae5",
|
||||
"sha256:66f82819ff47fa67a11540da96966fb9245504b7f496034f534b81cacf333861",
|
||||
"sha256:79e5fe3ccd5144ae80777e12973027bd2f4f5e3ae8eb286cabe787bed9780138",
|
||||
"sha256:83410258eb886f3456714eea4d4304db3a1fc8624623fc3f38a487ab36c0f653",
|
||||
"sha256:8b6a7b596ce1d2a6d93c3562f1178ebd3b7bb445b3b0dd33b09f9255e312a965",
|
||||
"sha256:9576cb63897fbfa69df60f994082c3f4b8e6adb49cccb60efb2a80a208e6f996",
|
||||
"sha256:95a25d9f3449046ecbe9065be8f8380c03c56081bc5d41fe0fb964aaa30b2195",
|
||||
"sha256:a424f048bebc4476620e77f3e4d1f282920cef9bc376ba16d0b8fe97eec87cde",
|
||||
"sha256:aaec1cfd94f4f3e9a25e144d5b0ed1eb8a9596ec36d7318a504d813412563a85",
|
||||
"sha256:acb673eecbae089ea3be3dcf75bfe45fc8d4dcdc951e27d8691887963cf421c7",
|
||||
"sha256:b15bc8d2c2848a4a7c04f76c9b3dc3561e95d4dabc6b4f24bfabe5fd81a0b14f",
|
||||
"sha256:b1c240d565e977d80c0083404c01e4d59c5772c977fae2c483f100567f50847b",
|
||||
"sha256:c595693de998461bcd49b8d20568c8870b3209b8ea323b2a7b0ea86d85864694",
|
||||
"sha256:ce3be5d520b4d2c3e5eeb4cd2ef62b9b9ab8ac6b6fedbaa0e39cdb6f50644278",
|
||||
"sha256:e0f910f84b35c36a3513b96d816e6442ae138862257ae18a0019d2fc67b041dc",
|
||||
"sha256:ea36e19ac0a483eea239320aef0bd40702404ff8c7e42179a2d9d36c5afcb55c",
|
||||
"sha256:efabbcd4f406b532206b8801058c8bab9e79645b9880329253ae3322b7b02cd5",
|
||||
"sha256:f923406e6b32c86309261b8195e24e18b6a8801df0cfc7814ac44017bfcb3939"
|
||||
],
|
||||
"markers": "python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.2.*' and python_version != '3.3.*'",
|
||||
"version": "==1.0.1"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
|
||||
],
|
||||
"version": "==1.0"
|
||||
},
|
||||
"matplotlib": {
|
||||
"hashes": [
|
||||
"sha256:0ba8e3ec1b0feddc6b068fe70dc38dcf2917e301ad8d2b3f848c14ad463a4157",
|
||||
"sha256:10a48e33e64dbd95f0776ba162f379c5cc55301c2d155506e79ce0c26b52f2ce",
|
||||
"sha256:1376535fe731adbba55ab9e48896de226b7e89dbb55390c5fbd8f7161b7ae3be",
|
||||
"sha256:16f0f8ba22df1e2c9f06c87088de45742322fde282a93b5c744c0f969cf7932e",
|
||||
"sha256:1c6c999f2212858021329537f8e0f98f3f29086ec3683511dd1ecec84409f51d",
|
||||
"sha256:2316dc177fc7b3d8848b49365498de0c385b4c9bba511edddd24c34fbe3d37a4",
|
||||
"sha256:3398bfb533482bf21974cecf28224dd23784ad4e4848be582903f7a2436ec12e",
|
||||
"sha256:3477cb1e1061b34210acc43d20050be8444478ff50b8adfac5fe2b45fc97df01",
|
||||
"sha256:3cc06333b8264428d02231804e2e726b902e9161dc16f573183dee6cb7ef621f",
|
||||
"sha256:4259ea7cb2c238355ee13275eddd261d869cefbdeb18a65f35459589d6d17def",
|
||||
"sha256:4addcf93234b6122f530f90f485fd3d00d158911fbc1ed24db3fa66cd49fe565",
|
||||
"sha256:50c0e24bcbce9c54346f4a2f4e97b0ed111f0413ac3fe9954061ae1c8aa7021f",
|
||||
"sha256:62ed7597d9e54db6e133420d779c642503c25eba390e1178d85dfb2ba0d05948",
|
||||
"sha256:69f6d51e41a17f6a5f70c56bb10b8ded9f299609204495a7fa2782a3a755ffc5",
|
||||
"sha256:6d232e49b74e3d2db22c63c25a9a0166d965e87e2b057f795487f1f244b61d9d",
|
||||
"sha256:7355bf757ecacd5f0ac9dd9523c8e1a1103faadf8d33c22664178e17533f8ce5",
|
||||
"sha256:886b1045c5105631f10c1cbc999f910e44d33af3e9c7efd68c2123efc06ab636",
|
||||
"sha256:9e1f353edd7fc7e5e9101abd5bc0201946f77a1b59e0da49095086c03db856ed",
|
||||
"sha256:b3a343dfcbe296dbe0f26c731beee72a792ff948407e6979524298ae7bc3234e",
|
||||
"sha256:d93675af09ca497a25f4f8d62f3313cf0f21e45427a87487049fe84898b99909",
|
||||
"sha256:e2409ef9d37804dfb566f39c962e6ed70f281ff516b8131b3e6b4e6442711ff1",
|
||||
"sha256:f8b653b0f89938ba72e92ab080c2f3aa24c1b72e2f61add22880cd1b9a6e3cdd"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.2.3"
|
||||
},
|
||||
"mistune": {
|
||||
"hashes": [
|
||||
"sha256:b4c512ce2fc99e5a62eb95a4aba4b73e5f90264115c40b70a21e1f7d4e0eac91",
|
||||
"sha256:bc10c33bfdcaa4e749b779f62f60d6e12f8215c46a292d05e486b869ae306619"
|
||||
],
|
||||
"version": "==0.8.3"
|
||||
},
|
||||
"nbconvert": {
|
||||
"hashes": [
|
||||
"sha256:08d21cf4203fabafd0d09bbd63f06131b411db8ebeede34b0fd4be4548351779",
|
||||
"sha256:a8a2749f972592aa9250db975304af6b7337f32337e523a2c995cc9e12c07807"
|
||||
],
|
||||
"version": "==5.4.0"
|
||||
},
|
||||
"nbformat": {
|
||||
"hashes": [
|
||||
"sha256:b9a0dbdbd45bb034f4f8893cafd6f652ea08c8c1674ba83f2dc55d3955743b0b",
|
||||
"sha256:f7494ef0df60766b7cabe0a3651556345a963b74dbc16bc7c18479041170d402"
|
||||
],
|
||||
"version": "==4.4.0"
|
||||
},
|
||||
"notebook": {
|
||||
"hashes": [
|
||||
"sha256:66dd59e76e755584ae9450eb015c39f55d4bb1d8ec68f2c694d2b3cba7bf5c7e",
|
||||
"sha256:e2c8e931cc19db4f8c63e6a396efbc13a228b2cb5b2919df011b946f28239a08"
|
||||
],
|
||||
"version": "==5.6.0"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:1c362ad12dd09a43b348bb28dd2295dd9cdf77f41f0f45965e04ba97f525b864",
|
||||
"sha256:2156a06bd407918df4ac0122df6497a9c137432118f585e5b17d543e593d1587",
|
||||
"sha256:24e4149c38489b51fc774b1e1faa9103e82f73344d7a00ba66f6845ab4769f3f",
|
||||
"sha256:340ec1697d9bb3a9c464028af7a54245298502e91178bddb4c37626d36e197b7",
|
||||
"sha256:35db8d419345caa4eeaa65cd63f34a15208acd87530a30f0bc25fc84f55c8c80",
|
||||
"sha256:361370e9b7f5e44c41eee29f2bb5cb3b755abb4b038bce6d6cbe08db7ff9cb74",
|
||||
"sha256:36e8dcd1813ca92ce7e4299120cee6c03adad33d89b54862c1b1a100443ac399",
|
||||
"sha256:378378973546ecc1dfaf9e24c160d683dd04df871ecd2dcc86ce658ca20f92c0",
|
||||
"sha256:419e6faee16097124ee627ed31572c7e80a1070efa25260b78097cca240e219a",
|
||||
"sha256:4287104c24e6a09b9b418761a1e7b1bbde65105f110690ca46a23600a3c606b8",
|
||||
"sha256:549f3e9778b148a47f4fb4682955ed88057eb627c9fe5467f33507c536deda9d",
|
||||
"sha256:5e359e9c531075220785603e5966eef20ccae9b3b6b8a06fdfb66c084361ce92",
|
||||
"sha256:5ee7f3dbbdba0da75dec7e94bd7a2b10fe57a83e1b38e678200a6ad8e7b14fdc",
|
||||
"sha256:62d55e96ec7b117d3d5e618c15efcf769e70a6effaee5842857b64fb4883887a",
|
||||
"sha256:719b6789acb2bc86ea9b33a701d7c43dc2fc56d95107fd3c5b0a8230164d4dfb",
|
||||
"sha256:7a70f2b60d48828cba94a54a8776b61a9c2657a803d47f5785f8062e3a9c7c55",
|
||||
"sha256:7b9e37f194f8bcdca8e9e6af92e2cbad79e360542effc2dd6b98d63955d8d8a3",
|
||||
"sha256:83b8fc18261b70f45bece2d392537c93dc81eb6c539a16c9ac994c47fc79f09a",
|
||||
"sha256:9473ad28375710ab18378e72b59422399b27e957e9339c413bf00793b4b12df0",
|
||||
"sha256:95b085b253080e5d09f7826f5e27dce067bae813a132023a77b739614a29de6e",
|
||||
"sha256:98b86c62c08c2e5dc98a9c856d4a95329d11b1c6058cb9b5191d5ea6891acd09",
|
||||
"sha256:a3bd01d6d3ed3d7c06d7f9979ba5d68281f15383fafd53b81aa44b9191047cf8",
|
||||
"sha256:c81a6afc1d2531a9ada50b58f8c36197f8418ef3d0611d4c1d7af93fdcda764f",
|
||||
"sha256:ce75ed495a746e3e78cfa22a77096b3bff2eda995616cb7a542047f233091268",
|
||||
"sha256:dae8618c0bcbfcf6cf91350f8abcdd84158323711566a8c5892b5c7f832af76f",
|
||||
"sha256:df0b02c6705c5d1c25cc35c7b5d6b6f9b3b30833f9d178843397ae55ecc2eebb",
|
||||
"sha256:e3660744cda0d94b90141cdd0db9308b958a372cfeee8d7188fdf5ad9108ea82",
|
||||
"sha256:f2362d0ca3e16c37782c1054d7972b8ad2729169567e3f0f4e5dd3cdf85f188e"
|
||||
],
|
||||
"markers": "python_version != '3.3.*' and python_version != '3.1.*' and python_version != '3.0.*' and python_version >= '2.7' and python_version != '3.2.*'",
|
||||
"version": "==1.15.1"
|
||||
},
|
||||
"pandas": {
|
||||
"hashes": [
|
||||
"sha256:11975fad9edbdb55f1a560d96f91830e83e29bed6ad5ebf506abda09818eaf60",
|
||||
"sha256:12e13d127ca1b585dd6f6840d3fe3fa6e46c36a6afe2dbc5cb0b57032c902e31",
|
||||
"sha256:1c87fcb201e1e06f66e23a61a5fea9eeebfe7204a66d99df24600e3f05168051",
|
||||
"sha256:242e9900de758e137304ad4b5663c2eff0d798c2c3b891250bd0bd97144579da",
|
||||
"sha256:26c903d0ae1542890cb9abadb4adcb18f356b14c2df46e4ff657ae640e3ac9e7",
|
||||
"sha256:2e1e88f9d3e5f107b65b59cd29f141995597b035d17cc5537e58142038942e1a",
|
||||
"sha256:31b7a48b344c14691a8e92765d4023f88902ba3e96e2e4d0364d3453cdfd50db",
|
||||
"sha256:4fd07a932b4352f8a8973761ab4e84f965bf81cc750fb38e04f01088ab901cb8",
|
||||
"sha256:5b24ca47acf69222e82530e89111dd9d14f9b970ab2cd3a1c2c78f0c4fbba4f4",
|
||||
"sha256:647b3b916cc8f6aeba240c8171be3ab799c3c1b2ea179a3be0bd2712c4237553",
|
||||
"sha256:66b060946046ca27c0e03e9bec9bba3e0b918bafff84c425ca2cc2e157ce121e",
|
||||
"sha256:6efa9fa6e1434141df8872d0fa4226fc301b17aacf37429193f9d70b426ea28f",
|
||||
"sha256:be4715c9d8367e51dbe6bc6d05e205b1ae234f0dc5465931014aa1c4af44c1ba",
|
||||
"sha256:bea90da782d8e945fccfc958585210d23de374fa9294a9481ed2abcef637ebfc",
|
||||
"sha256:d318d77ab96f66a59e792a481e2701fba879e1a453aefeebdb17444fe204d1ed",
|
||||
"sha256:d785fc08d6f4207437e900ffead930a61e634c5e4f980ba6d3dc03c9581748c7",
|
||||
"sha256:de9559287c4fe8da56e8c3878d2374abc19d1ba2b807bfa7553e912a8e5ba87c",
|
||||
"sha256:f4f98b190bb918ac0bc0e3dd2ab74ff3573da9f43106f6dba6385406912ec00f",
|
||||
"sha256:f71f1a7e2d03758f6e957896ed696254e2bc83110ddbc6942018f1a232dd9dad",
|
||||
"sha256:fb944c8f0b0ab5c1f7846c686bc4cdf8cde7224655c12edcd59d5212cd57bec0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.23.4"
|
||||
},
|
||||
"pandocfilters": {
|
||||
"hashes": [
|
||||
"sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9"
|
||||
],
|
||||
"version": "==1.4.2"
|
||||
},
|
||||
"parso": {
|
||||
"hashes": [
|
||||
"sha256:35704a43a3c113cce4de228ddb39aab374b8004f4f2407d070b6a2ca784ce8a2",
|
||||
"sha256:895c63e93b94ac1e1690f5fdd40b65f07c8171e3e53cbd7793b5b96c0e0a7f24"
|
||||
],
|
||||
"version": "==0.3.1"
|
||||
},
|
||||
"pexpect": {
|
||||
"hashes": [
|
||||
"sha256:2a8e88259839571d1251d278476f3eec5db26deb73a70be5ed5dc5435e418aba",
|
||||
"sha256:3fbd41d4caf27fa4a377bfd16fef87271099463e6fa73e92a52f92dfee5d425b"
|
||||
],
|
||||
"markers": "sys_platform != 'win32'",
|
||||
"version": "==4.6.0"
|
||||
},
|
||||
"pickleshare": {
|
||||
"hashes": [
|
||||
"sha256:84a9257227dfdd6fe1b4be1319096c20eb85ff1e82c7932f36efccfe1b09737b",
|
||||
"sha256:c9a2541f25aeabc070f12f452e1f2a8eae2abd51e1cd19e8430402bdf4c1d8b5"
|
||||
],
|
||||
"version": "==0.7.4"
|
||||
},
|
||||
"prometheus-client": {
|
||||
"hashes": [
|
||||
"sha256:17bc24c09431644f7c65d7bce9f4237252308070b6395d6d8e87767afe867e24"
|
||||
],
|
||||
"version": "==0.3.1"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:1df952620eccb399c53ebb359cc7d9a8d3a9538cb34c5a1344bdbeb29fbcc381",
|
||||
"sha256:3f473ae040ddaa52b52f97f6b4a493cfa9f5920c255a12dc56a7d34397a398a4",
|
||||
"sha256:858588f1983ca497f1cf4ffde01d978a3ea02b01c8a26a8bbc5cd2e66d816917"
|
||||
],
|
||||
"version": "==1.0.15"
|
||||
},
|
||||
"ptyprocess": {
|
||||
"hashes": [
|
||||
"sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0",
|
||||
"sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f"
|
||||
],
|
||||
"markers": "os_name != 'nt'",
|
||||
"version": "==0.6.0"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
|
||||
"sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"pyparsing": {
|
||||
"hashes": [
|
||||
"sha256:0832bcf47acd283788593e7a0f542407bd9550a55a8a8435214a1960e04bcb04",
|
||||
"sha256:fee43f17a9c4087e7ed1605bd6df994c6173c1e977d7ade7b651292fab2bd010"
|
||||
],
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:1adb80e7a782c12e52ef9a8182bebeb73f1d7e24e374397af06fb4956c8dc5c0",
|
||||
"sha256:e27001de32f627c22380a688bcc43ce83504a7bc5da472209b4c70f02829f0b8"
|
||||
],
|
||||
"version": "==2.7.3"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053",
|
||||
"sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277"
|
||||
],
|
||||
"version": "==2018.5"
|
||||
},
|
||||
"pyzmq": {
|
||||
"hashes": [
|
||||
"sha256:25a0715c8f69cf72f67cfe5a68a3f3ed391c67c063d2257bec0fe7fc2c7f08f8",
|
||||
"sha256:2bab63759632c6b9e0d5bf19cc63c3b01df267d660e0abcf230cf0afaa966349",
|
||||
"sha256:30ab49d99b24bf0908ebe1cdfa421720bfab6f93174e4883075b7ff38cc555ba",
|
||||
"sha256:32c7ca9fc547a91e3c26fc6080b6982e46e79819e706eb414dd78f635a65d946",
|
||||
"sha256:41219ae72b3cc86d97557fe5b1ef5d1adc1057292ec597b50050874a970a39cf",
|
||||
"sha256:4b8c48a9a13cea8f1f16622f9bd46127108af14cd26150461e3eab71e0de3e46",
|
||||
"sha256:55724997b4a929c0d01b43c95051318e26ddbae23565018e138ae2dc60187e59",
|
||||
"sha256:65f0a4afae59d4fc0aad54a917ab599162613a761b760ba167d66cc646ac3786",
|
||||
"sha256:6f88591a8b246f5c285ee6ce5c1bf4f6bd8464b7f090b1333a446b6240a68d40",
|
||||
"sha256:75022a4c60dcd8765bb9ca32f6de75a0ec83b0d96e0309dc479f4c7b21f26cb7",
|
||||
"sha256:76ea493bfab18dcb090d825f3662b5612e2def73dffc196d51a5194b0294a81d",
|
||||
"sha256:7b60c045b80709e4e3c085bab9b691e71761b44c2b42dbb047b8b498e7bc16b3",
|
||||
"sha256:8e6af2f736734aef8ed6f278f9f552ec7f37b1a6b98e59b887484a840757f67d",
|
||||
"sha256:9ac2298e486524331e26390eac14e4627effd3f8e001d4266ed9d8f1d2d31cce",
|
||||
"sha256:9ba650f493a9bc1f24feca1d90fce0e5dd41088a252ac9840131dfbdbf3815ca",
|
||||
"sha256:a02a4a385e394e46012dc83d2e8fd6523f039bb52997c1c34a2e0dd49ed839c1",
|
||||
"sha256:a3ceee84114d9f5711fa0f4db9c652af0e4636c89eabc9b7f03a3882569dd1ed",
|
||||
"sha256:a72b82ac1910f2cf61a49139f4974f994984475f771b0faa730839607eeedddf",
|
||||
"sha256:ab136ac51027e7c484c53138a0fab4a8a51e80d05162eb7b1585583bcfdbad27",
|
||||
"sha256:c095b224300bcac61e6c445e27f9046981b1ac20d891b2f1714da89d34c637c8",
|
||||
"sha256:c5cc52d16c06dc2521340d69adda78a8e1031705924e103c0eb8fc8af861d810",
|
||||
"sha256:d612e9833a89e8177f8c1dc68d7b4ff98d3186cd331acd616b01bbdab67d3a7b",
|
||||
"sha256:e828376a23c66c6fe90dcea24b4b72cd774f555a6ee94081670872918df87a19",
|
||||
"sha256:e9767c7ab2eb552796440168d5c6e23a99ecaade08dda16266d43ad461730192",
|
||||
"sha256:ebf8b800d42d217e4710d1582b0c8bff20cdcb4faad7c7213e52644034300924"
|
||||
],
|
||||
"markers": "python_version != '3.1*' and python_version >= '2.7' and python_version != '3.2*' and python_version != '3.0*'",
|
||||
"version": "==17.1.2"
|
||||
},
|
||||
"qtconsole": {
|
||||
"hashes": [
|
||||
"sha256:298431d376d71a02eb1a04fe6e72dd4beb82b83423d58b17d532e0af838e62fa",
|
||||
"sha256:7870b19e6a6b0ab3acc09ee65463c0ca7568b3a01a6902d7c4e1ed2c4fc4e176"
|
||||
],
|
||||
"version": "==4.4.1"
|
||||
},
|
||||
"scipy": {
|
||||
"hashes": [
|
||||
"sha256:0611ee97296265af4a21164a5323f8c1b4e8e15c582d3dfa7610825900136bb7",
|
||||
"sha256:08237eda23fd8e4e54838258b124f1cd141379a5f281b0a234ca99b38918c07a",
|
||||
"sha256:0e645dbfc03f279e1946cf07c9c754c2a1859cb4a41c5f70b25f6b3a586b6dbd",
|
||||
"sha256:0e9bb7efe5f051ea7212555b290e784b82f21ffd0f655405ac4f87e288b730b3",
|
||||
"sha256:108c16640849e5827e7d51023efb3bd79244098c3f21e4897a1007720cb7ce37",
|
||||
"sha256:340ef70f5b0f4e2b4b43c8c8061165911bc6b2ad16f8de85d9774545e2c47463",
|
||||
"sha256:3ad73dfc6f82e494195144bd3a129c7241e761179b7cb5c07b9a0ede99c686f3",
|
||||
"sha256:3b243c77a822cd034dad53058d7c2abf80062aa6f4a32e9799c95d6391558631",
|
||||
"sha256:404a00314e85eca9d46b80929571b938e97a143b4f2ddc2b2b3c91a4c4ead9c5",
|
||||
"sha256:423b3ff76957d29d1cce1bc0d62ebaf9a3fdfaf62344e3fdec14619bb7b5ad3a",
|
||||
"sha256:42d9149a2fff7affdd352d157fa5717033767857c11bd55aa4a519a44343dfef",
|
||||
"sha256:625f25a6b7d795e8830cb70439453c9f163e6870e710ec99eba5722775b318f3",
|
||||
"sha256:698c6409da58686f2df3d6f815491fd5b4c2de6817a45379517c92366eea208f",
|
||||
"sha256:729f8f8363d32cebcb946de278324ab43d28096f36593be6281ca1ee86ce6559",
|
||||
"sha256:8190770146a4c8ed5d330d5b5ad1c76251c63349d25c96b3094875b930c44692",
|
||||
"sha256:878352408424dffaa695ffedf2f9f92844e116686923ed9aa8626fc30d32cfd1",
|
||||
"sha256:8b984f0821577d889f3c7ca8445564175fb4ac7c7f9659b7c60bef95b2b70e76",
|
||||
"sha256:8f841bbc21d3dad2111a94c490fb0a591b8612ffea86b8e5571746ae76a3deac",
|
||||
"sha256:c22b27371b3866c92796e5d7907e914f0e58a36d3222c5d436ddd3f0e354227a",
|
||||
"sha256:d0cdd5658b49a722783b8b4f61a6f1f9c75042d0e29a30ccb6cacc9b25f6d9e2",
|
||||
"sha256:d40dc7f494b06dcee0d303e51a00451b2da6119acbeaccf8369f2d29e28917ac",
|
||||
"sha256:d8491d4784aceb1f100ddb8e31239c54e4afab8d607928a9f7ef2469ec35ae01",
|
||||
"sha256:dfc5080c38dde3f43d8fbb9c0539a7839683475226cf83e4b24363b227dfe552",
|
||||
"sha256:e24e22c8d98d3c704bb3410bce9b69e122a8de487ad3dbfe9985d154e5c03a40",
|
||||
"sha256:e7a01e53163818d56eabddcafdc2090e9daba178aad05516b20c6591c4811020",
|
||||
"sha256:ee677635393414930541a096fc8e61634304bb0153e4e02b75685b11eba14cae",
|
||||
"sha256:f0521af1b722265d824d6ad055acfe9bd3341765735c44b5a4d0069e189a0f40",
|
||||
"sha256:f25c281f12c0da726c6ed00535ca5d1622ec755c30a3f8eafef26cf43fede694"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"seaborn": {
|
||||
"hashes": [
|
||||
"sha256:42e627b24e849c2d3bbfd059e00005f6afbc4a76e4895baf44ae23fe8a4b09a5",
|
||||
"sha256:76c83f794ca320fb6b23a7c6192d5e185a5fcf4758966a0c0a54baee46d41e2f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.9.0"
|
||||
},
|
||||
"send2trash": {
|
||||
"hashes": [
|
||||
"sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2",
|
||||
"sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b"
|
||||
],
|
||||
"version": "==1.5.0"
|
||||
},
|
||||
"simplegeneric": {
|
||||
"hashes": [
|
||||
"sha256:dc972e06094b9af5b855b3df4a646395e43d1c9d0d39ed345b7393560d0b9173"
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
|
||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
|
||||
],
|
||||
"version": "==1.11.0"
|
||||
},
|
||||
"terminado": {
|
||||
"hashes": [
|
||||
"sha256:55abf9ade563b8f9be1f34e4233c7b7bde726059947a593322e8a553cc4c067a",
|
||||
"sha256:65011551baff97f5414c67018e908110693143cfbaeb16831b743fe7cad8b927"
|
||||
],
|
||||
"version": "==0.8.1"
|
||||
},
|
||||
"testpath": {
|
||||
"hashes": [
|
||||
"sha256:039fa6a6c9fd3488f8336d23aebbfead5fa602c4a47d49d83845f55a595ec1b4",
|
||||
"sha256:0d5337839c788da5900df70f8e01015aec141aa3fe7936cb0d0a2953f7ac7609"
|
||||
],
|
||||
"version": "==0.3.1"
|
||||
},
|
||||
"tornado": {
|
||||
"hashes": [
|
||||
"sha256:0662d28b1ca9f67108c7e3b77afabfb9c7e87bde174fbda78186ecedc2499a9d",
|
||||
"sha256:4e5158d97583502a7e2739951553cbd88a72076f152b4b11b64b9a10c4c49409",
|
||||
"sha256:732e836008c708de2e89a31cb2fa6c0e5a70cb60492bee6f1ea1047500feaf7f",
|
||||
"sha256:8154ec22c450df4e06b35f131adc4f2f3a12ec85981a203301d310abf580500f",
|
||||
"sha256:8e9d728c4579682e837c92fdd98036bd5cdefa1da2aaf6acf26947e6dd0c01c5",
|
||||
"sha256:d4b3e5329f572f055b587efc57d29bd051589fb5a43ec8898c77a47ec2fa2bbb",
|
||||
"sha256:e5f2585afccbff22390cddac29849df463b252b711aa2ce7c5f3f342a5b3b444"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*'",
|
||||
"version": "==5.1.1"
|
||||
},
|
||||
"traitlets": {
|
||||
"hashes": [
|
||||
"sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835",
|
||||
"sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9"
|
||||
],
|
||||
"version": "==4.3.2"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
|
||||
],
|
||||
"version": "==0.1.7"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
|
||||
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"widgetsnbextension": {
|
||||
"hashes": [
|
||||
"sha256:14b2c65f9940c9a7d3b70adbe713dbd38b5ec69724eebaba034d1036cf3d4740",
|
||||
"sha256:fa618be8435447a017fd1bf2c7ae922d0428056cfc7449f7a8641edf76b48265"
|
||||
],
|
||||
"version": "==3.4.2"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
95
README.md
95
README.md
|
|
@ -1,50 +1,63 @@
|
|||
```
|
||||
__________ ____
|
||||
________ __ _____/ ____/ | / __ \
|
||||
/ ___/ __` / __ / / / /| | / / / /
|
||||
/ /__/ /_/ / /_/ / /___/ ___ |/ /_/ /
|
||||
\___/\__,_/\__,_/\____/_/ |_/_____/
|
||||
by BlockScience
|
||||
======================================
|
||||
Complex Adaptive Dynamics
|
||||
o i e
|
||||
m d s
|
||||
p e i
|
||||
u d g
|
||||
t n
|
||||
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.
|
||||
# SimCad
|
||||
|
||||
# Getting Started
|
||||
## 1. Installation:
|
||||
Requires [Python 3](https://www.python.org/downloads/)
|
||||
|
||||
**Option A: Install Using [pip](https://pypi.org/project/cadCAD/)**
|
||||
**Dependencies:**
|
||||
```bash
|
||||
pip3 install cadCAD
|
||||
pip install pipenv fn tabulate
|
||||
```
|
||||
|
||||
**Option B:** Build From Source
|
||||
```
|
||||
pip3 install -r requirements.txt
|
||||
python3 setup.py sdist bdist_wheel
|
||||
pip3 install dist/*.whl
|
||||
**Project:**
|
||||
|
||||
Example Run File:
|
||||
`/DiffyQ-SimCAD/test.py`
|
||||
|
||||
**User Interface: Simulation Configuration**
|
||||
|
||||
Configurations:
|
||||
```bash
|
||||
/DiffyQ-SimCAD/ui/config.py
|
||||
```
|
||||
|
||||
|
||||
## 2. Learn the basics
|
||||
**Tutorials:** available both as [Jupyter Notebooks](tutorials)
|
||||
and [videos](https://www.youtube.com/watch?v=uJEiYHRWA9g&list=PLmWm8ksQq4YKtdRV-SoinhV6LbQMgX1we)
|
||||
**Build Tool & Package Import:**
|
||||
|
||||
Step 1. Build & Install Package locally:
|
||||
```bash
|
||||
pip install .
|
||||
pip install -e .
|
||||
```
|
||||
* [Package Creation Tutorial](https://python-packaging.readthedocs.io/en/latest/minimal.html)
|
||||
|
||||
Step 2. Import Package & Run:
|
||||
```python
|
||||
from engine import run
|
||||
run.main()
|
||||
```
|
||||
|
||||
**Warning**:
|
||||
**Do Not** publish this package / software to **Any** software repository **except** [DiffyQ-SimCAD's staging branch](https://github.com/BlockScience/DiffyQ-SimCAD/tree/staging) or its **Fork**
|
||||
|
||||
**Jupyter Setup:**
|
||||
|
||||
Step 1. Create Virtual Environment:
|
||||
```bash
|
||||
cd DiffyQ-SimCAD
|
||||
pipenv run python -m ipykernel install --user --name DiffyQ-SimCAD --display-name "DiffyQ-SimCAD Env"
|
||||
```
|
||||
Step 2. Run Jupter Notebook:
|
||||
```bash
|
||||
pipenv run jupyter notebook
|
||||
```
|
||||
Step 3. Notebook Management:
|
||||
|
||||
Notebook Directory:
|
||||
|
||||
`/DiffyQ-SimCAD/notebooks/`
|
||||
|
||||
Note:
|
||||
|
||||
Notebooks should run on the `DiffyQ-SimCAD Env` kernel.
|
||||
|
||||
|
||||
|
||||
|
||||
Familiarize yourself with some system modelling concepts and cadCAD terminology.
|
||||
|
||||
## 3. Documentation:
|
||||
* [System Model Configuration](documentation)
|
||||
* [System Simulation Execution](documentation/Simulation_Execution.md)
|
||||
* [Policy Aggregation](documentation/Policy_Aggregation.md)
|
||||
* [System Model Parameter Sweep](documentation/System_Model_Parameter_Sweep.md)
|
||||
|
||||
## 4. Connect
|
||||
Find other cadCAD users at our [Discourse](https://community.cadcad.org/). We are a small but rapidly growing community.
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
Complex Adaptive Dynamics
|
||||
o i e
|
||||
m d s
|
||||
p e i
|
||||
u d g
|
||||
t n
|
||||
e
|
||||
r
|
||||
|
||||
__________ ____
|
||||
________ __ _____/ ____/ | / __ \
|
||||
/ ___/ __` / __ / / / /| | / / / /
|
||||
/ /__/ /_/ / /_/ / /___/ ___ |/ /_/ /
|
||||
\___/\__,_/\__,_/\____/_/ |_/_____/
|
||||
by BlockScience
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
name = "cadCAD"
|
||||
configs = []
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
from typing import Dict, Callable, List, Tuple
|
||||
from functools import reduce
|
||||
import pandas as pd
|
||||
from pandas.core.frame import DataFrame
|
||||
|
||||
from cadCAD import configs
|
||||
from cadCAD.utils import key_filter
|
||||
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
|
||||
|
||||
|
||||
class Configuration(object):
|
||||
def __init__(self, sim_config={}, initial_state={}, seeds={}, env_processes={},
|
||||
exogenous_states={}, partial_state_update_blocks={}, policy_ops=[lambda a, b: a + b],
|
||||
**kwargs) -> None:
|
||||
# print(exogenous_states)
|
||||
self.sim_config = sim_config
|
||||
self.initial_state = initial_state
|
||||
self.seeds = seeds
|
||||
self.env_processes = env_processes
|
||||
self.exogenous_states = exogenous_states
|
||||
self.partial_state_updates = partial_state_update_blocks
|
||||
self.policy_ops = policy_ops
|
||||
self.kwargs = kwargs
|
||||
|
||||
sanitize_config(self)
|
||||
|
||||
|
||||
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:
|
||||
exogenous_states = exo_update_per_ts(raw_exogenous_states)
|
||||
else:
|
||||
exogenous_states = raw_exogenous_states
|
||||
|
||||
if isinstance(sim_configs, dict):
|
||||
sim_configs = [sim_configs]
|
||||
|
||||
for sim_config in sim_configs:
|
||||
config = Configuration(
|
||||
sim_config=sim_config,
|
||||
initial_state=initial_state,
|
||||
seeds=seeds,
|
||||
exogenous_states=exogenous_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=partial_state_update_blocks,
|
||||
policy_ops=policy_ops
|
||||
)
|
||||
print(sim_configs)
|
||||
#for each sim config create new config
|
||||
configs.append(config)
|
||||
|
||||
|
||||
class Identity:
|
||||
def __init__(self, policy_id: Dict[str, int] = {'identity': 0}) -> None:
|
||||
self.beh_id_return_val = policy_id
|
||||
|
||||
def p_identity(self, var_dict, sub_step, sL, s):
|
||||
return self.beh_id_return_val
|
||||
|
||||
def policy_identity(self, k: str) -> Callable:
|
||||
return self.p_identity
|
||||
|
||||
def no_state_identity(self, var_dict, sub_step, sL, s, _input):
|
||||
return None
|
||||
|
||||
def state_identity(self, k: str) -> Callable:
|
||||
return lambda var_dict, sub_step, sL, s, _input: (k, s[k])
|
||||
|
||||
def apply_identity_funcs(self, identity: Callable, df: DataFrame, cols: List[str]) -> List[DataFrame]:
|
||||
def fillna_with_id_func(identity, df, col):
|
||||
return df[[col]].fillna(value=identity(col))
|
||||
|
||||
return list(map(lambda col: fillna_with_id_func(identity, df, col), cols))
|
||||
|
||||
|
||||
class Processor:
|
||||
def __init__(self, id: Identity = Identity()) -> None:
|
||||
self.id = id
|
||||
self.p_identity = id.p_identity
|
||||
self.policy_identity = id.policy_identity
|
||||
self.no_state_identity = id.no_state_identity
|
||||
self.state_identity = id.state_identity
|
||||
self.apply_identity_funcs = id.apply_identity_funcs
|
||||
|
||||
def create_matrix_field(self, partial_state_updates, key: str) -> DataFrame:
|
||||
if key == 'variables':
|
||||
identity = self.state_identity
|
||||
elif key == 'policies':
|
||||
identity = self.policy_identity
|
||||
|
||||
df = pd.DataFrame(key_filter(partial_state_updates, key))
|
||||
col_list = self.apply_identity_funcs(identity, df, list(df.columns))
|
||||
if len(col_list) != 0:
|
||||
return reduce((lambda x, y: pd.concat([x, y], axis=1)), col_list)
|
||||
else:
|
||||
return pd.DataFrame({'empty': []})
|
||||
|
||||
def generate_config(self, initial_state, partial_state_updates, exo_proc
|
||||
) -> List[Tuple[List[Callable], List[Callable]]]:
|
||||
|
||||
def no_update_handler(bdf, sdf):
|
||||
if (bdf.empty == False) and (sdf.empty == True):
|
||||
bdf_values = bdf.values.tolist()
|
||||
sdf_values = [[self.no_state_identity] * len(bdf_values) for m in range(len(partial_state_updates))]
|
||||
return sdf_values, bdf_values
|
||||
elif (bdf.empty == True) and (sdf.empty == False):
|
||||
sdf_values = sdf.values.tolist()
|
||||
bdf_values = [[self.p_identity] * len(sdf_values) for m in range(len(partial_state_updates))]
|
||||
return sdf_values, bdf_values
|
||||
else:
|
||||
sdf_values = sdf.values.tolist()
|
||||
bdf_values = bdf.values.tolist()
|
||||
return sdf_values, bdf_values
|
||||
|
||||
def only_ep_handler(state_dict):
|
||||
sdf_functions = [
|
||||
lambda var_dict, sub_step, sL, s, _input: (k, v) for k, v in zip(state_dict.keys(), state_dict.values())
|
||||
]
|
||||
sdf_values = [sdf_functions]
|
||||
bdf_values = [[self.p_identity] * len(sdf_values)]
|
||||
return sdf_values, bdf_values
|
||||
|
||||
if len(partial_state_updates) != 0:
|
||||
# backwards compatibility # ToDo: Move this
|
||||
partial_state_updates = sanitize_partial_state_updates(partial_state_updates)
|
||||
|
||||
bdf = self.create_matrix_field(partial_state_updates, 'policies')
|
||||
sdf = self.create_matrix_field(partial_state_updates, 'variables')
|
||||
sdf_values, bdf_values = no_update_handler(bdf, sdf)
|
||||
zipped_list = list(zip(sdf_values, bdf_values))
|
||||
else:
|
||||
sdf_values, bdf_values = only_ep_handler(initial_state)
|
||||
zipped_list = list(zip(sdf_values, bdf_values))
|
||||
|
||||
return list(map(lambda x: (x[0] + exo_proc, x[1]), zipped_list))
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
from datetime import datetime, timedelta
|
||||
from copy import deepcopy
|
||||
from functools import reduce
|
||||
from fn.func import curried
|
||||
from funcy import curry
|
||||
import pandas as pd
|
||||
|
||||
from cadCAD.configuration.utils.depreciationHandler import sanitize_partial_state_updates
|
||||
from cadCAD.utils import dict_filter, contains_type, flatten_tabulated_dict, tabulate_dict
|
||||
|
||||
|
||||
class TensorFieldReport:
|
||||
def __init__(self, config_proc):
|
||||
self.config_proc = config_proc
|
||||
|
||||
# ToDo: backwards compatibility
|
||||
def create_tensor_field(self, partial_state_updates, exo_proc, keys = ['policies', 'variables']):
|
||||
|
||||
partial_state_updates = sanitize_partial_state_updates(partial_state_updates) # Temporary
|
||||
|
||||
dfs = [self.config_proc.create_matrix_field(partial_state_updates, k) for k in keys]
|
||||
df = pd.concat(dfs, axis=1)
|
||||
for es, i in zip(exo_proc, range(len(exo_proc))):
|
||||
df['es' + str(i + 1)] = es
|
||||
df['m'] = df.index + 1
|
||||
return df
|
||||
|
||||
|
||||
def state_update(y, x):
|
||||
return lambda var_dict, sub_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:
|
||||
res = bound_norm_random(rng, low, high)
|
||||
# return Decimal(res)
|
||||
return float(res)
|
||||
|
||||
|
||||
@curried
|
||||
def env_proc_trigger(timestep, f, time):
|
||||
if time == timestep:
|
||||
return f
|
||||
else:
|
||||
return lambda x: x
|
||||
|
||||
|
||||
tstep_delta = timedelta(days=0, minutes=0, seconds=30)
|
||||
def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', _timedelta = tstep_delta):
|
||||
# print(dt_str)
|
||||
dt = datetime.strptime(dt_str, dt_format)
|
||||
t = dt + _timedelta
|
||||
return t.strftime(dt_format)
|
||||
|
||||
|
||||
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)
|
||||
if s_condition:
|
||||
return time_step(dt_str, fromat_str, _timedelta)
|
||||
else:
|
||||
return dt_str
|
||||
|
||||
|
||||
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([
|
||||
(k, dict_filter(v, lambda v: isinstance(v, list))) for k, v in partial_state_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_partial_states(_type, in_config):
|
||||
configs = []
|
||||
# filtered_mech_states
|
||||
filtered_partial_states = partial_state_sweep_filter(_type, in_config.partial_state_updates)
|
||||
if len(filtered_partial_states) > 0:
|
||||
for partial_state, state_dict in filtered_partial_states.items():
|
||||
for state, state_funcs in state_dict.items():
|
||||
for f in state_funcs:
|
||||
config = deepcopy(in_config)
|
||||
config.partial_state_updates[partial_state][_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, var_dict, sub_step, sL, s, _input):
|
||||
if s['substep'] + 1 == 1:
|
||||
return f(var_dict, sub_step, sL, s, _input)
|
||||
else:
|
||||
return y, s[y]
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def var_substep_trigger(substeps):
|
||||
def trigger(end_substep, y, f):
|
||||
pre_conditions = {'substep': substeps}
|
||||
cond_opp = lambda a, b: a and b
|
||||
return var_trigger(y, f, pre_conditions, cond_opp)
|
||||
|
||||
return lambda y, f: curry(trigger)(substeps)(y)(f)
|
||||
|
||||
|
||||
def env_trigger(end_substep):
|
||||
def trigger(end_substep, trigger_field, trigger_vals, funct_list):
|
||||
def env_update(state_dict, sweep_dict, target_value):
|
||||
state_dict_copy = deepcopy(state_dict)
|
||||
# Use supstep to simulate current sysMetrics
|
||||
if state_dict_copy['substep'] == end_substep:
|
||||
state_dict_copy['timestep'] = state_dict_copy['timestep'] + 1
|
||||
|
||||
if state_dict_copy[trigger_field] in trigger_vals:
|
||||
for g in funct_list:
|
||||
target_value = g(sweep_dict, target_value)
|
||||
|
||||
del state_dict_copy
|
||||
return target_value
|
||||
|
||||
return env_update
|
||||
|
||||
return lambda trigger_field, trigger_vals, funct_list: \
|
||||
curry(trigger)(end_substep)(trigger_field)(trigger_vals)(funct_list)
|
||||
|
||||
|
||||
def config_sim(d):
|
||||
def process_variables(d):
|
||||
return flatten_tabulated_dict(tabulate_dict(d))
|
||||
|
||||
if "M" in d:
|
||||
return [{"N": d["N"], "T": d["T"], "M": M} for M in process_variables(d["M"])]
|
||||
else:
|
||||
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):
|
||||
filtered_policies = {k: v for (k, v) in policies.items() if k in policy_ids}
|
||||
filtered_state_updates = {k: v for (k, v) in state_updates.items() if k in state_list}
|
||||
PSUBS.append(psub(filtered_policies, filtered_state_updates))
|
||||
|
||||
return PSUBS
|
||||
|
||||
|
||||
def access_block(state_history, target_field, psu_block_offset, exculsion_list=[]):
|
||||
exculsion_list += [target_field]
|
||||
def filter_history(key_list, sH):
|
||||
filter = lambda key_list: \
|
||||
lambda d: {k: v for k, v in d.items() if k not in key_list}
|
||||
return list(map(filter(key_list), sH))
|
||||
|
||||
if psu_block_offset < -1:
|
||||
if len(state_history) >= abs(psu_block_offset):
|
||||
return filter_history(exculsion_list, state_history[psu_block_offset])
|
||||
else:
|
||||
return []
|
||||
elif psu_block_offset == -1:
|
||||
return filter_history(exculsion_list, state_history[psu_block_offset])
|
||||
else:
|
||||
return []
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
from copy import deepcopy
|
||||
|
||||
|
||||
def sanitize_config(config):
|
||||
for key, value in config.kwargs.items():
|
||||
if key == 'state_dict':
|
||||
config.initial_state = value
|
||||
elif key == 'seed':
|
||||
config.seeds = value
|
||||
elif key == 'mechanisms':
|
||||
config.partial_state_updates = value
|
||||
|
||||
if config.initial_state == {}:
|
||||
raise Exception('The initial conditions of the system have not been set')
|
||||
|
||||
|
||||
def sanitize_partial_state_updates(partial_state_updates):
|
||||
new_partial_state_updates = deepcopy(partial_state_updates)
|
||||
def rename_keys(d):
|
||||
if 'behaviors' in d:
|
||||
d['policies'] = d.pop('behaviors')
|
||||
|
||||
if 'states' in d:
|
||||
d['variables'] = d.pop('states')
|
||||
|
||||
|
||||
if isinstance(new_partial_state_updates, list):
|
||||
for v in new_partial_state_updates:
|
||||
rename_keys(v)
|
||||
elif isinstance(new_partial_state_updates, dict):
|
||||
for k, v in new_partial_state_updates.items():
|
||||
rename_keys(v)
|
||||
|
||||
del partial_state_updates
|
||||
return new_partial_state_updates
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
from fn.op import foldr
|
||||
from fn.func import curried
|
||||
|
||||
|
||||
def get_base_value(x):
|
||||
if isinstance(x, str):
|
||||
return ''
|
||||
elif isinstance(x, int):
|
||||
return 0
|
||||
elif isinstance(x, list):
|
||||
return []
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def policy_to_dict(v):
|
||||
return dict(list(zip(map(lambda n: 'p' + str(n + 1), list(range(len(v)))), v)))
|
||||
|
||||
|
||||
add = lambda a, b: a + b
|
||||
|
||||
|
||||
@curried
|
||||
def foldr_dict_vals(f, d):
|
||||
return foldr(f)(list(d.values()))
|
||||
|
||||
|
||||
def sum_dict_values():
|
||||
return foldr_dict_vals(add)
|
||||
|
||||
|
||||
@curried
|
||||
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(source_dict[key])
|
||||
else:
|
||||
return target_dict[key]
|
||||
|
||||
key_set = set(list(d1.keys()) + list(d2.keys()))
|
||||
|
||||
return {k: f(set_base_value(d1, d2, k), set_base_value(d2, d1, k)) for k in key_set}
|
||||
|
||||
def dict_elemwise_sum():
|
||||
return dict_op(add)
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
from collections import namedtuple
|
||||
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
|
||||
|
||||
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 isinstance(v, DataFrame) is not True
|
||||
}
|
||||
members['methods'] = [k for k, v in self.__dict__.items() if str(type(v)) == "<class 'method'>"]
|
||||
|
||||
members.update(variables)
|
||||
return f"{members}"
|
||||
|
||||
|
||||
class udcBroker(object):
|
||||
def __init__(self, obj, function_filter=['__init__']):
|
||||
d = {}
|
||||
funcs = dict(getmembers(obj, ismethod))
|
||||
filtered_functions = {k: v for k, v in funcs.items() if k not in function_filter}
|
||||
d['obj'] = obj
|
||||
# d.update(deepcopy(vars(obj))) # somehow is enough
|
||||
d.update(vars(obj)) # somehow is enough
|
||||
d.update(filtered_functions)
|
||||
|
||||
self.members_dict = d
|
||||
|
||||
def get_members(self):
|
||||
return self.members_dict
|
||||
|
||||
def get_view(self, masked_members):
|
||||
return udcView(self.members_dict, masked_members)
|
||||
|
||||
def get_namedtuple(self):
|
||||
return namedtuple("Hydra", self.members_dict.keys())(*self.members_dict.values())
|
||||
|
||||
|
||||
def UDO(udo, masked_members=['obj']):
|
||||
return udcBroker(udo).get_view(masked_members)
|
||||
|
||||
|
||||
def udoPipe(obj_view):
|
||||
return UDO(obj_view.obj, obj_view.masked_members)
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
from typing import Callable, Dict, List, Any, Tuple
|
||||
from pathos.multiprocessing import ProcessingPool as PPool
|
||||
from pandas.core.frame import DataFrame
|
||||
|
||||
from cadCAD.utils import flatten
|
||||
from cadCAD.configuration import Configuration, Processor
|
||||
from cadCAD.configuration.utils import TensorFieldReport
|
||||
from cadCAD.engine.simulation import Executor as SimExecutor
|
||||
|
||||
VarDictType = Dict[str, List[Any]]
|
||||
StatesListsType = List[Dict[str, Any]]
|
||||
ConfigsType = List[Tuple[List[Callable], List[Callable]]]
|
||||
EnvProcessesType = Dict[str, Callable]
|
||||
|
||||
|
||||
class ExecutionMode:
|
||||
single_proc = 'single_proc'
|
||||
multi_proc = 'multi_proc'
|
||||
|
||||
|
||||
def single_proc_exec(
|
||||
simulation_execs: List[Callable],
|
||||
var_dict_list: List[VarDictType],
|
||||
states_lists: List[StatesListsType],
|
||||
configs_structs: List[ConfigsType],
|
||||
env_processes_list: List[EnvProcessesType],
|
||||
Ts: List[range],
|
||||
Ns: List[int]
|
||||
):
|
||||
l = [simulation_execs, states_lists, configs_structs, env_processes_list, Ts, Ns]
|
||||
simulation_exec, states_list, config, env_processes, T, N = list(map(lambda x: x.pop(), l))
|
||||
result = simulation_exec(var_dict_list, states_list, config, env_processes, T, N)
|
||||
return flatten(result)
|
||||
|
||||
|
||||
def parallelize_simulations(
|
||||
simulation_execs: List[Callable],
|
||||
var_dict_list: List[VarDictType],
|
||||
states_lists: List[StatesListsType],
|
||||
configs_structs: List[ConfigsType],
|
||||
env_processes_list: List[EnvProcessesType],
|
||||
Ts: List[range],
|
||||
Ns: List[int]
|
||||
):
|
||||
l = list(zip(simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, Ns))
|
||||
with PPool(len(configs_structs)) as p:
|
||||
results = p.map(lambda t: t[0](t[1], t[2], t[3], t[4], t[5], t[6]), l)
|
||||
return results
|
||||
|
||||
|
||||
class ExecutionContext:
|
||||
def __init__(self, context: str = ExecutionMode.multi_proc) -> None:
|
||||
self.name = context
|
||||
self.method = None
|
||||
|
||||
if context == 'single_proc':
|
||||
self.method = single_proc_exec
|
||||
elif context == 'multi_proc':
|
||||
self.method = parallelize_simulations
|
||||
|
||||
|
||||
class Executor:
|
||||
def __init__(self, exec_context: ExecutionContext, configs: List[Configuration]) -> None:
|
||||
self.SimExecutor = SimExecutor
|
||||
self.exec_method = exec_context.method
|
||||
self.exec_context = exec_context.name
|
||||
self.configs = configs
|
||||
|
||||
def execute(self) -> Tuple[List[Dict[str, Any]], DataFrame]:
|
||||
config_proc = Processor()
|
||||
create_tensor_field = TensorFieldReport(config_proc).create_tensor_field
|
||||
|
||||
|
||||
print(r'''
|
||||
__________ ____
|
||||
________ __ _____/ ____/ | / __ \
|
||||
/ ___/ __` / __ / / / /| | / / / /
|
||||
/ /__/ /_/ / /_/ / /___/ ___ |/ /_/ /
|
||||
\___/\__,_/\__,_/\____/_/ |_/_____/
|
||||
by BlockScience
|
||||
''')
|
||||
print(f'Execution Mode: {self.exec_context + ": " + str(self.configs)}')
|
||||
print(f'Configurations: {self.configs}')
|
||||
|
||||
var_dict_list, states_lists, Ts, Ns, eps, configs_structs, env_processes_list, partial_state_updates, simulation_execs = \
|
||||
[], [], [], [], [], [], [], [], []
|
||||
config_idx = 0
|
||||
|
||||
for x in self.configs:
|
||||
|
||||
Ts.append(x.sim_config['T'])
|
||||
Ns.append(x.sim_config['N'])
|
||||
var_dict_list.append(x.sim_config['M'])
|
||||
states_lists.append([x.initial_state])
|
||||
eps.append(list(x.exogenous_states.values()))
|
||||
configs_structs.append(config_proc.generate_config(x.initial_state, x.partial_state_updates, eps[config_idx]))
|
||||
# print(env_processes_list)
|
||||
env_processes_list.append(x.env_processes)
|
||||
partial_state_updates.append(x.partial_state_updates)
|
||||
simulation_execs.append(SimExecutor(x.policy_ops).simulation)
|
||||
|
||||
config_idx += 1
|
||||
|
||||
final_result = None
|
||||
|
||||
if self.exec_context == ExecutionMode.single_proc:
|
||||
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
|
||||
elif self.exec_context == ExecutionMode.multi_proc:
|
||||
# if len(self.configs) > 1:
|
||||
simulations = self.exec_method(simulation_execs, var_dict_list, states_lists, configs_structs, env_processes_list, Ts, Ns)
|
||||
results = []
|
||||
for result, partial_state_updates, ep in list(zip(simulations, partial_state_updates, eps)):
|
||||
results.append((flatten(result), create_tensor_field(partial_state_updates, ep)))
|
||||
|
||||
final_result = results
|
||||
|
||||
return final_result
|
||||
|
|
@ -1,234 +0,0 @@
|
|||
from typing import Any, Callable, Dict, List, Tuple
|
||||
from pathos.pools import ThreadPool as TPool
|
||||
from copy import deepcopy
|
||||
from functools import reduce
|
||||
|
||||
from cadCAD.engine.utils import engine_exception
|
||||
from cadCAD.utils import flatten
|
||||
|
||||
id_exception: Callable = engine_exception(KeyError, KeyError, None)
|
||||
|
||||
|
||||
class Executor:
|
||||
def __init__(
|
||||
self,
|
||||
policy_ops: List[Callable],
|
||||
policy_update_exception: Callable = id_exception,
|
||||
state_update_exception: Callable = id_exception
|
||||
) -> None:
|
||||
|
||||
self.policy_ops = policy_ops
|
||||
self.state_update_exception = state_update_exception
|
||||
self.policy_update_exception = policy_update_exception
|
||||
|
||||
def get_policy_input(
|
||||
self,
|
||||
sweep_dict: Dict[str, List[Any]],
|
||||
sub_step: int,
|
||||
sL: List[Dict[str, Any]],
|
||||
s: Dict[str, Any],
|
||||
funcs: List[Callable]
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
ops = self.policy_ops
|
||||
|
||||
def get_col_results(sweep_dict, sub_step, sL, s, funcs):
|
||||
return list(map(lambda f: f(sweep_dict, sub_step, sL, s), funcs))
|
||||
|
||||
def compose(init_reduction_funct, funct_list, val_list):
|
||||
result, i = None, 0
|
||||
composition = lambda x: [reduce(init_reduction_funct, x)] + funct_list
|
||||
for g in composition(val_list):
|
||||
if i == 0:
|
||||
result = g
|
||||
i = 1
|
||||
else:
|
||||
result = g(result)
|
||||
return result
|
||||
|
||||
col_results = get_col_results(sweep_dict, sub_step, sL, s, funcs)
|
||||
key_set = list(set(list(reduce(lambda a, b: a + b, list(map(lambda x: list(x.keys()), col_results))))))
|
||||
new_dict = {k: [] for k in key_set}
|
||||
for d in col_results:
|
||||
for k in d.keys():
|
||||
new_dict[k].append(d[k])
|
||||
|
||||
ops_head, *ops_tail = ops
|
||||
return {
|
||||
k: compose(
|
||||
init_reduction_funct=ops_head, # func executed on value list
|
||||
funct_list=ops_tail,
|
||||
val_list=val_list
|
||||
) for k, val_list in new_dict.items()
|
||||
}
|
||||
|
||||
|
||||
def apply_env_proc(
|
||||
self,
|
||||
sweep_dict,
|
||||
env_processes: Dict[str, Callable],
|
||||
state_dict: Dict[str, Any],
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
def env_composition(target_field, state_dict, target_value):
|
||||
function_type = type(lambda x: x)
|
||||
env_update = env_processes[target_field]
|
||||
if isinstance(env_update, list):
|
||||
for f in env_update:
|
||||
target_value = f(sweep_dict, target_value)
|
||||
elif isinstance(env_update, function_type):
|
||||
target_value = env_update(state_dict, sweep_dict, target_value)
|
||||
else:
|
||||
target_value = env_update
|
||||
|
||||
return target_value
|
||||
|
||||
filtered_state_dict = {k: v for k, v in state_dict.items() if k in env_processes.keys()}
|
||||
env_proc_dict = {
|
||||
target_field: env_composition(target_field, state_dict, target_value)
|
||||
for target_field, target_value in filtered_state_dict.items()
|
||||
}
|
||||
|
||||
for k, v in env_proc_dict.items():
|
||||
state_dict[k] = v
|
||||
|
||||
return state_dict
|
||||
|
||||
# mech_step
|
||||
def partial_state_update(
|
||||
self,
|
||||
sweep_dict: Dict[str, List[Any]],
|
||||
sub_step: int,
|
||||
sL: Any,
|
||||
sH: Any,
|
||||
state_funcs: List[Callable],
|
||||
policy_funcs: List[Callable],
|
||||
env_processes: Dict[str, Callable],
|
||||
time_step: int,
|
||||
run: int
|
||||
) -> List[Dict[str, Any]]:
|
||||
|
||||
last_in_obj: Dict[str, Any] = deepcopy(sL[-1])
|
||||
_input: Dict[str, Any] = self.policy_update_exception(
|
||||
self.get_policy_input(sweep_dict, sub_step, sH, last_in_obj, policy_funcs)
|
||||
)
|
||||
|
||||
|
||||
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))
|
||||
|
||||
def transfer_missing_fields(source, destination):
|
||||
for k in source:
|
||||
if k not in destination:
|
||||
destination[k] = source[k]
|
||||
del source # last_in_obj
|
||||
return destination
|
||||
|
||||
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)
|
||||
last_in_copy['substep'], last_in_copy['timestep'], last_in_copy['run'] = sub_step, time_step, run
|
||||
|
||||
sL.append(last_in_copy)
|
||||
del last_in_copy
|
||||
|
||||
return sL
|
||||
|
||||
# mech_pipeline - state_update_block
|
||||
def state_update_pipeline(
|
||||
self,
|
||||
sweep_dict: Dict[str, List[Any]],
|
||||
simulation_list, #states_list: List[Dict[str, Any]],
|
||||
configs: List[Tuple[List[Callable], List[Callable]]],
|
||||
env_processes: Dict[str, Callable],
|
||||
time_step: int,
|
||||
run: int
|
||||
) -> List[Dict[str, Any]]:
|
||||
|
||||
sub_step = 0
|
||||
states_list_copy: List[Dict[str, Any]] = deepcopy(simulation_list[-1])
|
||||
genesis_states: Dict[str, Any] = states_list_copy[-1]
|
||||
|
||||
if len(states_list_copy) == 1:
|
||||
genesis_states['substep'] = sub_step
|
||||
# genesis_states['timestep'] = 0
|
||||
# else:
|
||||
# genesis_states['timestep'] = time_step
|
||||
|
||||
del states_list_copy
|
||||
states_list: List[Dict[str, Any]] = [genesis_states]
|
||||
|
||||
sub_step += 1
|
||||
|
||||
for [s_conf, p_conf] in configs: # tensor field
|
||||
|
||||
states_list: List[Dict[str, Any]] = self.partial_state_update(
|
||||
sweep_dict, sub_step, states_list, simulation_list, s_conf, p_conf, env_processes, time_step, run
|
||||
)
|
||||
sub_step += 1
|
||||
|
||||
time_step += 1
|
||||
|
||||
return states_list
|
||||
|
||||
# state_update_pipeline
|
||||
def run_pipeline(
|
||||
self,
|
||||
sweep_dict: Dict[str, List[Any]],
|
||||
states_list: List[Dict[str, Any]],
|
||||
configs: List[Tuple[List[Callable], List[Callable]]],
|
||||
env_processes: Dict[str, Callable],
|
||||
time_seq: range,
|
||||
run: int
|
||||
) -> List[List[Dict[str, Any]]]:
|
||||
|
||||
time_seq: List[int] = [x + 1 for x in time_seq]
|
||||
simulation_list: List[List[Dict[str, Any]]] = [states_list]
|
||||
|
||||
for time_step in time_seq:
|
||||
pipe_run: List[Dict[str, Any]] = self.state_update_pipeline(
|
||||
sweep_dict, simulation_list, configs, env_processes, time_step, run
|
||||
)
|
||||
|
||||
_, *pipe_run = pipe_run
|
||||
simulation_list.append(pipe_run)
|
||||
|
||||
return simulation_list
|
||||
|
||||
def simulation(
|
||||
self,
|
||||
sweep_dict: Dict[str, List[Any]],
|
||||
states_list: List[Dict[str, Any]],
|
||||
configs: List[Tuple[List[Callable], List[Callable]]],
|
||||
env_processes: Dict[str, Callable],
|
||||
time_seq: range,
|
||||
runs: int
|
||||
) -> List[List[Dict[str, Any]]]:
|
||||
|
||||
def execute_run(sweep_dict, states_list, configs, env_processes, time_seq, run) -> List[Dict[str, Any]]:
|
||||
run += 1
|
||||
|
||||
def generate_init_sys_metrics(genesis_states_list):
|
||||
for d in genesis_states_list:
|
||||
d['run'], d['substep'], d['timestep'] = run, 0, 0
|
||||
yield d
|
||||
|
||||
states_list_copy: List[Dict[str, Any]] = list(generate_init_sys_metrics(deepcopy(states_list)))
|
||||
|
||||
first_timestep_per_run: List[Dict[str, Any]] = self.run_pipeline(
|
||||
sweep_dict, states_list_copy, configs, env_processes, time_seq, run
|
||||
)
|
||||
del states_list_copy
|
||||
|
||||
return first_timestep_per_run
|
||||
|
||||
tp = TPool(runs)
|
||||
pipe_run: List[List[Dict[str, Any]]] = flatten(
|
||||
tp.map(
|
||||
lambda run: execute_run(sweep_dict, states_list, configs, env_processes, time_seq, run),
|
||||
list(range(runs))
|
||||
)
|
||||
)
|
||||
|
||||
tp.clear()
|
||||
return pipe_run
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
from datetime import datetime
|
||||
from fn.func import curried
|
||||
|
||||
|
||||
def datetime_range(start, end, delta, dt_format='%Y-%m-%d %H:%M:%S'):
|
||||
reverse_head = end
|
||||
[start, end] = [datetime.strptime(x, dt_format) for x in [start, end]]
|
||||
|
||||
def _datetime_range(start, end, delta):
|
||||
current = start
|
||||
while current < end:
|
||||
yield current
|
||||
current += delta
|
||||
|
||||
reverse_tail = [dt.strftime(dt_format) for dt in _datetime_range(start, end, delta)]
|
||||
return reverse_tail + [reverse_head]
|
||||
|
||||
|
||||
def last_index(l):
|
||||
return len(l)-1
|
||||
|
||||
|
||||
def retrieve_state(l, offset):
|
||||
return l[last_index(l) + offset + 1]
|
||||
|
||||
|
||||
@curried
|
||||
def engine_exception(ErrorType, error_message, exception_function, try_function):
|
||||
try:
|
||||
return try_function
|
||||
except ErrorType:
|
||||
print(error_message)
|
||||
return exception_function
|
||||
|
||||
|
||||
@curried
|
||||
def fit_param(param, x):
|
||||
return x + param
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
from functools import reduce
|
||||
from typing import Dict, List
|
||||
from collections import defaultdict, Counter
|
||||
from itertools import product
|
||||
import warnings
|
||||
|
||||
from pandas import DataFrame
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
class IndexCounter:
|
||||
def __init__(self):
|
||||
self.i = 0
|
||||
|
||||
def __call__(self):
|
||||
self.i += 1
|
||||
return self.i
|
||||
|
||||
|
||||
def compose(*functions):
|
||||
return reduce(lambda f, g: lambda x: f(g(x)), functions, lambda x: x)
|
||||
|
||||
def pipe(x):
|
||||
return x
|
||||
|
||||
|
||||
def print_pipe(x):
|
||||
print(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: Dict[str, List[int]]) -> int:
|
||||
return len(max(g.values(), key=len))
|
||||
|
||||
|
||||
def tabulate_dict(d: Dict[str, List[int]]) -> Dict[str, List[int]]:
|
||||
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: Dict[str, List[int]]) -> List[Dict[str, int]]:
|
||||
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):
|
||||
if (type(l) == list):
|
||||
return [v[keyname] for v in l]
|
||||
# Keeping support to dictionaries for backwards compatibility
|
||||
# Should be removed in the future
|
||||
warnings.warn(
|
||||
"The use of a dictionary to describe Partial State Update Blocks will be deprecated. Use a list instead.",
|
||||
FutureWarning)
|
||||
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')
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
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:
|
||||
return y, time_step(dt_str=s[y], dt_format=ts_format, _timedelta=time_delta)
|
||||
else:
|
||||
return y, s[y]
|
||||
return lambda _g, step, sL, s, _input: apply_incriment_condition(s)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,91 +0,0 @@
|
|||
Historical State Access
|
||||
==
|
||||
#### Motivation
|
||||
The current state (values of state variables) is accessed through the `s` list. When the user requires previous state variable values, they may be accessed through the state history list, `sH`. Accessing the state history should be implemented without creating unintended feedback loops on the current state.
|
||||
|
||||
The 3rd parameter of state and policy update functions (labeled as `sH` of type `List[List[dict]]`) provides access to past Partial State Update Block (PSUB) given a negative offset number. `access_block` is used to access past PSUBs (`List[dict]`) from `sH`. For example, an offset of `-2` denotes the second to last PSUB.
|
||||
|
||||
#### Exclusion List
|
||||
Create a list of states to exclude from the reported PSU.
|
||||
```python
|
||||
exclusion_list = [
|
||||
'nonexistent', 'last_x', '2nd_to_last_x', '3rd_to_last_x', '4th_to_last_x'
|
||||
]
|
||||
```
|
||||
##### Example Policy Updates
|
||||
###### Last partial state update
|
||||
```python
|
||||
def last_update(_params, substep, sH, s):
|
||||
return {"last_x": access_block(
|
||||
state_history=sH,
|
||||
target_field="last_x", # Add a field to the exclusion list
|
||||
psu_block_offset=-1,
|
||||
exculsion_list=exclusion_list
|
||||
)
|
||||
}
|
||||
```
|
||||
* Note: Although `target_field` adding a field to the exclusion may seem redundant, it is useful in the case of the exclusion list being empty while the `target_field` is assigned to a state or a policy key.
|
||||
##### Define State Updates
|
||||
###### 2nd to last partial state update
|
||||
```python
|
||||
def second2last_update(_params, substep, sH, s):
|
||||
return {"2nd_to_last_x": access_block(sH, "2nd_to_last_x", -2, exclusion_list)}
|
||||
```
|
||||
|
||||
|
||||
###### 3rd to last partial state update
|
||||
```python
|
||||
def third_to_last_x(_params, substep, sH, s, _input):
|
||||
return '3rd_to_last_x', access_block(sH, "3rd_to_last_x", -3, exclusion_list)
|
||||
```
|
||||
###### 4rd to last partial state update
|
||||
```python
|
||||
def fourth_to_last_x(_params, substep, sH, s, _input):
|
||||
return '4th_to_last_x', access_block(sH, "4th_to_last_x", -4, exclusion_list)
|
||||
```
|
||||
###### Non-exsistent partial state update
|
||||
* `psu_block_offset >= 0` doesn't exist
|
||||
```python
|
||||
def nonexistent(_params, substep, sH, s, _input):
|
||||
return 'nonexistent', access_block(sH, "nonexistent", 0, exclusion_list)
|
||||
```
|
||||
|
||||
#### [Example Simulation:](examples/historical_state_access.py)
|
||||
|
||||
|
||||
#### Example Output:
|
||||
###### State History
|
||||
```
|
||||
+----+-------+-----------+------------+-----+
|
||||
| | run | substep | timestep | x |
|
||||
|----+-------+-----------+------------+-----|
|
||||
| 0 | 1 | 0 | 0 | 0 |
|
||||
| 1 | 1 | 1 | 1 | 1 |
|
||||
| 2 | 1 | 2 | 1 | 2 |
|
||||
| 3 | 1 | 3 | 1 | 3 |
|
||||
| 4 | 1 | 1 | 2 | 4 |
|
||||
| 5 | 1 | 2 | 2 | 5 |
|
||||
| 6 | 1 | 3 | 2 | 6 |
|
||||
| 7 | 1 | 1 | 3 | 7 |
|
||||
| 8 | 1 | 2 | 3 | 8 |
|
||||
| 9 | 1 | 3 | 3 | 9 |
|
||||
+----+-------+-----------+------------+-----+
|
||||
```
|
||||
###### Accessed State History:
|
||||
Example: `last_x`
|
||||
```
|
||||
+----+-----------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| | last_x |
|
||||
|----+-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 0 | [] |
|
||||
| 1 | [{'x': 0, 'run': 1, 'substep': 0, 'timestep': 0}] |
|
||||
| 2 | [{'x': 0, 'run': 1, 'substep': 0, 'timestep': 0}] |
|
||||
| 3 | [{'x': 0, 'run': 1, 'substep': 0, 'timestep': 0}] |
|
||||
| 4 | [{'x': 1, 'run': 1, 'substep': 1, 'timestep': 1}, {'x': 2, 'run': 1, 'substep': 2, 'timestep': 1}, {'x': 3, 'run': 1, 'substep': 3, 'timestep': 1}] |
|
||||
| 5 | [{'x': 1, 'run': 1, 'substep': 1, 'timestep': 1}, {'x': 2, 'run': 1, 'substep': 2, 'timestep': 1}, {'x': 3, 'run': 1, 'substep': 3, 'timestep': 1}] |
|
||||
| 6 | [{'x': 1, 'run': 1, 'substep': 1, 'timestep': 1}, {'x': 2, 'run': 1, 'substep': 2, 'timestep': 1}, {'x': 3, 'run': 1, 'substep': 3, 'timestep': 1}] |
|
||||
| 7 | [{'x': 4, 'run': 1, 'substep': 1, 'timestep': 2}, {'x': 5, 'run': 1, 'substep': 2, 'timestep': 2}, {'x': 6, 'run': 1, 'substep': 3, 'timestep': 2}] |
|
||||
| 8 | [{'x': 4, 'run': 1, 'substep': 1, 'timestep': 2}, {'x': 5, 'run': 1, 'substep': 2, 'timestep': 2}, {'x': 6, 'run': 1, 'substep': 3, 'timestep': 2}] |
|
||||
| 9 | [{'x': 4, 'run': 1, 'substep': 1, 'timestep': 2}, {'x': 5, 'run': 1, 'substep': 2, 'timestep': 2}, {'x': 6, 'run': 1, 'substep': 3, 'timestep': 2}] |
|
||||
+----+-----------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
```
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
Policy Aggregation
|
||||
==
|
||||
|
||||
For each Partial State Update, multiple policy dictionaries are aggregated into a single dictionary to be imputted into
|
||||
all state functions using an initial reduction function and optional subsequent map functions.
|
||||
|
||||
#### Aggregate Function Composition:
|
||||
```python
|
||||
# Reduce Function
|
||||
add = lambda a, b: a + b # Used to add policy values of the same key
|
||||
# Map Function
|
||||
mult_by_2 = lambda y: y * 2 # Used to multiply all policy values by 2
|
||||
policy_ops=[add, mult_by_2]
|
||||
```
|
||||
|
||||
##### Example Policy Updates per Partial State Update (PSU)
|
||||
```python
|
||||
def p1_psu1(_params, step, sH, s):
|
||||
return {'policy1': 1}
|
||||
def p2_psu1(_params, step, sH, s):
|
||||
return {'policy2': 2}
|
||||
```
|
||||
* `add` not applicable due to lack of redundant policies
|
||||
* `mult_by_2` applied to all policies
|
||||
* Result: `{'policy1': 2, 'policy2': 4}`
|
||||
|
||||
```python
|
||||
def p1_psu2(_params, step, sH, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
def p2_psu2(_params, step, sH, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
```
|
||||
* `add` applicable due to redundant policies
|
||||
* `mult_by_2` applied to all policies
|
||||
* Result: `{'policy1': 8, 'policy2': 8}`
|
||||
|
||||
```python
|
||||
def p1_psu3(_params, step, sH, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
def p2_psu3(_params, step, sH, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
```
|
||||
* `add` applicable due to redundant policies
|
||||
* `mult_by_2` applied to all policies
|
||||
* Result: `{'policy1': 4, 'policy2': 8, 'policy3': 12}`
|
||||
|
||||
#### Aggregate Policies using functions
|
||||
```python
|
||||
from cadCAD.configuration import append_configs
|
||||
|
||||
append_configs(
|
||||
sim_configs=???,
|
||||
initial_state=???,
|
||||
partial_state_update_blocks=???,
|
||||
policy_ops=[add, mult_by_2] # Default: [lambda a, b: a + b]
|
||||
)
|
||||
```
|
||||
|
||||
#### Example
|
||||
##### * [System Model Configuration](examples/policy_aggregation.py)
|
||||
##### * Simulation Results:
|
||||
```
|
||||
+----+---------------------------------------------+-------+------+-----------+------------+
|
||||
| | policies | run | s1 | substep | timestep |
|
||||
|----+---------------------------------------------+-------+------+-----------+------------|
|
||||
| 0 | {} | 1 | 0 | 0 | 0 |
|
||||
| 1 | {'policy1': 2, 'policy2': 4} | 1 | 1 | 1 | 1 |
|
||||
| 2 | {'policy1': 8, 'policy2': 8} | 1 | 2 | 2 | 1 |
|
||||
| 3 | {'policy3': 12, 'policy1': 4, 'policy2': 8} | 1 | 3 | 3 | 1 |
|
||||
| 4 | {'policy1': 2, 'policy2': 4} | 1 | 4 | 1 | 2 |
|
||||
| 5 | {'policy1': 8, 'policy2': 8} | 1 | 5 | 2 | 2 |
|
||||
| 6 | {'policy3': 12, 'policy1': 4, 'policy2': 8} | 1 | 6 | 3 | 2 |
|
||||
| 7 | {'policy1': 2, 'policy2': 4} | 1 | 7 | 1 | 3 |
|
||||
| 8 | {'policy1': 8, 'policy2': 8} | 1 | 8 | 2 | 3 |
|
||||
| 9 | {'policy3': 12, 'policy1': 4, 'policy2': 8} | 1 | 9 | 3 | 3 |
|
||||
+----+---------------------------------------------+-------+------+-----------+------------+
|
||||
```
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
Simulation Configuration
|
||||
==
|
||||
|
||||
## Introduction
|
||||
|
||||
Given a **Simulation Configuration**, cadCAD produces datasets that represent the evolution of the state of a system
|
||||
over [discrete time](https://en.wikipedia.org/wiki/Discrete_time_and_continuous_time#Discrete_time). The state of the
|
||||
system is described by a set of [State Variables](#State-Variables). The dynamic of the system is described by
|
||||
[Policy Functions](#Policy-Functions) and [State Update Functions](#State-Update-Functions), which are evaluated by
|
||||
cadCAD according to the definitions set by the user in [Partial State Update Blocks](#Partial-State-Update-Blocks).
|
||||
|
||||
A Simulation Configuration is comprised of a [System Model](#System-Model) and a set of
|
||||
[Simulation Properties](#Simulation-Properties)
|
||||
|
||||
`append_configs`, stores a **Simulation Configuration** to be [Executed](/JS4Q9oayQASihxHBJzz4Ug) by cadCAD
|
||||
|
||||
```python
|
||||
from cadCAD.configuration import append_configs
|
||||
|
||||
append_configs(
|
||||
initial_state = ..., # System Model
|
||||
partial_state_update_blocks = .., # System Model
|
||||
policy_ops = ..., # System Model
|
||||
sim_configs = ... # Simulation Properties
|
||||
)
|
||||
```
|
||||
Parameters:
|
||||
* **initial_state** : _dict_ - [State Variables](#State-Variables) and their initial values
|
||||
* **partial_state_update_blocks** : List[dict[dict]] - List of [Partial State Update Blocks](#Partial-State-Update-Blocks)
|
||||
* **policy_ops** : List[functions] - See [Policy Aggregation](/63k2ncjITuqOPCUHzK7Viw)
|
||||
* **sim_configs** - See [System Model Parameter Sweep](/4oJ_GT6zRWW8AO3yMhFKrg)
|
||||
|
||||
## Simulation Properties
|
||||
|
||||
Simulation properties are passed to `append_configs` in the `sim_configs` parameter. To construct this parameter, we
|
||||
use the `config_sim` function in `cadCAD.configuration.utils`
|
||||
|
||||
```python
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
|
||||
c = config_sim({
|
||||
"N": ...,
|
||||
"T": range(...),
|
||||
"M": ...
|
||||
})
|
||||
|
||||
append_configs(
|
||||
...
|
||||
sim_configs = c # Simulation Properties
|
||||
)
|
||||
```
|
||||
|
||||
### T - Simulation Length
|
||||
Computer simulations run in discrete time:
|
||||
|
||||
>Discrete time views values of variables as occurring at distinct, separate "points in time", or equivalently as being
|
||||
unchanged throughout each non-zero region of time ("time period")—that is, time is viewed as a discrete variable. (...)
|
||||
This view of time corresponds to a digital clock that gives a fixed reading of 10:37 for a while, and then jumps to a
|
||||
new fixed reading of 10:38, etc.
|
||||
([source: Wikipedia](https://en.wikipedia.org/wiki/Discrete_time_and_continuous_time#Discrete_time))
|
||||
|
||||
As is common in many simulation tools, in cadCAD too we refer to each discrete unit of time as a **timestep**. cadCAD
|
||||
increments a "time counter", and at each step it updates the state variables according to the equations that describe
|
||||
the system.
|
||||
|
||||
The main simulation property that the user must set when creating a Simulation Configuration is the number of timesteps
|
||||
in the simulation. In other words, for how long do they want to simulate the system that has been modeled.
|
||||
|
||||
### N - Number of Runs
|
||||
|
||||
cadCAD facilitates running multiple simulations of the same system sequentially, reporting the results of all those
|
||||
runs in a single dataset. This is especially helpful for running
|
||||
[Monte Carlo Simulations](../tutorials/robot-marbles-part-4/robot-marbles-part-4.ipynb).
|
||||
|
||||
### M - Parameters of the System
|
||||
|
||||
Parameters of the system, passed to the state update functions and the policy functions in the `params` parameter are
|
||||
defined here. See [System Model Parameter Sweep](/4oJ_GT6zRWW8AO3yMhFKrg) for more information.
|
||||
|
||||
## System Model
|
||||
The System Model describes the system that will be simulated in cadCAD. It is comprised of a set of
|
||||
[State Variables](###Sate-Variables) and the [State Update Functions](#State-Update-Functions) that determine the
|
||||
evolution of the state of the system over time. [Policy Functions](#Policy-Functions) (representations of user policies
|
||||
or internal system control policies) may also be part of a System Model.
|
||||
|
||||
### State Variables
|
||||
>A state variable is one of the set of variables that are used to describe the mathematical "state" of a dynamical
|
||||
system. Intuitively, the state of a system describes enough about the system to determine its future behaviour in the
|
||||
absence of any external forces affecting the system. ([source: Wikipedia](https://en.wikipedia.org/wiki/State_variable))
|
||||
|
||||
cadCAD can handle state variables of any Python data type, including custom classes. It is up to the user of cadCAD to
|
||||
determine the state variables needed to **sufficiently and accurately** describe the system they are interested in.
|
||||
|
||||
State Variables are passed to `append_configs` along with its initial values, as a Python `dict` where the `dict_keys`
|
||||
are the names of the variables and the `dict_values` are their initial values.
|
||||
|
||||
```python
|
||||
from cadCAD.configuration import append_configs
|
||||
|
||||
genesis_states = {
|
||||
'state_variable_1': 0,
|
||||
'state_variable_2': 0,
|
||||
'state_variable_3': 1.5,
|
||||
'timestamp': '2019-01-01 00:00:00'
|
||||
}
|
||||
|
||||
append_configs(
|
||||
initial_state = genesis_states,
|
||||
...
|
||||
)
|
||||
```
|
||||
### State Update Functions
|
||||
State Update Functions represent equations according to which the state variables change over time. Each state update
|
||||
function must return a tuple containing a string with the name of the state variable being updated and its new value.
|
||||
Each state update function can only modify a single state variable. The general structure of a state update function is:
|
||||
```python
|
||||
def state_update_function_A(_params, substep, sH, s, _input):
|
||||
...
|
||||
return 'state_variable_name', new_value
|
||||
```
|
||||
Parameters:
|
||||
* **_params** : _dict_ - [System parameters](/4oJ_GT6zRWW8AO3yMhFKrg)
|
||||
* **substep** : _int_ - Current [substep](#Substep)
|
||||
* **sH** : _list[list[dict_]] - Historical values of all state variables for the simulation. See
|
||||
[Historical State Access](/smiyQTnATtC9xPwvF8KbBQ) for details
|
||||
* **s** : _dict_ - Current state of the system, where the `dict_keys` are the names of the state variables and the
|
||||
`dict_values` are their current values.
|
||||
* **_input** : _dict_ - Aggregation of the signals of all policy functions in the current
|
||||
[Partial State Update Block](#Partial-State-Update-Block)
|
||||
|
||||
Return:
|
||||
* _tuple_ containing a string with the name of the state variable being updated and its new value.
|
||||
|
||||
State update functions should not modify any of the parameters passed to it, as those are mutable Python objects that
|
||||
cadCAD relies on in order to run the simulation according to the specifications.
|
||||
|
||||
### Policy Functions
|
||||
A Policy Function computes one or more signals to be passed to [State Update Functions](#State-Update-Functions)
|
||||
(via the _\_input_ parameter). Read
|
||||
[this article](../tutorials/robot-marbles-part-2/robot-marbles-part-2.ipynb)
|
||||
for details on why and when to use policy functions.
|
||||
|
||||
<!-- We would then expand the tutorials with these kind of concepts
|
||||
#### Policies
|
||||
Policies consist of the potential action made available through mechanisms. The action taken is expected to be the
|
||||
result of a conditional determination of the past state.
|
||||
|
||||
While executed the same, the modeller can approach policies dependent on the availability of a mechanism to a population.
|
||||
|
||||
- ***Control Policy***
|
||||
When the controlling or deploying entity has the ability to act in order to affect some aspect of the system, this is a
|
||||
control policy.
|
||||
- ***User Policy*** model agent behaviors in reaction to state variables and exogenous variables. The resulted user
|
||||
action will become an input to PSUs. Note that user behaviors should not directly update value of state variables.
|
||||
The action taken, as well as the potential to act, through a mechanism is a behavior. -->
|
||||
|
||||
The general structure of a policy function is:
|
||||
```python
|
||||
def policy_function_1(_params, substep, sH, s):
|
||||
...
|
||||
return {'signal_1': value_1, ..., 'signal_N': value_N}
|
||||
```
|
||||
Parameters:
|
||||
* **_params** : _dict_ - [System parameters](/4oJ_GT6zRWW8AO3yMhFKrg)
|
||||
* **substep** : _int_ - Current [substep](#Substep)
|
||||
* **sH** : _list[list[dict_]] - Historical values of all state variables for the simulation. See
|
||||
[Historical State Access](/smiyQTnATtC9xPwvF8KbBQ) for details
|
||||
* **s** : _dict_ - Current state of the system, where the `dict_keys` are the names of the state variables and the
|
||||
`dict_values` are their current values.
|
||||
|
||||
Return:
|
||||
* _dict_ of signals to be passed to the state update functions in the same
|
||||
[Partial State Update Block](#Partial-State-Update-Blocks)
|
||||
|
||||
Policy functions should not modify any of the parameters passed to it, as those are mutable Python objects that cadCAD
|
||||
relies on in order to run the simulation according to the specifications.
|
||||
|
||||
At each [Partial State Update Block](#Partial-State-Update-Blocks) (PSUB), the `dicts` returned by all policy functions
|
||||
within that PSUB dictionaries are aggregated into a single `dict` using an initial reduction function
|
||||
(a key-wise operation, default: `dic1['keyA'] + dic2['keyA']`) and optional subsequent map functions. The resulting
|
||||
aggregated `dict` is then passed as the `_input` parameter to the state update functions in that PSUB. For more
|
||||
information on how to modify the aggregation method, see [Policy Aggregation](/63k2ncjITuqOPCUHzK7Viw).
|
||||
|
||||
### Partial State Update Blocks
|
||||
|
||||
A **Partial State Update Block** (PSUB) is a set of State Update Functions and Policy Functions such that State Update
|
||||
Functions in the set are independent from each other and Policies in the set are independent from each other and from
|
||||
the State Update Functions in the set. In other words, if a state variable is updated in a PSUB, its new value cannot
|
||||
impact the State Update Functions and Policy Functions in that PSUB - only those in the next PSUB.
|
||||
|
||||

|
||||
|
||||
Partial State Update Blocks are passed to `append_configs` as a List of Python `dicts` where the `dict_keys` are named
|
||||
`"policies"` and `"variables"` and the values are also Python `dicts` where the keys are the names of the policy and
|
||||
state update functions and the values are the functions.
|
||||
|
||||
```python
|
||||
PSUBs = [
|
||||
{
|
||||
"policies": {
|
||||
"b_1": policy_function_1,
|
||||
...
|
||||
"b_J": policy_function_J
|
||||
},
|
||||
"variables": {
|
||||
"s_1": state_update_function_1,
|
||||
...
|
||||
"s_K": state_update_function_K
|
||||
}
|
||||
}, #PSUB_1,
|
||||
{...}, #PSUB_2,
|
||||
...
|
||||
{...} #PSUB_M
|
||||
]
|
||||
|
||||
append_configs(
|
||||
...
|
||||
partial_state_update_blocks = PSUBs,
|
||||
...
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
#### Substep
|
||||
At each timestep, cadCAD iterates over the `partial_state_update_blocks` list. For each Partial State Update Block,
|
||||
cadCAD returns a record containing the state of the system at the end of that PSUB. We refer to that subdivision of a
|
||||
timestep as a `substep`.
|
||||
|
||||
## Result Dataset
|
||||
|
||||
cadCAD returns a dataset containing the evolution of the state variables defined by the user over time, with three `int`
|
||||
indexes:
|
||||
* `run` - id of the [run](#N-Number-of-Runs)
|
||||
* `timestep` - discrete unit of time (the total number of timesteps is defined by the user in the
|
||||
[T Simulation Parameter](#T-Simulation-Length))
|
||||
* `substep` - subdivision of timestep (the number of [substeps](#Substeps) is the same as the number of Partial State
|
||||
Update Blocks)
|
||||
|
||||
Therefore, the total number of records in the resulting dataset is `N` x `T` x `len(partial_state_update_blocks)`
|
||||
|
||||
#### [System Simulation Execution](Simulation_Execution.md)
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
Simulation Execution
|
||||
==
|
||||
System Simulations are executed with the execution engine executor (`cadCAD.engine.Executor`) given System Model
|
||||
Configurations. There are multiple simulation Execution Modes and Execution Contexts.
|
||||
|
||||
### Steps:
|
||||
1. #### *Choose Execution Mode*:
|
||||
* ##### Simulation Execution Modes:
|
||||
`cadCAD` executes a process per System Model Configuration and a thread per System Simulation.
|
||||
##### Class: `cadCAD.engine.ExecutionMode`
|
||||
##### Attributes:
|
||||
* **Single Process:** A single process Execution Mode for a single System Model Configuration (Example:
|
||||
`cadCAD.engine.ExecutionMode().single_proc`).
|
||||
* **Multi-Process:** Multiple process Execution Mode for System Model Simulations which executes on a thread per
|
||||
given System Model Configuration (Example: `cadCAD.engine.ExecutionMode().multi_proc`).
|
||||
2. #### *Create Execution Context using Execution Mode:*
|
||||
```python
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext
|
||||
exec_mode = ExecutionMode()
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
```
|
||||
3. #### *Create Simulation Executor*
|
||||
```python
|
||||
from cadCAD.engine import Executor
|
||||
from cadCAD import configs
|
||||
simulation = Executor(exec_context=single_proc_ctx, configs=configs)
|
||||
```
|
||||
4. #### *Execute Simulation: Produce System Event Dataset*
|
||||
A Simulation execution produces a System Event Dataset and the Tensor Field applied to initial states used to create it.
|
||||
```python
|
||||
import pandas as pd
|
||||
raw_system_events, tensor_field = simulation.execute()
|
||||
|
||||
# Simulation Result Types:
|
||||
# raw_system_events: List[dict]
|
||||
# tensor_field: pd.DataFrame
|
||||
|
||||
# Result System Events DataFrame
|
||||
simulation_result = pd.DataFrame(raw_system_events)
|
||||
```
|
||||
|
||||
##### Example Tensor Field
|
||||
```
|
||||
+----+-----+--------------------------------+--------------------------------+
|
||||
| | m | b1 | s1 |
|
||||
|----+-----+--------------------------------+--------------------------------|
|
||||
| 0 | 1 | <function p1m1 at 0x10c458ea0> | <function s1m1 at 0x10c464510> |
|
||||
| 1 | 2 | <function p1m2 at 0x10c464048> | <function s1m2 at 0x10c464620> |
|
||||
| 2 | 3 | <function p1m3 at 0x10c464400> | <function s1m3 at 0x10c464730> |
|
||||
+----+-----+--------------------------------+--------------------------------+
|
||||
```
|
||||
|
||||
##### Example Result: System Events DataFrame
|
||||
```
|
||||
+----+-------+------------+-----------+------+-----------+
|
||||
| | run | timestep | substep | s1 | s2 |
|
||||
|----+-------+------------+-----------+------+-----------|
|
||||
| 0 | 1 | 0 | 0 | 0 | 0.0 |
|
||||
| 1 | 1 | 1 | 1 | 1 | 4 |
|
||||
| 2 | 1 | 1 | 2 | 2 | 6 |
|
||||
| 3 | 1 | 1 | 3 | 3 | [ 30 300] |
|
||||
| 4 | 2 | 0 | 0 | 0 | 0.0 |
|
||||
| 5 | 2 | 1 | 1 | 1 | 4 |
|
||||
| 6 | 2 | 1 | 2 | 2 | 6 |
|
||||
| 7 | 2 | 1 | 3 | 3 | [ 30 300] |
|
||||
+----+-------+------------+-----------+------+-----------+
|
||||
```
|
||||
|
||||
### Execution Examples:
|
||||
##### Single Simulation Execution (Single Process Execution)
|
||||
Example System Model Configurations:
|
||||
* [System Model A](examples/sys_model_A.py): `/documentation/examples/sys_model_A.py`
|
||||
* [System Model B](examples/sys_model_B.py): `/documentation/examples/sys_model_B.py`
|
||||
Example Simulation Executions:
|
||||
* [System Model A](examples/sys_model_A_exec.py): `/documentation/examples/sys_model_A_exec.py`
|
||||
* [System Model B](examples/sys_model_B_exec.py): `/documentation/examples/sys_model_B_exec.py`
|
||||
```python
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import sys_model_A
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
# Single Process Execution using a Single System Model Configuration:
|
||||
# sys_model_A
|
||||
sys_model_A = [configs[0]] # sys_model_A
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
sys_model_A_simulation = Executor(exec_context=single_proc_ctx, configs=sys_model_A)
|
||||
|
||||
sys_model_A_raw_result, sys_model_A_tensor_field = sys_model_A_simulation.execute()
|
||||
sys_model_A_result = pd.DataFrame(sys_model_A_raw_result)
|
||||
print()
|
||||
print("Tensor Field: sys_model_A")
|
||||
print(tabulate(sys_model_A_tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Result: System Events DataFrame")
|
||||
print(tabulate(sys_model_A_result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
```
|
||||
|
||||
##### Multiple Simulation Execution
|
||||
|
||||
* ##### *Multi Process Execution*
|
||||
Documentation: Simulation Execution
|
||||
[Example Simulation Executions::](examples/sys_model_AB_exec.py) `/documentation/examples/sys_model_AB_exec.py`
|
||||
Example System Model Configurations:
|
||||
* [System Model A](examples/sys_model_A.py): `/documentation/examples/sys_model_A.py`
|
||||
* [System Model B](examples/sys_model_B.py): `/documentation/examples/sys_model_B.py`
|
||||
```python
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import sys_model_A, sys_model_B
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
# # Multiple Processes Execution using Multiple System Model Configurations:
|
||||
# # sys_model_A & sys_model_B
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
sys_model_AB_simulation = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
i = 0
|
||||
config_names = ['sys_model_A', 'sys_model_B']
|
||||
for sys_model_AB_raw_result, sys_model_AB_tensor_field in sys_model_AB_simulation.execute():
|
||||
sys_model_AB_result = pd.DataFrame(sys_model_AB_raw_result)
|
||||
print()
|
||||
print(f"Tensor Field: {config_names[i]}")
|
||||
print(tabulate(sys_model_AB_tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Result: System Events DataFrame:")
|
||||
print(tabulate(sys_model_AB_result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
i += 1
|
||||
```
|
||||
|
||||
* ##### [*System Model Parameter Sweep*](System_Model_Parameter_Sweep.md)
|
||||
|
||||
[Example:](examples/param_sweep.py) `/documentation/examples/param_sweep.py`
|
||||
```python
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import param_sweep
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
for raw_result, tensor_field in run.execute():
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field:")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
```
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
System Model Parameter Sweep
|
||||
==
|
||||
Parametrization of a System Model configuration that produces multiple configurations.
|
||||
|
||||
##### Set Parameters
|
||||
```python
|
||||
params = {
|
||||
'alpha': [1],
|
||||
'beta': [2, 5],
|
||||
'gamma': [3, 4],
|
||||
'omega': [7]
|
||||
}
|
||||
```
|
||||
The parameters above produce 2 simulations.
|
||||
* Simulation 1:
|
||||
* `alpha = 1`
|
||||
* `beta = 2`
|
||||
* `gamma = 3`
|
||||
* `omega = 7`
|
||||
* Simulation 2:
|
||||
* `alpha = 1`
|
||||
* `beta = 5`
|
||||
* `gamma = 4`
|
||||
* `omega = 7`
|
||||
|
||||
All parameters can also be set to include a single parameter each, which will result in a single simulation.
|
||||
|
||||
##### Example State Updates
|
||||
|
||||
Previous State:
|
||||
`y = 0`
|
||||
|
||||
```python
|
||||
def state_update(_params, step, sH, s, _input):
|
||||
y = 'state'
|
||||
x = s['state'] + _params['alpha'] + _params['gamma']
|
||||
return y, x
|
||||
```
|
||||
* Updated State:
|
||||
* Simulation 1: `y = 4 = 0 + 1 + 3`
|
||||
* Simulation 2: `y = 5 = 0 + 1 + 4`
|
||||
|
||||
##### Example Policy Updates
|
||||
```python
|
||||
# Internal States per Mechanism
|
||||
def policies(_params, step, sH, s):
|
||||
return {'beta': _params['beta'], 'gamma': _params['gamma']}
|
||||
```
|
||||
* Simulation 1: `{'beta': 2, 'gamma': 3]}`
|
||||
* Simulation 2: `{'beta': 5, 'gamma': 4}`
|
||||
|
||||
##### Configure Simulation
|
||||
```python
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
|
||||
g = {
|
||||
'alpha': [1],
|
||||
'beta': [2, 5],
|
||||
'gamma': [3, 4],
|
||||
'omega': [7]
|
||||
}
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
"M": g,
|
||||
}
|
||||
)
|
||||
```
|
||||
#### Example
|
||||
##### * [System Model Configuration](examples/param_sweep.py)
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
from pprint import pprint
|
||||
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import sys_model_A, sys_model_B
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
# Single Process Execution using a Single System Model Configuration:
|
||||
# sys_model_A
|
||||
sys_model_A = [configs[0]]
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
sys_model_A_simulation = Executor(exec_context=single_proc_ctx, configs=sys_model_A)
|
||||
|
||||
sys_model_A_raw_result, sys_model_A_tensor_field = sys_model_A_simulation.execute()
|
||||
sys_model_A_result = pd.DataFrame(sys_model_A_raw_result)
|
||||
print()
|
||||
print("Tensor Field: sys_model_A")
|
||||
print(tabulate(sys_model_A_tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Result: System Events DataFrame")
|
||||
print(tabulate(sys_model_A_result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
||||
# # Multiple Processes Execution using Multiple System Model Configurations:
|
||||
# # sys_model_A & sys_model_B
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
sys_model_AB_simulation = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
|
||||
|
||||
i = 0
|
||||
config_names = ['sys_model_A', 'sys_model_B']
|
||||
for sys_model_AB_raw_result, sys_model_AB_tensor_field in sys_model_AB_simulation.execute():
|
||||
print()
|
||||
pprint(sys_model_AB_raw_result)
|
||||
# sys_model_AB_result = pd.DataFrame(sys_model_AB_raw_result)
|
||||
print()
|
||||
print(f"Tensor Field: {config_names[i]}")
|
||||
print(tabulate(sys_model_AB_tensor_field, headers='keys', tablefmt='psql'))
|
||||
# print("Result: System Events DataFrame:")
|
||||
# print(tabulate(sys_model_AB_result, headers='keys', tablefmt='psql'))
|
||||
# print()
|
||||
i += 1
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim, access_block
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD import configs
|
||||
|
||||
|
||||
policies, variables = {}, {}
|
||||
exclusion_list = ['nonexsistant', 'last_x', '2nd_to_last_x', '3rd_to_last_x', '4th_to_last_x']
|
||||
|
||||
# Policies per Mechanism
|
||||
|
||||
# state_history, target_field, psu_block_offset, exculsion_list
|
||||
def last_update(_g, substep, sH, s):
|
||||
return {"last_x": access_block(
|
||||
state_history=sH,
|
||||
target_field="last_x",
|
||||
psu_block_offset=-1,
|
||||
exculsion_list=exclusion_list
|
||||
)
|
||||
}
|
||||
policies["last_x"] = last_update
|
||||
|
||||
def second2last_update(_g, substep, sH, s):
|
||||
return {"2nd_to_last_x": access_block(sH, "2nd_to_last_x", -2, exclusion_list)}
|
||||
policies["2nd_to_last_x"] = second2last_update
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
|
||||
# WARNING: DO NOT delete elements from sH
|
||||
def add(y, x):
|
||||
return lambda _g, substep, sH, s, _input: (y, s[y] + x)
|
||||
variables['x'] = add('x', 1)
|
||||
|
||||
# last_partial_state_update_block
|
||||
def nonexsistant(_g, substep, sH, s, _input):
|
||||
return 'nonexsistant', access_block(sH, "nonexsistant", 0, exclusion_list)
|
||||
variables['nonexsistant'] = nonexsistant
|
||||
|
||||
# last_partial_state_update_block
|
||||
def last_x(_g, substep, sH, s, _input):
|
||||
return 'last_x', _input["last_x"]
|
||||
variables['last_x'] = last_x
|
||||
|
||||
# 2nd to last partial state update block
|
||||
def second_to_last_x(_g, substep, sH, s, _input):
|
||||
return '2nd_to_last_x', _input["2nd_to_last_x"]
|
||||
variables['2nd_to_last_x'] = second_to_last_x
|
||||
|
||||
# 3rd to last partial state update block
|
||||
def third_to_last_x(_g, substep, sH, s, _input):
|
||||
return '3rd_to_last_x', access_block(sH, "3rd_to_last_x", -3, exclusion_list)
|
||||
variables['3rd_to_last_x'] = third_to_last_x
|
||||
|
||||
# 4th to last partial state update block
|
||||
def fourth_to_last_x(_g, substep, sH, s, _input):
|
||||
return '4th_to_last_x', access_block(sH, "4th_to_last_x", -4, exclusion_list)
|
||||
variables['4th_to_last_x'] = fourth_to_last_x
|
||||
|
||||
|
||||
genesis_states = {
|
||||
'x': 0,
|
||||
'nonexsistant': [],
|
||||
'last_x': [],
|
||||
'2nd_to_last_x': [],
|
||||
'3rd_to_last_x': [],
|
||||
'4th_to_last_x': []
|
||||
}
|
||||
|
||||
PSUB = {
|
||||
"policies": policies,
|
||||
"variables": variables
|
||||
}
|
||||
|
||||
psubs = {
|
||||
"PSUB1": PSUB,
|
||||
"PSUB2": PSUB,
|
||||
"PSUB3": PSUB
|
||||
}
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
"T": range(3),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
partial_state_update_blocks=psubs
|
||||
)
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=configs)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
cols = ['run','substep','timestep','x','nonexsistant','last_x','2nd_to_last_x','3rd_to_last_x','4th_to_last_x']
|
||||
result = result[cols]
|
||||
|
||||
print()
|
||||
print("Tensor Field:")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
import pprint
|
||||
from typing import Dict, List
|
||||
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import env_trigger, var_substep_trigger, config_sim, psub_list
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD import configs
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
|
||||
def some_function(x):
|
||||
return x
|
||||
|
||||
|
||||
g: Dict[str, List[int]] = {
|
||||
'alpha': [1],
|
||||
'beta': [2, 5],
|
||||
'gamma': [3, 4],
|
||||
'omega': [some_function]
|
||||
}
|
||||
|
||||
psu_steps = ['1', '2', '3']
|
||||
system_substeps = len(psu_steps)
|
||||
var_timestep_trigger = var_substep_trigger([0, system_substeps])
|
||||
env_timestep_trigger = env_trigger(system_substeps)
|
||||
env_process = {}
|
||||
|
||||
|
||||
# Policies
|
||||
def gamma(_params, step, sH, s):
|
||||
return {'gamma': _params['gamma']}
|
||||
|
||||
|
||||
def omega(_params, step, sH, s):
|
||||
return {'omega': _params['omega'](7)}
|
||||
|
||||
|
||||
# Internal States
|
||||
def alpha(_params, step, sH, s, _input):
|
||||
return 'alpha', _params['alpha']
|
||||
|
||||
def alpha_plus_gamma(_params, step, sH, s, _input):
|
||||
return 'alpha_plus_gamma', _params['alpha'] + _params['gamma']
|
||||
|
||||
|
||||
def beta(_params, step, sH, s, _input):
|
||||
return 'beta', _params['beta']
|
||||
|
||||
|
||||
def policies(_params, step, sH, s, _input):
|
||||
return 'policies', _input
|
||||
|
||||
|
||||
def sweeped(_params, step, sH, s, _input):
|
||||
return 'sweeped', {'beta': _params['beta'], 'gamma': _params['gamma']}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
genesis_states = {
|
||||
'alpha_plus_gamma': 0,
|
||||
'alpha': 0,
|
||||
'beta': 0,
|
||||
'policies': {},
|
||||
'sweeped': {}
|
||||
}
|
||||
|
||||
env_process['sweeped'] = env_timestep_trigger(trigger_field='timestep', trigger_vals=[5], funct_list=[lambda _g, x: _g['beta']])
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
"M": g,
|
||||
}
|
||||
)
|
||||
|
||||
psu_block = {k: {"policies": {}, "variables": {}} for k in psu_steps}
|
||||
for m in psu_steps:
|
||||
psu_block[m]['policies']['gamma'] = gamma
|
||||
psu_block[m]['policies']['omega'] = omega
|
||||
psu_block[m]["variables"]['alpha'] = alpha_plus_gamma
|
||||
psu_block[m]["variables"]['alpha_plus_gamma'] = alpha
|
||||
psu_block[m]["variables"]['beta'] = beta
|
||||
psu_block[m]['variables']['policies'] = policies
|
||||
psu_block[m]["variables"]['sweeped'] = var_timestep_trigger(y='sweeped', f=sweeped)
|
||||
|
||||
psubs = psub_list(psu_block, psu_steps)
|
||||
print()
|
||||
pp.pprint(psu_block)
|
||||
print()
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
env_processes=env_process,
|
||||
partial_state_update_blocks=psubs
|
||||
)
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
for raw_result, tensor_field in run.execute():
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field:")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD import configs
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sH, s):
|
||||
return {'policy1': 1}
|
||||
def p2m1(_g, step, sH, s):
|
||||
return {'policy2': 2}
|
||||
|
||||
def p1m2(_g, step, sH, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
def p2m2(_g, step, sH, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
|
||||
def p1m3(_g, step, sH, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
def p2m3(_g, step, sH, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def add(y, x):
|
||||
return lambda _g, step, sH, s, _input: (y, s[y] + x)
|
||||
|
||||
def policies(_g, step, sH, s, _input):
|
||||
y = 'policies'
|
||||
x = _input
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
'policies': {},
|
||||
's1': 0
|
||||
}
|
||||
|
||||
variables = {
|
||||
's1': add('s1', 1),
|
||||
"policies": policies
|
||||
}
|
||||
|
||||
psubs = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"p1": p1m1,
|
||||
"p2": p2m1
|
||||
},
|
||||
"variables": variables
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"p1": p1m2,
|
||||
"p2": p2m2
|
||||
},
|
||||
"variables": variables
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"p1": p1m3,
|
||||
"p2": p2m3
|
||||
},
|
||||
"variables": variables
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
"T": range(3),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
partial_state_update_blocks=psubs,
|
||||
policy_ops=[lambda a, b: a + b, lambda y: y * 2] # Default: lambda a, b: a + b
|
||||
)
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=configs)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
|
||||
print()
|
||||
print("Tensor Field:")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
import numpy as np
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import bound_norm_random, config_sim, time_step, env_trigger
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(4)
|
||||
}
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sH, s):
|
||||
return {'param1': 1}
|
||||
def p2m1(_g, step, sH, s):
|
||||
return {'param1': 1, 'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sH, s):
|
||||
return {'param1': 'a', 'param2': 2}
|
||||
def p2m2(_g, step, sH, s):
|
||||
return {'param1': 'b', 'param2': 4}
|
||||
|
||||
def p1m3(_g, step, sH, s):
|
||||
return {'param1': ['c'], 'param2': np.array([10, 100])}
|
||||
def p2m3(_g, step, sH, s):
|
||||
return {'param1': ['d'], 'param2': np.array([20, 200])}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sH, s, _input):
|
||||
y = 's1'
|
||||
x = s['s1'] + 1
|
||||
return (y, x)
|
||||
def s2m1(_g, step, sH, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m2(_g, step, sH, s, _input):
|
||||
y = 's1'
|
||||
x = s['s1'] + 1
|
||||
return (y, x)
|
||||
def s2m2(_g, step, sH, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m3(_g, step, sH, s, _input):
|
||||
y = 's1'
|
||||
x = s['s1'] + 1
|
||||
return (y, x)
|
||||
def s2m3(_g, step, sH, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def policies(_g, step, sH, s, _input):
|
||||
y = 'policies'
|
||||
x = _input
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Exogenous States
|
||||
proc_one_coef_A = 0.7
|
||||
proc_one_coef_B = 1.3
|
||||
|
||||
def es3(_g, step, sH, s, _input):
|
||||
y = 's3'
|
||||
x = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def es4(_g, step, sH, s, _input):
|
||||
y = 's4'
|
||||
x = s['s4'] * bound_norm_random(seeds['b'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def update_timestamp(_g, step, sH, s, _input):
|
||||
y = 'timestamp'
|
||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
's1': 0.0,
|
||||
's2': 0.0,
|
||||
's3': 1.0,
|
||||
's4': 1.0,
|
||||
'timestamp': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# Environment Process
|
||||
# ToDo: Depreciation Waring for env_proc_trigger convention
|
||||
trigger_timestamps = ['2018-10-01 15:16:25', '2018-10-01 15:16:27', '2018-10-01 15:16:29']
|
||||
env_processes = {
|
||||
"s3": [lambda _g, x: 5],
|
||||
"s4": env_trigger(3)(trigger_field='timestamp', trigger_vals=trigger_timestamps, funct_list=[lambda _g, x: 10])
|
||||
}
|
||||
|
||||
|
||||
psubs = [
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m1,
|
||||
"b2": p2m1
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m1,
|
||||
"s2": s2m1,
|
||||
"s3": es3,
|
||||
"s4": es4,
|
||||
"timestamp": update_timestamp
|
||||
}
|
||||
},
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m2,
|
||||
"b2": p2m2
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m2,
|
||||
"s2": s2m2,
|
||||
# "s3": es3p1,
|
||||
# "s4": es4p2,
|
||||
}
|
||||
},
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m3,
|
||||
"b2": p2m3
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m3,
|
||||
"s2": s2m3,
|
||||
# "s3": es3p1,
|
||||
# "s4": es4p2,
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(1),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=psubs,
|
||||
policy_ops=[lambda a, b: a + b]
|
||||
)
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import sys_model_A, sys_model_B
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
# # Multiple Processes Execution using Multiple System Model Configurations:
|
||||
# # sys_model_A & sys_model_B
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
sys_model_AB_simulation = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
i = 0
|
||||
config_names = ['sys_model_A', 'sys_model_B']
|
||||
for sys_model_AB_raw_result, sys_model_AB_tensor_field in sys_model_AB_simulation.execute():
|
||||
sys_model_AB_result = pd.DataFrame(sys_model_AB_raw_result)
|
||||
print()
|
||||
print(f"Tensor Field: {config_names[i]}")
|
||||
print(tabulate(sys_model_AB_tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Result: System Events DataFrame:")
|
||||
print(tabulate(sys_model_AB_result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
i += 1
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import sys_model_A
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
# Single Process Execution using a Single System Model Configuration:
|
||||
# sys_model_A
|
||||
sys_model_A = [configs[0]] # sys_model_A
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
sys_model_A_simulation = Executor(exec_context=single_proc_ctx, configs=sys_model_A)
|
||||
|
||||
sys_model_A_raw_result, sys_model_A_tensor_field = sys_model_A_simulation.execute()
|
||||
sys_model_A_result = pd.DataFrame(sys_model_A_raw_result)
|
||||
print()
|
||||
print("Tensor Field: sys_model_A")
|
||||
print(tabulate(sys_model_A_tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Result: System Events DataFrame")
|
||||
print(tabulate(sys_model_A_result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
import numpy as np
|
||||
from datetime import timedelta
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import bound_norm_random, config_sim, env_trigger, time_step
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sH, s):
|
||||
return {'param1': 1}
|
||||
def p2m1(_g, step, sH, s):
|
||||
return {'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sH, s):
|
||||
return {'param1': 'a', 'param2': 2}
|
||||
def p2m2(_g, step, sH, s):
|
||||
return {'param1': 'b', 'param2': 4}
|
||||
|
||||
def p1m3(_g, step, sH, s):
|
||||
return {'param1': ['c'], 'param2': np.array([10, 100])}
|
||||
def p2m3(_g, step, sH, s):
|
||||
return {'param1': ['d'], 'param2': np.array([20, 200])}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sH, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
return (y, x)
|
||||
def s2m1(_g, step, sH, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m2(_g, step, sH, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
return (y, x)
|
||||
def s2m2(_g, step, sH, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m3(_g, step, sH, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
return (y, x)
|
||||
def s2m3(_g, step, sH, 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 es3(_g, step, sH, s, _input):
|
||||
y = 's3'
|
||||
x = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def es4(_g, step, sH, s, _input):
|
||||
y = 's4'
|
||||
x = s['s4'] * bound_norm_random(seeds['b'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def update_timestamp(_g, step, sH, s, _input):
|
||||
y = 'timestamp'
|
||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
's1': 0,
|
||||
's2': 0,
|
||||
's3': 1,
|
||||
's4': 1,
|
||||
'timestamp': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# Environment Process
|
||||
# ToDo: Depreciation Waring for env_proc_trigger convention
|
||||
trigger_timestamps = ['2018-10-01 15:16:25', '2018-10-01 15:16:27', '2018-10-01 15:16:29']
|
||||
env_processes = {
|
||||
"s3": [lambda _g, x: 5],
|
||||
"s4": env_trigger(3)(trigger_field='timestamp', trigger_vals=trigger_timestamps, funct_list=[lambda _g, x: 10])
|
||||
}
|
||||
|
||||
psubs = [
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m1,
|
||||
# "b2": p2m1
|
||||
},
|
||||
"states": {
|
||||
"s1": s1m1,
|
||||
# "s2": s2m1
|
||||
"s3": es3,
|
||||
"s4": es4,
|
||||
"timestep": update_timestamp
|
||||
}
|
||||
},
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m2,
|
||||
# "b2": p2m2
|
||||
},
|
||||
"states": {
|
||||
"s1": s1m2,
|
||||
# "s2": s2m2
|
||||
}
|
||||
},
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m3,
|
||||
"b2": p2m3
|
||||
},
|
||||
"states": {
|
||||
"s1": s1m3,
|
||||
"s2": s2m3
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=psubs
|
||||
)
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from documentation.examples import sys_model_B
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains sys_model_B
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field: sys_model_B")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
from ui.config import state_dict, mechanisms, exogenous_states, env_processes, sim_config
|
||||
from engine.configProcessor import generate_config
|
||||
from engine.mechanismExecutor import simulation
|
||||
from engine.utils import flatten
|
||||
|
||||
#from tabulate import tabulate
|
||||
import pandas as pd
|
||||
|
||||
def main():
|
||||
states_list = [state_dict]
|
||||
configs = generate_config(mechanisms, exogenous_states)
|
||||
# p = pipeline(states_list, configs, env_processes, range(10))
|
||||
N = sim_config['N']
|
||||
r = range(5)
|
||||
# Dimensions: N x r x mechs
|
||||
s = simulation(states_list, configs, env_processes, r, N)
|
||||
result = pd.DataFrame(flatten(s))
|
||||
print('Test')
|
||||
# print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
# remove print and tabulate functions, so it returns a dataframe
|
||||
return result
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# if beh list empty, repeat 0 x n_states in list
|
||||
def generate_config(mechanisms, exogenous_states):
|
||||
es_funcs = [exogenous_states[state] for state in list(exogenous_states.keys())]
|
||||
config = list(
|
||||
map(
|
||||
lambda m: (
|
||||
list(mechanisms[m]["states"].values()) + es_funcs,
|
||||
list(mechanisms[m]["behaviors"].values())
|
||||
),
|
||||
list(mechanisms.keys())
|
||||
)
|
||||
)
|
||||
return config
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
from copy import deepcopy
|
||||
from fn import op, _
|
||||
|
||||
def getColResults(step, sL, s, funcs):
|
||||
return list(map(lambda f: f(step, sL, s), funcs))
|
||||
|
||||
|
||||
def getBehaviorInput(step, sL, s, funcs):
|
||||
return op.foldr(_ + _)(getColResults(step, sL, s, funcs))
|
||||
|
||||
|
||||
def apply_env_proc(env_processes, state_dict, step):
|
||||
for state in state_dict.keys():
|
||||
if state in list(env_processes.keys()):
|
||||
state_dict[state] = env_processes[state](step)(state_dict[state])
|
||||
|
||||
|
||||
def mech_step(m_step, sL, state_funcs, behavior_funcs, env_processes, t_step):
|
||||
in_copy, mutatable_copy, out_copy = deepcopy(sL), deepcopy(sL), deepcopy(sL)
|
||||
last_in_obj, last_mut_obj = in_copy[-1], mutatable_copy[-1]
|
||||
|
||||
_input = getBehaviorInput(m_step, sL, last_in_obj, behavior_funcs)
|
||||
|
||||
# OLD: no bueno! Mutation Bad
|
||||
# for f in state_funcs:
|
||||
# f(m_step, sL, last_mut_obj, _input)
|
||||
|
||||
# New
|
||||
last_mut_obj = dict([ f(m_step, sL, last_mut_obj, _input) for f in state_funcs ])
|
||||
|
||||
apply_env_proc(env_processes, last_mut_obj, last_mut_obj['timestamp'])
|
||||
|
||||
last_mut_obj["mech_step"], last_mut_obj["time_step"] = m_step, t_step
|
||||
out_copy.append(last_mut_obj)
|
||||
|
||||
del last_in_obj, last_mut_obj, in_copy, mutatable_copy,
|
||||
|
||||
return out_copy
|
||||
|
||||
|
||||
def block_gen(states_list, configs, env_processes, t_step):
|
||||
m_step = 0
|
||||
states_list_copy = deepcopy(states_list)
|
||||
genesis_states = states_list_copy[-1]
|
||||
genesis_states['mech_step'], genesis_states['time_step'] = m_step, t_step
|
||||
states_list = [genesis_states]
|
||||
|
||||
m_step += 1
|
||||
for config in configs:
|
||||
s_conf, b_conf = config[0], config[1]
|
||||
states_list = mech_step(m_step, states_list, s_conf, b_conf, env_processes, t_step)
|
||||
m_step += 1
|
||||
|
||||
t_step += 1
|
||||
|
||||
return states_list
|
||||
|
||||
|
||||
def pipeline(states_list, configs, env_processes, time_seq):
|
||||
time_seq = [x + 1 for x in time_seq]
|
||||
simulation_list = [states_list]
|
||||
for time_step in time_seq:
|
||||
pipeline_run = block_gen(simulation_list[-1], configs, env_processes, time_step)
|
||||
head, *pipeline_run = pipeline_run
|
||||
simulation_list.append(pipeline_run)
|
||||
|
||||
return simulation_list
|
||||
|
||||
|
||||
def simulation(states_list, configs, env_processes, time_seq, runs):
|
||||
pipeline_run = []
|
||||
for run in range(runs):
|
||||
if run == 0:
|
||||
head, *tail = pipeline(states_list, configs, env_processes, time_seq)
|
||||
head[-1]['mech_step'], head[-1]['time_step'] = 0, 0
|
||||
simulation_list = [head] + tail
|
||||
pipeline_run += simulation_list
|
||||
else:
|
||||
transient_states_list = [pipeline_run[-1][-1]]
|
||||
head, *tail = pipeline(transient_states_list, configs, env_processes, time_seq)
|
||||
pipeline_run += tail
|
||||
|
||||
return pipeline_run
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
from ui.simpleBC_Config import state_dict, mechanisms, exogenous_states, env_processes, sim_config
|
||||
from engine.configProcessor import generate_config
|
||||
from engine.mechanismExecutor import simulation
|
||||
from engine.utils import flatten
|
||||
|
||||
#from tabulate import tabulate
|
||||
import pandas as pd
|
||||
|
||||
def main():
|
||||
states_list = [state_dict]
|
||||
configs = generate_config(mechanisms, exogenous_states)
|
||||
# p = pipeline(states_list, configs, env_processes, range(10))
|
||||
N = sim_config['N']
|
||||
r = range(sim_config["R"])
|
||||
# Dimensions: N x r x mechs
|
||||
s = simulation(states_list, configs, env_processes, r, N)
|
||||
result = pd.DataFrame(flatten(s))
|
||||
print('Test')
|
||||
# print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
# remove print and tabulate functions, so it returns a dataframe
|
||||
return result
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
from datetime import datetime, timedelta
|
||||
from decimal import Decimal
|
||||
from functools import partial
|
||||
|
||||
flatten = lambda l: [item for sublist in l for item in sublist]
|
||||
|
||||
def flatmap(f, items):
|
||||
return list(map(f, items))
|
||||
|
||||
|
||||
def datetime_range(start, end, delta, dt_format='%Y-%m-%d %H:%M:%S'):
|
||||
reverse_head = end
|
||||
[start, end] = [datetime.strptime(x, dt_format) for x in [start, end]]
|
||||
|
||||
def _datetime_range(start, end, delta):
|
||||
current = start
|
||||
while current < end:
|
||||
yield current
|
||||
current += delta
|
||||
|
||||
reverse_tail = [dt.strftime(dt_format) for dt in _datetime_range(start, end, delta)]
|
||||
return reverse_tail + [reverse_head]
|
||||
|
||||
def last_index(l):
|
||||
return len(l)-1
|
||||
|
||||
def retrieve_state(l, offset):
|
||||
return l[last_index(l) + offset + 1]
|
||||
|
||||
def bound_norm_random(rng, low, high):
|
||||
# Add RNG Seed
|
||||
res = rng.normal((high+low)/2,(high-low)/6)
|
||||
if (res<low or res>high):
|
||||
res = bound_norm_random(rng, low, high)
|
||||
return Decimal(res)
|
||||
|
||||
def env_proc(trigger_step, update_f):
|
||||
def env_step_trigger(trigger_step, update_f, step):
|
||||
if step == trigger_step:
|
||||
return update_f
|
||||
else:
|
||||
return lambda x: x
|
||||
return partial(env_step_trigger, trigger_step, update_f)
|
||||
|
||||
|
||||
# accept timedelta instead of timedelta params
|
||||
def time_step(dt_str, dt_format='%Y-%m-%d %H:%M:%S', days=0, minutes=0, seconds=30):
|
||||
dt = datetime.strptime(dt_str, dt_format)
|
||||
t = dt + timedelta(days=days, minutes=minutes, seconds=seconds)
|
||||
return t.strftime(dt_format)
|
||||
|
||||
# accept timedelta instead of timedelta params
|
||||
def ep_time_step(s, dt_str, fromat_str='%Y-%m-%d %H:%M:%S', days=0, minutes=0, seconds=1):
|
||||
if s['mech_step'] == 0:
|
||||
return time_step(dt_str, fromat_str, days, minutes, seconds)
|
||||
else:
|
||||
return dt_str
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"assert pd.__version__ == '0.23.4'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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.7.0"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ModuleNotFoundError",
|
||||
"evalue": "No module named 'ui'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[1;32m<ipython-input-1-a6e895c51fc0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mengine\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mrun\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mrun\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;32m~\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\engine\\run.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mui\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconfig\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mstate_dict\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmechanisms\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexogenous_states\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0menv_processes\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msim_config\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mengine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mconfigProcessor\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mgenerate_config\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mengine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmechanismExecutor\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0msimulation\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mengine\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mutils\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mflatten\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'ui'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from engine import run\n",
|
||||
"run.main()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,877 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 491,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"from scipy.stats import poisson\n",
|
||||
"import numpy as np\n",
|
||||
"import math\n",
|
||||
"import seaborn as sns\n",
|
||||
"import matplotlib as mpl\n",
|
||||
"import matplotlib.pyplot as plt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# UTILS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 492,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def bound_norm_random(low, high):\n",
|
||||
" res = np.random.normal((high+low)/2,(high-low)/6)\n",
|
||||
" if (res<low or res>high):\n",
|
||||
" res = bound_norm_random(low, high)\n",
|
||||
" return res"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# TYPE/PHASE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 493,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"EXPERIMENT_TYPES = ['1 off run', 'Monte Carlo', 'Monte Carlo Parameter Sweep', 'Monte Carlo Pairwise']\n",
|
||||
"\n",
|
||||
"experiment_type = EXPERIMENT_TYPES[1]\n",
|
||||
"monte_carlo_runs = 100\n",
|
||||
"\n",
|
||||
"#correct number of runs if inconsistent with experiment type\n",
|
||||
"if (experiment_type == EXPERIMENT_TYPES[0]):\n",
|
||||
" monte_carlo_runs = 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# TIMESCALE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 494,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"SECOND = 1\n",
|
||||
"MINUTE = 60*SECOND\n",
|
||||
"HOUR = 60*MINUTE\n",
|
||||
"DAY = 24*HOUR\n",
|
||||
"DURATION_OF_A_STEP = 1*DAY\n",
|
||||
"\n",
|
||||
"experiment_steps = 1000\n",
|
||||
"experiment_duration = experiment_steps * DURATION_OF_A_STEP\n",
|
||||
"time_array = np.arange(0,experiment_steps*DURATION_OF_A_STEP,DURATION_OF_A_STEP)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# MECHANISMS (dimension)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 495,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mechanisms_names = ['mech_one', 'mech_two', 'mech_three']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# STATES (dimension)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 496,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"states_names = ['a', 'b', 'c']\n",
|
||||
"states_data = [[np.zeros(experiment_steps)]*len(states_names)]*monte_carlo_runs\n",
|
||||
"states_data = np.zeros((monte_carlo_runs, experiment_steps, len(states_names)), dtype=int)\n",
|
||||
"# states_data is a 3-dimensional array - montecarlo, time, states\n",
|
||||
"# montecarlo[time[states]]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Initial Conditions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 497,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"states_0 = {\n",
|
||||
" 'a': 0,\n",
|
||||
" 'b': 0,\n",
|
||||
" 'c': 300\n",
|
||||
"}\n",
|
||||
"# an initial condition must be set for every state\n",
|
||||
"assert np.array([k in states_0 for k in states_names]).all(), 'Error: The initial condition of one or more states is unkonwn'\n",
|
||||
"\n",
|
||||
"# copy initial condition to the states dataset\n",
|
||||
"for i in range(len(states_names)):\n",
|
||||
" states_data[:,0,i] = states_0[states_names[i]]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 498,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"T_0 = 0\n",
|
||||
"time_array = T_0 + time_array"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Mechanisms Coef (params)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 499,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mech_one_coef_A = 0.05"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# MECHANISMS EQUATIONS (func)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 500,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# state/mechanism matrix\n",
|
||||
"def mech_one(_states_data, _time_array, _run, _step, args):\n",
|
||||
"# print('mech 1')\n",
|
||||
" _states_data[_run, _step, states_names.index('a')] += (1-mech_one_coef_A)*args[0]\n",
|
||||
" _states_data[_run, _step, states_names.index('b')] += mech_one_coef_A*args[0]\n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"def mech_two(_states_data, _time_array, _run, _step, args):\n",
|
||||
"# print('mech 2')\n",
|
||||
" _states_data[_run, _step, states_names.index('a')] -= args[0]\n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"def mech_three(_states_data, _time_array, _run, _step, args):\n",
|
||||
"# print('mech 3')\n",
|
||||
" _states_data[_run, _step, states_names.index('b')] -= args[0]\n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"def mech_four(_states_data, _time_array, _run, _step):\n",
|
||||
"# print('mech 4')\n",
|
||||
" _states_data[_run, _step, states_names.index('a')] = _states_data[_run, _step-1, states_names.index('a')]\n",
|
||||
" _states_data[_run, _step, states_names.index('b')] = _states_data[_run, _step-1, states_names.index('b')] \n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"mechanisms = [eval(m) for m in mechanisms_names]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Behavioral Model Coef (params) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 501,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"behavior_one_coef_A = 0.01\n",
|
||||
"behavior_one_coef_B = -0.01\n",
|
||||
"\n",
|
||||
"behavior_two_coef_A = 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# BEHAVIORAL MODEL (func)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 502,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"behaviors_names = ['behavior_one', 'behavior_two']\n",
|
||||
"def behavior_one(_states_data, _time_array, _run, _step): \n",
|
||||
" c_var = ( _states_data[_run, _step, states_names.index('c')]\n",
|
||||
" - _states_data[_run, _step-1, states_names.index('c')] )\n",
|
||||
" c_var_perc = c_var / _states_data[_run, _step-1, states_names.index('c')]\n",
|
||||
" \n",
|
||||
" if (c_var_perc > behavior_one_coef_A):\n",
|
||||
" return mech_one(_states_data, _time_array, _run, _step, [c_var])\n",
|
||||
" elif (c_var_perc < behavior_one_coef_B):\n",
|
||||
" return mech_two(_states_data, _time_array, _run, _step, [-c_var])\n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"def behavior_two(_states_data, _time_array, _run, _step):\n",
|
||||
" b_balance = _states_data[_run, _step-1, states_names.index('b')]\n",
|
||||
" if (b_balance > behavior_two_coef_A):\n",
|
||||
" return mech_three(_states_data, _time_array, _run, _step, [b_balance])\n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"behaviors = [eval(b) for b in behaviors_names] "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ENVIRONMENTAL PROCESS (dimension)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 503,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"env_proc_names = ['proc_one']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Stochastic Process Coef (params)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 504,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"proc_one_coef_A = 0.7\n",
|
||||
"proc_one_coef_B = 1.3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ENVIRONMENTAL PROCESS (func)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 505,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def proc_one(_states_data, _time_array, _run, _step):\n",
|
||||
" _states_data[_run, _step, states_names.index('a')] = _states_data[_run, _step-1, states_names.index('a')]\n",
|
||||
" _states_data[_run, _step, states_names.index('b')] = _states_data[_run, _step-1, states_names.index('b')] \n",
|
||||
" _states_data[_run, _step, states_names.index('c')] = ( _states_data[_run, _step-1, states_names.index('c')]\n",
|
||||
" * bound_norm_random(proc_one_coef_A, proc_one_coef_B) )\n",
|
||||
" return _states_data\n",
|
||||
"\n",
|
||||
"env_proc = [eval(p) for p in env_proc_names]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ENGINE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 506,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/markusbkoch/.local/share/virtualenvs/DiffyQ-SimCAD-4_qpgnP9/lib/python3.6/site-packages/ipykernel_launcher.py:5: RuntimeWarning: invalid value encountered in long_scalars\n",
|
||||
" \"\"\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"for i in range(monte_carlo_runs):\n",
|
||||
" for t in range(1,experiment_steps):\n",
|
||||
" for p in env_proc:\n",
|
||||
" states_data = p(_states_data=states_data,\n",
|
||||
" _time_array=time_array, \n",
|
||||
" _run=i, \n",
|
||||
" _step=t)\n",
|
||||
" for b in behaviors:\n",
|
||||
" states_data = b(_states_data=states_data,\n",
|
||||
" _time_array=time_array, \n",
|
||||
" _run=i, \n",
|
||||
" _step=t) #behaviors have access to exogenous data @ step-1, not @ step"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# DATA COLLECTION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 507,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th></th>\n",
|
||||
" <th>a</th>\n",
|
||||
" <th>b</th>\n",
|
||||
" <th>c</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th rowspan=\"30\" valign=\"top\">0</th>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>300</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>86400</th>\n",
|
||||
" <td>-7</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>293</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>172800</th>\n",
|
||||
" <td>-20</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>280</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>259200</th>\n",
|
||||
" <td>-86</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>214</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>345600</th>\n",
|
||||
" <td>-67</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>234</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>432000</th>\n",
|
||||
" <td>-67</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>233</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>518400</th>\n",
|
||||
" <td>-91</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>209</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>604800</th>\n",
|
||||
" <td>-99</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>201</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>691200</th>\n",
|
||||
" <td>-93</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>207</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>777600</th>\n",
|
||||
" <td>-104</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>196</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>864000</th>\n",
|
||||
" <td>-101</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>199</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>950400</th>\n",
|
||||
" <td>-86</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>214</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1036800</th>\n",
|
||||
" <td>-92</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>208</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1123200</th>\n",
|
||||
" <td>-92</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>210</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1209600</th>\n",
|
||||
" <td>-99</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>203</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1296000</th>\n",
|
||||
" <td>-122</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>180</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1382400</th>\n",
|
||||
" <td>-135</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>167</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1468800</th>\n",
|
||||
" <td>-161</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>141</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1555200</th>\n",
|
||||
" <td>-161</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>141</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1641600</th>\n",
|
||||
" <td>-187</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>115</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1728000</th>\n",
|
||||
" <td>-195</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>107</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1814400</th>\n",
|
||||
" <td>-201</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>101</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1900800</th>\n",
|
||||
" <td>-189</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>113</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1987200</th>\n",
|
||||
" <td>-189</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>112</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2073600</th>\n",
|
||||
" <td>-189</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>111</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2160000</th>\n",
|
||||
" <td>-191</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>109</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2246400</th>\n",
|
||||
" <td>-200</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2332800</th>\n",
|
||||
" <td>-206</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>94</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2419200</th>\n",
|
||||
" <td>-206</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>94</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2505600</th>\n",
|
||||
" <td>-218</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>82</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>...</th>\n",
|
||||
" <th>...</th>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" <td>...</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th rowspan=\"30\" valign=\"top\">99</th>\n",
|
||||
" <th>83808000</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>83894400</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>83980800</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84067200</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84153600</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84240000</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84326400</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84412800</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84499200</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84585600</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84672000</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84758400</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84844800</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>84931200</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85017600</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85104000</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85190400</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85276800</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85363200</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85449600</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85536000</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85622400</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85708800</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85795200</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85881600</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>85968000</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>86054400</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>86140800</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>86227200</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>86313600</th>\n",
|
||||
" <td>-386</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"<p>100000 rows × 3 columns</p>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" a b c\n",
|
||||
"0 0 0 0 300\n",
|
||||
" 86400 -7 0 293\n",
|
||||
" 172800 -20 0 280\n",
|
||||
" 259200 -86 0 214\n",
|
||||
" 345600 -67 1 234\n",
|
||||
" 432000 -67 1 233\n",
|
||||
" 518400 -91 1 209\n",
|
||||
" 604800 -99 1 201\n",
|
||||
" 691200 -93 1 207\n",
|
||||
" 777600 -104 1 196\n",
|
||||
" 864000 -101 1 199\n",
|
||||
" 950400 -86 1 214\n",
|
||||
" 1036800 -92 1 208\n",
|
||||
" 1123200 -92 1 210\n",
|
||||
" 1209600 -99 1 203\n",
|
||||
" 1296000 -122 1 180\n",
|
||||
" 1382400 -135 1 167\n",
|
||||
" 1468800 -161 1 141\n",
|
||||
" 1555200 -161 1 141\n",
|
||||
" 1641600 -187 1 115\n",
|
||||
" 1728000 -195 1 107\n",
|
||||
" 1814400 -201 1 101\n",
|
||||
" 1900800 -189 1 113\n",
|
||||
" 1987200 -189 1 112\n",
|
||||
" 2073600 -189 1 111\n",
|
||||
" 2160000 -191 1 109\n",
|
||||
" 2246400 -200 1 100\n",
|
||||
" 2332800 -206 1 94\n",
|
||||
" 2419200 -206 1 94\n",
|
||||
" 2505600 -218 1 82\n",
|
||||
"... ... .. ...\n",
|
||||
"99 83808000 -386 0 0\n",
|
||||
" 83894400 -386 0 0\n",
|
||||
" 83980800 -386 0 0\n",
|
||||
" 84067200 -386 0 0\n",
|
||||
" 84153600 -386 0 0\n",
|
||||
" 84240000 -386 0 0\n",
|
||||
" 84326400 -386 0 0\n",
|
||||
" 84412800 -386 0 0\n",
|
||||
" 84499200 -386 0 0\n",
|
||||
" 84585600 -386 0 0\n",
|
||||
" 84672000 -386 0 0\n",
|
||||
" 84758400 -386 0 0\n",
|
||||
" 84844800 -386 0 0\n",
|
||||
" 84931200 -386 0 0\n",
|
||||
" 85017600 -386 0 0\n",
|
||||
" 85104000 -386 0 0\n",
|
||||
" 85190400 -386 0 0\n",
|
||||
" 85276800 -386 0 0\n",
|
||||
" 85363200 -386 0 0\n",
|
||||
" 85449600 -386 0 0\n",
|
||||
" 85536000 -386 0 0\n",
|
||||
" 85622400 -386 0 0\n",
|
||||
" 85708800 -386 0 0\n",
|
||||
" 85795200 -386 0 0\n",
|
||||
" 85881600 -386 0 0\n",
|
||||
" 85968000 -386 0 0\n",
|
||||
" 86054400 -386 0 0\n",
|
||||
" 86140800 -386 0 0\n",
|
||||
" 86227200 -386 0 0\n",
|
||||
" 86313600 -386 0 0\n",
|
||||
"\n",
|
||||
"[100000 rows x 3 columns]"
|
||||
]
|
||||
},
|
||||
"execution_count": 507,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"data = pd.DataFrame(states_data[0], \n",
|
||||
" index=[[0]*experiment_steps, time_array], \n",
|
||||
" columns=states_names)\n",
|
||||
"for i in range(1,monte_carlo_runs):\n",
|
||||
" b = pd.DataFrame(states_data[i],\n",
|
||||
" index=[[i]*experiment_steps, time_array], \n",
|
||||
" columns=states_names)\n",
|
||||
" data = data.append(b)\n",
|
||||
"data"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "DiffyQ-SimCAD Env",
|
||||
"language": "python",
|
||||
"name": "diffyq-simcad"
|
||||
},
|
||||
"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": 2
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"assert pd.__version__ == '0.23.4'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"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": 2
|
||||
}
|
||||
|
|
@ -0,0 +1,422 @@
|
|||
|
||||
% Default to the notebook output style
|
||||
|
||||
|
||||
|
||||
|
||||
% Inherit from the specified cell style.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
\documentclass[11pt]{article}
|
||||
|
||||
|
||||
|
||||
\usepackage[T1]{fontenc}
|
||||
% Nicer default font (+ math font) than Computer Modern for most use cases
|
||||
\usepackage{mathpazo}
|
||||
|
||||
% Basic figure setup, for now with no caption control since it's done
|
||||
% automatically by Pandoc (which extracts  syntax from Markdown).
|
||||
\usepackage{graphicx}
|
||||
% We will generate all images so they have a width \maxwidth. This means
|
||||
% that they will get their normal width if they fit onto the page, but
|
||||
% are scaled down if they would overflow the margins.
|
||||
\makeatletter
|
||||
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth
|
||||
\else\Gin@nat@width\fi}
|
||||
\makeatother
|
||||
\let\Oldincludegraphics\includegraphics
|
||||
% Set max figure width to be 80% of text width, for now hardcoded.
|
||||
\renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=.8\maxwidth]{#1}}
|
||||
% Ensure that by default, figures have no caption (until we provide a
|
||||
% proper Figure object with a Caption API and a way to capture that
|
||||
% in the conversion process - todo).
|
||||
\usepackage{caption}
|
||||
\DeclareCaptionLabelFormat{nolabel}{}
|
||||
\captionsetup{labelformat=nolabel}
|
||||
|
||||
\usepackage{adjustbox} % Used to constrain images to a maximum size
|
||||
\usepackage{xcolor} % Allow colors to be defined
|
||||
\usepackage{enumerate} % Needed for markdown enumerations to work
|
||||
\usepackage{geometry} % Used to adjust the document margins
|
||||
\usepackage{amsmath} % Equations
|
||||
\usepackage{amssymb} % Equations
|
||||
\usepackage{textcomp} % defines textquotesingle
|
||||
% Hack from http://tex.stackexchange.com/a/47451/13684:
|
||||
\AtBeginDocument{%
|
||||
\def\PYZsq{\textquotesingle}% Upright quotes in Pygmentized code
|
||||
}
|
||||
\usepackage{upquote} % Upright quotes for verbatim code
|
||||
\usepackage{eurosym} % defines \euro
|
||||
\usepackage[mathletters]{ucs} % Extended unicode (utf-8) support
|
||||
\usepackage[utf8x]{inputenc} % Allow utf-8 characters in the tex document
|
||||
\usepackage{fancyvrb} % verbatim replacement that allows latex
|
||||
\usepackage{grffile} % extends the file name processing of package graphics
|
||||
% to support a larger range
|
||||
% The hyperref package gives us a pdf with properly built
|
||||
% internal navigation ('pdf bookmarks' for the table of contents,
|
||||
% internal cross-reference links, web links for URLs, etc.)
|
||||
\usepackage{hyperref}
|
||||
\usepackage{longtable} % longtable support required by pandoc >1.10
|
||||
\usepackage{booktabs} % table support for pandoc > 1.12.2
|
||||
\usepackage[inline]{enumitem} % IRkernel/repr support (it uses the enumerate* environment)
|
||||
\usepackage[normalem]{ulem} % ulem is needed to support strikethroughs (\sout)
|
||||
% normalem makes italics be italics, not underlines
|
||||
|
||||
|
||||
|
||||
|
||||
% Colors for the hyperref package
|
||||
\definecolor{urlcolor}{rgb}{0,.145,.698}
|
||||
\definecolor{linkcolor}{rgb}{.71,0.21,0.01}
|
||||
\definecolor{citecolor}{rgb}{.12,.54,.11}
|
||||
|
||||
% ANSI colors
|
||||
\definecolor{ansi-black}{HTML}{3E424D}
|
||||
\definecolor{ansi-black-intense}{HTML}{282C36}
|
||||
\definecolor{ansi-red}{HTML}{E75C58}
|
||||
\definecolor{ansi-red-intense}{HTML}{B22B31}
|
||||
\definecolor{ansi-green}{HTML}{00A250}
|
||||
\definecolor{ansi-green-intense}{HTML}{007427}
|
||||
\definecolor{ansi-yellow}{HTML}{DDB62B}
|
||||
\definecolor{ansi-yellow-intense}{HTML}{B27D12}
|
||||
\definecolor{ansi-blue}{HTML}{208FFB}
|
||||
\definecolor{ansi-blue-intense}{HTML}{0065CA}
|
||||
\definecolor{ansi-magenta}{HTML}{D160C4}
|
||||
\definecolor{ansi-magenta-intense}{HTML}{A03196}
|
||||
\definecolor{ansi-cyan}{HTML}{60C6C8}
|
||||
\definecolor{ansi-cyan-intense}{HTML}{258F8F}
|
||||
\definecolor{ansi-white}{HTML}{C5C1B4}
|
||||
\definecolor{ansi-white-intense}{HTML}{A1A6B2}
|
||||
|
||||
% commands and environments needed by pandoc snippets
|
||||
% extracted from the output of `pandoc -s`
|
||||
\providecommand{\tightlist}{%
|
||||
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
|
||||
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
|
||||
% Add ',fontsize=\small' for more characters per line
|
||||
\newenvironment{Shaded}{}{}
|
||||
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
|
||||
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}
|
||||
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
|
||||
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
|
||||
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
|
||||
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
|
||||
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
|
||||
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}
|
||||
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}
|
||||
\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
|
||||
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}
|
||||
\newcommand{\RegionMarkerTok}[1]{{#1}}
|
||||
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
|
||||
\newcommand{\NormalTok}[1]{{#1}}
|
||||
|
||||
% Additional commands for more recent versions of Pandoc
|
||||
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}}
|
||||
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
|
||||
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
|
||||
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}}
|
||||
\newcommand{\ImportTok}[1]{{#1}}
|
||||
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}}
|
||||
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
|
||||
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
|
||||
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}}
|
||||
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
|
||||
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}}
|
||||
\newcommand{\BuiltInTok}[1]{{#1}}
|
||||
\newcommand{\ExtensionTok}[1]{{#1}}
|
||||
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}}
|
||||
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}}
|
||||
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
|
||||
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
|
||||
|
||||
|
||||
% Define a nice break command that doesn't care if a line doesn't already
|
||||
% exist.
|
||||
\def\br{\hspace*{\fill} \\* }
|
||||
% Math Jax compatability definitions
|
||||
\def\gt{>}
|
||||
\def\lt{<}
|
||||
% Document parameters
|
||||
\title{testBC}
|
||||
|
||||
|
||||
|
||||
|
||||
% Pygments definitions
|
||||
|
||||
\makeatletter
|
||||
\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
|
||||
\let\PY@ul=\relax \let\PY@tc=\relax%
|
||||
\let\PY@bc=\relax \let\PY@ff=\relax}
|
||||
\def\PY@tok#1{\csname PY@tok@#1\endcsname}
|
||||
\def\PY@toks#1+{\ifx\relax#1\empty\else%
|
||||
\PY@tok{#1}\expandafter\PY@toks\fi}
|
||||
\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
|
||||
\PY@it{\PY@bf{\PY@ff{#1}}}}}}}
|
||||
\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}
|
||||
|
||||
\expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
|
||||
\expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
|
||||
\expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
|
||||
\expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}}
|
||||
\expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
|
||||
\expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
|
||||
\expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit}
|
||||
\expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf}
|
||||
\expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
|
||||
\expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
|
||||
\expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
|
||||
\expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@fm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
|
||||
\expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
|
||||
\expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
|
||||
\expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
|
||||
\expandafter\def\csname PY@tok@vm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sa\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@dl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
|
||||
\expandafter\def\csname PY@tok@mb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
|
||||
\expandafter\def\csname PY@tok@ch\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@cpf\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
|
||||
\expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
|
||||
|
||||
\def\PYZbs{\char`\\}
|
||||
\def\PYZus{\char`\_}
|
||||
\def\PYZob{\char`\{}
|
||||
\def\PYZcb{\char`\}}
|
||||
\def\PYZca{\char`\^}
|
||||
\def\PYZam{\char`\&}
|
||||
\def\PYZlt{\char`\<}
|
||||
\def\PYZgt{\char`\>}
|
||||
\def\PYZsh{\char`\#}
|
||||
\def\PYZpc{\char`\%}
|
||||
\def\PYZdl{\char`\$}
|
||||
\def\PYZhy{\char`\-}
|
||||
\def\PYZsq{\char`\'}
|
||||
\def\PYZdq{\char`\"}
|
||||
\def\PYZti{\char`\~}
|
||||
% for compatibility with earlier versions
|
||||
\def\PYZat{@}
|
||||
\def\PYZlb{[}
|
||||
\def\PYZrb{]}
|
||||
\makeatother
|
||||
|
||||
|
||||
% Exact colors from NB
|
||||
\definecolor{incolor}{rgb}{0.0, 0.0, 0.5}
|
||||
\definecolor{outcolor}{rgb}{0.545, 0.0, 0.0}
|
||||
|
||||
|
||||
|
||||
|
||||
% Prevent overflowing lines due to hard-to-break entities
|
||||
\sloppy
|
||||
% Setup hyperref package
|
||||
\hypersetup{
|
||||
breaklinks=true, % so long urls are correctly broken across lines
|
||||
colorlinks=true,
|
||||
urlcolor=urlcolor,
|
||||
linkcolor=linkcolor,
|
||||
citecolor=citecolor,
|
||||
}
|
||||
% Slightly bigger margins than the latex defaults
|
||||
|
||||
\geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}
|
||||
|
||||
|
||||
|
||||
\begin{document}
|
||||
|
||||
|
||||
\maketitle
|
||||
|
||||
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}1}]:} \PY{k+kn}{from} \PY{n+nn}{engine} \PY{k}{import} \PY{n}{run}
|
||||
\PY{k+kn}{import} \PY{n+nn}{matplotlib}\PY{n+nn}{.}\PY{n+nn}{pyplot} \PY{k}{as} \PY{n+nn}{plt}
|
||||
\PY{k+kn}{import} \PY{n+nn}{numpy} \PY{k}{as} \PY{n+nn}{np}
|
||||
|
||||
\PY{o}{\PYZpc{}}\PY{k}{matplotlib} inline
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}2}]:} \PY{n}{d}\PY{o}{=}\PY{n}{run}\PY{o}{.}\PY{n}{main}\PY{p}{(}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
Test
|
||||
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}3}]:} \PY{n}{names} \PY{o}{=} \PY{n}{d}\PY{o}{.}\PY{n}{keys}\PY{p}{(}\PY{p}{)}\PY{p}{[}\PY{p}{:}\PY{l+m+mi}{4}\PY{p}{]}
|
||||
\PY{k}{for} \PY{n}{n} \PY{o+ow}{in} \PY{n}{names}\PY{p}{:}
|
||||
\PY{n}{d}\PY{p}{[}\PY{n}{n}\PY{p}{]}\PY{o}{=}\PY{n}{d}\PY{p}{[}\PY{n}{n}\PY{p}{]}\PY{o}{.}\PY{n}{apply}\PY{p}{(}\PY{n+nb}{float}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}15}]:} \PY{n}{d}\PY{o}{.}\PY{n}{plot}\PY{p}{(}\PY{n}{x}\PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{time\PYZus{}step}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{y}\PY{o}{=}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{Pool}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{Supply}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{,} \PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{15}\PY{p}{,}\PY{l+m+mi}{10}\PY{p}{)}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
/anaconda3/lib/python3.6/site-packages/pandas/plotting/\_core.py:1716: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html\#attribute-access
|
||||
series.name = label
|
||||
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{outcolor}Out[{\color{outcolor}15}]:} <matplotlib.axes.\_subplots.AxesSubplot at 0x113bd9438>
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{center}
|
||||
\adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{output_3_2.png}
|
||||
\end{center}
|
||||
{ \hspace*{\fill} \\}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}13}]:} \PY{n}{d}\PY{o}{.}\PY{n}{plot}\PY{p}{(}\PY{n}{x}\PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{time\PYZus{}step}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{n}{y}\PY{o}{=}\PY{p}{[}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{Pool}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,} \PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{Supply}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]}\PY{p}{,} \PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{15}\PY{p}{,}\PY{l+m+mi}{10}\PY{p}{)}\PY{p}{,} \PY{n}{logy}\PY{o}{=}\PY{k+kc}{True}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
/anaconda3/lib/python3.6/site-packages/pandas/plotting/\_core.py:1716: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html\#attribute-access
|
||||
series.name = label
|
||||
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{outcolor}Out[{\color{outcolor}13}]:} <matplotlib.axes.\_subplots.AxesSubplot at 0x1132f1e80>
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{center}
|
||||
\adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{output_4_2.png}
|
||||
\end{center}
|
||||
{ \hspace*{\fill} \\}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}8}]:} \PY{n}{d}\PY{p}{[}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{invar}\PY{l+s+s2}{\PYZdq{}}\PY{p}{]}\PY{o}{=}\PY{p}{(}\PY{n}{d}\PY{o}{.}\PY{n}{Pool}\PY{o}{/}\PY{n}{d}\PY{o}{.}\PY{n}{Supply}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}9}]:} \PY{n}{d}\PY{o}{.}\PY{n}{invar}\PY{o}{.}\PY{n}{describe}\PY{p}{(}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{outcolor}Out[{\color{outcolor}9}]:} count 2001.0
|
||||
mean 2.0
|
||||
std 0.0
|
||||
min 2.0
|
||||
25\% 2.0
|
||||
50\% 2.0
|
||||
75\% 2.0
|
||||
max 2.0
|
||||
Name: invar, dtype: float64
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}10}]:} \PY{n}{d}\PY{o}{.}\PY{n}{tail}\PY{p}{(}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{outcolor}Out[{\color{outcolor}10}]:} Belief Pool Price Supply mech\_step time\_step \textbackslash{}
|
||||
1996 1.479643 6.525178e+08 2.394507 3.262589e+08 2 998
|
||||
1997 1.604208 6.525178e+08 2.464774 3.262589e+08 1 999
|
||||
1998 1.806759 5.766994e+08 2.381050 2.883497e+08 2 999
|
||||
1999 1.988029 5.766994e+08 2.394131 2.883497e+08 1 1000
|
||||
2000 2.061324 5.198756e+08 2.332448 2.599378e+08 2 1000
|
||||
|
||||
timestamp invar
|
||||
1996 2018-10-01 15:33:02 2.0
|
||||
1997 2018-10-01 15:33:03 2.0
|
||||
1998 2018-10-01 15:33:03 2.0
|
||||
1999 2018-10-01 15:33:04 2.0
|
||||
2000 2018-10-01 15:33:04 2.0
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor}11}]:} \PY{n}{d}\PY{o}{.}\PY{n}{plot}\PY{p}{(}\PY{n}{x}\PY{o}{=}\PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{time\PYZus{}step}\PY{l+s+s1}{\PYZsq{}}\PY{p}{,}\PY{n}{y}\PY{o}{=}\PY{p}{[}\PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Price}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{l+s+s2}{\PYZdq{}}\PY{l+s+s2}{Belief}\PY{l+s+s2}{\PYZdq{}}\PY{p}{,} \PY{l+s+s1}{\PYZsq{}}\PY{l+s+s1}{invar}\PY{l+s+s1}{\PYZsq{}}\PY{p}{]} \PY{p}{,}\PY{n}{figsize}\PY{o}{=}\PY{p}{(}\PY{l+m+mi}{15}\PY{p}{,}\PY{l+m+mi}{10}\PY{p}{)}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
/anaconda3/lib/python3.6/site-packages/pandas/plotting/\_core.py:1716: UserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html\#attribute-access
|
||||
series.name = label
|
||||
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{outcolor}Out[{\color{outcolor}11}]:} <matplotlib.axes.\_subplots.AxesSubplot at 0x113300940>
|
||||
\end{Verbatim}
|
||||
|
||||
\begin{center}
|
||||
\adjustimage{max size={0.9\linewidth}{0.9\paperheight}}{output_8_2.png}
|
||||
\end{center}
|
||||
{ \hspace*{\fill} \\}
|
||||
|
||||
\begin{Verbatim}[commandchars=\\\{\}]
|
||||
{\color{incolor}In [{\color{incolor} }]:} \PY{n}{d}\PY{o}{.}\PY{n}{head}\PY{p}{(}\PY{l+m+mi}{11}\PY{p}{)}
|
||||
\end{Verbatim}
|
||||
|
||||
|
||||
|
||||
% Add a bibliography block to the postdoc
|
||||
|
||||
|
||||
|
||||
\end{document}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ImportError",
|
||||
"evalue": "cannot import name 'run'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mImportError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[1;32m<ipython-input-5-a6e895c51fc0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mengine\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mrun\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mrun\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
||||
"\u001b[1;31mImportError\u001b[0m: cannot import name 'run'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from engine import run\n",
|
||||
"run.main()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"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": 2
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +0,0 @@
|
|||
pandas
|
||||
wheel
|
||||
pathos
|
||||
fn
|
||||
tabulate
|
||||
funcy
|
||||
45
setup.py
45
setup.py
|
|
@ -1,38 +1,11 @@
|
|||
from setuptools import setup, find_packages
|
||||
from setuptools import setup
|
||||
|
||||
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
|
||||
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
|
||||
provided.
|
||||
"""
|
||||
|
||||
setup(name='cadCAD',
|
||||
version='0.3.1',
|
||||
description="cadCAD: a differential games based simulation software package for research, validation, and \
|
||||
Computer Aided Design of economic systems",
|
||||
long_description=long_description,
|
||||
url='https://github.com/BlockScience/cadCAD',
|
||||
setup(name='SimCAD',
|
||||
version='0.1',
|
||||
description='Sim-Cad Enigne',
|
||||
url='https://github.com/BlockScience/DiffyQ-SimCAD',
|
||||
author='Joshua E. Jodesty',
|
||||
author_email='joshua@block.science, joshua.jodesty@gmail.com',
|
||||
license='LICENSE.txt',
|
||||
packages=find_packages(),
|
||||
install_requires=[
|
||||
"pandas",
|
||||
"wheel",
|
||||
"pathos",
|
||||
"fn",
|
||||
"tabulate",
|
||||
"funcy"
|
||||
]
|
||||
)
|
||||
author_email='joshua@block.science',
|
||||
license='MIT',
|
||||
packages=['engine'],
|
||||
zip_safe=False)
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,27 +0,0 @@
|
|||
ds1,ds2,ds3,run,substep,timestep
|
||||
0,0,1,1,0,0
|
||||
1,40,5,1,1,1
|
||||
2,40,5,1,2,1
|
||||
3,40,5,1,3,1
|
||||
4,40,5,1,1,2
|
||||
5,40,5,1,2,2
|
||||
6,40,5,1,3,2
|
||||
7,40,5,1,1,3
|
||||
8,40,5,1,2,3
|
||||
9,40,5,1,3,3
|
||||
10,40,5,1,1,4
|
||||
11,40,5,1,2,4
|
||||
12,40,5,1,3,4
|
||||
0,0,1,2,0,0
|
||||
1,40,5,2,1,1
|
||||
2,40,5,2,2,1
|
||||
3,40,5,2,3,1
|
||||
4,40,5,2,1,2
|
||||
5,40,5,2,2,2
|
||||
6,40,5,2,3,2
|
||||
7,40,5,2,1,3
|
||||
8,40,5,2,2,3
|
||||
9,40,5,2,3,3
|
||||
10,40,5,2,1,4
|
||||
11,40,5,2,2,4
|
||||
12,40,5,2,3,4
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
# from simulations.validation import config1_test_pipe
|
||||
# from simulations.validation import config1
|
||||
from simulations.validation import write_simulation
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, _ = run.main()
|
||||
result = pd.DataFrame(raw_result)
|
||||
result.to_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv', index=False)
|
||||
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.validation import sweep_config
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Concurrent Execution")
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
i = 0
|
||||
config_names = ['sweep_config_A', 'sweep_config_B']
|
||||
for raw_result, tensor_field in run.execute():
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field: " + config_names[i])
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
i += 1
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
import numpy as np
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import bound_norm_random, config_sim, time_step, env_trigger
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(4)
|
||||
}
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'param1': 1}
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'param1': 1, 'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'param1': 'a', 'param2': 2}
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'param1': 'b', 'param2': 4}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'param1': ['c'], 'param2': np.array([10, 100])}
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'param1': ['d'], 'param2': np.array([20, 200])}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = s['s1'] + 1
|
||||
return (y, x)
|
||||
def s2m1(_g, step, sL, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m2(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = s['s1'] + 1
|
||||
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 = s['s1'] + 1
|
||||
return (y, x)
|
||||
def s2m3(_g, step, sL, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def policies(_g, step, sL, s, _input):
|
||||
y = 'policies'
|
||||
x = _input
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Exogenous States
|
||||
proc_one_coef_A = 0.7
|
||||
proc_one_coef_B = 1.3
|
||||
|
||||
def es3(_g, step, sL, s, _input):
|
||||
y = 's3'
|
||||
x = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def es4(_g, step, sL, s, _input):
|
||||
y = 's4'
|
||||
x = s['s4'] * bound_norm_random(seeds['b'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def update_timestamp(_g, step, sL, s, _input):
|
||||
y = 'timestamp'
|
||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
's1': 0.0,
|
||||
's2': 0.0,
|
||||
's3': 1.0,
|
||||
's4': 1.0,
|
||||
'timestamp': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# Environment Process
|
||||
# ToDo: Depreciation Waring for env_proc_trigger convention
|
||||
trigger_timestamps = ['2018-10-01 15:16:25', '2018-10-01 15:16:27', '2018-10-01 15:16:29']
|
||||
env_processes = {
|
||||
"s3": [lambda _g, x: 5],
|
||||
"s4": env_trigger(3)(trigger_field='timestamp', trigger_vals=trigger_timestamps, funct_list=[lambda _g, x: 10])
|
||||
}
|
||||
|
||||
|
||||
partial_state_update_block = [
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m1,
|
||||
"b2": p2m1
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m1,
|
||||
"s2": s2m1,
|
||||
"s3": es3,
|
||||
"s4": es4,
|
||||
"timestamp": update_timestamp
|
||||
}
|
||||
},
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m2,
|
||||
"b2": p2m2
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m2,
|
||||
"s2": s2m2,
|
||||
# "s3": es3p1,
|
||||
# "s4": es4p2,
|
||||
}
|
||||
},
|
||||
{
|
||||
"policies": {
|
||||
"b1": p1m3,
|
||||
"b2": p2m3
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m3,
|
||||
"s2": s2m3,
|
||||
# "s3": es3p1,
|
||||
# "s4": es4p2,
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
# "N": 5,
|
||||
"T": range(5),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=partial_state_update_block,
|
||||
policy_ops=[lambda a, b: a + b]
|
||||
)
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
import numpy as np
|
||||
from datetime import timedelta
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import bound_norm_random, config_sim, env_trigger, time_step
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'param1': 1}
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'param1': 'a', 'param2': 2}
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'param1': 'b', 'param2': 4}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'param1': ['c'], 'param2': np.array([10, 100])}
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'param1': ['d'], 'param2': np.array([20, 200])}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
return (y, x)
|
||||
def s2m1(_g, step, sL, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m2(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
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 = _input['param1']
|
||||
return (y, x)
|
||||
def s2m3(_g, 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 es3(_g, step, sL, s, _input):
|
||||
y = 's3'
|
||||
x = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def es4(_g, step, sL, s, _input):
|
||||
y = 's4'
|
||||
x = s['s4'] * bound_norm_random(seeds['b'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def update_timestamp(_g, step, sL, s, _input):
|
||||
y = 'timestamp'
|
||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
's1': 0,
|
||||
's2': 0,
|
||||
's3': 1,
|
||||
's4': 1,
|
||||
'timestamp': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# Environment Process
|
||||
# ToDo: Depreciation Waring for env_proc_trigger convention
|
||||
trigger_timestamps = ['2018-10-01 15:16:25', '2018-10-01 15:16:27', '2018-10-01 15:16:29']
|
||||
env_processes = {
|
||||
"s3": [lambda _g, x: 5],
|
||||
"s4": env_trigger(3)(trigger_field='timestamp', trigger_vals=trigger_timestamps, funct_list=[lambda _g, x: 10])
|
||||
}
|
||||
|
||||
partial_state_update_block = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"b1": p1m1,
|
||||
# "b2": p2m1
|
||||
},
|
||||
"states": {
|
||||
"s1": s1m1,
|
||||
# "s2": s2m1
|
||||
"s3": es3,
|
||||
"s4": es4,
|
||||
"timestep": update_timestamp
|
||||
}
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"b1": p1m2,
|
||||
# "b2": p2m2
|
||||
},
|
||||
"states": {
|
||||
"s1": s1m2,
|
||||
# "s2": s2m2
|
||||
}
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"b1": p1m3,
|
||||
"b2": p2m3
|
||||
},
|
||||
"states": {
|
||||
"s1": s1m3,
|
||||
"s2": s2m3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=partial_state_update_block
|
||||
)
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
import pandas as pd
|
||||
from cadCAD.utils import SilentDF
|
||||
|
||||
df = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv'))
|
||||
|
||||
|
||||
def query(s, df):
|
||||
return df[
|
||||
(df['run'] == s['run']) & (df['substep'] == s['substep']) & (df['timestep'] == s['timestep'])
|
||||
].drop(columns=['run', 'substep', "timestep"])
|
||||
|
||||
def p1(_g, substep, sL, s):
|
||||
result_dict = query(s, df).to_dict()
|
||||
del result_dict["ds3"]
|
||||
return {k: list(v.values()).pop() for k, v in result_dict.items()}
|
||||
|
||||
def p2(_g, substep, sL, s):
|
||||
result_dict = query(s, df).to_dict()
|
||||
del result_dict["ds1"], result_dict["ds2"]
|
||||
return {k: list(v.values()).pop() for k, v in result_dict.items()}
|
||||
|
||||
# ToDo: SilentDF(df) wont work
|
||||
#integrate_ext_dataset
|
||||
def integrate_ext_dataset(_g, step, sL, s, _input):
|
||||
result_dict = query(s, df).to_dict()
|
||||
return 'external_data', {k: list(v.values()).pop() for k, v in result_dict.items()}
|
||||
|
||||
def increment(y, incr_by):
|
||||
return lambda _g, step, sL, s, _input: (y, s[y] + incr_by)
|
||||
increment = increment('increment', 1)
|
||||
|
||||
def view_policies(_g, step, sL, s, _input):
|
||||
return 'policies', _input
|
||||
|
||||
|
||||
external_data = {'ds1': None, 'ds2': None, 'ds3': None}
|
||||
state_dict = {
|
||||
'increment': 0,
|
||||
'external_data': external_data,
|
||||
'policies': external_data
|
||||
}
|
||||
|
||||
|
||||
policies = {"p1": p1, "p2": p2}
|
||||
states = {'increment': increment, 'external_data': integrate_ext_dataset, 'policies': view_policies}
|
||||
PSUB = {'policies': policies, 'states': states}
|
||||
|
||||
# needs M1&2 need behaviors
|
||||
partial_state_update_blocks = {
|
||||
'PSUB1': PSUB,
|
||||
'PSUB2': PSUB,
|
||||
'PSUB3': PSUB
|
||||
}
|
||||
|
||||
sim_config = config_sim({
|
||||
"N": 2,
|
||||
"T": range(4)
|
||||
})
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=state_dict,
|
||||
partial_state_update_blocks=partial_state_update_blocks,
|
||||
policy_ops=[lambda a, b: {**a, **b}]
|
||||
)
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim, access_block
|
||||
|
||||
policies, variables = {}, {}
|
||||
exclusion_list = ['nonexsistant', 'last_x', '2nd_to_last_x', '3rd_to_last_x', '4th_to_last_x']
|
||||
|
||||
# Policies per Mechanism
|
||||
|
||||
# WARNING: DO NOT delete elements from sH
|
||||
# state_history, target_field, psu_block_offset, exculsion_list
|
||||
def last_update(_g, substep, sH, s):
|
||||
return {"last_x": access_block(
|
||||
state_history=sH,
|
||||
target_field="last_x",
|
||||
psu_block_offset=-1,
|
||||
exculsion_list=exclusion_list
|
||||
)
|
||||
}
|
||||
policies["last_x"] = last_update
|
||||
|
||||
def second2last_update(_g, substep, sH, s):
|
||||
return {"2nd_to_last_x": access_block(sH, "2nd_to_last_x", -2, exclusion_list)}
|
||||
policies["2nd_to_last_x"] = second2last_update
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
|
||||
# WARNING: DO NOT delete elements from sH
|
||||
def add(y, x):
|
||||
return lambda _g, substep, sH, s, _input: (y, s[y] + x)
|
||||
variables['x'] = add('x', 1)
|
||||
|
||||
# last_partial_state_update_block
|
||||
def nonexsistant(_g, substep, sH, s, _input):
|
||||
return 'nonexsistant', access_block(sH, "nonexsistant", 0, exclusion_list)
|
||||
variables['nonexsistant'] = nonexsistant
|
||||
|
||||
# last_partial_state_update_block
|
||||
def last_x(_g, substep, sH, s, _input):
|
||||
return 'last_x', _input["last_x"]
|
||||
variables['last_x'] = last_x
|
||||
|
||||
# 2nd to last partial state update block
|
||||
def second_to_last_x(_g, substep, sH, s, _input):
|
||||
return '2nd_to_last_x', _input["2nd_to_last_x"]
|
||||
variables['2nd_to_last_x'] = second_to_last_x
|
||||
|
||||
# 3rd to last partial state update block
|
||||
def third_to_last_x(_g, substep, sH, s, _input):
|
||||
return '3rd_to_last_x', access_block(sH, "3rd_to_last_x", -3, exclusion_list)
|
||||
variables['3rd_to_last_x'] = third_to_last_x
|
||||
|
||||
# 4th to last partial state update block
|
||||
def fourth_to_last_x(_g, substep, sH, s, _input):
|
||||
return '4th_to_last_x', access_block(sH, "4th_to_last_x", -4, exclusion_list)
|
||||
variables['4th_to_last_x'] = fourth_to_last_x
|
||||
|
||||
|
||||
genesis_states = {
|
||||
'x': 0,
|
||||
'nonexsistant': [],
|
||||
'last_x': [],
|
||||
'2nd_to_last_x': [],
|
||||
'3rd_to_last_x': [],
|
||||
'4th_to_last_x': []
|
||||
}
|
||||
|
||||
PSUB = {
|
||||
"policies": policies,
|
||||
"variables": variables
|
||||
}
|
||||
|
||||
partial_state_update_block = {
|
||||
"PSUB1": PSUB,
|
||||
"PSUB2": PSUB,
|
||||
"PSUB3": PSUB
|
||||
}
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
"T": range(3),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
partial_state_update_blocks=partial_state_update_block
|
||||
)
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'policy1': 1}
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'policy2': 2}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def add(y, x):
|
||||
return lambda _g, step, sH, s, _input: (y, s[y] + x)
|
||||
|
||||
def policies(_g, step, sH, s, _input):
|
||||
y = 'policies'
|
||||
x = _input
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
'policies': {},
|
||||
's1': 0
|
||||
}
|
||||
|
||||
variables = {
|
||||
's1': add('s1', 1),
|
||||
"policies": policies
|
||||
}
|
||||
|
||||
partial_state_update_block = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"p1": p1m1,
|
||||
"p2": p2m1
|
||||
},
|
||||
"variables": variables
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"p1": p1m2,
|
||||
"p2": p2m2
|
||||
},
|
||||
"variables": variables
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"p1": p1m3,
|
||||
"p2": p2m3
|
||||
},
|
||||
"variables": variables
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
"T": range(3),
|
||||
}
|
||||
)
|
||||
|
||||
# Aggregation == Reduce Map / Reduce Map Aggregation
|
||||
# using env functions (include in reg test using / for env proc)
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
partial_state_update_blocks=partial_state_update_block,
|
||||
# ToDo: subsequent functions should include policy dict for access to each policy (i.e shouldnt be a map)
|
||||
policy_ops=[lambda a, b: a + b, lambda y: y * 2] # Default: lambda a, b: a + b ToDO: reduction function requires high lvl explanation
|
||||
)
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
import numpy as np
|
||||
from datetime import timedelta
|
||||
import pprint
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import env_trigger, var_substep_trigger, config_sim, time_step, psub_list
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
# Optional
|
||||
g: Dict[str, List[int]] = {
|
||||
'alpha': [1],
|
||||
# 'beta': [2],
|
||||
# 'gamma': [3],
|
||||
'beta': [2, 5],
|
||||
'gamma': [3, 4],
|
||||
'omega': [7]
|
||||
}
|
||||
|
||||
psu_steps = ['m1', 'm2', 'm3']
|
||||
system_substeps = len(psu_steps)
|
||||
var_timestep_trigger = var_substep_trigger([0, system_substeps])
|
||||
env_timestep_trigger = env_trigger(system_substeps)
|
||||
env_process = {}
|
||||
psu_block = {k: {"policies": {}, "variables": {}} for k in psu_steps}
|
||||
|
||||
# ['s1', 's2', 's3', 's4']
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'param1': 1}
|
||||
psu_block['m1']['policies']['p1'] = p1m1
|
||||
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'param2': 4}
|
||||
psu_block['m1']['policies']['p2'] = p2m1
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'param1': 'a', 'param2': _g['beta']}
|
||||
psu_block['m2']['policies']['p1'] = p1m2
|
||||
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'param1': 'b', 'param2': 0}
|
||||
psu_block['m2']['policies']['p2'] = p2m2
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'param1': np.array([10, 100])}
|
||||
psu_block['m3']['policies']['p1'] = p1m3
|
||||
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'param1': np.array([20, 200])}
|
||||
psu_block['m3']['policies']['p2'] = p2m3
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sL, s, _input):
|
||||
return 's1', 0
|
||||
psu_block['m1']["variables"]['s1'] = s1m1
|
||||
|
||||
def s2m1(_g, step, sL, s, _input):
|
||||
return 's2', _g['beta']
|
||||
psu_block['m1']["variables"]['s2'] = s2m1
|
||||
|
||||
def s1m2(_g, step, sL, s, _input):
|
||||
return 's1', _input['param2']
|
||||
psu_block['m2']["variables"]['s1'] = s1m2
|
||||
|
||||
def s2m2(_g, step, sL, s, _input):
|
||||
return 's2', _input['param2']
|
||||
psu_block['m2']["variables"]['s2'] = s2m2
|
||||
|
||||
def s1m3(_g, step, sL, s, _input):
|
||||
return 's1', 0
|
||||
psu_block['m3']["variables"]['s1'] = s1m3
|
||||
|
||||
def s2m3(_g, step, sL, s, _input):
|
||||
return 's2', 0
|
||||
psu_block['m3']["variables"]['s2'] = s2m3
|
||||
|
||||
|
||||
# Exogenous States
|
||||
def update_timestamp(_g, step, sL, s, _input):
|
||||
y = 'timestamp'
|
||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||
for m in ['m1','m2','m3']:
|
||||
# psu_block[m]["variables"]['timestamp'] = update_timestamp
|
||||
psu_block[m]["variables"]['timestamp'] = var_timestep_trigger(y='timestamp', f=update_timestamp)
|
||||
# psu_block[m]["variables"]['timestamp'] = var_trigger(
|
||||
# y='timestamp', f=update_timestamp, pre_conditions={'substep': [0, system_substeps]}, cond_op=lambda a, b: a and b
|
||||
# )
|
||||
|
||||
proc_one_coef = 0.7
|
||||
def es3(_g, step, sL, s, _input):
|
||||
return 's3', s['s3'] + proc_one_coef
|
||||
# use `timestep_trigger` to update every ts
|
||||
for m in ['m1','m2','m3']:
|
||||
psu_block[m]["variables"]['s3'] = var_timestep_trigger(y='s3', f=es3)
|
||||
|
||||
|
||||
def es4(_g, step, sL, s, _input):
|
||||
return 's4', s['s4'] + _g['gamma']
|
||||
for m in ['m1','m2','m3']:
|
||||
psu_block[m]["variables"]['s4'] = var_timestep_trigger(y='s4', f=es4)
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
's1': 0.0,
|
||||
's2': 0.0,
|
||||
's3': 1.0,
|
||||
's4': 1.0,
|
||||
'timestamp': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# Environment Process
|
||||
# ToDo: Validate - make env proc trigger field agnostic
|
||||
env_process["s3"] = [lambda _g, x: _g['beta'], lambda _g, x: x + 1]
|
||||
env_process["s4"] = env_timestep_trigger(trigger_field='timestep', trigger_vals=[5], funct_list=[lambda _g, x: _g['beta']])
|
||||
|
||||
|
||||
# config_sim Necessary
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
"M": g, # Optional
|
||||
}
|
||||
)
|
||||
|
||||
# New Convention
|
||||
partial_state_update_blocks = psub_list(psu_block, psu_steps)
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
seeds=seeds,
|
||||
env_processes=env_process,
|
||||
partial_state_update_blocks=partial_state_update_blocks
|
||||
)
|
||||
|
||||
|
||||
print()
|
||||
print("Policie State Update Block:")
|
||||
pp.pprint(partial_state_update_blocks)
|
||||
print()
|
||||
print()
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import unittest
|
||||
|
||||
import pandas as pd
|
||||
# from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import policy_aggregation
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
|
||||
class TestStringMethods(unittest.TestCase):
|
||||
def __init__(self, result: pd.DataFrame, tensor_field: pd.DataFrame) -> None:
|
||||
self.result = result
|
||||
self.tensor_field = tensor_field
|
||||
|
||||
def test_upper(self):
|
||||
self.assertEqual('foo'.upper(), 'FOO')
|
||||
|
||||
def test_isupper(self):
|
||||
self.assertTrue('FOO'.isupper())
|
||||
self.assertFalse('Foo'.isupper())
|
||||
|
||||
def test_split(self):
|
||||
s = 'hello world'
|
||||
self.assertEqual(s.split(), ['hello', 'world'])
|
||||
# check that s.split fails when the separator is not a string
|
||||
with self.assertRaises(TypeError):
|
||||
s.split(2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
from copy import deepcopy
|
||||
|
||||
import pandas as pd
|
||||
from fn.func import curried
|
||||
from datetime import timedelta
|
||||
import pprint as pp
|
||||
|
||||
from cadCAD.utils import SilentDF #, val_switch
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import time_step, config_sim, var_trigger, var_substep_trigger, env_trigger, psub_list
|
||||
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||
|
||||
|
||||
DF = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv'))
|
||||
|
||||
|
||||
class udoExample(object):
|
||||
def __init__(self, x, dataset=None):
|
||||
self.x = x
|
||||
self.mem_id = str(hex(id(self)))
|
||||
self.ds = dataset # for setting ds initially or querying
|
||||
self.perception = {}
|
||||
|
||||
def anon(self, f):
|
||||
return f(self)
|
||||
|
||||
def updateX(self):
|
||||
self.x += 1
|
||||
return self
|
||||
|
||||
def updateDS(self):
|
||||
self.ds.iloc[0,0] -= 10
|
||||
# pp.pprint(self.ds)
|
||||
return self
|
||||
|
||||
def perceive(self, s):
|
||||
self.perception = self.ds[
|
||||
(self.ds['run'] == s['run']) & (self.ds['substep'] == s['substep']) & (self.ds['timestep'] == s['timestep'])
|
||||
].drop(columns=['run', 'substep']).to_dict()
|
||||
return self
|
||||
|
||||
def read(self, ds_uri):
|
||||
self.ds = SilentDF(pd.read_csv(ds_uri))
|
||||
return self
|
||||
|
||||
def write(self, ds_uri):
|
||||
pd.to_csv(ds_uri)
|
||||
|
||||
# ToDo: Generic update function
|
||||
|
||||
pass
|
||||
|
||||
|
||||
state_udo = UDO(udo=udoExample(0, DF), masked_members=['obj', 'perception'])
|
||||
policy_udoA = UDO(udo=udoExample(0, DF), masked_members=['obj', 'perception'])
|
||||
policy_udoB = UDO(udo=udoExample(0, DF), masked_members=['obj', 'perception'])
|
||||
|
||||
|
||||
sim_config = config_sim({
|
||||
"N": 2,
|
||||
"T": range(4)
|
||||
})
|
||||
|
||||
# ToDo: DataFrame Column order
|
||||
state_dict = {
|
||||
'increment': 0,
|
||||
'state_udo': state_udo, 'state_udo_tracker': 0,
|
||||
'state_udo_perception_tracker': {"ds1": None, "ds2": None, "ds3": None, "timestep": None},
|
||||
'udo_policies': {'udo_A': policy_udoA, 'udo_B': policy_udoB},
|
||||
'udo_policy_tracker': (0, 0),
|
||||
'timestamp': '2019-01-01 00:00:00'
|
||||
}
|
||||
|
||||
psu_steps = ['m1', 'm2', 'm3']
|
||||
system_substeps = len(psu_steps)
|
||||
var_timestep_trigger = var_substep_trigger([0, system_substeps])
|
||||
env_timestep_trigger = env_trigger(system_substeps)
|
||||
psu_block = {k: {"policies": {}, "variables": {}} for k in psu_steps}
|
||||
|
||||
def udo_policyA(_g, step, sL, s):
|
||||
s['udo_policies']['udo_A'].updateX()
|
||||
return {'udo_A': udoPipe(s['udo_policies']['udo_A'])}
|
||||
# policies['a'] = udo_policyA
|
||||
for m in psu_steps:
|
||||
psu_block[m]['policies']['a'] = udo_policyA
|
||||
|
||||
def udo_policyB(_g, step, sL, s):
|
||||
s['udo_policies']['udo_B'].updateX()
|
||||
return {'udo_B': udoPipe(s['udo_policies']['udo_B'])}
|
||||
# policies['b'] = udo_policyB
|
||||
for m in psu_steps:
|
||||
psu_block[m]['policies']['b'] = udo_policyB
|
||||
|
||||
|
||||
# policies = {"p1": udo_policyA, "p2": udo_policyB}
|
||||
# policies = {"A": udo_policyA, "B": udo_policyB}
|
||||
|
||||
def add(y: str, added_val):
|
||||
return lambda _g, step, sL, s, _input: (y, s[y] + added_val)
|
||||
# state_updates['increment'] = add('increment', 1)
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['increment'] = add('increment', 1)
|
||||
|
||||
|
||||
@curried
|
||||
def perceive(s, self):
|
||||
self.perception = self.ds[
|
||||
(self.ds['run'] == s['run']) & (self.ds['substep'] == s['substep']) & (self.ds['timestep'] == s['timestep'])
|
||||
].drop(columns=['run', 'substep']).to_dict()
|
||||
return self
|
||||
|
||||
|
||||
def state_udo_update(_g, step, sL, s, _input):
|
||||
y = 'state_udo'
|
||||
# s['hydra_state'].updateX().anon(perceive(s))
|
||||
s['state_udo'].updateX().perceive(s).updateDS()
|
||||
x = udoPipe(s['state_udo'])
|
||||
return y, x
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['state_udo'] = state_udo_update
|
||||
|
||||
|
||||
def track(destination, source):
|
||||
return lambda _g, step, sL, s, _input: (destination, s[source].x)
|
||||
state_udo_tracker = track('state_udo_tracker', 'state_udo')
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['state_udo_tracker'] = state_udo_tracker
|
||||
|
||||
|
||||
def track_state_udo_perception(destination, source):
|
||||
def id(past_perception):
|
||||
if len(past_perception) == 0:
|
||||
return state_dict['state_udo_perception_tracker']
|
||||
else:
|
||||
return past_perception
|
||||
return lambda _g, step, sL, s, _input: (destination, id(s[source].perception))
|
||||
state_udo_perception_tracker = track_state_udo_perception('state_udo_perception_tracker', 'state_udo')
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['state_udo_perception_tracker'] = state_udo_perception_tracker
|
||||
|
||||
|
||||
def view_udo_policy(_g, step, sL, s, _input):
|
||||
return 'udo_policies', _input
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['udo_policies'] = view_udo_policy
|
||||
|
||||
|
||||
def track_udo_policy(destination, source):
|
||||
def val_switch(v):
|
||||
if isinstance(v, pd.DataFrame) is True or isinstance(v, SilentDF) is True:
|
||||
return SilentDF(v)
|
||||
else:
|
||||
return v.x
|
||||
return lambda _g, step, sL, s, _input: (destination, tuple(val_switch(v) for _, v in s[source].items()))
|
||||
udo_policy_tracker = track_udo_policy('udo_policy_tracker', 'udo_policies')
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['udo_policy_tracker'] = udo_policy_tracker
|
||||
|
||||
|
||||
def update_timestamp(_g, step, sL, s, _input):
|
||||
y = 'timestamp'
|
||||
return y, time_step(dt_str=s[y], dt_format='%Y-%m-%d %H:%M:%S', _timedelta=timedelta(days=0, minutes=0, seconds=1))
|
||||
for m in psu_steps:
|
||||
psu_block[m]["variables"]['timestamp'] = var_timestep_trigger(y='timestamp', f=update_timestamp)
|
||||
# psu_block[m]["variables"]['timestamp'] = var_trigger(
|
||||
# y='timestamp', f=update_timestamp,
|
||||
# pre_conditions={'substep': [0, system_substeps]}, cond_op=lambda a, b: a and b
|
||||
# )
|
||||
# psu_block[m]["variables"]['timestamp'] = update_timestamp
|
||||
|
||||
# ToDo: Bug without specifying parameters
|
||||
# New Convention
|
||||
partial_state_update_blocks = psub_list(psu_block, psu_steps)
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=state_dict,
|
||||
partial_state_update_blocks=partial_state_update_blocks
|
||||
)
|
||||
|
||||
print()
|
||||
print("State Updates:")
|
||||
pp.pprint(partial_state_update_blocks)
|
||||
print()
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
import pandas as pd
|
||||
import pprint as pp
|
||||
from fn.func import curried
|
||||
from datetime import timedelta
|
||||
|
||||
from cadCAD.utils import SilentDF #, val_switch
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import time_step, config_sim
|
||||
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||
|
||||
|
||||
DF = SilentDF(pd.read_csv('/Users/jjodesty/Projects/DiffyQ-SimCAD/simulations/external_data/output.csv'))
|
||||
|
||||
class udoExample(object):
|
||||
def __init__(self, x, dataset=None):
|
||||
self.x = x
|
||||
self.mem_id = str(hex(id(self)))
|
||||
self.ds = dataset # for setting ds initially or querying
|
||||
self.perception = {}
|
||||
|
||||
def anon(self, f):
|
||||
return f(self)
|
||||
|
||||
def updateX(self):
|
||||
self.x += 1
|
||||
return self
|
||||
|
||||
def perceive(self, s):
|
||||
self.perception = self.ds[
|
||||
(self.ds['run'] == s['run']) & (self.ds['substep'] == s['substep']) & (self.ds['timestep'] == s['timestep'])
|
||||
].drop(columns=['run', 'substep']).to_dict()
|
||||
return self
|
||||
|
||||
def read(self, ds_uri):
|
||||
self.ds = SilentDF(pd.read_csv(ds_uri))
|
||||
return self
|
||||
|
||||
def write(self, ds_uri):
|
||||
pd.to_csv(ds_uri)
|
||||
|
||||
# ToDo: Generic update function
|
||||
|
||||
pass
|
||||
|
||||
# can be accessed after an update within the same substep and timestep
|
||||
|
||||
state_udo = UDO(udo=udoExample(0, DF), masked_members=['obj', 'perception'])
|
||||
policy_udoA = UDO(udo=udoExample(0, DF), masked_members=['obj', 'perception'])
|
||||
policy_udoB = UDO(udo=udoExample(0, DF), masked_members=['obj', 'perception'])
|
||||
|
||||
def udo_policyA(_g, step, sL, s):
|
||||
s['udo_policies']['udo_A'].updateX()
|
||||
return {'udo_A': udoPipe(s['udo_policies']['udo_A'])}
|
||||
|
||||
def udo_policyB(_g, step, sL, s):
|
||||
s['udo_policies']['udo_B'].updateX()
|
||||
return {'udo_B': udoPipe(s['udo_policies']['udo_B'])}
|
||||
|
||||
|
||||
policies = {"p1": udo_policyA, "p2": udo_policyB}
|
||||
|
||||
# ToDo: DataFrame Column order
|
||||
state_dict = {
|
||||
'increment': 0,
|
||||
'state_udo': state_udo, 'state_udo_tracker_a': 0, 'state_udo_tracker_b': 0,
|
||||
'state_udo_perception_tracker': {"ds1": None, "ds2": None, "ds3": None, "timestep": None},
|
||||
'udo_policies': {'udo_A': policy_udoA, 'udo_B': policy_udoB},
|
||||
'udo_policy_tracker_a': (0, 0), 'udo_policy_tracker_b': (0, 0),
|
||||
'timestamp': '2019-01-01 00:00:00'
|
||||
}
|
||||
|
||||
@curried
|
||||
def perceive(s, self):
|
||||
self.perception = self.ds[
|
||||
(self.ds['run'] == s['run']) & (self.ds['substep'] == s['substep']) & (self.ds['timestep'] == s['timestep'])
|
||||
].drop(columns=['run', 'substep']).to_dict()
|
||||
return self
|
||||
|
||||
def view_udo_policy(_g, step, sL, s, _input):
|
||||
return 'udo_policies', _input
|
||||
|
||||
def state_udo_update(_g, step, sL, s, _input):
|
||||
y = 'state_udo'
|
||||
# s['hydra_state'].updateX().anon(perceive(s))
|
||||
s['state_udo'].updateX().perceive(s)
|
||||
x = udoPipe(s['state_udo'])
|
||||
return y, x
|
||||
|
||||
def increment(y, incr_by):
|
||||
return lambda _g, step, sL, s, _input: (y, s[y] + incr_by)
|
||||
|
||||
def track(destination, source):
|
||||
return lambda _g, step, sL, s, _input: (destination, s[source].x)
|
||||
|
||||
def track_udo_policy(destination, source):
|
||||
def val_switch(v):
|
||||
if isinstance(v, pd.DataFrame) is True or isinstance(v, SilentDF) is True:
|
||||
return SilentDF(v)
|
||||
else:
|
||||
return v.x
|
||||
return lambda _g, step, sL, s, _input: (destination, tuple(val_switch(v) for _, v in s[source].items()))
|
||||
|
||||
def track_state_udo_perception(destination, source):
|
||||
def id(past_perception):
|
||||
if len(past_perception) == 0:
|
||||
return state_dict['state_udo_perception_tracker']
|
||||
else:
|
||||
return past_perception
|
||||
return lambda _g, step, sL, s, _input: (destination, id(s[source].perception))
|
||||
|
||||
|
||||
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:
|
||||
return y, time_step(dt_str=s[y], dt_format=ts_format, _timedelta=time_delta)
|
||||
else:
|
||||
return y, s[y]
|
||||
return lambda _g, step, sL, s, _input: apply_incriment_condition(s)
|
||||
|
||||
|
||||
states = {
|
||||
'increment': increment('increment', 1),
|
||||
'state_udo_tracker_a': track('state_udo_tracker_a', 'state_udo'),
|
||||
'state_udo': state_udo_update,
|
||||
'state_udo_perception_tracker': track_state_udo_perception('state_udo_perception_tracker', 'state_udo'),
|
||||
'state_udo_tracker_b': track('state_udo_tracker_b', 'state_udo'),
|
||||
'udo_policy_tracker_a': track_udo_policy('udo_policy_tracker_a', 'udo_policies'),
|
||||
'udo_policies': view_udo_policy,
|
||||
'udo_policy_tracker_b': track_udo_policy('udo_policy_tracker_b', 'udo_policies')
|
||||
}
|
||||
|
||||
substeps=3
|
||||
update_timestamp = time_model(
|
||||
'timestamp',
|
||||
substeps=3,
|
||||
time_delta=timedelta(days=0, minutes=0, seconds=1),
|
||||
ts_format='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
states['timestamp'] = update_timestamp
|
||||
|
||||
PSUB = {
|
||||
'policies': policies,
|
||||
'states': states
|
||||
}
|
||||
|
||||
# needs M1&2 need behaviors
|
||||
partial_state_update_blocks = [PSUB] * substeps
|
||||
# pp.pprint(partial_state_update_blocks)
|
||||
|
||||
sim_config = config_sim({
|
||||
"N": 2,
|
||||
"T": range(4)
|
||||
})
|
||||
|
||||
# ToDo: Bug without specifying parameters
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=state_dict,
|
||||
seeds={},
|
||||
raw_exogenous_states={},
|
||||
env_processes={},
|
||||
partial_state_update_blocks=partial_state_update_blocks,
|
||||
# policy_ops=[lambda a, b: {**a, **b}]
|
||||
)
|
||||
|
||||
print()
|
||||
print("State Updates:")
|
||||
pp.pprint(partial_state_update_blocks)
|
||||
print()
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import pandas as pd
|
||||
from typing import List
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import config1
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
# print(raw_result)
|
||||
print(tabulate(tensor_field[['m', 'b1', 's1', 's2']], headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import config2
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config2
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import external_dataset
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
result = pd.concat([result, result['external_data'].apply(pd.Series)], axis=1)[
|
||||
['run', 'substep', 'timestep', 'increment', 'external_data', 'policies', 'ds1', 'ds2', 'ds3', ]
|
||||
]
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import historical_state_access
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
# cols = ['run','substep','timestep','x','nonexsistant','last_x','2nd_to_last_x','3rd_to_last_x','4th_to_last_x']
|
||||
cols = ['last_x']
|
||||
result = result[cols]
|
||||
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import config1, config2
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Concurrent Execution")
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
# print(configs)
|
||||
i = 0
|
||||
config_names = ['config1', 'config2']
|
||||
for raw_result, tensor_field in run.execute():
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print(f"Tensor Field: {config_names[i]}")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
i += 1
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import sweep_config
|
||||
from cadCAD import configs
|
||||
|
||||
# pprint(configs)
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Concurrent Execution")
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
i = 0
|
||||
config_names = ['sweep_config_A', 'sweep_config_B']
|
||||
for raw_result, tensor_field in run.execute():
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field: " + config_names[i])
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
i += 1
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
from pprint import pprint
|
||||
|
||||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import policy_aggregation
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)
|
||||
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import udo
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
|
||||
|
||||
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=configs)
|
||||
# cols = configs[0].initial_state.keys()
|
||||
cols = [
|
||||
'increment',
|
||||
'state_udo_tracker', 'state_udo', 'state_udo_perception_tracker',
|
||||
'udo_policies', 'udo_policy_tracker',
|
||||
'timestamp'
|
||||
]
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)[['run', 'substep', 'timestep'] + cols]
|
||||
# result = pd.concat([result.drop(['c'], axis=1), result['c'].apply(pd.Series)], axis=1)
|
||||
|
||||
# print(list(result['c']))
|
||||
|
||||
# print(tabulate(result['c'].apply(pd.Series), headers='keys', tablefmt='psql'))
|
||||
|
||||
# print(result.iloc[8,:]['state_udo'].ds)
|
||||
|
||||
# ctypes.cast(id(v['state_udo']['mem_id']), ctypes.py_object).value
|
||||
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
print(result.info(verbose=True))
|
||||
|
||||
# def f(df, col):
|
||||
# for k in df[col].iloc[0].keys():
|
||||
# df[k] = None
|
||||
# for index, row in df.iterrows():
|
||||
# # df.apply(lambda row:, axis=1)
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from simulations.regression_tests import udo_inter_substep_update
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
|
||||
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
# cols = configs[0].initial_state.keys()
|
||||
cols = [
|
||||
'increment',
|
||||
'state_udo_tracker_a', 'state_udo', 'state_udo_perception_tracker', 'state_udo_tracker_b',
|
||||
'udo_policy_tracker_a', 'udo_policies', 'udo_policy_tracker_b',
|
||||
'timestamp'
|
||||
]
|
||||
raw_result, tensor_field = run.execute()
|
||||
result = pd.DataFrame(raw_result)[['run', 'substep', 'timestep'] + cols]
|
||||
# result = pd.concat([result.drop(['c'], axis=1), result['c'].apply(pd.Series)], axis=1)
|
||||
|
||||
# print(list(result['c']))
|
||||
|
||||
# print(tabulate(result['c'].apply(pd.Series), headers='keys', tablefmt='psql'))
|
||||
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
print(result.info(verbose=True))
|
||||
|
||||
# def f(df, col):
|
||||
# for k in df[col].iloc[0].keys():
|
||||
# df[k] = None
|
||||
# for index, row in df.iterrows():
|
||||
# # df.apply(lambda row:, axis=1)
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD.configuration import Configuration
|
||||
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
import pprint as pp
|
||||
|
||||
T = 50 #iterations in our simulation
|
||||
n = 3 #number of boxes in our network
|
||||
m = 2 #for barabasi graph type number of edges is (n-2)*m
|
||||
|
||||
G = nx.barabasi_albert_graph(n, m)
|
||||
k = len(G.edges)
|
||||
|
||||
|
||||
# class udoExample(object):
|
||||
# def __init__(self, G):
|
||||
# self.G = G
|
||||
# self.mem_id = str(hex(id(self)))
|
||||
|
||||
|
||||
g = UDO(udo=G)
|
||||
print()
|
||||
# print(g.edges)
|
||||
# print(G.edges)
|
||||
# pp.pprint(f"{type(g)}: {g}")
|
||||
# next
|
||||
balls = np.zeros(n,)
|
||||
|
||||
for node in g.nodes:
|
||||
rv = np.random.randint(1,25)
|
||||
g.nodes[node]['initial_balls'] = rv
|
||||
balls[node] = rv
|
||||
|
||||
# pp.pprint(balls)
|
||||
|
||||
# next
|
||||
scale=100
|
||||
nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls'))
|
||||
|
||||
# next
|
||||
|
||||
initial_conditions = {'balls':balls, 'network':G}
|
||||
print(initial_conditions)
|
||||
|
||||
# next
|
||||
|
||||
def update_balls(params, step, sL, s, _input):
|
||||
delta_balls = _input['delta']
|
||||
new_balls = s['balls']
|
||||
for e in G.edges:
|
||||
move_ball = delta_balls[e]
|
||||
src = e[0]
|
||||
dst = e[1]
|
||||
if (new_balls[src] >= move_ball) and (new_balls[dst] >= -move_ball):
|
||||
new_balls[src] = new_balls[src] - move_ball
|
||||
new_balls[dst] = new_balls[dst] + move_ball
|
||||
|
||||
key = 'balls'
|
||||
value = new_balls
|
||||
|
||||
return (key, value)
|
||||
|
||||
|
||||
def update_network(params, step, sL, s, _input):
|
||||
new_nodes = _input['nodes']
|
||||
new_edges = _input['edges']
|
||||
new_balls = _input['quantity']
|
||||
|
||||
graph = s['network']
|
||||
|
||||
for node in new_nodes:
|
||||
graph.add_node(node)
|
||||
graph.nodes[node]['initial_balls'] = new_balls[node]
|
||||
graph.nodes[node]['strat'] = _input['node_strats'][node]
|
||||
|
||||
for edge in new_edges:
|
||||
graph.add_edge(edge[0], edge[1])
|
||||
graph.edges[edge]['strat'] = _input['edge_strats'][edge]
|
||||
|
||||
key = 'network'
|
||||
value = graph
|
||||
return (key, value)
|
||||
|
||||
|
||||
def update_network_balls(params, step, sL, s, _input):
|
||||
new_nodes = _input['nodes']
|
||||
new_balls = _input['quantity']
|
||||
balls = np.zeros(len(s['balls']) + len(new_nodes))
|
||||
|
||||
for node in s['network'].nodes:
|
||||
balls[node] = s['balls'][node]
|
||||
|
||||
for node in new_nodes:
|
||||
balls[node] = new_balls[node]
|
||||
|
||||
key = 'balls'
|
||||
value = balls
|
||||
|
||||
return (key, value)
|
||||
|
||||
# next
|
||||
|
||||
|
||||
def greedy_robot(src_balls, dst_balls):
|
||||
# robot wishes to accumlate balls at its source
|
||||
# takes half of its neighbors balls
|
||||
if src_balls < dst_balls:
|
||||
delta = -np.floor(dst_balls / 2)
|
||||
else:
|
||||
delta = 0
|
||||
|
||||
return delta
|
||||
|
||||
|
||||
def fair_robot(src_balls, dst_balls):
|
||||
# robot follows the simple balancing rule
|
||||
delta = np.sign(src_balls - dst_balls)
|
||||
|
||||
return delta
|
||||
|
||||
|
||||
def giving_robot(src_balls, dst_balls):
|
||||
# robot wishes to gice away balls one at a time
|
||||
if src_balls > 0:
|
||||
delta = 1
|
||||
else:
|
||||
delta = 0
|
||||
|
||||
return delta
|
||||
|
||||
# next
|
||||
|
||||
robot_strategies = [greedy_robot,fair_robot, giving_robot]
|
||||
|
||||
for node in G.nodes:
|
||||
nstrats = len(robot_strategies)
|
||||
rv = np.random.randint(0,nstrats)
|
||||
G.nodes[node]['strat'] = robot_strategies[rv]
|
||||
|
||||
for e in G.edges:
|
||||
owner_node = e[0]
|
||||
G.edges[e]['strat'] = G.nodes[owner_node]['strat']
|
||||
|
||||
# next
|
||||
|
||||
def robotic_network(params, step, sL, s):
|
||||
graph = s['network']
|
||||
|
||||
delta_balls = {}
|
||||
for e in graph.edges:
|
||||
src = e[0]
|
||||
src_balls = s['balls'][src]
|
||||
dst = e[1]
|
||||
dst_balls = s['balls'][dst]
|
||||
|
||||
# transfer balls according to specific robot strat
|
||||
strat = graph.edges[e]['strat']
|
||||
delta_balls[e] = strat(src_balls, dst_balls)
|
||||
|
||||
return_dict = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': delta_balls}
|
||||
|
||||
return (return_dict)
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils.userDefinedObject import udoPipe, UDO
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
T = 50 #iterations in our simulation
|
||||
n = 3 #number of boxes in our network
|
||||
m = 2 #for barabasi graph type number of edges is (n-2)*m
|
||||
|
||||
G = nx.barabasi_albert_graph(n, m)
|
||||
k = len(G.edges)
|
||||
|
||||
balls = np.zeros(n,)
|
||||
|
||||
for node in G.nodes:
|
||||
rv = np.random.randint(1,25)
|
||||
G.nodes[node]['initial_balls'] = rv
|
||||
balls[node] = rv
|
||||
|
||||
scale=100
|
||||
nx.draw_kamada_kawai(G, node_size=balls*scale,labels=nx.get_node_attributes(G,'initial_balls'))
|
||||
|
||||
def greedy_robot(src_balls, dst_balls):
|
||||
# robot wishes to accumlate balls at its source
|
||||
# takes half of its neighbors balls
|
||||
if src_balls < dst_balls:
|
||||
return -np.floor(dst_balls / 2)
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
def fair_robot(src_balls, dst_balls):
|
||||
# robot follows the simple balancing rule
|
||||
return np.sign(src_balls - dst_balls)
|
||||
|
||||
|
||||
def giving_robot(src_balls, dst_balls):
|
||||
# robot wishes to gice away balls one at a time
|
||||
if src_balls > 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
robot_strategies = [greedy_robot,fair_robot, giving_robot]
|
||||
|
||||
for node in G.nodes:
|
||||
nstrats = len(robot_strategies)
|
||||
rv = np.random.randint(0,nstrats)
|
||||
G.nodes[node]['strat'] = robot_strategies[rv]
|
||||
|
||||
for e in G.edges:
|
||||
owner_node = e[0]
|
||||
G.edges[e]['strat'] = G.nodes[owner_node]['strat']
|
||||
|
||||
default_policy = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': {}}
|
||||
class robot(object):
|
||||
def __init__(self, graph, balls, internal_policy=default_policy):
|
||||
self.mem_id = str(hex(id(self)))
|
||||
self.internal_policy = internal_policy
|
||||
self.graph = graph
|
||||
self.balls = balls
|
||||
|
||||
|
||||
def robotic_network(self, graph, balls): # move balls
|
||||
self.graph, self.balls = graph, balls
|
||||
delta_balls = {}
|
||||
for e in self.graph.edges:
|
||||
src = e[0]
|
||||
src_balls = self.balls[src]
|
||||
dst = e[1]
|
||||
dst_balls = self.balls[dst]
|
||||
|
||||
# transfer balls according to specific robot strat
|
||||
strat = self.graph.edges[e]['strat']
|
||||
delta_balls[e] = strat(src_balls, dst_balls)
|
||||
|
||||
self.internal_policy = {'nodes': [], 'edges': {}, 'quantity': {}, 'node_strats': {}, 'edge_strats': {}, 'delta': delta_balls}
|
||||
return self
|
||||
|
||||
def agent_arrival(self, graph, balls): # add node
|
||||
self.graph, self.balls = graph, balls
|
||||
node = len(self.graph.nodes)
|
||||
edge_list = self.graph.edges
|
||||
|
||||
# choose a m random edges without replacement
|
||||
# new = np.random.choose(edgelist,m)
|
||||
new = [0, 1] # tester
|
||||
|
||||
nodes = [node]
|
||||
edges = [(node, new_node) for new_node in new]
|
||||
|
||||
initial_balls = {node: np.random.randint(1, 25)}
|
||||
|
||||
rv = np.random.randint(0, nstrats)
|
||||
node_strat = {node: robot_strategies[rv]}
|
||||
|
||||
edge_strats = {e: robot_strategies[rv] for e in edges}
|
||||
|
||||
self.internal_policy = {'nodes': nodes,
|
||||
'edges': edges,
|
||||
'quantity': initial_balls,
|
||||
'node_strats': node_strat,
|
||||
'edge_strats': edge_strats,
|
||||
'delta': np.zeros(node + 1)
|
||||
}
|
||||
|
||||
return self
|
||||
|
||||
robot_udo = UDO(udo=robot(G, balls), masked_members=['obj'])
|
||||
initial_conditions = {'balls': balls, 'network': G, 'robot': robot_udo}
|
||||
|
||||
|
||||
def update_balls(params, step, sL, s, _input):
|
||||
delta_balls = _input['robot'].internal_policy['delta']
|
||||
new_balls = s['balls']
|
||||
for e in G.edges:
|
||||
move_ball = delta_balls[e]
|
||||
src = e[0]
|
||||
dst = e[1]
|
||||
if (new_balls[src] >= move_ball) and (new_balls[dst] >= -move_ball):
|
||||
new_balls[src] = new_balls[src] - move_ball
|
||||
new_balls[dst] = new_balls[dst] + move_ball
|
||||
|
||||
key = 'balls'
|
||||
value = new_balls
|
||||
|
||||
return (key, value)
|
||||
|
||||
|
||||
def update_network(params, step, sL, s, _input):
|
||||
new_nodes = _input['robot'].internal_policy['nodes']
|
||||
new_edges = _input['robot'].internal_policy['edges']
|
||||
new_balls = _input['robot'].internal_policy['quantity']
|
||||
|
||||
graph = s['network']
|
||||
|
||||
for node in new_nodes:
|
||||
graph.add_node(node)
|
||||
graph.nodes[node]['initial_balls'] = new_balls[node]
|
||||
graph.nodes[node]['strat'] = _input['robot'].internal_policy['node_strats'][node]
|
||||
|
||||
for edge in new_edges:
|
||||
graph.add_edge(edge[0], edge[1])
|
||||
graph.edges[edge]['strat'] = _input['robot'].internal_policy['edge_strats'][edge]
|
||||
|
||||
key = 'network'
|
||||
value = graph
|
||||
return (key, value)
|
||||
|
||||
|
||||
def update_network_balls(params, step, sL, s, _input):
|
||||
new_nodes = _input['robot'].internal_policy['nodes']
|
||||
new_balls = _input['robot'].internal_policy['quantity']
|
||||
balls = np.zeros(len(s['balls']) + len(new_nodes))
|
||||
|
||||
for node in s['network'].nodes:
|
||||
balls[node] = s['balls'][node]
|
||||
|
||||
for node in new_nodes:
|
||||
balls[node] = new_balls[node]
|
||||
|
||||
key = 'balls'
|
||||
value = balls
|
||||
|
||||
return (key, value)
|
||||
|
||||
|
||||
def robotic_network(params, step, sL, s):
|
||||
s['robot'].robotic_network(s['network'], s['balls'])
|
||||
return {'robot': udoPipe(s['robot'])}
|
||||
|
||||
|
||||
def agent_arrival(params, step, sL, s):
|
||||
s['robot'].agent_arrival(s['network'], s['balls'])
|
||||
return {'robot': udoPipe(s['robot'])}
|
||||
|
||||
def get_robot(params, step, sL, s, _input):
|
||||
return 'robot', _input['robot']
|
||||
|
||||
partial_state_update_blocks = [
|
||||
{
|
||||
'policies': {
|
||||
# The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||
'p1': robotic_network
|
||||
},
|
||||
'variables': { # The following state variables will be updated simultaneously
|
||||
'balls': update_balls,
|
||||
'robot': get_robot
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
# The following policy functions will be evaluated and their returns will be passed to the state update functions
|
||||
'p1': agent_arrival
|
||||
},
|
||||
'variables': { # The following state variables will be updated simultaneously
|
||||
'network': update_network,
|
||||
'balls': update_network_balls,
|
||||
'robot': get_robot
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
simulation_parameters = {
|
||||
'T': range(T),
|
||||
'N': 1,
|
||||
'M': {}
|
||||
}
|
||||
append_configs(
|
||||
sim_configs=simulation_parameters, #dict containing state update functions
|
||||
initial_state=initial_conditions, #dict containing variable names and initial values
|
||||
partial_state_update_blocks= partial_state_update_blocks #, #dict containing state update functions
|
||||
# policy_ops=[lambda a, b: {**a, **b}]
|
||||
)
|
||||
# config = Configuration(initial_state=initial_conditions, #dict containing variable names and initial values
|
||||
# partial_state_update_blocks=partial_state_update_blocks, #dict containing state update functions
|
||||
# sim_config=simulation_parameters #dict containing simulation parameters
|
||||
# )
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import pandas as pd
|
||||
from tabulate import tabulate
|
||||
# The following imports NEED to be in the exact order
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
|
||||
print("Simulation Execution: Single Configuration")
|
||||
print()
|
||||
first_config = configs # only contains config1
|
||||
single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)
|
||||
run = Executor(exec_context=single_proc_ctx, configs=first_config)
|
||||
|
||||
raw_result, tensor_field = run.main()
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print("Tensor Field: config1")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print("Output:")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print(result[['network']])
|
||||
print()
|
||||
|
||||
print(result[['network', 'substep']])
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,139 +0,0 @@
|
|||
from decimal import Decimal
|
||||
import numpy as np
|
||||
from datetime import timedelta
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import env_proc_trigger, bound_norm_random, ep_time_step, config_sim
|
||||
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'param1': 1}
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'param1': 'a', 'param2': 2}
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'param1': 'b', 'param2': 4}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'param1': ['c'], 'param2': np.array([10, 100])}
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'param1': ['d'], 'param2': np.array([20, 200])}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
return (y, x)
|
||||
def s2m1(_g, step, sL, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m2(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = _input['param1']
|
||||
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 = _input['param1']
|
||||
return (y, x)
|
||||
def s2m3(_g, step, sL, s, _input):
|
||||
y = 's2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
def s1m4(_g, step, sL, s, _input):
|
||||
y = 's1'
|
||||
x = [1]
|
||||
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 = s['s3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
def es4p2(_g, step, sL, s, _input):
|
||||
y = 's4'
|
||||
x = s['s4'] * bound_norm_random(seeds['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(_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
|
||||
def env_a(x):
|
||||
return 5
|
||||
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'
|
||||
}
|
||||
|
||||
|
||||
raw_exogenous_states = {
|
||||
"s3": es3p1,
|
||||
"s4": es4p2,
|
||||
"timestamp": es5p2
|
||||
}
|
||||
|
||||
|
||||
env_processes = {
|
||||
"s3": env_a,
|
||||
"s4": env_proc_trigger('2018-10-01 15:16:25', env_b)
|
||||
}
|
||||
|
||||
|
||||
partial_state_update_block = [
|
||||
]
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
seeds={},
|
||||
raw_exogenous_states={},
|
||||
env_processes={},
|
||||
partial_state_update_blocks=partial_state_update_block
|
||||
)
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,150 +0,0 @@
|
|||
import networkx as nx
|
||||
from scipy.stats import expon, gamma
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
#helper functions
|
||||
def get_nodes_by_type(g, node_type_selection):
|
||||
return [node for node in g.nodes if g.nodes[node]['type']== node_type_selection ]
|
||||
|
||||
def get_edges_by_type(g, edge_type_selection):
|
||||
return [edge for edge in g.edges if g.edges[edge]['type']== edge_type_selection ]
|
||||
|
||||
def total_funds_given_total_supply(total_supply):
|
||||
|
||||
#can put any bonding curve invariant here for initializatio!
|
||||
total_funds = total_supply
|
||||
|
||||
return total_funds
|
||||
|
||||
#maximum share of funds a proposal can take
|
||||
default_beta = .2 #later we should set this to be param so we can sweep it
|
||||
# tuning param for the trigger function
|
||||
default_rho = .001
|
||||
|
||||
def trigger_threshold(requested, funds, supply, beta = default_beta, rho = default_rho):
|
||||
|
||||
share = requested/funds
|
||||
if share < beta:
|
||||
return rho*supply/(beta-share)**2
|
||||
else:
|
||||
return np.inf
|
||||
|
||||
def initialize_network(n,m, funds_func=total_funds_given_total_supply, trigger_func =trigger_threshold ):
|
||||
network = nx.DiGraph()
|
||||
for i in range(n):
|
||||
network.add_node(i)
|
||||
network.nodes[i]['type']="participant"
|
||||
|
||||
h_rv = expon.rvs(loc=0.0, scale=1000)
|
||||
network.nodes[i]['holdings'] = h_rv
|
||||
|
||||
s_rv = np.random.rand()
|
||||
network.nodes[i]['sentiment'] = s_rv
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
initial_supply = np.sum([ network.nodes[i]['holdings'] for i in participants])
|
||||
|
||||
initial_funds = funds_func(initial_supply)
|
||||
|
||||
#generate initial proposals
|
||||
for ind in range(m):
|
||||
j = n+ind
|
||||
network.add_node(j)
|
||||
network.nodes[j]['type']="proposal"
|
||||
network.nodes[j]['conviction']=0
|
||||
network.nodes[j]['status']='candidate'
|
||||
network.nodes[j]['age']=0
|
||||
|
||||
r_rv = gamma.rvs(3,loc=0.001, scale=10000)
|
||||
network.node[j]['funds_requested'] = r_rv
|
||||
|
||||
network.nodes[j]['trigger']= trigger_threshold(r_rv, initial_funds, initial_supply)
|
||||
|
||||
for i in range(n):
|
||||
network.add_edge(i, j)
|
||||
|
||||
rv = np.random.rand()
|
||||
a_rv = 1-4*(1-rv)*rv #polarized distribution
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
network.edges[(i,j)]['tokens'] = 0
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
total_requested = np.sum([ network.nodes[i]['funds_requested'] for i in proposals])
|
||||
|
||||
return network, initial_funds, initial_supply, total_requested
|
||||
|
||||
def trigger_sweep(field, trigger_func,xmax=.2,default_alpha=.5):
|
||||
|
||||
if field == 'token_supply':
|
||||
alpha = default_alpha
|
||||
share_of_funds = np.arange(.001,xmax,.001)
|
||||
total_supply = np.arange(0,10**9, 10**6)
|
||||
demo_data_XY = np.outer(share_of_funds,total_supply)
|
||||
|
||||
demo_data_Z0=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z1=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z2=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z3=np.empty(demo_data_XY.shape)
|
||||
for sof_ind in range(len(share_of_funds)):
|
||||
sof = share_of_funds[sof_ind]
|
||||
for ts_ind in range(len(total_supply)):
|
||||
ts = total_supply[ts_ind]
|
||||
tc = ts /(1-alpha)
|
||||
trigger = trigger_func(sof, 1, ts)
|
||||
demo_data_Z0[sof_ind,ts_ind] = np.log10(trigger)
|
||||
demo_data_Z1[sof_ind,ts_ind] = trigger
|
||||
demo_data_Z2[sof_ind,ts_ind] = trigger/tc #share of maximum possible conviction
|
||||
demo_data_Z3[sof_ind,ts_ind] = np.log10(trigger/tc)
|
||||
return {'log10_trigger':demo_data_Z0,
|
||||
'trigger':demo_data_Z1,
|
||||
'share_of_max_conv': demo_data_Z2,
|
||||
'log10_share_of_max_conv':demo_data_Z3,
|
||||
'total_supply':total_supply,
|
||||
'share_of_funds':share_of_funds}
|
||||
elif field == 'alpha':
|
||||
alpha = np.arange(.5,1,.01)
|
||||
share_of_funds = np.arange(.001,xmax,.001)
|
||||
total_supply = 10**9
|
||||
demo_data_XY = np.outer(share_of_funds,alpha)
|
||||
|
||||
demo_data_Z4=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z5=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z6=np.empty(demo_data_XY.shape)
|
||||
demo_data_Z7=np.empty(demo_data_XY.shape)
|
||||
for sof_ind in range(len(share_of_funds)):
|
||||
sof = share_of_funds[sof_ind]
|
||||
for a_ind in range(len(alpha)):
|
||||
ts = total_supply
|
||||
a = alpha[a_ind]
|
||||
tc = ts /(1-a)
|
||||
trigger = trigger_func(sof, 1, ts)
|
||||
demo_data_Z4[sof_ind,a_ind] = np.log10(trigger)
|
||||
demo_data_Z5[sof_ind,a_ind] = trigger
|
||||
demo_data_Z6[sof_ind,a_ind] = trigger/tc #share of maximum possible conviction
|
||||
demo_data_Z7[sof_ind,a_ind] = np.log10(trigger/tc)
|
||||
|
||||
return {'log10_trigger':demo_data_Z4,
|
||||
'trigger':demo_data_Z5,
|
||||
'share_of_max_conv': demo_data_Z6,
|
||||
'log10_share_of_max_conv':demo_data_Z7,
|
||||
'alpha':alpha,
|
||||
'share_of_funds':share_of_funds}
|
||||
|
||||
else:
|
||||
return "invalid field"
|
||||
|
||||
def trigger_plotter(share_of_funds,Z, color_label,y, ylabel,cmap='jet'):
|
||||
dims = (10, 5)
|
||||
fig, ax = plt.subplots(figsize=dims)
|
||||
|
||||
cf = plt.contourf(share_of_funds, y, Z.T, 100, cmap=cmap)
|
||||
cbar=plt.colorbar(cf)
|
||||
plt.axis([share_of_funds[0], share_of_funds[-1], y[0], y[-1]])
|
||||
#ax.set_xscale('log')
|
||||
plt.ylabel(ylabel)
|
||||
plt.xlabel('Share of Funds Requested')
|
||||
plt.title('Trigger Function Map')
|
||||
|
||||
cbar.ax.set_ylabel(color_label)
|
||||
|
|
@ -1,548 +0,0 @@
|
|||
import numpy as np
|
||||
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
from simulations.validation.conviction_helpers import *
|
||||
#import networkx as nx
|
||||
from scipy.stats import expon, gamma
|
||||
|
||||
|
||||
#functions for partial state update block 1
|
||||
|
||||
#Driving processes: arrival of participants, proposals and funds
|
||||
##-----------------------------------------
|
||||
def gen_new_participant(network, new_participant_holdings):
|
||||
|
||||
i = len([node for node in network.nodes])
|
||||
|
||||
network.add_node(i)
|
||||
network.nodes[i]['type']="participant"
|
||||
|
||||
s_rv = np.random.rand()
|
||||
network.nodes[i]['sentiment'] = s_rv
|
||||
network.nodes[i]['holdings']=new_participant_holdings
|
||||
|
||||
for j in get_nodes_by_type(network, 'proposal'):
|
||||
network.add_edge(i, j)
|
||||
|
||||
rv = np.random.rand()
|
||||
a_rv = 1-4*(1-rv)*rv #polarized distribution
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
network.edges[(i,j)]['tokens'] = a_rv*network.nodes[i]['holdings']
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
|
||||
return network
|
||||
|
||||
|
||||
scale_factor = 1000
|
||||
|
||||
def gen_new_proposal(network, funds, supply, total_funds, trigger_func):
|
||||
j = len([node for node in network.nodes])
|
||||
network.add_node(j)
|
||||
network.nodes[j]['type']="proposal"
|
||||
|
||||
network.nodes[j]['conviction']=0
|
||||
network.nodes[j]['status']='candidate'
|
||||
network.nodes[j]['age']=0
|
||||
|
||||
rescale = scale_factor*funds/total_funds
|
||||
r_rv = gamma.rvs(3,loc=0.001, scale=rescale)
|
||||
network.node[j]['funds_requested'] = r_rv
|
||||
|
||||
network.nodes[j]['trigger']= trigger_func(r_rv, funds, supply)
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
proposing_participant = np.random.choice(participants)
|
||||
|
||||
for i in participants:
|
||||
network.add_edge(i, j)
|
||||
if i==proposing_participant:
|
||||
network.edges[(i, j)]['affinity']=1
|
||||
else:
|
||||
rv = np.random.rand()
|
||||
a_rv = 1-4*(1-rv)*rv #polarized distribution
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
network.edges[(i,j)]['tokens'] = 0
|
||||
return network
|
||||
|
||||
|
||||
|
||||
def driving_process(params, step, sL, s):
|
||||
|
||||
#placeholder plumbing for random processes
|
||||
arrival_rate = 10/s['sentiment']
|
||||
rv1 = np.random.rand()
|
||||
new_participant = bool(rv1<1/arrival_rate)
|
||||
if new_participant:
|
||||
h_rv = expon.rvs(loc=0.0, scale=1000)
|
||||
new_participant_holdings = h_rv
|
||||
else:
|
||||
new_participant_holdings = 0
|
||||
|
||||
network = s['network']
|
||||
affinities = [network.edges[e]['affinity'] for e in network.edges ]
|
||||
median_affinity = np.median(affinities)
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
fund_requests = [network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='candidate' ]
|
||||
|
||||
funds = s['funds']
|
||||
total_funds_requested = np.sum(fund_requests)
|
||||
|
||||
proposal_rate = 10/median_affinity * total_funds_requested/funds
|
||||
rv2 = np.random.rand()
|
||||
new_proposal = bool(rv2<1/proposal_rate)
|
||||
|
||||
sentiment = s['sentiment']
|
||||
funds = s['funds']
|
||||
scale_factor = 1+4000*sentiment**2
|
||||
|
||||
#this shouldn't happen but expon is throwing domain errors
|
||||
if scale_factor > 1:
|
||||
funds_arrival = expon.rvs(loc = 0, scale = scale_factor )
|
||||
else:
|
||||
funds_arrival = 0
|
||||
|
||||
return({'new_participant':new_participant,
|
||||
'new_participant_holdings':new_participant_holdings,
|
||||
'new_proposal':new_proposal,
|
||||
'funds_arrival':funds_arrival})
|
||||
|
||||
|
||||
#Mechanisms for updating the state based on driving processes
|
||||
##---
|
||||
def update_network(params, step, sL, s, _input):
|
||||
|
||||
print(params)
|
||||
print(type(params))
|
||||
|
||||
network = s['network']
|
||||
funds = s['funds']
|
||||
supply = s['supply']
|
||||
trigger_func = params['trigger_func']
|
||||
|
||||
new_participant = _input['new_participant'] #T/F
|
||||
new_proposal = _input['new_proposal'] #T/F
|
||||
|
||||
if new_participant:
|
||||
new_participant_holdings = _input['new_participant_holdings']
|
||||
network = gen_new_participant(network, new_participant_holdings)
|
||||
|
||||
if new_proposal:
|
||||
network= gen_new_proposal(network,funds,supply )
|
||||
|
||||
#update age of the existing proposals
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
|
||||
for j in proposals:
|
||||
network.nodes[j]['age'] = network.nodes[j]['age']+1
|
||||
if network.nodes[j]['status'] == 'candidate':
|
||||
requested = network.nodes[j]['funds_requested']
|
||||
network.nodes[j]['trigger'] = trigger_func(requested, funds, supply)
|
||||
else:
|
||||
network.nodes[j]['trigger'] = np.nan
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def increment_funds(params, step, sL, s, _input):
|
||||
|
||||
funds = s['funds']
|
||||
funds_arrival = _input['funds_arrival']
|
||||
|
||||
#increment funds
|
||||
funds = funds + funds_arrival
|
||||
|
||||
key = 'funds'
|
||||
value = funds
|
||||
|
||||
return (key, value)
|
||||
|
||||
def increment_supply(params, step, sL, s, _input):
|
||||
|
||||
supply = s['supply']
|
||||
supply_arrival = _input['new_participant_holdings']
|
||||
|
||||
#increment funds
|
||||
supply = supply + supply_arrival
|
||||
|
||||
key = 'supply'
|
||||
value = supply
|
||||
|
||||
return (key, value)
|
||||
|
||||
#functions for partial state update block 2
|
||||
|
||||
#Driving processes: completion of previously funded proposals
|
||||
##-----------------------------------------
|
||||
|
||||
def check_progress(params, step, sL, s):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
|
||||
completed = []
|
||||
for j in proposals:
|
||||
if network.nodes[j]['status'] == 'active':
|
||||
grant_size = network.nodes[j]['funds_requested']
|
||||
base_completion_rate=params['base_completion_rate']
|
||||
likelihood = 1.0/(base_completion_rate+np.log(grant_size))
|
||||
if np.random.rand() < likelihood:
|
||||
completed.append(j)
|
||||
|
||||
return({'completed':completed})
|
||||
|
||||
|
||||
#Mechanisms for updating the state based on check progress
|
||||
##---
|
||||
def complete_proposal(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
|
||||
completed = _input['completed']
|
||||
for j in completed:
|
||||
network.nodes[j]['status']='completed'
|
||||
for i in participants:
|
||||
force = network.edges[(i,j)]['affinity']
|
||||
sentiment = network.node[i]['sentiment']
|
||||
network.node[i]['sentiment'] = get_sentimental(sentiment, force, decay=0)
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_sentiment_on_completion(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
completed = _input['completed']
|
||||
|
||||
grants_outstanding = np.sum([network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='active'])
|
||||
|
||||
grants_completed = np.sum([network.nodes[j]['funds_requested'] for j in completed])
|
||||
|
||||
sentiment = s['sentiment']
|
||||
|
||||
force = grants_completed/grants_outstanding
|
||||
mu = params['sentiment_decay']
|
||||
if (force >=0) and (force <=1):
|
||||
sentiment = get_sentimental(sentiment, force, mu)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, mu)
|
||||
|
||||
|
||||
key = 'sentiment'
|
||||
value = sentiment
|
||||
|
||||
return (key, value)
|
||||
|
||||
def get_sentimental(sentiment, force, decay=0):
|
||||
mu = decay
|
||||
sentiment = sentiment*(1-mu) + force
|
||||
|
||||
if sentiment > 1:
|
||||
sentiment = 1
|
||||
|
||||
return sentiment
|
||||
|
||||
#functions for partial state update block 3
|
||||
|
||||
#Decision processes: trigger function policy
|
||||
##-----------------------------------------
|
||||
|
||||
def trigger_function(params, step, sL, s):
|
||||
|
||||
network = s['network']
|
||||
funds = s['funds']
|
||||
supply = s['supply']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
tmin = params['tmin']
|
||||
|
||||
accepted = []
|
||||
triggers = {}
|
||||
for j in proposals:
|
||||
if network.nodes[j]['status'] == 'candidate':
|
||||
requested = network.nodes[j]['funds_requested']
|
||||
age = network.nodes[j]['age']
|
||||
threshold = trigger_threshold(requested, funds, supply)
|
||||
if age > tmin:
|
||||
conviction = network.nodes[j]['conviction']
|
||||
if conviction >threshold:
|
||||
accepted.append(j)
|
||||
else:
|
||||
threshold = np.nan
|
||||
|
||||
triggers[j] = threshold
|
||||
|
||||
|
||||
|
||||
return({'accepted':accepted, 'triggers':triggers})
|
||||
|
||||
def decrement_funds(params, step, sL, s, _input):
|
||||
|
||||
funds = s['funds']
|
||||
network = s['network']
|
||||
accepted = _input['accepted']
|
||||
|
||||
#decrement funds
|
||||
for j in accepted:
|
||||
funds = funds - network.nodes[j]['funds_requested']
|
||||
|
||||
key = 'funds'
|
||||
value = funds
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_proposals(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
accepted = _input['accepted']
|
||||
triggers = _input['triggers']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
proposals = get_nodes_by_type(network, 'proposals')
|
||||
sensitivity = params['sensitivity']
|
||||
|
||||
for j in proposals:
|
||||
network.nodes[j]['trigger'] = triggers[j]
|
||||
|
||||
#bookkeeping conviction and participant sentiment
|
||||
for j in accepted:
|
||||
network.nodes[j]['status']='active'
|
||||
network.nodes[j]['conviction']=np.nan
|
||||
#change status to active
|
||||
for i in participants:
|
||||
|
||||
#operating on edge = (i,j)
|
||||
#reset tokens assigned to other candidates
|
||||
network.edges[(i,j)]['tokens']=0
|
||||
network.edges[(i,j)]['conviction'] = np.nan
|
||||
|
||||
#update participants sentiments (positive or negative)
|
||||
affinities = [network.edges[(i,p)]['affinity'] for p in proposals if not(p in accepted)]
|
||||
if len(affinities)>1:
|
||||
max_affinity = np.max(affinities)
|
||||
force = network.edges[(i,j)]['affinity']-sensitivity*max_affinity
|
||||
else:
|
||||
force = 0
|
||||
|
||||
#based on what their affinities to the accepted proposals
|
||||
network.nodes[i]['sentiment'] = get_sentimental(network.nodes[i]['sentiment'], force, False)
|
||||
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_sentiment_on_release(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
accepted = _input['accepted']
|
||||
|
||||
proposals_outstanding = np.sum([network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='candidate'])
|
||||
|
||||
proposals_accepted = np.sum([network.nodes[j]['funds_requested'] for j in accepted])
|
||||
|
||||
sentiment = s['sentiment']
|
||||
force = proposals_accepted/proposals_outstanding
|
||||
if (force >=0) and (force <=1):
|
||||
sentiment = get_sentimental(sentiment, force, False)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, False)
|
||||
|
||||
key = 'sentiment'
|
||||
value = sentiment
|
||||
|
||||
return (key, value)
|
||||
|
||||
def participants_decisions(params, step, sL, s):
|
||||
network = s['network']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
candidates = [j for j in proposals if network.nodes[j]['status']=='candidate']
|
||||
sensitivity = params['sensitivity']
|
||||
|
||||
gain = .01
|
||||
delta_holdings={}
|
||||
proposals_supported ={}
|
||||
for i in participants:
|
||||
force = network.nodes[i]['sentiment']-sensitivity
|
||||
delta_holdings[i] = network.nodes[i]['holdings']*gain*force
|
||||
|
||||
support = []
|
||||
for j in candidates:
|
||||
affinity = network.edges[(i, j)]['affinity']
|
||||
cutoff = sensitivity*np.max([network.edges[(i,p)]['affinity'] for p in candidates])
|
||||
if cutoff <.5:
|
||||
cutoff = .5
|
||||
|
||||
if affinity > cutoff:
|
||||
support.append(j)
|
||||
|
||||
proposals_supported[i] = support
|
||||
|
||||
return({'delta_holdings':delta_holdings, 'proposals_supported':proposals_supported})
|
||||
|
||||
def update_tokens(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
delta_holdings = _input['delta_holdings']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
proposals_supported = _input['proposals_supported']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
alpha = params['alpha']
|
||||
|
||||
for i in participants:
|
||||
network.nodes[i]['holdings'] = network.nodes[i]['holdings']+delta_holdings[i]
|
||||
supported = proposals_supported[i]
|
||||
total_affinity = np.sum([ network.edges[(i, j)]['affinity'] for j in supported])
|
||||
for j in proposals:
|
||||
if j in supported:
|
||||
normalized_affinity = network.edges[(i, j)]['affinity']/total_affinity
|
||||
network.edges[(i, j)]['tokens'] = normalized_affinity*network.nodes[i]['holdings']
|
||||
else:
|
||||
network.edges[(i, j)]['tokens'] = 0
|
||||
|
||||
prior_conviction = network.edges[(i, j)]['conviction']
|
||||
current_tokens = network.edges[(i, j)]['tokens']
|
||||
network.edges[(i, j)]['conviction'] =current_tokens+alpha*prior_conviction
|
||||
|
||||
for j in proposals:
|
||||
network.nodes[j]['conviction'] = np.sum([ network.edges[(i, j)]['conviction'] for i in participants])
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_supply(params, step, sL, s, _input):
|
||||
|
||||
supply = s['supply']
|
||||
delta_holdings = _input['delta_holdings']
|
||||
delta_supply = np.sum([v for v in delta_holdings.values()])
|
||||
|
||||
supply = supply + delta_supply
|
||||
|
||||
key = 'supply'
|
||||
value = supply
|
||||
|
||||
return (key, value)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# The Partial State Update Blocks
|
||||
partial_state_update_blocks = [
|
||||
{
|
||||
'policies': {
|
||||
#new proposals or new participants
|
||||
'random': driving_process
|
||||
},
|
||||
'variables': {
|
||||
'network': update_network,
|
||||
'funds':increment_funds,
|
||||
'supply':increment_supply
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
'completion': check_progress #see if any of the funded proposals completes
|
||||
},
|
||||
'variables': { # The following state variables will be updated simultaneously
|
||||
'sentiment': update_sentiment_on_completion, #note completing decays sentiment, completing bumps it
|
||||
'network': complete_proposal #book-keeping
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
'release': trigger_function #check each proposal to see if it passes
|
||||
},
|
||||
'variables': { # The following state variables will be updated simultaneously
|
||||
'funds': decrement_funds, #funds expended
|
||||
'sentiment': update_sentiment_on_release, #releasing funds can bump sentiment
|
||||
'network': update_proposals #reset convictions, and participants sentiments
|
||||
#update based on affinities
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
'participants_act': participants_decisions, #high sentiment, high affinity =>buy
|
||||
#low sentiment, low affinities => burn
|
||||
#assign tokens to top affinities
|
||||
},
|
||||
'variables': {
|
||||
'supply': update_supply,
|
||||
'network': update_tokens #update everyones holdings
|
||||
#and their conviction for each proposal
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
n= 25 #initial participants
|
||||
m= 3 #initial proposals
|
||||
|
||||
initial_sentiment = .5
|
||||
|
||||
network, initial_funds, initial_supply, total_requested = initialize_network(n,m,total_funds_given_total_supply,trigger_threshold)
|
||||
|
||||
initial_conditions = {'network':network,
|
||||
'supply': initial_supply,
|
||||
'funds':initial_funds,
|
||||
'sentiment': initial_sentiment}
|
||||
|
||||
#power of 1 token forever
|
||||
# conviction_capactity = [2]
|
||||
# alpha = [1-1/cc for cc in conviction_capactity]
|
||||
# print(alpha)
|
||||
|
||||
params={
|
||||
'sensitivity': [.75],
|
||||
'tmin': [7], #unit days; minimum periods passed before a proposal can pass
|
||||
'sentiment_decay': [.001], #termed mu in the state update function
|
||||
'alpha': [0.5, 0.9],
|
||||
'base_completion_rate': [10],
|
||||
'trigger_func': [trigger_threshold]
|
||||
}
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Settings of general simulation parameters, unrelated to the system itself
|
||||
# `T` is a range with the number of discrete units of time the simulation will run for;
|
||||
# `N` is the number of times the simulation will be run (Monte Carlo runs)
|
||||
time_periods_per_run = 250
|
||||
monte_carlo_runs = 1
|
||||
|
||||
simulation_parameters = config_sim({
|
||||
'T': range(time_periods_per_run),
|
||||
'N': monte_carlo_runs,
|
||||
'M': params
|
||||
})
|
||||
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# The configurations above are then packaged into a `Configuration` object
|
||||
append_configs(
|
||||
initial_state=initial_conditions, #dict containing variable names and initial values
|
||||
partial_state_update_blocks=partial_state_update_blocks, #dict containing state update functions
|
||||
sim_configs=simulation_parameters #dict containing simulation parameters
|
||||
)
|
||||
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD import configs
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
raw_result, tensor = run.execute()
|
||||
|
||||
# exec_mode = ExecutionMode()
|
||||
# exec_context = ExecutionContext(context=exec_mode.multi_proc)
|
||||
# # run = Executor(exec_context=exec_context, configs=configs)
|
||||
# executor = Executor(exec_context, configs) # Pass the configuration object inside an array
|
||||
# raw_result, tensor = executor.execute() # The `main()` method returns a tuple; its first elements contains the raw results
|
||||
|
|
@ -1,555 +0,0 @@
|
|||
from pprint import pprint
|
||||
|
||||
import numpy as np
|
||||
from tabulate import tabulate
|
||||
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
from simulations.validation.conviction_helpers import *
|
||||
#import networkx as nx
|
||||
from scipy.stats import expon, gamma
|
||||
|
||||
|
||||
#functions for partial state update block 1
|
||||
|
||||
#Driving processes: arrival of participants, proposals and funds
|
||||
##-----------------------------------------
|
||||
|
||||
|
||||
def gen_new_participant(network, new_participant_holdings):
|
||||
|
||||
i = len([node for node in network.nodes])
|
||||
|
||||
network.add_node(i)
|
||||
network.nodes[i]['type']="participant"
|
||||
|
||||
s_rv = np.random.rand()
|
||||
network.nodes[i]['sentiment'] = s_rv
|
||||
network.nodes[i]['holdings']=new_participant_holdings
|
||||
|
||||
for j in get_nodes_by_type(network, 'proposal'):
|
||||
network.add_edge(i, j)
|
||||
|
||||
rv = np.random.rand()
|
||||
a_rv = 1-4*(1-rv)*rv #polarized distribution
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
network.edges[(i,j)]['tokens'] = a_rv*network.nodes[i]['holdings']
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
|
||||
return network
|
||||
|
||||
|
||||
scale_factor = 1000
|
||||
|
||||
def gen_new_proposal(network, funds, supply, trigger_func):
|
||||
j = len([node for node in network.nodes])
|
||||
network.add_node(j)
|
||||
network.nodes[j]['type']="proposal"
|
||||
|
||||
network.nodes[j]['conviction']=0
|
||||
network.nodes[j]['status']='candidate'
|
||||
network.nodes[j]['age']=0
|
||||
|
||||
rescale = scale_factor*funds
|
||||
r_rv = gamma.rvs(3,loc=0.001, scale=rescale)
|
||||
network.node[j]['funds_requested'] = r_rv
|
||||
|
||||
network.nodes[j]['trigger']= trigger_func(r_rv, funds, supply)
|
||||
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
proposing_participant = np.random.choice(participants)
|
||||
|
||||
for i in participants:
|
||||
network.add_edge(i, j)
|
||||
if i==proposing_participant:
|
||||
network.edges[(i, j)]['affinity']=1
|
||||
else:
|
||||
rv = np.random.rand()
|
||||
a_rv = 1-4*(1-rv)*rv #polarized distribution
|
||||
network.edges[(i, j)]['affinity'] = a_rv
|
||||
|
||||
network.edges[(i, j)]['conviction'] = 0
|
||||
network.edges[(i,j)]['tokens'] = 0
|
||||
return network
|
||||
|
||||
|
||||
|
||||
def driving_process(params, step, sL, s):
|
||||
|
||||
#placeholder plumbing for random processes
|
||||
arrival_rate = 10/s['sentiment']
|
||||
rv1 = np.random.rand()
|
||||
new_participant = bool(rv1<1/arrival_rate)
|
||||
if new_participant:
|
||||
h_rv = expon.rvs(loc=0.0, scale=1000)
|
||||
new_participant_holdings = h_rv
|
||||
else:
|
||||
new_participant_holdings = 0
|
||||
|
||||
network = s['network']
|
||||
affinities = [network.edges[e]['affinity'] for e in network.edges ]
|
||||
median_affinity = np.median(affinities)
|
||||
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
fund_requests = [network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='candidate' ]
|
||||
|
||||
funds = s['funds']
|
||||
total_funds_requested = np.sum(fund_requests)
|
||||
|
||||
proposal_rate = 10/median_affinity * total_funds_requested/funds
|
||||
rv2 = np.random.rand()
|
||||
new_proposal = bool(rv2<1/proposal_rate)
|
||||
|
||||
sentiment = s['sentiment']
|
||||
funds = s['funds']
|
||||
scale_factor = 1+4000*sentiment**2
|
||||
|
||||
#this shouldn't happen but expon is throwing domain errors
|
||||
if scale_factor > 1:
|
||||
funds_arrival = expon.rvs(loc = 0, scale = scale_factor )
|
||||
else:
|
||||
funds_arrival = 0
|
||||
|
||||
return({'new_participant':new_participant,
|
||||
'new_participant_holdings':new_participant_holdings,
|
||||
'new_proposal':new_proposal,
|
||||
'funds_arrival':funds_arrival})
|
||||
|
||||
|
||||
#Mechanisms for updating the state based on driving processes
|
||||
##---
|
||||
def update_network(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
funds = s['funds']
|
||||
supply = s['supply']
|
||||
trigger_func = params['trigger_func']
|
||||
|
||||
new_participant = _input['new_participant'] #T/F
|
||||
new_proposal = _input['new_proposal'] #T/F
|
||||
|
||||
if new_participant:
|
||||
new_participant_holdings = _input['new_participant_holdings']
|
||||
network = gen_new_participant(network, new_participant_holdings)
|
||||
|
||||
if new_proposal:
|
||||
network= gen_new_proposal(network,funds,supply,trigger_func )
|
||||
|
||||
#update age of the existing proposals
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
|
||||
for j in proposals:
|
||||
network.nodes[j]['age'] = network.nodes[j]['age']+1
|
||||
if network.nodes[j]['status'] == 'candidate':
|
||||
requested = network.nodes[j]['funds_requested']
|
||||
network.nodes[j]['trigger'] = trigger_func(requested, funds, supply)
|
||||
else:
|
||||
network.nodes[j]['trigger'] = np.nan
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def increment_funds(params, step, sL, s, _input):
|
||||
|
||||
funds = s['funds']
|
||||
funds_arrival = _input['funds_arrival']
|
||||
|
||||
#increment funds
|
||||
funds = funds + funds_arrival
|
||||
|
||||
key = 'funds'
|
||||
value = funds
|
||||
|
||||
return (key, value)
|
||||
|
||||
def increment_supply(params, step, sL, s, _input):
|
||||
|
||||
supply = s['supply']
|
||||
supply_arrival = _input['new_participant_holdings']
|
||||
|
||||
#increment funds
|
||||
supply = supply + supply_arrival
|
||||
|
||||
key = 'supply'
|
||||
value = supply
|
||||
|
||||
return (key, value)
|
||||
|
||||
#functions for partial state update block 2
|
||||
|
||||
#Driving processes: completion of previously funded proposals
|
||||
##-----------------------------------------
|
||||
|
||||
def check_progress(params, step, sL, s):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
|
||||
completed = []
|
||||
for j in proposals:
|
||||
if network.nodes[j]['status'] == 'active':
|
||||
grant_size = network.nodes[j]['funds_requested']
|
||||
base_completion_rate=params['base_completion_rate']
|
||||
likelihood = 1.0/(base_completion_rate+np.log(grant_size))
|
||||
if np.random.rand() < likelihood:
|
||||
completed.append(j)
|
||||
|
||||
return({'completed':completed})
|
||||
|
||||
|
||||
#Mechanisms for updating the state based on check progress
|
||||
##---
|
||||
def complete_proposal(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
|
||||
completed = _input['completed']
|
||||
for j in completed:
|
||||
network.nodes[j]['status']='completed'
|
||||
for i in participants:
|
||||
force = network.edges[(i,j)]['affinity']
|
||||
sentiment = network.node[i]['sentiment']
|
||||
network.node[i]['sentiment'] = get_sentimental(sentiment, force, decay=0)
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_sentiment_on_completion(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
completed = _input['completed']
|
||||
|
||||
grants_outstanding = np.sum([network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='active'])
|
||||
|
||||
grants_completed = np.sum([network.nodes[j]['funds_requested'] for j in completed])
|
||||
|
||||
sentiment = s['sentiment']
|
||||
|
||||
force = grants_completed/grants_outstanding
|
||||
mu = params['sentiment_decay']
|
||||
if (force >=0) and (force <=1):
|
||||
sentiment = get_sentimental(sentiment, force, mu)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, mu)
|
||||
|
||||
|
||||
key = 'sentiment'
|
||||
value = sentiment
|
||||
|
||||
return (key, value)
|
||||
|
||||
def get_sentimental(sentiment, force, decay=0):
|
||||
mu = decay
|
||||
sentiment = sentiment*(1-mu) + force
|
||||
|
||||
if sentiment > 1:
|
||||
sentiment = 1
|
||||
|
||||
return sentiment
|
||||
|
||||
#functions for partial state update block 3
|
||||
|
||||
#Decision processes: trigger function policy
|
||||
##-----------------------------------------
|
||||
|
||||
def trigger_function(params, step, sL, s):
|
||||
|
||||
network = s['network']
|
||||
funds = s['funds']
|
||||
supply = s['supply']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
tmin = params['tmin']
|
||||
|
||||
accepted = []
|
||||
triggers = {}
|
||||
for j in proposals:
|
||||
if network.nodes[j]['status'] == 'candidate':
|
||||
requested = network.nodes[j]['funds_requested']
|
||||
age = network.nodes[j]['age']
|
||||
threshold = trigger_threshold(requested, funds, supply)
|
||||
if age > tmin:
|
||||
conviction = network.nodes[j]['conviction']
|
||||
if conviction >threshold:
|
||||
accepted.append(j)
|
||||
else:
|
||||
threshold = np.nan
|
||||
|
||||
triggers[j] = threshold
|
||||
|
||||
|
||||
|
||||
return({'accepted':accepted, 'triggers':triggers})
|
||||
|
||||
def decrement_funds(params, step, sL, s, _input):
|
||||
|
||||
funds = s['funds']
|
||||
network = s['network']
|
||||
accepted = _input['accepted']
|
||||
|
||||
#decrement funds
|
||||
for j in accepted:
|
||||
funds = funds - network.nodes[j]['funds_requested']
|
||||
|
||||
key = 'funds'
|
||||
value = funds
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_proposals(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
accepted = _input['accepted']
|
||||
triggers = _input['triggers']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
proposals = get_nodes_by_type(network, 'proposals')
|
||||
sensitivity = params['sensitivity']
|
||||
|
||||
for j in proposals:
|
||||
network.nodes[j]['trigger'] = triggers[j]
|
||||
|
||||
#bookkeeping conviction and participant sentiment
|
||||
for j in accepted:
|
||||
network.nodes[j]['status']='active'
|
||||
network.nodes[j]['conviction']=np.nan
|
||||
#change status to active
|
||||
for i in participants:
|
||||
|
||||
#operating on edge = (i,j)
|
||||
#reset tokens assigned to other candidates
|
||||
network.edges[(i,j)]['tokens']=0
|
||||
network.edges[(i,j)]['conviction'] = np.nan
|
||||
|
||||
#update participants sentiments (positive or negative)
|
||||
affinities = [network.edges[(i,p)]['affinity'] for p in proposals if not(p in accepted)]
|
||||
if len(affinities)>1:
|
||||
max_affinity = np.max(affinities)
|
||||
force = network.edges[(i,j)]['affinity']-sensitivity*max_affinity
|
||||
else:
|
||||
force = 0
|
||||
|
||||
#based on what their affinities to the accepted proposals
|
||||
network.nodes[i]['sentiment'] = get_sentimental(network.nodes[i]['sentiment'], force, False)
|
||||
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_sentiment_on_release(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
accepted = _input['accepted']
|
||||
|
||||
proposals_outstanding = np.sum([network.nodes[j]['funds_requested'] for j in proposals if network.nodes[j]['status']=='candidate'])
|
||||
|
||||
proposals_accepted = np.sum([network.nodes[j]['funds_requested'] for j in accepted])
|
||||
|
||||
sentiment = s['sentiment']
|
||||
force = proposals_accepted/proposals_outstanding
|
||||
if (force >=0) and (force <=1):
|
||||
sentiment = get_sentimental(sentiment, force, False)
|
||||
else:
|
||||
sentiment = get_sentimental(sentiment, 0, False)
|
||||
|
||||
key = 'sentiment'
|
||||
value = sentiment
|
||||
|
||||
return (key, value)
|
||||
|
||||
def participants_decisions(params, step, sL, s):
|
||||
network = s['network']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
candidates = [j for j in proposals if network.nodes[j]['status']=='candidate']
|
||||
sensitivity = params['sensitivity']
|
||||
|
||||
gain = .01
|
||||
delta_holdings={}
|
||||
proposals_supported ={}
|
||||
for i in participants:
|
||||
force = network.nodes[i]['sentiment']-sensitivity
|
||||
delta_holdings[i] = network.nodes[i]['holdings']*gain*force
|
||||
|
||||
support = []
|
||||
for j in candidates:
|
||||
affinity = network.edges[(i, j)]['affinity']
|
||||
cutoff = sensitivity*np.max([network.edges[(i,p)]['affinity'] for p in candidates])
|
||||
if cutoff <.5:
|
||||
cutoff = .5
|
||||
|
||||
if affinity > cutoff:
|
||||
support.append(j)
|
||||
|
||||
proposals_supported[i] = support
|
||||
|
||||
return({'delta_holdings':delta_holdings, 'proposals_supported':proposals_supported})
|
||||
|
||||
def update_tokens(params, step, sL, s, _input):
|
||||
|
||||
network = s['network']
|
||||
delta_holdings = _input['delta_holdings']
|
||||
proposals = get_nodes_by_type(network, 'proposal')
|
||||
proposals_supported = _input['proposals_supported']
|
||||
participants = get_nodes_by_type(network, 'participant')
|
||||
alpha = params['alpha']
|
||||
|
||||
for i in participants:
|
||||
network.nodes[i]['holdings'] = network.nodes[i]['holdings']+delta_holdings[i]
|
||||
supported = proposals_supported[i]
|
||||
total_affinity = np.sum([ network.edges[(i, j)]['affinity'] for j in supported])
|
||||
for j in proposals:
|
||||
if j in supported:
|
||||
normalized_affinity = network.edges[(i, j)]['affinity']/total_affinity
|
||||
network.edges[(i, j)]['tokens'] = normalized_affinity*network.nodes[i]['holdings']
|
||||
else:
|
||||
network.edges[(i, j)]['tokens'] = 0
|
||||
|
||||
prior_conviction = network.edges[(i, j)]['conviction']
|
||||
current_tokens = network.edges[(i, j)]['tokens']
|
||||
network.edges[(i, j)]['conviction'] =current_tokens+alpha*prior_conviction
|
||||
|
||||
for j in proposals:
|
||||
network.nodes[j]['conviction'] = np.sum([ network.edges[(i, j)]['conviction'] for i in participants])
|
||||
|
||||
key = 'network'
|
||||
value = network
|
||||
|
||||
return (key, value)
|
||||
|
||||
def update_supply(params, step, sL, s, _input):
|
||||
|
||||
supply = s['supply']
|
||||
delta_holdings = _input['delta_holdings']
|
||||
delta_supply = np.sum([v for v in delta_holdings.values()])
|
||||
|
||||
supply = supply + delta_supply
|
||||
|
||||
key = 'supply'
|
||||
value = supply
|
||||
|
||||
return (key, value)
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# The Partial State Update Blocks
|
||||
partial_state_update_blocks = [
|
||||
{
|
||||
'policies': {
|
||||
#new proposals or new participants
|
||||
'random': driving_process
|
||||
},
|
||||
'variables': {
|
||||
'network': update_network,
|
||||
'funds':increment_funds,
|
||||
'supply':increment_supply
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
'completion': check_progress #see if any of the funded proposals completes
|
||||
},
|
||||
'variables': { # The following state variables will be updated simultaneously
|
||||
'sentiment': update_sentiment_on_completion, #note completing decays sentiment, completing bumps it
|
||||
'network': complete_proposal #book-keeping
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
'release': trigger_function #check each proposal to see if it passes
|
||||
},
|
||||
'variables': { # The following state variables will be updated simultaneously
|
||||
'funds': decrement_funds, #funds expended
|
||||
'sentiment': update_sentiment_on_release, #releasing funds can bump sentiment
|
||||
'network': update_proposals #reset convictions, and participants sentiments
|
||||
#update based on affinities
|
||||
}
|
||||
},
|
||||
{
|
||||
'policies': {
|
||||
'participants_act': participants_decisions, #high sentiment, high affinity =>buy
|
||||
#low sentiment, low affinities => burn
|
||||
#assign tokens to top affinities
|
||||
},
|
||||
'variables': {
|
||||
'supply': update_supply,
|
||||
'network': update_tokens #update everyones holdings
|
||||
#and their conviction for each proposal
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
n= 25 #initial participants
|
||||
m= 3 #initial proposals
|
||||
|
||||
initial_sentiment = .5
|
||||
|
||||
network, initial_funds, initial_supply, total_requested = initialize_network(n,m,total_funds_given_total_supply,trigger_threshold)
|
||||
|
||||
initial_conditions = {'network':network,
|
||||
'supply': initial_supply,
|
||||
'funds':initial_funds,
|
||||
'sentiment': initial_sentiment}
|
||||
|
||||
#power of 1 token forever
|
||||
# conviction_capactity = [2]
|
||||
# alpha = [1-1/cc for cc in conviction_capactity]
|
||||
# print(alpha)
|
||||
|
||||
params={
|
||||
'sensitivity': [.75],
|
||||
'tmin': [7], #unit days; minimum periods passed before a proposal can pass
|
||||
'sentiment_decay': [.001], #termed mu in the state update function
|
||||
'alpha': [0.5],
|
||||
'base_completion_rate': [10],
|
||||
'trigger_func': [trigger_threshold]
|
||||
}
|
||||
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Settings of general simulation parameters, unrelated to the system itself
|
||||
# `T` is a range with the number of discrete units of time the simulation will run for;
|
||||
# `N` is the number of times the simulation will be run (Monte Carlo runs)
|
||||
time_periods_per_run = 250
|
||||
monte_carlo_runs = 1
|
||||
|
||||
simulation_parameters = config_sim({
|
||||
'T': range(time_periods_per_run),
|
||||
'N': monte_carlo_runs,
|
||||
'M': params
|
||||
})
|
||||
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# The configurations above are then packaged into a `Configuration` object
|
||||
append_configs(
|
||||
initial_state=initial_conditions, #dict containing variable names and initial values
|
||||
partial_state_update_blocks=partial_state_update_blocks, #dict containing state update functions
|
||||
sim_configs=simulation_parameters #dict containing simulation parameters
|
||||
)
|
||||
|
||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||
from cadCAD import configs
|
||||
import pandas as pd
|
||||
|
||||
exec_mode = ExecutionMode()
|
||||
multi_proc_ctx = ExecutionContext(context=exec_mode.multi_proc)
|
||||
run = Executor(exec_context=multi_proc_ctx, configs=configs)
|
||||
|
||||
i = 0
|
||||
for raw_result, tensor_field in run.execute():
|
||||
result = pd.DataFrame(raw_result)
|
||||
print()
|
||||
print(f"Tensor Field: {type(tensor_field)}")
|
||||
print(tabulate(tensor_field, headers='keys', tablefmt='psql'))
|
||||
print(f"Output: {type(result)}")
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
print()
|
||||
i += 1
|
||||
|
|
@ -1,763 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exogenous Example\n",
|
||||
"## Authored by BlockScience, MV Barlin\n",
|
||||
"### Updated July-10-2019 \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Key assumptions and space:\n",
|
||||
"1. Implementation of System Model in cell 2\n",
|
||||
"2. Timestep = day\n",
|
||||
"3. Launch simulation, without intervention from changing governance policies"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Library Imports"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from IPython.display import Image\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib as mpl\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import seaborn as sns\n",
|
||||
"import math\n",
|
||||
"#from tabulate import tabulate\n",
|
||||
"from scipy import stats\n",
|
||||
"sns.set_style('whitegrid')\n",
|
||||
"from decimal import Decimal\n",
|
||||
"from datetime import timedelta\n",
|
||||
"\n",
|
||||
"%matplotlib inline"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## cadCAD Setup\n",
|
||||
"#### ----------------cadCAD LIBRARY IMPORTS------------------------"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from cadCAD.engine import ExecutionMode, ExecutionContext, Executor\n",
|
||||
"#from simulations.validation import sweep_config\n",
|
||||
"from cadCAD import configs\n",
|
||||
"from cadCAD.configuration import append_configs\n",
|
||||
"from cadCAD.configuration.utils import proc_trigger, ep_time_step, config_sim"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#from cadCAD.configuration.utils.parameterSweep import config_sim"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import Dict, List"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### ----------------Random State Seed-----------------------------"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"seed = {\n",
|
||||
"# 'z': np.random.RandomState(1)\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Timestamp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"ts_format = '%Y-%m-%d %H:%M:%S'\n",
|
||||
"t_delta = timedelta(days=0, minutes=0, seconds=1)\n",
|
||||
"def set_time(_g, step, sL, s, _input):\n",
|
||||
" y = 'timestamp'\n",
|
||||
" x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=t_delta)\n",
|
||||
" return (y, x)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ASSUMED PARAMETERS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### PRICE LIST"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# dai_xns_conversion = 1.0 # Assumed for static conversion 'PUBLISHED PRICE LIST' DEPRECATED"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Initial Condition State Variables"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del_stake_pct = 2\n",
|
||||
"\n",
|
||||
"starting_xns = float(10**10) # initial supply of xns tokens\n",
|
||||
"starting_broker_xns = float(1 * 10**8) # inital holding of xns token by broker app\n",
|
||||
"starting_broker_fiat = float(1 * 10**5) # inital holding of xns token by broker app\n",
|
||||
"starting_broker_stable = float(1 * 10**6) # inital holding of stable token by broker app\n",
|
||||
"starting_deposit_acct = float(100) # inital deposit locked for first month of resources TBD: make function of resource*price\n",
|
||||
"starting_entrance = float(1 * 10**4) # TBD: make function of entrance fee % * cost * # of initial apps\n",
|
||||
"starting_app_usage = float(10) # initial fees from app usage \n",
|
||||
"starting_platform = float(100) # initial platform fees \n",
|
||||
"starting_resource_fees = float(10) # initial resource fees usage paid by apps \n",
|
||||
"starting_app_subsidy = float(0.25* 10**9) # initial application subsidy pool\n",
|
||||
"starting_stake = float(4 * 10**7)\n",
|
||||
"starting_stake_pool = starting_stake + ((3*10**7)*(del_stake_pct)) # initial staked pool + ((3*10**7)*(del_stake_pct))\n",
|
||||
"\n",
|
||||
"#starting_block_reward = float(0) # initial block reward MOVED ABOVE TO POLICY\n",
|
||||
"starting_capacity_subsidy = float(7.5 * 10**7) # initial capacity subsidy pool\n",
|
||||
"starting_delegate_holdings = 0.15 * starting_xns\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Initial Condition Composite State Variables"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# subsidy limit is 30% of the 10B supply\n",
|
||||
"starting_treasury = float(5.5 * 10**9) \n",
|
||||
"starting_app_income = float(0) # initial income to application\n",
|
||||
"starting_resource_income = float(0) # initial income to application\n",
|
||||
"starting_delegate_income = float(0) # initial income to delegate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Initial Condition Exogoneous State Variables "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"starting_xns_fiat = float(0.01) # initial xns per fiat signal\n",
|
||||
"starting_fiat_ext = float(1) # initial xns per fiat signal\n",
|
||||
"starting_stable_ext = float(1) # initial stable signal"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Exogenous Price Updates"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def delta_price(mean,sd):\n",
|
||||
" '''Returns normal random variable generated by first two central moments of price change of input ticker'''\n",
|
||||
" rv = np.random.normal(mean, sd)\n",
|
||||
" return rv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"def xns_ext_update(_g, step, sL, s, _input):\n",
|
||||
" key = 'XNS_fiat_external'\n",
|
||||
" \n",
|
||||
" value = s['XNS_fiat_external'] * (1 + delta_price(0.000000, 0.005))\n",
|
||||
" \n",
|
||||
" return key, value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"From Currency Analysis of DAI-USD pair \n",
|
||||
"May-09-2018 through June-10-2019 \n",
|
||||
"Datasource: BitFinex \n",
|
||||
"Analysis of daily return percentage performed by BlockScience"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"DAI_mean = 0.0000719\n",
|
||||
"DAI_sd = 0.006716"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The daily return is computed as: \n",
|
||||
"$$ r = \\frac{Price_n - Price_{n-1}}{Price_{n-1}} $$ \n",
|
||||
"Thus, the modelled current price can be as: \n",
|
||||
"$$ Price_n = Price_{n-1} * r + Price_{n-1} $$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"def stable_update(_g, step, sL, s, _input):\n",
|
||||
" key = 'stable_external'\n",
|
||||
" \n",
|
||||
" value = s['stable_external'] * (1 + delta_price(DAI_mean, DAI_sd))\n",
|
||||
" return key, value\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Assumed Parameters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"apps_deployed = 1 # Make part of test- application deployment model\n",
|
||||
"\n",
|
||||
"starting_deposit_acct = float(100) # inital deposit locked for first month of resources TBD: make function of resource*price\n",
|
||||
"\n",
|
||||
"app_resource_fee_constant = 10**1 # in STABLE, assumed per day per total nodes \n",
|
||||
"platform_fee_constant = 10 # in XNS\n",
|
||||
"# ^^^^^^^^^^^^ MAKE A PERCENTAGE OR FLAT FEE as PART of TESTING"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1000"
|
||||
]
|
||||
},
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\n",
|
||||
"alpha = 100 # Fee Rate\n",
|
||||
"beta = 0.10 # FIXED Too high because multiplied by constant and resource fees\n",
|
||||
"app_platform = alpha * platform_fee_constant\n",
|
||||
"app_platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"10.0"
|
||||
]
|
||||
},
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"beta_out =beta*100\n",
|
||||
"beta_out"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"0.15"
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"starting_capacity_subsidy / (5 * 10**7) / 10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"weight = 0.95 # 0.95 internal weight 5% friction from external markets\n",
|
||||
"\n",
|
||||
"def xns_int_update(_g, step, sL, s, _input):\n",
|
||||
" key = 'XNS_fiat_internal'\n",
|
||||
"\n",
|
||||
" internal = s['XNS_fiat_internal'] * weight\n",
|
||||
" external = s['XNS_fiat_external'] * (1 - weight)\n",
|
||||
" value = internal + external\n",
|
||||
" \n",
|
||||
" return key, value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### CONFIGURATION DICTIONARY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"time_step_count = 3652 # days = 10 years\n",
|
||||
"run_count = 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Genesis States"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#----------STATE VARIABLE Genesis DICTIONARY---------------------------\n",
|
||||
"genesis_states = {\n",
|
||||
" 'XNS_fiat_external' : starting_xns_fiat,\n",
|
||||
" 'XNS_fiat_internal' : starting_xns_fiat,\n",
|
||||
" # 'fiat_external' : starting_fiat_ext,\n",
|
||||
" 'stable_external' : starting_stable_ext,\n",
|
||||
" 'timestamp': '2018-10-01 15:16:24', #es5\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#--------------EXOGENOUS STATE MECHANISM DICTIONARY--------------------\n",
|
||||
"exogenous_states = {\n",
|
||||
" 'XNS_fiat_external' : xns_ext_update,\n",
|
||||
"# 'fiat_external' : starting_fiat_ext,\n",
|
||||
" 'stable_external' : stable_update,\n",
|
||||
" \"timestamp\": set_time,\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"#--------------ENVIRONMENTAL PROCESS DICTIONARY------------------------\n",
|
||||
"env_processes = {\n",
|
||||
"# \"Poisson\": env_proc_id\n",
|
||||
"}\n",
|
||||
"#----------------------SIMULATION RUN SETUP----------------------------\n",
|
||||
"sim_config = config_sim(\n",
|
||||
" {\n",
|
||||
" \"N\": run_count,\n",
|
||||
" \"T\": range(time_step_count)\n",
|
||||
"# \"M\": g # for parameter sweep\n",
|
||||
"}\n",
|
||||
")\n",
|
||||
"#----------------------MECHANISM AND BEHAVIOR DICTIONARY---------------\n",
|
||||
"partial_state_update_block = {\n",
|
||||
" \"price\": { \n",
|
||||
" \"policies\": { \n",
|
||||
" },\n",
|
||||
" \"variables\": {\n",
|
||||
" 'XNS_fiat_internal' : xns_int_update\n",
|
||||
"# 'app_income' : app_earn,\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"append_configs(\n",
|
||||
" sim_configs=sim_config,\n",
|
||||
" initial_state=genesis_states,\n",
|
||||
" seeds=seed,\n",
|
||||
" raw_exogenous_states= exogenous_states,\n",
|
||||
" env_processes=env_processes,\n",
|
||||
" partial_state_update_blocks=partial_state_update_block\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Running cadCAD"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Simulation Execution: Single Configuration\n",
|
||||
"\n",
|
||||
"single_proc: [<cadCAD.configuration.Configuration object at 0x0000024B3B37AF60>]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"C:\\Users\\mbarl\\AppData\\Local\\Continuum\\anaconda3\\lib\\site-packages\\cadCAD\\utils\\__init__.py:89: FutureWarning: The use of a dictionary to describe Partial State Update Blocks will be deprecated. Use a list instead.\n",
|
||||
" FutureWarning)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"exec_mode = ExecutionMode()\n",
|
||||
"\n",
|
||||
"print(\"Simulation Execution: Single Configuration\")\n",
|
||||
"print()\n",
|
||||
"first_config = configs # only contains config1\n",
|
||||
"single_proc_ctx = ExecutionContext(context=exec_mode.single_proc)\n",
|
||||
"run1 = Executor(exec_context=single_proc_ctx, configs=first_config)\n",
|
||||
"run1_raw_result, tensor_field = run1.main()\n",
|
||||
"result = pd.DataFrame(run1_raw_result)\n",
|
||||
"# print()\n",
|
||||
"# print(\"Tensor Field: config1\")\n",
|
||||
"# print(tabulate(tensor_field, headers='keys', tablefmt='psql'))\n",
|
||||
"# print(\"Output:\")\n",
|
||||
"# print(tabulate(result, headers='keys', tablefmt='psql'))\n",
|
||||
"# print()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = result"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>XNS_fiat_external</th>\n",
|
||||
" <th>XNS_fiat_internal</th>\n",
|
||||
" <th>run</th>\n",
|
||||
" <th>stable_external</th>\n",
|
||||
" <th>substep</th>\n",
|
||||
" <th>timestamp</th>\n",
|
||||
" <th>timestep</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>0.010000</td>\n",
|
||||
" <td>0.010000</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>1.000000</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" <td>2018-10-01 15:16:24</td>\n",
|
||||
" <td>0</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>0.009944</td>\n",
|
||||
" <td>0.010000</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>1.000172</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:25</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>0.009889</td>\n",
|
||||
" <td>0.009997</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>1.003516</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:26</td>\n",
|
||||
" <td>2</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>0.009848</td>\n",
|
||||
" <td>0.009992</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>0.990655</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:27</td>\n",
|
||||
" <td>3</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>0.009814</td>\n",
|
||||
" <td>0.009985</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>1.001346</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:28</td>\n",
|
||||
" <td>4</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>5</th>\n",
|
||||
" <td>0.009798</td>\n",
|
||||
" <td>0.009976</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>1.002495</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:29</td>\n",
|
||||
" <td>5</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6</th>\n",
|
||||
" <td>0.009706</td>\n",
|
||||
" <td>0.009967</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>0.994911</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:30</td>\n",
|
||||
" <td>6</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>7</th>\n",
|
||||
" <td>0.009625</td>\n",
|
||||
" <td>0.009954</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>0.998919</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:31</td>\n",
|
||||
" <td>7</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>8</th>\n",
|
||||
" <td>0.009632</td>\n",
|
||||
" <td>0.009938</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>0.995047</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:32</td>\n",
|
||||
" <td>8</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>9</th>\n",
|
||||
" <td>0.009648</td>\n",
|
||||
" <td>0.009922</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>0.980786</td>\n",
|
||||
" <td>1</td>\n",
|
||||
" <td>2018-10-01 15:16:33</td>\n",
|
||||
" <td>9</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" XNS_fiat_external XNS_fiat_internal run stable_external substep \\\n",
|
||||
"0 0.010000 0.010000 1 1.000000 0 \n",
|
||||
"1 0.009944 0.010000 1 1.000172 1 \n",
|
||||
"2 0.009889 0.009997 1 1.003516 1 \n",
|
||||
"3 0.009848 0.009992 1 0.990655 1 \n",
|
||||
"4 0.009814 0.009985 1 1.001346 1 \n",
|
||||
"5 0.009798 0.009976 1 1.002495 1 \n",
|
||||
"6 0.009706 0.009967 1 0.994911 1 \n",
|
||||
"7 0.009625 0.009954 1 0.998919 1 \n",
|
||||
"8 0.009632 0.009938 1 0.995047 1 \n",
|
||||
"9 0.009648 0.009922 1 0.980786 1 \n",
|
||||
"\n",
|
||||
" timestamp timestep \n",
|
||||
"0 2018-10-01 15:16:24 0 \n",
|
||||
"1 2018-10-01 15:16:25 1 \n",
|
||||
"2 2018-10-01 15:16:26 2 \n",
|
||||
"3 2018-10-01 15:16:27 3 \n",
|
||||
"4 2018-10-01 15:16:28 4 \n",
|
||||
"5 2018-10-01 15:16:29 5 \n",
|
||||
"6 2018-10-01 15:16:30 6 \n",
|
||||
"7 2018-10-01 15:16:31 7 \n",
|
||||
"8 2018-10-01 15:16:32 8 \n",
|
||||
"9 2018-10-01 15:16:33 9 "
|
||||
]
|
||||
},
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df.head(10)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": 2
|
||||
}
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
from decimal import Decimal
|
||||
import numpy as np
|
||||
from datetime import timedelta
|
||||
import pprint
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import env_proc_trigger, ep_time_step, config_sim
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
# from cadCAD.utils.sys_config import exo, exo_check
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
# Optional
|
||||
g: Dict[str, List[int]] = {
|
||||
'alpha': [1],
|
||||
'beta': [2, 5],
|
||||
'gamma': [3, 4],
|
||||
'omega': [7]
|
||||
}
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'param1': 1}
|
||||
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'param1': 'a', 'param2': _g['beta']}
|
||||
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'param1': 'b', 'param2': 0}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'param1': np.array([10, 100])}
|
||||
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'param1': np.array([20, 200])}
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sL, s, _input):
|
||||
return 's1', 0
|
||||
|
||||
def s2m1(_g, step, sL, s, _input):
|
||||
return 's2', _g['beta']
|
||||
|
||||
def s1m2(_g, step, sL, s, _input):
|
||||
return 's1', _input['param2']
|
||||
|
||||
def s2m2(_g, step, sL, s, _input):
|
||||
return 's2', _input['param2']
|
||||
|
||||
def s1m3(_g, step, sL, s, _input):
|
||||
return 's1', 0
|
||||
|
||||
def s2m3(_g, step, sL, s, _input):
|
||||
return 's2', 0
|
||||
|
||||
|
||||
# Exogenous States
|
||||
proc_one_coef_A = 0.7
|
||||
proc_one_coef_B = 1.3
|
||||
|
||||
|
||||
def es3p1(_g, step, sL, s, _input):
|
||||
return 's3', _g['gamma']
|
||||
# @curried
|
||||
def es4p2(_g, step, sL, s, _input):
|
||||
return 's4', _g['gamma']
|
||||
|
||||
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 = 'timestep'
|
||||
x = ep_time_step(s, dt_str=s['timestep'], 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),
|
||||
# 'timestep': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# remove `exo_update_per_ts` to update every ts
|
||||
raw_exogenous_states = {
|
||||
"s3": es3p1,
|
||||
"s4": es4p2,
|
||||
# "timestep": es5p2
|
||||
}
|
||||
|
||||
|
||||
# ToDo: make env proc trigger field agnostic
|
||||
# ToDo: input json into function renaming __name__
|
||||
triggered_env_b = env_proc_trigger(1, 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
|
||||
|
||||
partial_state_update_block = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"b1": p1m1,
|
||||
"b2": p2m1
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m1,
|
||||
"s2": s2m1
|
||||
}
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"b1": p1m2,
|
||||
"b2": p2m2,
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m2,
|
||||
"s2": s2m2
|
||||
}
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"b1": p1m3,
|
||||
"b2": p2m3
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m3,
|
||||
"s2": s2m3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# config_sim Necessary
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
"M": g # Optional
|
||||
}
|
||||
)
|
||||
|
||||
# New Convention
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
seeds=seeds,
|
||||
raw_exogenous_states={}, #raw_exogenous_states,
|
||||
env_processes={}, #env_processes,
|
||||
partial_state_update_blocks=partial_state_update_block
|
||||
)
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
from decimal import Decimal
|
||||
import numpy as np
|
||||
from datetime import timedelta
|
||||
import pprint
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import env_proc_trigger, ep_time_step, config_sim
|
||||
|
||||
from typing import Dict, List
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
# Optional
|
||||
g: Dict[str, List[int]] = {
|
||||
'alpha': [1],
|
||||
'beta': [2, 5],
|
||||
'gamma': [3, 4],
|
||||
'omega': [7]
|
||||
}
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'param1': 1}
|
||||
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'param2': 4}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'param1': 'a', 'param2': _g['beta']}
|
||||
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'param1': 'b', 'param2': 0}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'param1': np.array([10, 100])}
|
||||
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'param1': np.array([20, 200])}
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1m1(_g, step, sL, s, _input):
|
||||
return 's1', 0
|
||||
|
||||
def s2m1(_g, step, sL, s, _input):
|
||||
return 's2', _g['beta']
|
||||
|
||||
def s1m2(_g, step, sL, s, _input):
|
||||
return 's1', _input['param2']
|
||||
|
||||
def s2m2(_g, step, sL, s, _input):
|
||||
return 's2', _input['param2']
|
||||
|
||||
def s1m3(_g, step, sL, s, _input):
|
||||
return 's1', 0
|
||||
|
||||
def s2m3(_g, step, sL, s, _input):
|
||||
return 's2', 0
|
||||
|
||||
|
||||
# Exogenous States
|
||||
proc_one_coef_A = 0.7
|
||||
proc_one_coef_B = 1.3
|
||||
|
||||
|
||||
def es3p1(_g, step, sL, s, _input):
|
||||
return 's3', _g['gamma']
|
||||
# @curried
|
||||
def es4p2(_g, step, sL, s, _input):
|
||||
return 's4', _g['gamma']
|
||||
|
||||
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 = 'timestep'
|
||||
x = ep_time_step(s, dt_str=s['timestep'], 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),
|
||||
# 'timestep': '2018-10-01 15:16:24'
|
||||
}
|
||||
|
||||
|
||||
# remove `exo_update_per_ts` to update every ts
|
||||
raw_exogenous_states = {
|
||||
"s3": es3p1,
|
||||
"s4": es4p2,
|
||||
# "timestep": es5p2
|
||||
}
|
||||
|
||||
|
||||
# ToDo: make env proc trigger field agnostic
|
||||
# ToDo: input json into function renaming __name__
|
||||
triggered_env_b = env_proc_trigger(1, 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
|
||||
|
||||
partial_state_update_block = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"b1": p1m1,
|
||||
"b2": p2m1
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m1,
|
||||
"s2": s2m1
|
||||
}
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"b1": p1m2,
|
||||
"b2": p2m2,
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m2,
|
||||
"s2": s2m2
|
||||
}
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"b1": p1m3,
|
||||
"b2": p2m3
|
||||
},
|
||||
"variables": {
|
||||
"s1": s1m3,
|
||||
"s2": s2m3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# config_sim Necessary
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
"M": g # Optional
|
||||
}
|
||||
)
|
||||
|
||||
# New Convention
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
seeds=seeds,
|
||||
raw_exogenous_states=raw_exogenous_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=partial_state_update_block
|
||||
)
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
from decimal import Decimal
|
||||
|
||||
import numpy as np
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import bound_norm_random, config_sim
|
||||
|
||||
seeds = {
|
||||
'z': np.random.RandomState(1),
|
||||
'a': np.random.RandomState(2),
|
||||
'b': np.random.RandomState(3),
|
||||
'c': np.random.RandomState(3)
|
||||
}
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1(_g, step, sL, s):
|
||||
return {'param1': 10}
|
||||
def p2(_g, step, sL, s):
|
||||
return {'param1': 10, 'param2': 40}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def s1(_g, step, sL, s, _input):
|
||||
y = 'ds1'
|
||||
x = s['ds1'] + 1
|
||||
return (y, x)
|
||||
def s2(_g, step, sL, s, _input):
|
||||
y = 'ds2'
|
||||
x = _input['param2']
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Exogenous States
|
||||
proc_one_coef_A = 0.7
|
||||
proc_one_coef_B = 1.3
|
||||
|
||||
def es(_g, step, sL, s, _input):
|
||||
y = 'ds3'
|
||||
x = s['ds3'] * bound_norm_random(seeds['a'], proc_one_coef_A, proc_one_coef_B)
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Environment States
|
||||
def env_a(x):
|
||||
return 5
|
||||
def env_b(x):
|
||||
return 10
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
'ds1': Decimal(0.0),
|
||||
'ds2': Decimal(0.0),
|
||||
'ds3': Decimal(1.0)
|
||||
}
|
||||
|
||||
|
||||
raw_exogenous_states = {
|
||||
"ds3": es
|
||||
}
|
||||
|
||||
|
||||
env_processes = {
|
||||
"ds3": env_a
|
||||
}
|
||||
|
||||
|
||||
partial_state_update_block = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"p1": p1,
|
||||
"p2": p2
|
||||
},
|
||||
"variables": {
|
||||
"ds1": s1,
|
||||
"ds2": s2
|
||||
}
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"p1": p1,
|
||||
"p2": p2
|
||||
},
|
||||
"variables": {
|
||||
"ds1": s1,
|
||||
"ds2": s2
|
||||
}
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"p1": p1,
|
||||
"p2": p2
|
||||
},
|
||||
"variables": {
|
||||
"ds1": s1,
|
||||
"ds2": s2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(4),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
seeds=seeds,
|
||||
raw_exogenous_states=raw_exogenous_states,
|
||||
env_processes=env_processes,
|
||||
partial_state_update_blocks=partial_state_update_block,
|
||||
policy_ops=[lambda a, b: a + b]
|
||||
)
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
from engine import run
|
||||
from tabulate import tabulate
|
||||
result = run.main()
|
||||
print(tabulate(result, headers='keys', tablefmt='psql'))
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
import unittest
|
||||
from parameterized import parameterized
|
||||
from functools import reduce
|
||||
|
||||
|
||||
def generate_assertions_df(df, expected_results, target_cols, evaluations):
|
||||
test_names = []
|
||||
for eval_f in evaluations:
|
||||
def wrapped_eval(a, b):
|
||||
try:
|
||||
return eval_f(a, b)
|
||||
except KeyError:
|
||||
return True
|
||||
|
||||
test_name = f"{eval_f.__name__}_test"
|
||||
test_names.append(test_name)
|
||||
df[test_name] = df.apply(
|
||||
lambda x: wrapped_eval(
|
||||
x.filter(items=target_cols).to_dict(),
|
||||
expected_results[(x['run'], x['timestep'], x['substep'])]
|
||||
),
|
||||
axis=1
|
||||
)
|
||||
|
||||
return df, test_names
|
||||
|
||||
|
||||
def make_generic_test(params):
|
||||
class TestSequence(unittest.TestCase):
|
||||
|
||||
def generic_test(self, tested_df, expected_reults, test_name):
|
||||
erroneous = tested_df[(tested_df[test_name] == False)]
|
||||
# print(tabulate(tested_df, headers='keys', tablefmt='psql'))
|
||||
|
||||
if erroneous.empty is False: # Or Entire df IS NOT erroneous
|
||||
for index, row in erroneous.iterrows():
|
||||
expected = expected_reults[(row['run'], row['timestep'], row['substep'])]
|
||||
unexpected = {f"invalid_{k}": expected[k] for k in expected if k in row and expected[k] != row[k]}
|
||||
|
||||
for key in unexpected.keys():
|
||||
erroneous[key] = None
|
||||
erroneous.at[index, key] = unexpected[key]
|
||||
# etc.
|
||||
|
||||
# ToDo: Condition that will change false to true
|
||||
self.assertTrue(reduce(lambda a, b: a and b, tested_df[test_name]))
|
||||
|
||||
|
||||
@parameterized.expand(params)
|
||||
def test_validation(self, name, result_df, expected_reults, target_cols, evaluations):
|
||||
# alt for (*) Exec Debug mode
|
||||
tested_df, test_names = generate_assertions_df(result_df, expected_reults, target_cols, evaluations)
|
||||
|
||||
for test_name in test_names:
|
||||
self.generic_test(tested_df, expected_reults, test_name)
|
||||
|
||||
return TestSequence
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
import pandas as pd
|
||||
from cadCAD.utils import SilentDF
|
||||
|
||||
df = SilentDF(pd.read_csv('/DiffyQ-SimCAD/simulations/external_data/output.csv'))
|
||||
|
||||
|
||||
def query(s, df):
|
||||
return df[
|
||||
(df['run'] == s['run']) & (df['substep'] == s['substep']) & (df['timestep'] == s['timestep'])
|
||||
].drop(columns=['run', 'substep', "timestep"])
|
||||
|
||||
def p1(_g, substep, sL, s):
|
||||
result_dict = query(s, df).to_dict()
|
||||
del result_dict["ds3"]
|
||||
return {k: list(v.values()).pop() for k, v in result_dict.items()}
|
||||
|
||||
def p2(_g, substep, sL, s):
|
||||
result_dict = query(s, df).to_dict()
|
||||
del result_dict["ds1"], result_dict["ds2"]
|
||||
return {k: list(v.values()).pop() for k, v in result_dict.items()}
|
||||
|
||||
# integrate_ext_dataset
|
||||
def integrate_ext_dataset(_g, step, sL, s, _input):
|
||||
result_dict = query(s, df).to_dict()
|
||||
return 'external_data', {k: list(v.values()).pop() for k, v in result_dict.items()}
|
||||
|
||||
def increment(y, incr_by):
|
||||
return lambda _g, step, sL, s, _input: (y, s[y] + incr_by)
|
||||
increment = increment('increment', 1)
|
||||
|
||||
def view_policies(_g, step, sL, s, _input):
|
||||
return 'policies', _input
|
||||
|
||||
|
||||
external_data = {'ds1': None, 'ds2': None, 'ds3': None}
|
||||
state_dict = {
|
||||
'increment': 0,
|
||||
'external_data': external_data,
|
||||
'policies': external_data
|
||||
}
|
||||
|
||||
|
||||
policies = {"p1": p1, "p2": p2}
|
||||
states = {'increment': increment, 'external_data': integrate_ext_dataset, 'policies': view_policies}
|
||||
PSUB = {'policies': policies, 'states': states}
|
||||
|
||||
# needs M1&2 need behaviors
|
||||
partial_state_update_blocks = {
|
||||
'PSUB1': PSUB,
|
||||
'PSUB2': PSUB,
|
||||
'PSUB3': PSUB
|
||||
}
|
||||
|
||||
sim_config = config_sim({
|
||||
"N": 2,
|
||||
"T": range(4)
|
||||
})
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=state_dict,
|
||||
partial_state_update_blocks=partial_state_update_blocks,
|
||||
policy_ops=[lambda a, b: {**a, **b}]
|
||||
)
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim, access_block
|
||||
|
||||
|
||||
policies, variables = {}, {}
|
||||
exclusion_list = ['nonexsistant', 'last_x', '2nd_to_last_x', '3rd_to_last_x', '4th_to_last_x']
|
||||
|
||||
# Policies per Mechanism
|
||||
|
||||
# WARNING: DO NOT delete elements from sH
|
||||
# state_history, target_field, psu_block_offset, exculsion_list
|
||||
def last_update(_g, substep, sH, s):
|
||||
return {"last_x": access_block(
|
||||
state_history=sH,
|
||||
target_field="last_x",
|
||||
psu_block_offset=-1,
|
||||
exculsion_list=exclusion_list
|
||||
)
|
||||
}
|
||||
policies["last_x"] = last_update
|
||||
|
||||
def second2last_update(_g, substep, sH, s):
|
||||
return {"2nd_to_last_x": access_block(sH, "2nd_to_last_x", -2, exclusion_list)}
|
||||
policies["2nd_to_last_x"] = second2last_update
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
|
||||
# WARNING: DO NOT delete elements from sH
|
||||
def add(y, x):
|
||||
return lambda _g, substep, sH, s, _input: (y, s[y] + x)
|
||||
variables['x'] = add('x', 1)
|
||||
|
||||
# last_partial_state_update_block
|
||||
def nonexsistant(_g, substep, sH, s, _input):
|
||||
return 'nonexsistant', access_block(sH, "nonexsistant", 0, exclusion_list)
|
||||
variables['nonexsistant'] = nonexsistant
|
||||
|
||||
# last_partial_state_update_block
|
||||
def last_x(_g, substep, sH, s, _input):
|
||||
return 'last_x', _input["last_x"]
|
||||
variables['last_x'] = last_x
|
||||
|
||||
# 2nd to last partial state update block
|
||||
def second_to_last_x(_g, substep, sH, s, _input):
|
||||
return '2nd_to_last_x', _input["2nd_to_last_x"]
|
||||
variables['2nd_to_last_x'] = second_to_last_x
|
||||
|
||||
# 3rd to last partial state update block
|
||||
def third_to_last_x(_g, substep, sH, s, _input):
|
||||
return '3rd_to_last_x', access_block(sH, "3rd_to_last_x", -3, exclusion_list)
|
||||
variables['3rd_to_last_x'] = third_to_last_x
|
||||
|
||||
# 4th to last partial state update block
|
||||
def fourth_to_last_x(_g, substep, sH, s, _input):
|
||||
return '4th_to_last_x', access_block(sH, "4th_to_last_x", -4, exclusion_list)
|
||||
variables['4th_to_last_x'] = fourth_to_last_x
|
||||
|
||||
|
||||
genesis_states = {
|
||||
'x': 0,
|
||||
'nonexsistant': [],
|
||||
'last_x': [],
|
||||
'2nd_to_last_x': [],
|
||||
'3rd_to_last_x': [],
|
||||
'4th_to_last_x': []
|
||||
}
|
||||
|
||||
PSUB = {
|
||||
"policies": policies,
|
||||
"variables": variables
|
||||
}
|
||||
|
||||
partial_state_update_block = {
|
||||
"PSUB1": PSUB,
|
||||
"PSUB2": PSUB,
|
||||
"PSUB3": PSUB
|
||||
}
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
"T": range(3),
|
||||
}
|
||||
)
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
partial_state_update_blocks=partial_state_update_block
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import pprint
|
||||
from typing import Dict, List
|
||||
|
||||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import env_trigger, var_substep_trigger, config_sim, psub_list
|
||||
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
def some_function(x):
|
||||
return x
|
||||
|
||||
# Optional
|
||||
# dict must contain lists opf 2 distinct lengths
|
||||
g: Dict[str, List[int]] = {
|
||||
'alpha': [1],
|
||||
'beta': [2, some_function],
|
||||
'gamma': [3, 4],
|
||||
'omega': [7]
|
||||
}
|
||||
|
||||
psu_steps = ['m1', 'm2', 'm3']
|
||||
system_substeps = len(psu_steps)
|
||||
var_timestep_trigger = var_substep_trigger([0, system_substeps])
|
||||
env_timestep_trigger = env_trigger(system_substeps)
|
||||
env_process = {}
|
||||
|
||||
|
||||
# ['s1', 's2', 's3', 's4']
|
||||
# Policies per Mechanism
|
||||
def gamma(_g, step, sL, s):
|
||||
return {'gamma': _g['gamma']}
|
||||
|
||||
|
||||
def omega(_g, step, sL, s):
|
||||
return {'omega': _g['omega']}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def alpha(_g, step, sL, s, _input):
|
||||
return 'alpha', _g['alpha']
|
||||
|
||||
|
||||
def beta(_g, step, sL, s, _input):
|
||||
return 'beta', _g['beta']
|
||||
|
||||
|
||||
def policies(_g, step, sL, s, _input):
|
||||
return 'policies', _input
|
||||
|
||||
|
||||
def sweeped(_g, step, sL, s, _input):
|
||||
return 'sweeped', {'beta': _g['beta'], 'gamma': _g['gamma']}
|
||||
|
||||
psu_block = {k: {"policies": {}, "variables": {}} for k in psu_steps}
|
||||
for m in psu_steps:
|
||||
psu_block[m]['policies']['gamma'] = gamma
|
||||
psu_block[m]['policies']['omega'] = omega
|
||||
psu_block[m]["variables"]['alpha'] = alpha
|
||||
psu_block[m]["variables"]['beta'] = beta
|
||||
psu_block[m]['variables']['policies'] = policies
|
||||
psu_block[m]["variables"]['sweeped'] = var_timestep_trigger(y='sweeped', f=sweeped)
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
'alpha': 0,
|
||||
'beta': 0,
|
||||
'policies': {},
|
||||
'sweeped': {}
|
||||
}
|
||||
|
||||
# Environment Process
|
||||
env_process['sweeped'] = env_timestep_trigger(trigger_field='timestep', trigger_vals=[5], funct_list=[lambda _g, x: _g['beta']])
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 2,
|
||||
"T": range(5),
|
||||
"M": g, # Optional
|
||||
}
|
||||
)
|
||||
|
||||
# New Convention
|
||||
partial_state_update_blocks = psub_list(psu_block, psu_steps)
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
env_processes=env_process,
|
||||
partial_state_update_blocks=partial_state_update_blocks
|
||||
)
|
||||
|
||||
|
||||
print()
|
||||
print("Policie State Update Block:")
|
||||
pp.pprint(partial_state_update_blocks)
|
||||
print()
|
||||
print()
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
from cadCAD.configuration import append_configs
|
||||
from cadCAD.configuration.utils import config_sim
|
||||
|
||||
|
||||
# Policies per Mechanism
|
||||
def p1m1(_g, step, sL, s):
|
||||
return {'policy1': 1}
|
||||
def p2m1(_g, step, sL, s):
|
||||
return {'policy2': 2}
|
||||
|
||||
def p1m2(_g, step, sL, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
def p2m2(_g, step, sL, s):
|
||||
return {'policy1': 2, 'policy2': 2}
|
||||
|
||||
def p1m3(_g, step, sL, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
def p2m3(_g, step, sL, s):
|
||||
return {'policy1': 1, 'policy2': 2, 'policy3': 3}
|
||||
|
||||
|
||||
# Internal States per Mechanism
|
||||
def add(y, x):
|
||||
return lambda _g, step, sH, s, _input: (y, s[y] + x)
|
||||
|
||||
def policies(_g, step, sH, s, _input):
|
||||
y = 'policies'
|
||||
x = _input
|
||||
return (y, x)
|
||||
|
||||
|
||||
# Genesis States
|
||||
genesis_states = {
|
||||
'policies': {},
|
||||
's1': 0
|
||||
}
|
||||
|
||||
variables = {
|
||||
's1': add('s1', 1),
|
||||
"policies": policies
|
||||
}
|
||||
|
||||
partial_state_update_block = {
|
||||
"m1": {
|
||||
"policies": {
|
||||
"p1": p1m1,
|
||||
"p2": p2m1
|
||||
},
|
||||
"variables": variables
|
||||
},
|
||||
"m2": {
|
||||
"policies": {
|
||||
"p1": p1m2,
|
||||
"p2": p2m2
|
||||
},
|
||||
"variables": variables
|
||||
},
|
||||
"m3": {
|
||||
"policies": {
|
||||
"p1": p1m3,
|
||||
"p2": p2m3
|
||||
},
|
||||
"variables": variables
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sim_config = config_sim(
|
||||
{
|
||||
"N": 1,
|
||||
"T": range(3),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
append_configs(
|
||||
sim_configs=sim_config,
|
||||
initial_state=genesis_states,
|
||||
partial_state_update_blocks=partial_state_update_block,
|
||||
policy_ops=[lambda a, b: a + b, lambda y: y * 2] # Default: lambda a, b: a + b
|
||||
)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue