├── docs ├── models.pdf ├── sphinx │ ├── tsi.rst │ ├── hybrid.rst │ ├── Makefile │ ├── evidence.rst │ ├── forecast.rst │ ├── make.bat │ ├── contactMatrix.rst │ ├── control.rst │ ├── stochastic.rst │ ├── deterministic.rst │ ├── conf.py │ ├── index.rst │ └── inference.rst ├── README.md └── changelogs.md ├── examples ├── others │ ├── banner.jpg │ ├── pipeline.jpg │ └── data │ │ ├── cm │ │ ├── README.md │ │ ├── uks.txt │ │ ├── ukw.txt │ │ ├── uko.txt │ │ └── ukh.txt │ │ ├── age_structures │ │ ├── README.md │ │ ├── Denmark-2019.csv │ │ ├── SouthAfrica-2019.csv │ │ ├── UK.csv │ │ ├── Germany-2019.csv │ │ ├── Italy-2019.csv │ │ ├── USA.csv │ │ ├── China-2019.csv │ │ ├── India-2019.csv │ │ └── France.txt │ │ ├── README.md │ │ └── covid-cases │ │ ├── README.md │ │ ├── italy.txt │ │ ├── china.txt │ │ ├── india.txt │ │ ├── london.txt │ │ ├── uk.txt │ │ ├── denmark.txt │ │ └── denmark_cases_by_age.csv ├── deterministic │ └── contactMatrix │ │ ├── three-node-SIR │ │ └── SIR_network │ │ │ ├── cnode_cmatrices.csv │ │ │ ├── cnode_parameters.csv │ │ │ ├── node_cmatrices.csv │ │ │ ├── node_parameters.csv │ │ │ ├── contact_matrices.json │ │ │ ├── node_populations.csv │ │ │ ├── commuter_networks.csv │ │ │ └── model.json │ │ ├── ex10-spatial-contact-matrix.ipynb │ │ ├── ex01-SIR.ipynb │ │ ├── ex12-SEIR-fastest-growing-mode.ipynb │ │ └── ex09_custom_temporal_protocol.ipynb ├── inference │ ├── UK Inference Data │ │ ├── ukmidyearestimates20182019ladcodes.xls │ │ ├── Weekly_Deaths - w e 24th April 2020.XLS │ │ ├── covid-deaths-data-week-17_Table 1 - COVID deaths.csv │ │ ├── DeathsTrim.csv │ │ ├── Population.csv │ │ ├── CFR.csv │ │ └── out.csv │ ├── gradient_computation │ │ ├── dA_059353052c8950bc5ffd3672518e5f4bc6b46199.bin │ │ ├── dB_059353052c8950bc5ffd3672518e5f4bc6b46199.bin │ │ ├── dJ_059353052c8950bc5ffd3672518e5f4bc6b46199.bin │ │ └── dinvcov_059353052c8950bc5ffd3672518e5f4bc6b46199.bin │ └── ex03_SppQ_latent_inference.ipynb └── README.MD ├── pyproject.toml ├── MANIFEST.in ├── requirements.txt ├── binder └── environment.yml ├── .githooks ├── README.md └── pre-push ├── environment.yml ├── pyross ├── __init__.py ├── deterministic.pxd └── hybrid.pyx ├── CONTRIBUTING.md ├── .github └── workflows │ ├── ci.yml │ └── run_notebooks.yml ├── .gitignore ├── LICENSE ├── Makefile ├── setup.py ├── tests ├── notebook_test.py └── quick_test.py └── README.md /docs/models.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/docs/models.pdf -------------------------------------------------------------------------------- /examples/others/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/others/banner.jpg -------------------------------------------------------------------------------- /examples/others/pipeline.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/others/pipeline.jpg -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/cnode_cmatrices.csv: -------------------------------------------------------------------------------- 1 | Home,From,To,S,I,R 2 | ALL,ALL,ALL,,C_main, 3 | -------------------------------------------------------------------------------- /examples/others/data/cm/README.md: -------------------------------------------------------------------------------- 1 | Source: https://www.medrxiv.org/content/10.1101/2020.02.16.20023754v2.supplementary-material 2 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/cnode_parameters.csv: -------------------------------------------------------------------------------- 1 | Home,From,To,Age,Area,beta,gamma 2 | ALL,ALL,ALL,ALL,1,0.01,0.03 3 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/node_cmatrices.csv: -------------------------------------------------------------------------------- 1 | Home,Location,S,I,R 2 | ALL,ALL,,C_main, 3 | ALL,HOME,,C_main, 4 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/node_parameters.csv: -------------------------------------------------------------------------------- 1 | Home,Location,Age,Area,beta,gamma 2 | ALL,ALL,ALL,1,0.01,0.03 3 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools >= 40.8; python_version > '3'", 3 | "wheel", 4 | "cython", 5 | "numpy", 6 | ] 7 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include pyross/*pyx 2 | include pyross/*pxd 3 | include pyross/tsi/*pyx 4 | include pyross/tsi/*pxd 5 | include LICENSE 6 | include requirements.txt 7 | include README.md 8 | 9 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cython 2 | numpy 3 | scipy 4 | sympy 5 | nlopt 6 | pathos 7 | cma 8 | dill 9 | wheel 10 | matplotlib 11 | ipython 12 | jupyter 13 | nbconvert 14 | dynesty 15 | emcee 16 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/README.md: -------------------------------------------------------------------------------- 1 | The French data is from: https://www.insee.fr/en/statistiques/2382597?sommaire=2382613 2 | 3 | 4 | The rest are from: https://www.populationpyramid.net/ 5 | -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/ukmidyearestimates20182019ladcodes.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/UK Inference Data/ukmidyearestimates20182019ladcodes.xls -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/Weekly_Deaths - w e 24th April 2020.XLS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/UK Inference Data/Weekly_Deaths - w e 24th April 2020.XLS -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/contact_matrices.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_main" : [ 3 | [0.002, 0.008, 0.002], 4 | [0.004, 0.007, 0.001], 5 | [0.002, 0.009, 0.002] 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/node_populations.csv: -------------------------------------------------------------------------------- 1 | Home,Location,S0,I0,R0,S1,I1,R1,S2,I2,R2 2 | 0,0,2000,10,5,2000,1,1,1000,1,1 3 | 1,1,1000,1,1,1500,1,1,500,1,1 4 | 2,2,1000,1,1,1500,1,1,500,1,1 5 | -------------------------------------------------------------------------------- /examples/inference/gradient_computation/dA_059353052c8950bc5ffd3672518e5f4bc6b46199.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/gradient_computation/dA_059353052c8950bc5ffd3672518e5f4bc6b46199.bin -------------------------------------------------------------------------------- /examples/inference/gradient_computation/dB_059353052c8950bc5ffd3672518e5f4bc6b46199.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/gradient_computation/dB_059353052c8950bc5ffd3672518e5f4bc6b46199.bin -------------------------------------------------------------------------------- /examples/inference/gradient_computation/dJ_059353052c8950bc5ffd3672518e5f4bc6b46199.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/gradient_computation/dJ_059353052c8950bc5ffd3672518e5f4bc6b46199.bin -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/covid-deaths-data-week-17_Table 1 - COVID deaths.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/UK Inference Data/covid-deaths-data-week-17_Table 1 - COVID deaths.csv -------------------------------------------------------------------------------- /examples/inference/gradient_computation/dinvcov_059353052c8950bc5ffd3672518e5f4bc6b46199.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SoftMatterGroupCambridge/pyross/HEAD/examples/inference/gradient_computation/dinvcov_059353052c8950bc5ffd3672518e5f4bc6b46199.bin -------------------------------------------------------------------------------- /docs/sphinx/tsi.rst: -------------------------------------------------------------------------------- 1 | TSI 2 | ================================== 3 | 4 | Time since infection models 5 | 6 | Simulator 7 | ---------------------------------------- 8 | .. autoclass:: pyross.tsi.deterministic.Simulator 9 | :members: 10 | 11 | -------------------------------------------------------------------------------- /docs/sphinx/hybrid.rst: -------------------------------------------------------------------------------- 1 | Hybrid simulations 2 | ================================== 3 | Hybrid simulation scheme using a combination of stochastic and deterministic schemes. 4 | 5 | SIR 6 | -------------------- 7 | .. autoclass:: pyross.hybrid.SIR 8 | :members: 9 | -------------------------------------------------------------------------------- /binder/environment.yml: -------------------------------------------------------------------------------- 1 | name: pyross 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - python 6 | - cython 7 | - numpy 8 | - scipy 9 | - matplotlib 10 | - cma 11 | - sympy 12 | - dill 13 | - pip 14 | - pip: 15 | - pyross 16 | 17 | -------------------------------------------------------------------------------- /.githooks/README.md: -------------------------------------------------------------------------------- 1 | ## Git Hooks 2 | 3 | Git Hooks are scripts that automatically run during certain events (i.e 4 | when you push, commit etc). Please copy the file pre-push to `.git/hooks` 5 | to enable automatic unit testing before pushing. 6 | 7 | You can do this by running 8 | 9 | ``` 10 | cp .githooks/pre-push .git/hooks/ 11 | cd .git/hooks/ 12 | chmod +x pre-push 13 | ``` 14 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: pyross 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - python 6 | - cython 7 | - numpy 8 | - matplotlib 9 | - jupyter 10 | - scipy 11 | - pytest 12 | - pytest-cov 13 | - sympy 14 | - ipython 15 | - nbconvert 16 | - dynesty 17 | - emcee 18 | - nlopt 19 | - pip 20 | - pip: 21 | - cma 22 | - dill 23 | - pathos 24 | -------------------------------------------------------------------------------- /pyross/__init__.py: -------------------------------------------------------------------------------- 1 | import pyross.contactMatrix 2 | import pyross.control 3 | import pyross.deterministic 4 | import pyross.forecast 5 | import pyross.hybrid 6 | import pyross.inference 7 | import pyross.stochastic 8 | import pyross.utils 9 | import pyross.utils_python 10 | import pyross.evidence 11 | import pyross.tsi 12 | 13 | ## current version of PyRoss 14 | __version__="2.2.1" 15 | 16 | -------------------------------------------------------------------------------- /examples/others/data/README.md: -------------------------------------------------------------------------------- 1 | ## Data sources 2 | 3 | The age and social contact data that is needed to construct structured compartment models can be found at the following sources: 4 | 5 | **Age structure:** [Population Pyramid](https://www.populationpyramid.net/) website. 6 | 7 | The list of COVID-19 cases is obtained from: [Worldometers](https://www.worldometers.info/coronavirus) website. 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/commuter_networks.csv: -------------------------------------------------------------------------------- 1 | Home,From,To,Age,# to move,% to move,t1,t2,ct1,ct2,Allow S,Allow I,Allow R 2 | 0,0,1,0,210,-1,7,8,8,9,1,1,1 3 | 0,1,0,0,-1,1,17,18,18,19,1,1,1 4 | 0,0,2,1,500,-1,7,8,8,9,1,1,1 5 | 0,2,0,1,-1,1,17,18,18,19,1,1,1 6 | 1,1,0,1,100,-1,7,8,8,9,1,1,1 7 | 1,0,1,1,-1,1,17,18,18,19,1,1,1 8 | 2,2,1,0,300,-1,7,8,8,9,1,1,1 9 | 2,1,2,0,-1,1,17,18,18,19,1,1,1 10 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/three-node-SIR/SIR_network/model.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings" : { 3 | "classes" : ["S", "I", "R"] 4 | }, 5 | 6 | "S" : { 7 | "linear" : [], 8 | "infection" : [ ["I", "-beta"] ] 9 | }, 10 | 11 | "I" : { 12 | "linear" : [ ["I", "-gamma"] ], 13 | "infection" : [ ["I", "beta"] ] 14 | }, 15 | 16 | "R" : { 17 | "linear" : [ ["I", "gamma"] ], 18 | "infection" : [] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | CONTRIBUTING 2 | ============ 3 | 4 | When contributing code to PyRoss, you agree to release it under the project's license. Please first discuss the change you wish to make via issue, email, or any other method with the owners. 5 | 6 | Join our [Slack channel](https://join.slack.com/t/pyross/shared_invite/zt-e8th6kcz-S4b_oJIZWPsGLruSPl3Zuw) for discussion. Please follow the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) in all PyRoss fora. Thank you! 7 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/Denmark-2019.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,155083,147270 3 | 5-9,156940,148573 4 | 10-14,174005,164774 5 | 15-19,174082,167137 6 | 20-24,194805,184717 7 | 25-29,201921,193548 8 | 30-34,174221,168222 9 | 35-39,160544,159588 10 | 40-44,183041,183106 11 | 45-49,192779,193165 12 | 50-54,214342,208243 13 | 55-59,189732,191628 14 | 60-64,166561,171478 15 | 65-69,155332,163813 16 | 70-74,169371,177201 17 | 75-79,101656,118718 18 | 80-84,60952,79493 19 | 85-89,29424,46718 20 | 90-94,11890,25074 21 | 95-99,2786,8669 22 | 100+,205,1070 23 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/SouthAfrica-2019.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,2929541,2856070 3 | 5-9,2931113,2864891 4 | 10-14,2716259,2665504 5 | 15-19,2445035,2413807 6 | 20-24,2496689,2463553 7 | 25-29,2657660,2613858 8 | 30-34,2686086,2639035 9 | 35-39,2320124,2297221 10 | 40-44,1829662,1858565 11 | 45-49,1540318,1617202 12 | 50-54,1258726,1367461 13 | 55-59,1010360,1157566 14 | 60-64,784348,966575 15 | 65-69,563821,753685 16 | 70-74,347437,515421 17 | 75-79,210168,357766 18 | 80-84,95387,196853 19 | 85-89,30600,75542 20 | 90-94,5429,16457 21 | 95-99,530,1893 22 | 100+,9,40 23 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/UK.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,2022994,1928052 3 | 5-9,2105263,2008974 4 | 10-14,1985332,1899294 5 | 15-19,1879833,1804701 6 | 20-24,2096581,2023688 7 | 25-29,2285353,2224992 8 | 30-34,2343986,2339650 9 | 35-39,2245818,2274115 10 | 40-44,2129100,2141685 11 | 45-49,2154010,2199884 12 | 50-54,2300871,2374047 13 | 55-59,2196916,2266531 14 | 60-64,1868565,1930920 15 | 65-69,1658433,1748557 16 | 70-74,1595596,1733900 17 | 75-79,1088727,1255234 18 | 80-84,748505,950525 19 | 85-89,431640,631795 20 | 90-94,170828,323197 21 | 95-99,40247,106470 22 | 100+,2837,12515 23 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/Germany-2019.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,2045919,1941523 3 | 5-9,1928580,1810893 4 | 10-14,1971230,1826839 5 | 15-19,2163070,1987285 6 | 20-24,2376291,2175056 7 | 25-29,2538483,2331831 8 | 30-34,2812868,2630783 9 | 35-39,2711490,2615298 10 | 40-44,2512560,2475429 11 | 45-49,2724685,2687529 12 | 50-54,3448195,3415871 13 | 55-59,3347849,3362968 14 | 60-64,2776121,2889856 15 | 65-69,2228280,2453269 16 | 70-74,1796065,2037511 17 | 75-79,1681060,2074960 18 | 80-84,1335326,1871223 19 | 85-89,573159,978729 20 | 90-94,228579,521298 21 | 95-99,46133,165259 22 | 100+,3172,14520 23 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/Italy-2019.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,1227140,1155405 3 | 5-9,1400399,1320632 4 | 10-14,1476556,1392257 5 | 15-19,1484452,1387067 6 | 20-24,1533272,1422049 7 | 25-29,1630731,1549174 8 | 30-34,1711693,1678215 9 | 35-39,1861234,1849601 10 | 40-44,2157716,2166599 11 | 45-49,2432025,2468825 12 | 50-54,2410929,2484894 13 | 55-59,2221334,2336011 14 | 60-64,1854790,2003108 15 | 65-69,1680438,1852790 16 | 70-74,1553702,1771151 17 | 75-79,1163633,1446562 18 | 80-84,942098,1331834 19 | 85-89,484087,868523 20 | 90-94,186445,448312 21 | 95-99,45405,143036 22 | 100+,2956,13012 23 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/USA.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,10019240,9584856 3 | 5-9,10371128,9916621 4 | 10-14,10805817,10341652 5 | 15-19,10837194,10413408 6 | 20-24,11423547,11012420 7 | 25-29,12104301,11638797 8 | 30-34,11512068,11191353 9 | 35-39,10672776,10603872 10 | 40-44,10039561,10112012 11 | 45-49,10029885,10106982 12 | 50-54,10471185,10395279 13 | 55-59,10754302,10936920 14 | 60-64,9912939,10516713 15 | 65-69,8262182,9153264 16 | 70-74,6356712,7402146 17 | 75-79,4116773,5133603 18 | 80-84,2711133,3534132 19 | 85-89,1508564,2354382 20 | 90-94,705344,1348383 21 | 95-99,192914,470608 22 | 100+,18734,71215 23 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/README.md: -------------------------------------------------------------------------------- 1 | 2 | The columns in the files are: 3 | 4 | 5 | * india.txt: days, recovered cases and mortality, date, the cumulative number of infected individuals to date. 6 | 7 | * italy.txt: date and number of infected individuals. 8 | 9 | * china.txt: date and number of infected individuals. 10 | 11 | * denmark.txt: date, new cases, total cases, total death, recovery 12 | 13 | * london.txt: date and cumulative number of infected individuals to date. 14 | 15 | * uk.txt: date and cumulative number of infected individuals to date. 16 | 17 | * denmark_cases_by_age.csv: age-structured denmark data 18 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/China-2019.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,45106267,39934767 3 | 5-9,46319087,40225712 4 | 10-14,45044032,38648113 5 | 15-19,44286173,38535391 6 | 20-24,46956410,41620012 7 | 25-29,54633535,49681080 8 | 30-34,65544747,61670474 9 | 35-39,49370823,46920301 10 | 40-44,51155493,48766184 11 | 45-49,62836913,60442592 12 | 50-54,60946291,59710325 13 | 55-59,47588180,46379016 14 | 60-64,38607054,38368062 15 | 65-69,35185041,36260434 16 | 70-74,19746314,21631501 17 | 75-79,11801212,13715744 18 | 80-84,6808650,9097473 19 | 85-89,2787103,4583542 20 | 90-94,748881,1525990 21 | 95-99,140322,386612 22 | 100+,11731,56108 23 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/India-2019.csv: -------------------------------------------------------------------------------- 1 | Age,M,F 2 | 0-4,61184852,55596970 3 | 5-9,62910580,57039427 4 | 10-14,66812183,60172728 5 | 15-19,66525043,59164382 6 | 20-24,64478247,57319089 7 | 25-29,61604481,55079640 8 | 30-34,58243202,52817775 9 | 35-39,52838830,48499876 10 | 40-44,45523908,42635961 11 | 45-49,39881404,37840217 12 | 50-54,34484803,32947978 13 | 55-59,29500956,28445217 14 | 60-64,24129236,23591764 15 | 65-69,18287177,18288098 16 | 70-74,10982591,11861814 17 | 75-79,6861862,7794418 18 | 80-84,3746644,4538052 19 | 85-89,1554275,1903736 20 | 90-94,461093,576998 21 | 95-99,102398,145066 22 | 100+,15806,28978 23 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | 7 | build-and-test: 8 | name: install 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Set up Python 3.7 14 | uses: actions/setup-python@v2 15 | with: 16 | python-version: 3.7 17 | architecture: x64 18 | 19 | - name: Install dependencies 20 | run: python -m pip install -r requirements.txt 21 | 22 | - name: Install pyross 23 | run: python setup.py install 24 | 25 | - name: Test pyross 26 | run: cd tests && python quick_test.py 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /examples/README.MD: -------------------------------------------------------------------------------- 1 | The examples are classified as: 2 | 3 | * **control** shows examples of various control measures in epimodelling 4 | 5 | * **deterministic** is for integration of equations of motion in the limit of no stochastic components 6 | 7 | * **forecast** is for forecasting once the parameters are known 8 | 9 | * **inference** shows how to infer parameters and select models given data 10 | 11 | * **stochastic** is for integration of equations of motion with stochastic components 12 | 13 | * **others** are set of miscellaneous examples which include: 14 | - Hybrid simulation scheme using a combination of stochastic and deterministic schemes. 15 | - Simulation using time since infection models 16 | - Example on how to simulate upto a steady state 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/sphinx/evidence.rst: -------------------------------------------------------------------------------- 1 | Evidence 2 | ======== 3 | Additional functions for computing the evidence of a pyross compartment model. 4 | 5 | This is an extension of pyross.inference. 6 | Evidence computation via nested sampling is already directly implemented in the inference module. 7 | However, for large-scale (high-dimensional) inference problems, nested sampling can become very slow. 8 | In this module, we implement two additional ways to compute the evidence that work whenever the MCMC simulation of the posterior distribution is feasible. 9 | See the `ex-evidence.ipynb notebook `_ for a code example of all ways to compute the evidence. 10 | 11 | 12 | .. automodule:: pyross.evidence 13 | :members: 14 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/italy.txt: -------------------------------------------------------------------------------- 1 | 2020-02-21 20 2 | 2020-02-22 79 3 | 2020-02-23 150 4 | 2020-02-24 229 5 | 2020-02-25 322 6 | 2020-02-26 445 7 | 2020-02-27 650 8 | 2020-02-28 888 9 | 2020-02-29 1128 10 | 2020-03-01 1694 11 | 2020-03-02 2036 12 | 2020-03-03 2502 13 | 2020-03-04 3089 14 | 2020-03-05 3858 15 | 2020-03-06 4636 16 | 2020-03-07 5883 17 | 2020-03-08 7375 18 | 2020-03-09 9172 19 | 2020-03-10 10149 20 | 2020-03-11 12462 21 | 2020-03-12 15113 22 | 2020-03-13 17660 23 | 2020-03-14 21157 24 | 2020-03-15 24747 25 | 2020-03-16 27980 26 | 2020-03-17 31506 27 | 2020-03-18 35713 28 | 2020-03-19 41035 29 | 2020-03-20 47021 30 | 2020-03-21 53578 31 | 2020-03-22 59138 32 | 2020-03-23 63927 33 | 2020-03-24 69176 34 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/china.txt: -------------------------------------------------------------------------------- 1 | 2020-01-16 45 2 | 2020-01-17 62 3 | 2020-01-18 121 4 | 2020-01-19 198 5 | 2020-01-20 291 6 | 2020-01-21 440 7 | 2020-01-22 571 8 | 2020-01-23 830 9 | 2020-01-24 1287 10 | 2020-01-25 1975 11 | 2020-01-26 2744 12 | 2020-01-27 4515 13 | 2020-01-28 5974 14 | 2020-01-29 7711 15 | 2020-01-30 9692 16 | 2020-01-31 11791 17 | 2020-02-01 14380 18 | 2020-02-02 17205 19 | 2020-02-03 20438 20 | 2020-02-04 24324 21 | 2020-02-05 28018 22 | 2020-02-06 31161 23 | 2020-02-07 34546 24 | 2020-02-08 37198 25 | 2020-02-09 40171 26 | 2020-02-10 42638 27 | 2020-02-11 44653 28 | 2020-02-12 46472 29 | 2020-02-13 48467 30 | 2020-02-14 49970 31 | 2020-02-15 51091 32 | -------------------------------------------------------------------------------- /docs/sphinx/forecast.rst: -------------------------------------------------------------------------------- 1 | Forecasting 2 | ================================== 3 | Forecasting with the inferred parameters, error bars and, if there are latent variables, inferred initial conditions. 4 | 5 | 6 | SIR 7 | --------------------- 8 | .. autoclass:: pyross.forecast.SIR 9 | :members: 10 | 11 | SIR_latent 12 | ------------------------------ 13 | .. autoclass:: pyross.forecast.SIR_latent 14 | :members: 15 | 16 | SEIR 17 | --------------------- 18 | .. autoclass:: pyross.forecast.SEIR 19 | :members: 20 | 21 | SEIR_latent 22 | -------------------------------- 23 | .. autoclass:: pyross.forecast.SEIR_latent 24 | :members: 25 | 26 | SEAIRQ 27 | ---------------------------- 28 | .. autoclass:: pyross.forecast.SEAIRQ 29 | :members: 30 | 31 | SEAIRQ_latent 32 | ------------------------------------ 33 | .. autoclass:: pyross.forecast.SEAIRQ_latent 34 | :members: 35 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ### [Link to PyRoss Documentation on Read the Docs](https://pyross.readthedocs.io/en/latest/). 2 | 3 | 4 | Please have a look at the [examples folder](https://github.com/rajeshrinet/pyross/tree/master/examples) for notebook examples. 5 | The examples are structured along the following pipeline 6 | 7 | ![Imagel](../examples/others/pipeline.jpg) 8 | 9 | The examples are classified as: 10 | 11 | * [deterministic](https://github.com/rajeshrinet/pyross/tree/master/examples/deterministic) is for integration of equations of motion in the limit of no stochastic components 12 | 13 | * [stochastic](https://github.com/rajeshrinet/pyross/tree/master/examples/stochastic) is for integration of equations of motion with stochastic components 14 | 15 | * [inference](https://github.com/rajeshrinet/pyross/tree/master/examples/inference) shows how to infer parameters and select models given data 16 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/india.txt: -------------------------------------------------------------------------------- 1 | # of cases: https://en.wikipedia.org/wiki/2020_coronavirus_pandemic_in_India 2 | 1 0 2020-01-30 1 3 | 3 0 2020-02-02 2 4 | 4 0 2020-02-03 3 5 | 32 3 2020-03-02 5 6 | 33 3 2020-03-03 6 7 | 34 3 2020-03-04 28 8 | 35 3 2020-03-05 30 9 | 36 3 2020-03-06 31 10 | 37 3 2020-03-07 34 11 | 38 3 2020-03-08 39 12 | 39 3 2020-03-09 44 13 | 40 5 2020-03-10 50 14 | 41 5 2020-03-11 60 15 | 42 5 2020-03-12 73 16 | 43 6 2020-03-13 81 17 | 44 6 2020-03-14 97 18 | 45 15 2020-03-15 107 19 | 46 15 2020-03-16 118 20 | 47 17 2020-03-17 137 21 | 48 17 2020-03-18 151 22 | 49 18 2020-03-19 173 23 | 50 25 2020-03-20 223 24 | 51 27 2020-03-21 283 25 | 52 34 2020-03-22 360 26 | 53 37 2020-03-23 434 27 | 54 50 2020-03-24 519 28 | 55 55 2020-03-25 606 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.so 3 | *.ipynb_checkpoints 4 | *~ 5 | *.swp 6 | *.mat 7 | *.swo 8 | pyross/*.html 9 | pyross/*.c 10 | pyross/*.so 11 | pyross/*.cpp 12 | pyross/tsi/*.html 13 | pyross/tsi/*.c 14 | pyross/tsi/*.so 15 | pyross/tsi/*.cpp 16 | *.c 17 | *egg-info* 18 | dist 19 | build/ 20 | .DS_Store 21 | *.npy 22 | 23 | 24 | ## Build tool auxiliary files: 25 | *.fdb_latexmk 26 | *.synctex.gz 27 | *.synctex.gz(busy) 28 | *.pdfsync 29 | *.alg 30 | *.loa 31 | # amsthm 32 | *.thm 33 | # beamer 34 | *.nav 35 | *.snm 36 | *.vrb 37 | # hyperref 38 | *.brf 39 | # makeidx 40 | *.idx 41 | *.ilg 42 | *.ind 43 | *.ist 44 | # minitoc 45 | *.maf 46 | *.mtc 47 | *.mtc0 48 | *.pyg 49 | *.tdo 50 | *.vtk 51 | *.vtu 52 | *.pvsm 53 | *.npz 54 | *.pvd 55 | *.aux 56 | *.lof 57 | *.log 58 | *.lot 59 | *.fls 60 | *.out 61 | *.toc 62 | *.dvi 63 | *.bbl 64 | *.bcf 65 | *.blg 66 | *-blx.aux 67 | *-blx.bib 68 | *.run.xml 69 | build/ 70 | examples/control/ex7_SEkIkIkR_lockdown.pdf 71 | -------------------------------------------------------------------------------- /docs/sphinx/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/changelogs.md: -------------------------------------------------------------------------------- 1 | # PyRoss changelogs 2 | 3 | ## 2.2.0 4 | * Remove calls to "scipy.sparse.linalg.eigen" 5 | 6 | 7 | ## 2.0.1 8 | * Remove SEInR and SEAInR models from the codebase 9 | 10 | 11 | ## 2.0.0 12 | * `Model` class added. It is now the recommended model for new users. 13 | 14 | ## 1.3.0 15 | * Merge PyRossTSI with PyRoss 16 | 17 | ## 1.2.9 18 | * Updates to Spp classes in deterministic and stochastic and changes to inference 19 | 20 | ## 1.2.8 21 | * Use dynesty in place of nestle 22 | 23 | ## 1.2.3 24 | * new inference interface - see https://github.com/rajeshrinet/pyross/pull/33 25 | 26 | 27 | ## 1.2.0 28 | * updates to inference using fastest growing linear mode 29 | 30 | ## 1.1.7 31 | * updates to inference code 32 | 33 | ## 1.1.6 34 | * New class: SppQ stochastic 35 | 36 | ## 1.1.5 37 | * New class: SppQ deterministic 38 | 39 | ## 1.1.4 40 | * Update models.pdf 41 | 42 | ## 1.1.3 43 | * Remove 'fh' as parameter in SEI8R 44 | 45 | ## 1.1.2 46 | * Update docs 47 | 48 | ## 1.1.1 49 | * first version on PyPI 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 University of Cambridge 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/london.txt: -------------------------------------------------------------------------------- 1 | 03-11 104 2 | 03-12 136 3 | 03-13 167 4 | 03-14 313 5 | 03-15 407 6 | 03-16 480 7 | 03-17 621 8 | 03-18 953 9 | 03-19 1,221 10 | 03-20 1,588 11 | 03-21 1,965 12 | 03-22 2,189 13 | 03-23 2,433 14 | 03-24 2,872 15 | 03-25 3,247 16 | 03-26 3,919 17 | 03-27 4,637 18 | 03-28 5,299 19 | 03-29 5,957 20 | 03-30 6,521 21 | 03-31 7,121 22 | 04-01 8,341 23 | 04-02 9,291 24 | 04-03 10,247 25 | 04-04 10,764 26 | 04-05 11,978 27 | 04-06 12,636 28 | 04-07 13,378 29 | 04-08 14,355 30 | 04-09 15,271 31 | 04-10 16,011 32 | 04-11 16,721 33 | 04-12 17,479 34 | 04-13 18,000 35 | 04-14 18,472 36 | 04-15 18,951 37 | 04-16 19,511 38 | 04-17 20,215 39 | 04-18 20,904 40 | 04-19 21,357 41 | 04-20 21,654 42 | 04-21 22,072 43 | 04-22 22,352 44 | 04-23 22,767 45 | 04-24 23,063 46 | 04-25 23,341 47 | 04-26 23,608 48 | 04-27 23,833 49 | 04-28 23,979 50 | 04-29 24,090 51 | 04-30 24,297 52 | 05-01 24,477 53 | 05-02 24,700 54 | 05-03 24,828 55 | 05-04 24,988 56 | 05-05 25,240 57 | 05-06 25,357 58 | 05-07 25,499 59 | 05-08 25,623 60 | 05-09 25,734 61 | 05-10 25,829 62 | 05-11 25,891 63 | -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/DeathsTrim.csv: -------------------------------------------------------------------------------- 1 | Age,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,Death chance 2 | ,03/01/2020,10/01/2020,17/01/2020,24/01/2020,31/01/2020,07/02/2020,14/02/2020,21/02/2020,28/02/2020,06/03/2020,13/03/2020,20/03/2020,27/03/2020,03/04/2020,10/04/2020, 3 | all ages,,0,0,0,0,0,0,0,0,0,2,38,384,1774,4777,0.01 4 | 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 5 | 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 6 | 10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.002 7 | 15,0,0,0,0,0,0,0,0,0,0,0,0,2,3,1,0.002 8 | 20,0,0,0,0,0,0,0,0,0,0,0,1,1,5,1,0.002 9 | 25,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,0.002 10 | 30,0,0,0,0,0,0,0,0,0,0,0,0,10,10,4,0.002 11 | 35,0,0,0,0,0,0,0,0,0,0,0,0,8,13,20,0.002 12 | 40,0,0,0,0,0,0,0,0,0,0,1,2,8,23,30,0.004 13 | 45,0,0,0,0,0,0,0,0,0,0,0,6,24,66,57,0.004 14 | 50,0,0,0,0,0,0,0,0,0,0,0,15,36,85,125,0.013 15 | 55,0,0,0,0,0,0,0,0,0,0,1,13,69,179,193,0.013 16 | 60,0,0,0,0,0,0,0,0,0,0,3,19,86,253,315,0.036 17 | 65,0,0,0,0,0,0,0,0,0,0,4,27,123,334,393,0.036 18 | 70,0,0,0,0,0,0,0,0,0,0,6,34,209,548,627,0.08 19 | 75,0,0,0,0,0,0,0,0,0,1,2,45,282,751,944,0.08 20 | 80,0,0,0,0,0,0,0,0,0,1,6,71,335,954,1196,0.148 21 | 85,0,0,0,0,0,0,0,0,0,0,8,84,317,804,1176,0.148 22 | 90,0,0,0,0,0,0,0,0,0,0,7,66,261,744,1057,0.148 23 | -------------------------------------------------------------------------------- /docs/sphinx/contactMatrix.rst: -------------------------------------------------------------------------------- 1 | Contact matrix 2 | ================================== 3 | Classes and methods to compute contact matrix of a meta-population. The contact matrix :math:`C_{ij}` denotes the average number of contacts made per day by an individual in class :math:`i` with an individual in class :math:`j`. Clearly, the total number of contacts between group :math:`i` to group :math:`j` must equal the total number of contacts from group :math:`j` to group :math:`i`, and thus, for populations of fixed size the contact matrices obey the reciprocity relation :math:`N_{i}C_{ij}=N_{j}C_{ji}`. Here :math:`N_i` is the population in group :math:`i`. 4 | 5 | Contact Matrix Function 6 | ---------------------------------------------- 7 | Generates contact matrix for given interventions 8 | 9 | .. autoclass:: pyross.contactMatrix.ContactMatrixFunction 10 | :members: 11 | 12 | Spatial Contact Matrix 13 | --------------------------------------------------- 14 | Approximates the spatial contact matrix given the locations, populations and areas of 15 | the geographical regions and the overall age structured contact matrix. 16 | 17 | .. autoclass:: pyross.contactMatrix.SpatialContactMatrix 18 | :members: 19 | 20 | 21 | .. automethod:: pyross.contactMatrix.characterise_transient 22 | 23 | 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PYTHON=python 2 | path=examples 3 | recursive=True 4 | 5 | make: 6 | @echo Installing pyross... 7 | ${PYTHON} setup.py install 8 | @echo adding githook... 9 | cp .githooks/pre-push .git/hooks/ 10 | chmod +x .git/hooks/pre-push 11 | 12 | clean-local: 13 | @echo removing local compiled files 14 | rm pyross/*.c pyross/*.html pyross/*.cpp 15 | 16 | clean: 17 | @echo removing all compiled files 18 | ${PYTHON} setup.py clean 19 | rm pyross/*.c pyross/*.html pyross/*.cpp 20 | 21 | env: 22 | @echo creating conda environment... 23 | conda env create --file environment.yml 24 | # conda activate pyross 25 | @echo use make to install pyross 26 | 27 | test: 28 | @echo testing pyross... 29 | cd tests && python quick_test.py 30 | 31 | nbtest: 32 | @echo testing example notebooks... 33 | @echo test $(path) 34 | cd tests && python notebook_test.py --path $(path) --recursive $(recursive) 35 | 36 | 37 | pypitest: 38 | @echo testing pystokes... 39 | python setup.py sdist bdist_wheel 40 | python -m twine upload --repository testpypi dist/* 41 | 42 | pypi: 43 | @echo testing pystokes... 44 | python setup.py sdist bdist_wheel 45 | python -m twine upload dist/* 46 | 47 | cycov: 48 | python setup.py build_ext --force --inplace --define CYTHON_TRACE 49 | pytest tests/quick_test.py --cov=./ --cov-report=xml 50 | -------------------------------------------------------------------------------- /.github/workflows/run_notebooks.yml: -------------------------------------------------------------------------------- 1 | name: Notebooks 2 | 3 | on: [push, pull_request] 4 | #on: 5 | # schedule: 6 | # # 4am daily 7 | # - cron: '0 1 * * *' 8 | 9 | jobs: 10 | 11 | build-and-test: 12 | name: check examples 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Set up Python 3.7 18 | uses: actions/setup-python@v2 19 | with: 20 | python-version: 3.7 21 | architecture: x64 22 | - name: Install dependencies 23 | run: python -m pip install -r requirements.txt 24 | 25 | - name: Install pyross 26 | run: python setup.py install 27 | 28 | - name: testing-inference 29 | shell: bash -l {0} 30 | run: | 31 | make nbtest -e path="examples/inference" recursive=False 32 | - name: testing-deterministic 33 | shell: bash -l {0} 34 | run: | 35 | make nbtest -e path="examples/deterministic" recursive=False 36 | - name: testing-stochastic 37 | shell: bash -l {0} 38 | run: | 39 | make nbtest -e path="examples/stochastic" recursive=False 40 | - name: testing-control 41 | shell: bash -l {0} 42 | run: | 43 | make nbtest -e path="examples/control" recursive=False 44 | - name: testing-forecast 45 | shell: bash -l {0} 46 | run: | 47 | make nbtest -e path="examples/forecast/" recursive=False 48 | -------------------------------------------------------------------------------- /.githooks/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Hook file that automatically runs unit tests before a push 4 | 5 | CHANGED=$(git diff --name-only HEAD^ HEAD) 6 | make 7 | cd tests 8 | for item in $CHANGED 9 | do 10 | if [[ $item =~ pyross/stochastic ]]; 11 | then 12 | echo "pyross/stochastic changed, running tests..." 13 | python -m unittest quick_test.StochasticTest 14 | elif [[ $item =~ pyross/deterministic ]]; 15 | then 16 | echo "pyross/deterministic changed, running tests..." 17 | python -m unittest quick_test.DeterministicTest 18 | elif [[ $item =~ tests/quick_test ]]; 19 | then 20 | echo "quick_test changed, running tests..." 21 | python -m unittest -v quick_test 22 | elif [[ $item =~ pyross/control ]]; 23 | then 24 | echo "pyross/control changed, running tests..." 25 | python -m unittest quick_test.ControlTest 26 | elif [[ $item =~ pyross/inference ]]; 27 | then 28 | echo "pyross/inference changed, running tests..." 29 | python -m unittest quick_test.InferenceTest 30 | elif [[ $item =~ pyross/forecast ]]; 31 | then 32 | echo "pyross/forecast changed, running tests..." 33 | python -m unittest quick_test.ForecastTest 34 | elif [[ $item =~ pyross/utils_python ]]; 35 | then 36 | echo "pyross/utils_python changed, running tests..." 37 | python -m unittest quick_test.UtilsPythonTest 38 | fi 39 | done; 40 | -------------------------------------------------------------------------------- /docs/sphinx/control.rst: -------------------------------------------------------------------------------- 1 | Control with NPIs 2 | ================================================= 3 | 4 | Non-pharmaceutical interventions (NPIs) are strategies that mitigate the spread of a disease by suppressing its normal pathways for transmission. These include social distancing, wearing masks, working from home, and isolation of vulnerable populations. In contrast to pharmaceutical interventions, which are slow to develop but effective in the long term, NPIs can be rapidly implemented but are generally too costly to maintain indefinitely. In the modelling framework of PyRoss, we represent NPIs as modifications to the contact matrix. 5 | 6 | 7 | control_integration 8 | ------------------------------------ 9 | .. autoclass:: pyross.control.control_integration 10 | :members: 11 | 12 | SIR 13 | ------------------------------------ 14 | .. autoclass:: pyross.control.SIR 15 | :members: 16 | 17 | SEkIkIkR 18 | ------------------------------------ 19 | .. autoclass:: pyross.control.SEkIkIkR 20 | :members: 21 | 22 | SIRS 23 | --------------------- 24 | .. autoclass:: pyross.control.SIRS 25 | :members: 26 | 27 | SEIR 28 | --------------------- 29 | .. autoclass:: pyross.control.SEIR 30 | :members: 31 | 32 | 33 | SIkR 34 | ---------------------- 35 | .. autoclass:: pyross.control.SIkR 36 | :members: 37 | 38 | SEkIkR 39 | ------------------------ 40 | .. autoclass:: pyross.control.SEkIkR 41 | :members: 42 | 43 | 44 | SEAIR 45 | ----------------------- 46 | .. autoclass:: pyross.control.SEAIR 47 | :members: 48 | 49 | 50 | SEAIRQ 51 | ----------------------- 52 | .. autoclass:: pyross.control.SEAIRQ 53 | :members: 54 | -------------------------------------------------------------------------------- /examples/others/data/cm/uks.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0.002 0.001 0.003 0 0 0.001 0.006 0.011 0.005 0.003 0.001 0.004 0.002 0.003 0.003 0 2 | 0 0 0 0.006 0.001 0 0.002 0.003 0.005 0.007 0.025 0.033 0.012 0.015 0.005 0.006 0.007 0.016 0.004 3 | 0 0 0 0.092 0.014 0 0.001 0.001 0.002 0.002 0.004 0.007 0.008 0.009 0.001 0.006 0.001 0.001 0.004 4 | 0.005 0.016 0.149 0.352 0.145 0.011 0 0 0.003 0.006 0.006 0.008 0.001 0.005 0.001 0.004 0.007 0 0.015 5 | 0.003 0.003 0.016 0.100 0.548 0.060 0.002 0.002 0.013 0.002 0.003 0.005 0.007 0.007 0.006 0.003 0.003 0.001 0.004 6 | 0.007 0 0 0.011 0.084 0.153 0.039 0.017 0.008 0.003 0.003 0.007 0.000 0.010 0.003 0 0 0 0 7 | 0 0.005 0.001 0 0.003 0.037 0.069 0.026 0.010 0.002 0.003 0.005 0.001 0.003 0.002 0 0 0 0 8 | 0 0.005 0.001 0 0.002 0.010 0.016 0.015 0.005 0.001 0.002 0.001 0.001 0.001 0.000 0.002 0.001 0.003 0.002 9 | 0.001 0.005 0.001 0.001 0.006 0.003 0.004 0.003 0.004 0.003 0.001 0.001 0.001 0.001 0 0.001 0.000 0 0.000 10 | 0.005 0.006 0.001 0.002 0.001 0.001 0.001 0.001 0.003 0.003 0.005 0.002 0.002 0.002 0.001 0.002 0.001 0 0.001 11 | 0.010 0.024 0.002 0.002 0.001 0.001 0.001 0.001 0.001 0.005 0.006 0.006 0.003 0.002 0.001 0.000 0 0 0 12 | 0.005 0.034 0.004 0.003 0.003 0.003 0.002 0.001 0.002 0.002 0.006 0.009 0.005 0.003 0.003 0.002 0.001 0.001 0.000 13 | 0.003 0.011 0.004 0.000 0.003 0.000 0.000 0.001 0.001 0.002 0.003 0.004 0.003 0.002 0.001 0.000 0.000 0.000 0.001 14 | 0.001 0.013 0.005 0.001 0.003 0.003 0.001 0.001 0.001 0.002 0.002 0.003 0.002 0.001 0.002 0.001 0 0.000 0 15 | 0.004 0.005 0.000 0.000 0.003 0.001 0.001 0.000 0 0.001 0.001 0.002 0.001 0.002 0.002 0.001 0.000 0.000 0.001 16 | 0.002 0.006 0.004 0.002 0.001 0 0 0.001 0.001 0.002 0.001 0.002 0.000 0.001 0.001 0.001 0.001 0 0.004 17 | 0.004 0.009 0.001 0.003 0.002 0 0 0.001 0.000 0.001 0 0.002 0.000 0 0.000 0.001 0 0.001 0 18 | 0.004 0.021 0.001 0 0.001 0 0 0.002 0 0 0 0.001 0.000 0.001 0.000 0 0.001 0.001 0.004 19 | 0 0.003 0.002 0.004 0.002 0 0 0.001 0.000 0.000 0 0.000 0.001 0 0.001 0.003 0 0.003 0 20 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/uk.txt: -------------------------------------------------------------------------------- 1 | 2020-03-03 51 2 | 2020-03-04 85 3 | 2020-03-05 114 4 | 2020-03-06 160 5 | 2020-03-07 206 6 | 2020-03-08 271 7 | 2020-03-09 321 8 | 2020-03-10 373 9 | 2020-03-11 456 10 | 2020-03-12 590 11 | 2020-03-13 797 12 | 2020-03-14 1061 13 | 2020-03-15 1391 14 | 2020-03-16 1543 15 | 2020-03-17 1950 16 | 2020-03-18 2626 17 | 2020-03-19 3269 18 | 2020-03-20 3983 19 | 2020-03-21 5018 20 | 2020-03-22 5683 21 | 2020-03-23 6650 22 | 2020-03-24 8077 23 | 2020-03-25 9529 24 | 2020-03-26 11658 25 | 2020-03-27 14548 26 | 2020-03-28 17104 27 | 2020-03-29 19606 28 | 2020-03-30 22271 29 | 2020-03-31 25521 30 | 2020-04-01 30088 31 | 2020-04-02 34610 32 | 2020-04-03 39282 33 | 2020-04-04 43282 34 | 2020-04-05 49481 35 | 2020-04-06 53624 36 | 2020-04-07 57512 37 | 2020-04-08 63377 38 | 2020-04-09 68052 39 | 2020-04-10 73758 40 | 2020-04-11 78991 41 | 2020-04-12 84279 42 | 2020-04-13 88621 43 | 2020-04-14 93873 44 | 2020-04-15 98476 45 | 2020-04-16 103093 46 | 2020-04-17 108692 47 | 2020-04-18 114217 48 | 2020-04-19 120067 49 | 2020-04-20 124743 50 | 2020-04-21 129044 51 | 2020-04-22 133495 52 | 2020-04-23 138078 53 | 2020-04-24 143464 54 | 2020-04-25 148377 55 | 2020-04-26 152840 56 | 2020-04-27 157149 57 | 2020-04-28 161145 58 | 2020-04-29 165221 59 | 2020-04-30 171253 60 | 2020-05-01 177454 61 | 2020-05-02 182260 62 | 2020-05-03 186599 63 | 2020-05-04 190584 64 | 2020-05-05 194990 65 | 2020-05-06 201101 66 | 2020-05-07 206715 67 | 2020-05-08 211364 68 | 2020-05-09 215260 69 | 2020-05-10 219183 70 | 2020-05-11 223060 71 | 72 | -------------------------------------------------------------------------------- /examples/others/data/cm/ukw.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0 0.008 0 0.006 0.032 0.037 0.027 0.027 0.022 0.014 0.015 0.013 0.001 0.002 0 0 2 | 0 0 0 0 0.006 0.002 0.003 0.018 0.020 0.018 0.026 0.017 0.019 0.008 0.017 0.004 0.001 0 0 3 | 0 0 0 0 0.002 0 0.004 0.004 0.009 0.010 0.006 0.005 0.005 0.010 0.006 0.006 0 0 0 4 | 0 0 0 0 0.006 0 0.001 0.004 0.005 0.005 0.003 0.004 0.004 0.005 0.007 0.005 0 0 0 5 | 0.014 0.012 0.002 0.004 0.009 0.004 0.005 0.004 0.007 0.005 0.007 0.011 0.008 0.008 0.010 0.010 0.001 0 0.004 6 | 0 0.005 0 0 0.006 0.013 0.016 0.017 0.027 0.026 0.013 0.013 0.014 0.014 0.017 0.009 0.005 0.006 0.017 7 | 0.014 0.007 0.006 0.001 0.006 0.015 0.023 0.035 0.040 0.052 0.039 0.036 0.031 0.038 0.023 0.014 0.008 0.021 0.089 8 | 0.049 0.029 0.004 0.002 0.003 0.010 0.022 0.060 0.079 0.042 0.030 0.029 0.023 0.027 0.025 0.018 0.017 0.029 0.073 9 | 0.032 0.018 0.005 0.002 0.003 0.009 0.014 0.045 0.090 0.067 0.054 0.037 0.031 0.039 0.026 0.019 0.011 0.013 0.040 10 | 0.024 0.017 0.005 0.002 0.003 0.009 0.019 0.024 0.068 0.092 0.064 0.047 0.045 0.049 0.035 0.023 0.017 0.016 0.030 11 | 0.024 0.025 0.003 0.001 0.004 0.004 0.014 0.018 0.055 0.065 0.068 0.047 0.043 0.048 0.034 0.023 0.016 0.009 0.041 12 | 0.022 0.018 0.003 0.002 0.006 0.005 0.015 0.018 0.041 0.053 0.051 0.059 0.043 0.060 0.037 0.023 0.014 0.008 0.036 13 | 0.012 0.018 0.003 0.001 0.004 0.005 0.011 0.013 0.031 0.045 0.042 0.039 0.043 0.046 0.035 0.018 0.014 0.008 0.053 14 | 0.013 0.007 0.005 0.002 0.004 0.005 0.013 0.015 0.038 0.047 0.045 0.052 0.044 0.056 0.037 0.026 0.013 0.009 0.039 15 | 0.012 0.016 0.003 0.002 0.005 0.006 0.009 0.015 0.028 0.037 0.035 0.035 0.037 0.040 0.038 0.027 0.017 0.024 0.033 16 | 0.001 0.005 0.004 0.002 0.006 0.004 0.006 0.013 0.024 0.028 0.028 0.025 0.022 0.034 0.032 0.015 0.011 0.006 0.046 17 | 0.003 0.001 0 0 0.001 0.002 0.004 0.013 0.014 0.022 0.020 0.016 0.019 0.018 0.021 0.012 0.010 0.005 0.022 18 | 0 0 0 0 0 0.003 0.010 0.023 0.018 0.022 0.012 0.009 0.011 0.012 0.032 0.006 0.005 0.001 0.009 19 | 0 0 0 0 0.001 0.005 0.026 0.034 0.033 0.025 0.033 0.026 0.043 0.033 0.026 0.030 0.013 0.006 0.009 20 | -------------------------------------------------------------------------------- /examples/others/data/cm/uko.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0.010 0.009 0.012 0.007 0.009 0.032 0.058 0.046 0.028 0.017 0.013 0.027 0.036 0.053 0.049 0.013 2 | 0 0 0 0.014 0.009 0.007 0.005 0.007 0.014 0.014 0.030 0.021 0.020 0.007 0.012 0.033 0.036 0.028 0.018 3 | 0 0 0 0.022 0.012 0 0.004 0.003 0.004 0.007 0.009 0.012 0.008 0.006 0.004 0.006 0.013 0.022 0.009 4 | 0.026 0.038 0.035 0.047 0.029 0.008 0.009 0.012 0.010 0.014 0.031 0.037 0.032 0.036 0.006 0.016 0.016 0.031 0.072 5 | 0.016 0.017 0.014 0.020 0.127 0.027 0.005 0.010 0.027 0.012 0.019 0.017 0.019 0.025 0.008 0.005 0.006 0.014 0.018 6 | 0.031 0.020 0 0.008 0.038 0.247 0.078 0.050 0.061 0.048 0.022 0.039 0.022 0.021 0.021 0.016 0.012 0.008 0.034 7 | 0.018 0.012 0.006 0.008 0.007 0.074 0.177 0.103 0.108 0.045 0.042 0.031 0.030 0.040 0.024 0.015 0.014 0.015 0.031 8 | 0.014 0.012 0.003 0.007 0.008 0.030 0.066 0.159 0.140 0.074 0.037 0.036 0.032 0.050 0.026 0.022 0.015 0.019 0.025 9 | 0.028 0.013 0.002 0.003 0.013 0.021 0.039 0.079 0.196 0.109 0.050 0.042 0.036 0.039 0.049 0.039 0.027 0.025 0.038 10 | 0.052 0.013 0.004 0.005 0.006 0.016 0.016 0.042 0.110 0.186 0.095 0.055 0.046 0.050 0.054 0.050 0.059 0.035 0.026 11 | 0.042 0.028 0.005 0.010 0.009 0.008 0.016 0.021 0.052 0.096 0.122 0.081 0.048 0.041 0.041 0.052 0.048 0.039 0.026 12 | 0.027 0.022 0.007 0.014 0.009 0.015 0.012 0.023 0.048 0.061 0.088 0.095 0.065 0.047 0.039 0.049 0.059 0.052 0.033 13 | 0.015 0.018 0.004 0.010 0.009 0.007 0.011 0.018 0.036 0.046 0.046 0.058 0.064 0.055 0.044 0.030 0.034 0.042 0.048 14 | 0.011 0.006 0.003 0.011 0.012 0.007 0.014 0.027 0.038 0.048 0.038 0.041 0.054 0.081 0.056 0.048 0.053 0.044 0.067 15 | 0.025 0.012 0.002 0.002 0.004 0.007 0.009 0.016 0.052 0.057 0.042 0.037 0.046 0.061 0.091 0.073 0.052 0.049 0.071 16 | 0.039 0.038 0.004 0.006 0.003 0.007 0.007 0.015 0.049 0.062 0.063 0.054 0.037 0.062 0.086 0.110 0.081 0.071 0.090 17 | 0.062 0.044 0.009 0.007 0.004 0.005 0.007 0.011 0.036 0.078 0.062 0.069 0.045 0.073 0.066 0.087 0.123 0.119 0.142 18 | 0.060 0.036 0.016 0.014 0.009 0.004 0.007 0.015 0.034 0.049 0.052 0.064 0.059 0.062 0.064 0.079 0.123 0.110 0.172 19 | 0.010 0.013 0.004 0.019 0.007 0.009 0.009 0.011 0.031 0.021 0.020 0.024 0.039 0.056 0.055 0.059 0.087 0.101 0.093 20 | -------------------------------------------------------------------------------- /examples/others/data/cm/ukh.txt: -------------------------------------------------------------------------------- 1 | 0 0 0 0.029 0.020 0.021 0.021 0.036 0.108 0.354 0.416 0.186 0.063 0.021 0.035 0.051 0.059 0.021 0.004 2 | 0 0 0 0.055 0.042 0.019 0.014 0.008 0.047 0.122 0.317 0.395 0.186 0.065 0.024 0.038 0.045 0.030 0.013 3 | 0 0 0 0.082 0.047 0.016 0.012 0.003 0.016 0.030 0.077 0.201 0.175 0.072 0.019 0.014 0.019 0.022 0.009 4 | 0.078 0.154 0.133 0.041 0.066 0.015 0.006 0.009 0.008 0.016 0.063 0.271 0.352 0.213 0.048 0.016 0.019 0.020 0.048 5 | 0.037 0.081 0.052 0.046 0.077 0.050 0.020 0.009 0.010 0.020 0.043 0.117 0.262 0.184 0.089 0.024 0.014 0.012 0.037 6 | 0.054 0.052 0.026 0.015 0.070 0.201 0.087 0.045 0.021 0.019 0.021 0.065 0.151 0.229 0.095 0.016 0.004 0.005 0.034 7 | 0.050 0.036 0.018 0.006 0.026 0.082 0.285 0.153 0.083 0.012 0.010 0.034 0.070 0.186 0.095 0.027 0.008 0.009 0.038 8 | 0.056 0.013 0.003 0.005 0.008 0.027 0.097 0.261 0.177 0.043 0.009 0.013 0.039 0.093 0.067 0.031 0.010 0.009 0.022 9 | 0.094 0.043 0.008 0.003 0.005 0.007 0.030 0.100 0.397 0.153 0.041 0.017 0.015 0.031 0.060 0.036 0.017 0.008 0.013 10 | 0.313 0.114 0.016 0.005 0.010 0.007 0.004 0.025 0.155 0.437 0.172 0.046 0.016 0.018 0.031 0.036 0.025 0.007 0.016 11 | 0.375 0.301 0.042 0.021 0.021 0.007 0.004 0.005 0.043 0.175 0.388 0.167 0.055 0.018 0.010 0.024 0.036 0.023 0.011 12 | 0.184 0.412 0.120 0.101 0.063 0.025 0.014 0.008 0.019 0.051 0.184 0.350 0.174 0.063 0.019 0.017 0.027 0.024 0.018 13 | 0.056 0.172 0.093 0.116 0.125 0.051 0.025 0.022 0.015 0.016 0.053 0.154 0.292 0.139 0.040 0.020 0.017 0.020 0.027 14 | 0.018 0.058 0.037 0.068 0.085 0.075 0.065 0.051 0.030 0.018 0.017 0.054 0.134 0.280 0.132 0.044 0.017 0.015 0.049 15 | 0.033 0.024 0.011 0.017 0.045 0.034 0.036 0.040 0.064 0.033 0.011 0.017 0.042 0.144 0.262 0.123 0.050 0.024 0.042 16 | 0.055 0.043 0.009 0.007 0.014 0.007 0.012 0.022 0.044 0.044 0.029 0.018 0.025 0.056 0.144 0.253 0.133 0.048 0.052 17 | 0.069 0.055 0.013 0.008 0.009 0.002 0.004 0.007 0.023 0.033 0.047 0.032 0.023 0.024 0.063 0.143 0.246 0.115 0.050 18 | 0.025 0.038 0.016 0.009 0.008 0.002 0.005 0.007 0.011 0.010 0.032 0.029 0.027 0.022 0.032 0.054 0.119 0.265 0.132 19 | 0.003 0.010 0.004 0.013 0.014 0.009 0.011 0.010 0.010 0.013 0.009 0.013 0.022 0.041 0.032 0.034 0.031 0.078 0.218 20 | -------------------------------------------------------------------------------- /docs/sphinx/stochastic.rst: -------------------------------------------------------------------------------- 1 | Stochastic simulations 2 | ================================== 3 | Stochastic simulations with compartment models and age structure. Has Gillespie and tau-leaping implemented. 4 | 5 | A list of methods for stochastic simulations of age-structured compartment models along with link to notebook examples is given below. 6 | 7 | Model 8 | -------------------------------------- 9 | .. autoclass:: pyross.stochastic.Model 10 | :members: 11 | 12 | * `Link to example notebook `_ 13 | 14 | Spp 15 | -------------------------------------- 16 | .. autoclass:: pyross.stochastic.Spp 17 | :members: 18 | 19 | * `Link to example notebook `_ 20 | 21 | SppQ 22 | -------------------------- 23 | .. autoclass:: pyross.stochastic.SppQ 24 | :members: 25 | 26 | * `Link to example notebook `_ 27 | 28 | 29 | SIR 30 | ---------------------- 31 | .. autoclass:: pyross.stochastic.SIR 32 | :members: 33 | 34 | * `Link to example notebook `_ 35 | 36 | SIkR 37 | ------------------------ 38 | .. autoclass:: pyross.stochastic.SIkR 39 | :members: 40 | 41 | * `Link to example notebook `_ 42 | 43 | SEIR 44 | ------------------------- 45 | .. autoclass:: pyross.stochastic.SEIR 46 | :members: 47 | 48 | * `Link to example notebook `_ 49 | 50 | SEAIRQ 51 | --------------------------- 52 | .. autoclass:: pyross.stochastic.SEAIRQ 53 | :members: 54 | 55 | * `Link to example notebook `_ 56 | 57 | 58 | SEAIRQ_testing 59 | ------------------------------------- 60 | .. autoclass:: pyross.stochastic.SEAIRQ_testing 61 | :members: 62 | 63 | stochastic_integration 64 | -------------------------------------------- 65 | .. autoclass:: pyross.stochastic.stochastic_integration 66 | :members: 67 | 68 | -------------------------------------------------------------------------------- /docs/sphinx/deterministic.rst: -------------------------------------------------------------------------------- 1 | Deterministic simulations 2 | ================================== 3 | Deterministic simulations with compartment models and age structure 4 | 5 | A list of methods for deterministic simulations of age-structured compartment models along with link to notebook examples is given below. 6 | 7 | Model 8 | -------------------------- 9 | .. autoclass:: pyross.deterministic.Model 10 | :members: 11 | 12 | * `Link to example notebook `_ 13 | 14 | 15 | Spp 16 | -------------------------- 17 | .. autoclass:: pyross.deterministic.Spp 18 | :members: 19 | 20 | * `Link to example notebook `_ 21 | 22 | SppQ 23 | -------------------------- 24 | .. autoclass:: pyross.deterministic.SppQ 25 | :members: 26 | 27 | * `Link to example notebook `_ 28 | 29 | SIR 30 | -------------------------- 31 | .. autoclass:: pyross.deterministic.SIR 32 | :members: 33 | 34 | * `Link to example notebook `_ 35 | 36 | 37 | SIkR 38 | -------------------------- 39 | .. autoclass:: pyross.deterministic.SIkR 40 | :members: 41 | 42 | * `Link to example notebook `_ 43 | 44 | SEIR 45 | -------------------------- 46 | .. autoclass:: pyross.deterministic.SEIR 47 | :members: 48 | 49 | * `Link to example notebook `_ 50 | 51 | SEkIkR 52 | ----------------------------- 53 | .. autoclass:: pyross.deterministic.SEkIkR 54 | :members: 55 | 56 | * `Link to example notebook `_ 57 | 58 | 59 | SEAIRQ 60 | ------------------------------ 61 | .. autoclass:: pyross.deterministic.SEAIRQ 62 | :members: 63 | 64 | * `Link to example notebook `_ 65 | 66 | 67 | CommonMethods 68 | ---------------------------------------- 69 | .. autoclass:: pyross.deterministic.CommonMethods 70 | :members: 71 | 72 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/denmark.txt: -------------------------------------------------------------------------------- 1 | 27-02-2020 1 1 0 0 2 | 28-02-2020 1 2 0 0 3 | 29-02-2020 1 3 0 0 4 | 01-03-2020 1 4 0 0 5 | 02-03-2020 0 4 0 0 6 | 03-03-2020 6 10 0 0 7 | 04-03-2020 5 15 0 0 8 | 05-03-2020 5 20 0 0 9 | 06-03-2020 3 23 0 0 10 | 07-03-2020 6 29 0 0 11 | 08-03-2020 8 37 0 0 12 | 09-03-2020 55 92 0 0 13 | 10-03-2020 172 264 0 0 14 | 11-03-2020 252 516 0 0 15 | 12-03-2020 160 676 0 0 16 | 13-03-2020 128 804 1 0 17 | 14-03-2020 32 836 1 0 18 | 15-03-2020 39 875 2 0 19 | 16-03-2020 57 932 2 0 20 | 17-03-2020 92 1024 4 0 21 | 18-03-2020 91 1115 4 0 22 | 19-03-2020 108 1223 6 0 23 | 20-03-2020 112 1335 9 0 24 | 21-03-2020 83 1418 13 0 25 | 22-03-2020 94 1512 13 0 26 | 23-03-2020 70 1582 13 0 27 | 24-03-2020 135 1717 24 0 28 | 25-03-2020 144 1861 34 0 29 | 26-03-2020 162 2023 41 0 30 | 27-03-2020 176 2199 52 0 31 | 28-03-2020 167 2366 65 0 32 | 29-03-2020 198 2564 72 0 33 | 30-03-2020 191 2755 77 0 34 | 31-03-2020 284 3039 90 0 35 | 01-04-2020 251 3290 104 894 36 | 02-04-2020 283 3573 123 1172 37 | 03-04-2020 373 3946 139 1193 38 | 04-04-2020 322 4268 161 1379 39 | 05-04-2020 293 4561 179 1430 40 | 06-04-2020 314 4875 187 1489 41 | 07-04-2020 391 5266 203 1615 42 | 08-04-2020 331 5597 218 1762 43 | 09-04-2020 233 5830 237 1883 44 | 10-04-2020 184 6014 247 1929 45 | 11-04-2020 177 6191 260 2111 46 | 12-04-2020 178 6369 273 2291 47 | 13-04-2020 144 6513 285 2403 48 | 14-04-2020 193 6706 299 2689 49 | 15-04-2020 170 6876 309 2925 50 | 16-04-2020 198 7074 321 3203 51 | 17-04-2020 194 7268 336 3571 52 | 18-04-2020 169 7437 346 4031 53 | 19-04-2020 143 7580 355 4328 54 | 20-04-2020 131 7711 364 4500 55 | 21-04-2020 180 7891 370 4889 56 | 22-04-2020 217 8108 384 5276 57 | 23-04-2020 163 8271 394 5573 58 | 24-04-2020 137 8408 403 5715 59 | 25-04-2020 235 8643 418 5858 60 | 26-04-2020 130 8773 422 5994 61 | 27-04-2020 123 8896 427 6150 62 | 28-04-2020 153 9049 434 6312 63 | 29-04-2020 157 9206 443 6558 64 | 30-04-2020 150 9356 452 6741 65 | 01-05-2020 153 9509 460 6924 66 | 02-05-2020 96 9605 475 7084 67 | 03-05-2020 116 9721 484 7182 68 | 04-05-2020 147 9868 493 7284 69 | 05-05-2020 151 10019 503 7492 70 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import os, sys, re 3 | from setuptools import setup, Extension 4 | from Cython.Build import cythonize 5 | import Cython.Compiler.Options 6 | Cython.Compiler.Options.annotate=True 7 | 8 | 9 | if 'darwin'==(sys.platform).lower(): 10 | extension1 = Extension('pyross/*', ['pyross/*.pyx'], 11 | include_dirs=[numpy.get_include()], 12 | extra_compile_args=['-mmacosx-version-min=10.9'], 13 | extra_link_args=['-mmacosx-version-min=10.9'], 14 | ) 15 | else: 16 | extension1 = Extension('pyross/*', ['pyross/*.pyx'], 17 | include_dirs=[numpy.get_include()], 18 | ) 19 | 20 | 21 | with open("README.md", "r") as fh: 22 | long_description = fh.read() 23 | 24 | 25 | cwd = os.path.abspath(os.path.dirname(__file__)) 26 | with open(os.path.join(cwd, 'pyross', '__init__.py')) as fp: 27 | for line in fp: 28 | m = re.search(r'^\s*__version__\s*=\s*([\'"])([^\'"]+)\1\s*$', line) 29 | if m: 30 | version = m.group(2) 31 | break 32 | else: 33 | raise RuntimeError('Unable to find own __version__ string') 34 | 35 | 36 | setup( 37 | name='pyross', 38 | version=version, 39 | url='https://github.com/rajeshrinet/pyross', 40 | project_urls={ 41 | "Documentation": "https://pyross.readthedocs.io", 42 | "Source": "https://github.com/rajeshrinet/pyross", 43 | }, 44 | author='The PyRoss team', 45 | author_email = 'pyross@googlegroups.com', 46 | license='MIT', 47 | description='PyRoss is a numerical library for inference, forecasts,\ 48 | and optimal control of epidemiological models in Python', 49 | long_description=long_description, 50 | long_description_content_type='text/markdown', 51 | platforms='tested on Linux, macOS, and windows', 52 | ext_modules=cythonize([extension1], 53 | compiler_directives={'language_level': 3}, 54 | ), 55 | libraries=[], 56 | install_requires=['cython','numpy','scipy','matplotlib', 57 | 'cma','sympy','nlopt','dill'], 58 | packages=['pyross'], 59 | package_data={'pyross': ['*.pxd']}, 60 | include_package_data=True, 61 | setup_requires=['wheel'], 62 | classifiers=[ 63 | 'License :: OSI Approved :: MIT License', 64 | 'Programming Language :: Python :: 3', 65 | 'Programming Language :: Python :: 3.7', 66 | 'Topic :: Scientific/Engineering', 67 | 'Topic :: Scientific/Engineering :: Mathematics', 68 | 'Intended Audience :: Science/Research', 69 | 'Intended Audience :: Education', 70 | ], 71 | ) 72 | -------------------------------------------------------------------------------- /examples/others/data/covid-cases/denmark_cases_by_age.csv: -------------------------------------------------------------------------------- 1 | ,2020-03-13,2020-03-16,2020-03-17,2020-03-18,2020-03-19,2020-03-20,2020-03-21,2020-03-22,2020-03-23,2020-03-24,2020-03-25,2020-03-26,2020-03-27,2020-03-28,2020-03-29,2020-03-30,2020-03-31,2020-04-01,2020-04-02,2020-04-03,2020-04-04,2020-04-05,2020-04-06,2020-04-07,2020-04-08,2020-04-09,2020-04-10,2020-04-11,2020-04-12,2020-04-13,2020-04-14,2020-04-15,2020-04-16,2020-04-17,2020-04-18,2020-04-19,2020-04-20,2020-04-21,2020-04-22,2020-04-23,2020-04-24,2020-04-25,2020-04-26,2020-04-27,2020-04-28,2020-04-29,2020-04-30,2020-05-01,2020-05-02,2020-05-03,2020-05-04,2020-05-05 2 | 0-9,10,12,13,12,13,13,13,13,13,13,13,13,15,15,17,18,19,21,21,23,27,32,34,38,47,58,60,63,63,66,69,72,75,80,81,82,84,87,89,93,95,104,108,111,116,120,126,135,139,143,155,168 3 | 10-19,30,33,33,33,35,35,35,35,35,37,40,40,40,41,42,46,48,48,53,63,74,82,90,102,114,129,135,150,156,162,167,172,181,187,198,209,215,224,234,244,252,266,273,284,298,313,326,336,345,347,363,378 4 | 20-29,134,140,142,146,148,153,161,165,167,172,179,188,196,206,222,237,255,276,300,328,386,423,466,510,582,607,640,678,706,738,763,796,826,860,878,903,932,960,986,1011,1031,1064,1093,1112,1139,1160,1188,1227,1244,1265,1287,1308 5 | 30-39,135,143,147,156,162,170,184,191,193,203,211,223,239,260,279,289,315,355,394,433,492,545,594,643,708,745,763,788,823,846,877,898,920,945,971,992,1014,1046,1075,1095,1113,1140,1162,1181,1199,1230,1262,1284,1302,1315,1339,1368 6 | 40-49,253,284,294,305,325,345,362,375,386,402,420,436,454,486,520,544,598,660,711,765,837,890,949,1002,1062,1105,1140,1165,1188,1212,1243,1277,1315,1353,1381,1406,1419,1448,1488,1512,1545,1579,1600,1616,1644,1673,1687,1706,1719,1734,1757,1778 7 | 50-59,159,176,186,200,209,224,239,248,254,279,309,331,365,409,447,482,536,599,660,733,814,869,917,989,1073,1125,1155,1187,1220,1251,1278,1317,1369,1393,1420,1441,1457,1491,1537,1565,1588,1620,1637,1656,1682,1694,1714,1733,1755,1780,1805,1833 8 | 60-69,50,62,70,90,107,127,140,148,156,180,204,228,250,267,306,330,369,408,436,486,546,588,616,656,711,738,763,781,798,812,833,853,872,897,919,939,949,971,998,1017,1028,1054,1068,1074,1090,1106,1122,1137,1141,1155,1164,1178 9 | 70-79,5,26,39,55,70,82,100,118,132,167,192,224,261,304,331,355,388,409,436,462,490,512,534,560,586,607,620,628,642,647,664,674,681,696,708,716,728,736,751,766,776,801,806,819,825,833,842,848,851,864,871,876 10 | 80-89,7,18,28,38,51,65,77,87,98,106,124,140,158,178,194,214,240,260,286,310,331,342,355,376,395,409,422,432,448,454,468,482,493,507,524,531,545,556,577,588,593,623,628,642,649,666,673,682,685,693,701,706 11 | 90+,2,4,8,9,12,12,15,15,16,18,23,28,32,35,37,40,47,56,58,69,80,86,92,102,108,112,121,124,130,130,134,140,147,155,162,165,172,176,177,182,189,194,200,203,209,213,218,223,226,227,228,228 12 | -------------------------------------------------------------------------------- /docs/sphinx/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | import os 14 | import sys 15 | 16 | # -- Project information ----------------------------------------------------- 17 | 18 | project = 'PyRoss' 19 | copyright = '2020, Ronojoy Adhikari, Austen Bolitho, Fernando Caballero, Michael Cates, Jakub Dolezal, Timothy Ekeh, Jules Guioth, Robert Jack, Julian Kappler, Lukas Kikuchi, Irene Li, Joseph Peterson, Patrick Pietzonka, Benjamin Remez, Paul Rohrbach, Rajesh Singh, and Günther Turk' 20 | author = 'Ronojoy Adhikari, Austen Bolitho, Fernando Caballero, Michael Cates, Jakub Dolezal, Timothy Ekeh, Jules Guioth, Robert Jack, Julian Kappler, Lukas Kikuchi, Irene Li, Joseph Peterson, Patrick Pietzonka, Benjamin Remez, Paul Rohrbach, Rajesh Singh, and Günther Turk' 21 | 22 | # The full version, including alpha/beta/rc tags 23 | release = '1.0.0' 24 | 25 | 26 | # -- General configuration --------------------------------------------------- 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | 32 | extensions = [ 33 | 'sphinx.ext.autodoc', 34 | 'sphinx.ext.coverage', 35 | 'sphinx.ext.napoleon', 36 | # 'numpydoc' 37 | ] 38 | 39 | autodoc_member_order = 'bysource' 40 | autodoc_inherit_docstrings = False 41 | napoleon_numpy_docstring = True 42 | pygments_style = 'sphinx' 43 | 44 | # Add any paths that contain templates here, relative to this directory. 45 | templates_path = ['_templates'] 46 | 47 | # List of patterns, relative to source directory, that match files and 48 | # directories to ignore when looking for source files. 49 | # This pattern also affects html_static_path and html_extra_path. 50 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 51 | 52 | 53 | # -- Options for HTML output ------------------------------------------------- 54 | 55 | # The theme to use for HTML and HTML Help pages. See the documentation for 56 | # a list of builtin themes. 57 | # 58 | html_theme = "sphinx_rtd_theme" 59 | 60 | # Add any paths that contain custom static files (such as style sheets) here, 61 | # relative to this directory. They are copied after the builtin static files, 62 | # so a file named "default.css" will overwrite the builtin "default.css". 63 | master_doc = 'index' 64 | -------------------------------------------------------------------------------- /examples/others/data/age_structures/France.txt: -------------------------------------------------------------------------------- 1 | 0 360058 346324 706382 2 | 1 365656 350503 716159 3 | 2 371835 357304 729139 4 | 3 382535 366607 749142 5 | 4 393693 377204 770897 6 | 5 403548 391501 795049 7 | 6 409134 392202 801336 8 | 7 419746 399227 818973 9 | 8 420236 404030 824266 10 | 9 430787 413625 844412 11 | 10 428212 408398 836610 12 | 11 430731 411043 841774 13 | 12 425893 407591 833484 14 | 13 432473 414777 847250 15 | 14 424444 404430 828874 16 | 15 424188 404036 828224 17 | 16 422558 402977 825535 18 | 17 422993 401250 824243 19 | 18 426940 403919 830859 20 | 19 427764 404371 832135 21 | 20 398800 379795 778595 22 | 21 390940 376479 767419 23 | 22 373892 364363 738255 24 | 23 372960 368533 741493 25 | 24 365819 365901 731720 26 | 25 352810 357004 709814 27 | 26 352119 358110 710229 28 | 27 369044 378321 747365 29 | 28 376549 386191 762740 30 | 29 384258 399020 783278 31 | 30 385549 408207 793756 32 | 31 391686 414023 805709 33 | 32 392288 417174 809462 34 | 33 398561 425827 824388 35 | 34 398500 424654 823154 36 | 35 396432 421184 817616 37 | 36 392284 416829 809113 38 | 37 418774 441409 860183 39 | 38 423924 444590 868514 40 | 39 427805 448557 876362 41 | 40 405284 425335 830619 42 | 41 398834 413726 812560 43 | 42 402575 412954 815529 44 | 43 391152 403860 795012 45 | 44 403928 414578 818506 46 | 45 424573 434834 859407 47 | 46 446674 458834 905508 48 | 47 458045 467783 925828 49 | 48 456949 464142 921091 50 | 49 445768 454621 900389 51 | 50 439368 449572 888940 52 | 51 431757 446380 878137 53 | 52 429154 443790 872944 54 | 53 437583 454330 891913 55 | 54 437857 455939 893796 56 | 55 439911 461505 901416 57 | 56 432906 456383 889289 58 | 57 417223 440637 857860 59 | 58 417146 441038 858184 60 | 59 411659 440968 852627 61 | 60 407015 438821 845836 62 | 61 395560 431486 827046 63 | 62 390560 427710 818270 64 | 63 384101 425002 809103 65 | 64 377452 421955 799407 66 | 65 375899 419167 795066 67 | 66 366489 409584 776073 68 | 67 369758 414522 784280 69 | 68 357936 403062 760998 70 | 69 367412 416115 783527 71 | 70 357423 409011 766434 72 | 71 353971 405651 759622 73 | 72 343786 395417 739203 74 | 73 319209 373675 692884 75 | 74 236133 282822 518955 76 | 75 228151 274365 502516 77 | 76 218015 265820 483835 78 | 77 198121 245327 443448 79 | 78 171413 217897 389310 80 | 79 171850 225603 397453 81 | 80 173240 234771 408011 82 | 81 163237 226815 390052 83 | 82 152718 219891 372609 84 | 83 145045 217005 362050 85 | 84 130057 206227 336284 86 | 85 122635 202703 325338 87 | 86 107243 186398 293641 88 | 87 98622 181628 280250 89 | 88 85287 164968 250255 90 | 89 73609 152444 226053 91 | 90 57533 128482 186015 92 | 91 47092 113470 160562 93 | 92 36852 95551 132403 94 | 93 28358 82108 110466 95 | 94 22290 67040 89330 96 | 95 16359 53442 69801 97 | 96 11552 41649 53201 98 | 97 7728 32000 39728 99 | 98 5514 23516 29030 100 | 99 7290 35705 41895 101 | -------------------------------------------------------------------------------- /docs/sphinx/index.rst: -------------------------------------------------------------------------------- 1 | PyRoss API 2 | ================================== 3 | .. image:: ../../examples/others/banner.jpg 4 | :width: 800 5 | :alt: PyRoss banner 6 | 7 | PyRoss is a numerical library for inference, prediction and non-pharmaceutical interventions in age-structured epidemiological compartment models. The library is designed to be model-agnostic and allows the user to define models using a Python dictionary. 8 | 9 | 10 | The library supports models formulated stochastically (as chemical master equations) or deterministically (as systems of differential equations). Inference on pre-defined or user-defined models is performed using model-adapted Gaussian processes on the epidemiological manifold or its tangent space. This method allows for latent variable inference and fast computation of the model evidence and the Fisher information matrix. These estimates are convolved with the instrinsic stochasticty of the dynamics to provide Bayesian forecasts of the progress of the epidemic. 11 | 12 | 13 | Installation 14 | ------------ 15 | 16 | From a checkout of PyRoss GitHub repository 17 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 | This is the recommended way as it downloads a whole suite of examples along with the package. 19 | 20 | Install PyRoss and an extended list of dependencies using 21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 22 | 23 | .. code:: bash 24 | 25 | >> git clone https://github.com/rajeshrinet/pyross.git 26 | >> cd pyross 27 | >> pip install -r requirements.txt 28 | >> python setup.py install 29 | 30 | Install PyRoss and an extended list of dependencies, via `Anaconda `__, in an `environment `__ named ``pyross``: 31 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 32 | 33 | .. code:: bash 34 | 35 | >> git clone https://github.com/rajeshrinet/pyross.git 36 | >> cd pyross 37 | >> make env 38 | >> conda activate pyross 39 | >> make 40 | 41 | Via pip 42 | ~~~~~~~ 43 | 44 | Install the latest `PyPI `__ version 45 | 46 | .. code:: bash 47 | 48 | >> pip install pyross 49 | 50 | See also installation instructions and more details in the `README.md `_ on GitHub. 51 | 52 | Tutorial examples 53 | ========================== 54 | 55 | Please have a look at the `examples folder `_ for Jupyter notebook examples on GitHub. 56 | 57 | 58 | API Reference 59 | ============= 60 | 61 | .. toctree:: 62 | :maxdepth: 1 63 | 64 | deterministic 65 | stochastic 66 | hybrid 67 | inference 68 | control 69 | contactMatrix 70 | forecast 71 | evidence 72 | tsi 73 | -------------------------------------------------------------------------------- /docs/sphinx/inference.rst: -------------------------------------------------------------------------------- 1 | Bayesian inference 2 | ================================== 3 | Inference for age structured compartment models using the diffusion approximation (via the van Kampen expansion). 4 | See this `paper `_ for more details on the method. 5 | 6 | There are two ways to do inference: manifold method (sec 3.3 in the report) and tangent space method (sec 3.4 in the report). 7 | In various degrees of `less robust but fast` to `more robust but slow`: 8 | 9 | * tangent space method. 10 | * manifold method with few internal steps and fast integration method (`det_method` = `RK2`, `lyapunov_method` = `euler`). 11 | * manifold method with large number of internel steps and robust integration method (`solve_ivp` from scipy library). 12 | 13 | ============================= ========================================================== 14 | Methods for full data 15 | ============================= ========================================================== 16 | infer Infers epidemiological and control parameters given all information. 17 | infer_mcmc Explore the posterior distribution given all information. 18 | infer_nested_sampling Compute the model evidence (and generate posterior samples) given all information. 19 | obtain_minus_log_p Computes -log(p) of a fully observed trajectory. 20 | compute_hessian Computes the Hessian of -log(p). 21 | nested_sampling_inference Compute the log-evidence and weighted samples. 22 | ============================= ========================================================== 23 | 24 | ================================ =========================================================== 25 | Methods for partial data 26 | ================================ =========================================================== 27 | latent_infer Infers epidemiological and control parameters and initial conditions. 28 | latent_infer_mcmc Explore the posterior distribution. 29 | latent_infer_nested_sampling Compute the model evidence (and generate posterior samples). 30 | minus_logp_red Computes -log(p) of a partially observed trajectory. 31 | compute_hessian_latent Computes the Hessian of -log(p). 32 | nested_sampling_latent_inference Compute the log-evidence and weighted samples. 33 | ================================ =========================================================== 34 | 35 | 36 | ======================= =================================================================== 37 | Sensitivity analysis 38 | ======================= =================================================================== 39 | FIM Computes the Fisher Information Matrix of the stochastic model. 40 | FIM_det Computes the Fisher Information Matrix of the deterministic model. 41 | sensitivity Computes the normalized sensitivity measure 42 | ======================= =================================================================== 43 | 44 | ======================= =========================================================== 45 | Helper function 46 | ======================= =========================================================== 47 | integrate A wrapper around 'simulate' in pyross.deterministic. 48 | set_params Sets parameters. 49 | set_det_method Sets the integration method of the deterministic equation 50 | set_lyapunov_method Sets the integration method of the Lyapunov equation 51 | set_det_model Sets the internal deterministic model 52 | set_contact_matrix Sets the contact matrix 53 | fill_params_dict Fills and returns a parameter dictionary 54 | get_mean_inits Constructs full initial conditions from the prior dict 55 | ======================= =========================================================== 56 | 57 | The functions are documented under the parent class `SIR_type`. 58 | 59 | SIR_type 60 | ---------------------------- 61 | .. autoclass:: pyross.inference.SIR_type 62 | :members: 63 | 64 | Model 65 | ------------------------ 66 | .. autoclass:: pyross.inference.Model 67 | :members: 68 | * `Link to example notebook `_ 69 | 70 | Spp 71 | ------------------------ 72 | .. autoclass:: pyross.inference.Spp 73 | :members: 74 | * `Link to example notebook `_ 75 | 76 | SIR 77 | ------------------------ 78 | .. autoclass:: pyross.inference.SIR 79 | :members: 80 | 81 | SEIR 82 | ------------------------- 83 | .. autoclass:: pyross.inference.SEIR 84 | :members: 85 | 86 | SEAIRQ 87 | -------------------------- 88 | .. autoclass:: pyross.inference.SEAIRQ 89 | :members: 90 | 91 | SppQ 92 | ------------------------ 93 | .. autoclass:: pyross.inference.SppQ 94 | :members: 95 | 96 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/ex10-spatial-contact-matrix.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np \n", 10 | "from matplotlib import pyplot as plt \n", 11 | "import pyross" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 33, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# make up three populations \n", 21 | "total_populations = [2e5, 1e5, 0.5e5]\n", 22 | "populations = np.array([[p/4, p*3/4] for p in total_populations])\n", 23 | "areas = np.array([1000, 800, 500])\n", 24 | "densities = total_populations/areas\n", 25 | "commutes = np.array([[[p1*0.01, p2*0.01]]*3 for (p1, p2) in populations])" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 19, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "b = 1\n", 35 | "work_ratio = 1/3\n", 36 | "generator = pyross.contactMatrix.SpatialContactMatrix(b, work_ratio, populations, areas, commutes)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 34, 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "C = np.array([[18., 9.], \n", 46 | " [3., 12.]]) \n", 47 | "\n", 48 | "C_spatial = generator.spatial_contact_matrix(C)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 27, 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "[[18.95209893 9.47604946]\n", 61 | " [ 3.15868315 12.63473262]]\n" 62 | ] 63 | } 64 | ], 65 | "source": [ 66 | "# contact matrix for 0\n", 67 | "print(np.array(C_spatial)[0, :, 0, :])" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 28, 73 | "metadata": {}, 74 | "outputs": [ 75 | { 76 | "name": "stdout", 77 | "output_type": "stream", 78 | "text": [ 79 | "[[14.80514566 7.40257283]\n", 80 | " [ 2.46752428 9.8700971 ]]\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "# contact matrix for 1\n", 86 | "print(np.array(C_spatial)[1, :, 1, :])" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 29, 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "[[18.94894791 9.47447396]\n", 99 | " [ 3.15815799 12.63263194]]\n" 100 | ] 101 | } 102 | ], 103 | "source": [ 104 | "# contact matrix for 2\n", 105 | "print(np.array(C_spatial)[2, :, 2, :])" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 30, 111 | "metadata": {}, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "[[0.08166627 0.04083313]\n", 118 | " [0.01361104 0.05444418]]\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "# contact matrix between 0 and 1 \n", 124 | "print(np.array(C_spatial)[0, :, 1, :])" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 31, 130 | "metadata": {}, 131 | "outputs": [ 132 | { 133 | "name": "stdout", 134 | "output_type": "stream", 135 | "text": [ 136 | "[[0.07867531 0.03933765]\n", 137 | " [0.01311255 0.0524502 ]]\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "# contact matrix between 0 and 2\n", 143 | "print(np.array(C_spatial)[0, :, 2, :])" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "## Check that the local spatial matrices sum to give the overall one \n", 151 | "\n", 152 | "We want $$ C_{ij} = (\\sum_{\\mu, \\nu} C^{\\mu \\nu}_{ij} N^\\mu_i)/N_i$$" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 32, 158 | "metadata": {}, 159 | "outputs": [ 160 | { 161 | "data": { 162 | "text/plain": [ 163 | "array([[18., 3.],\n", 164 | " [ 9., 12.]])" 165 | ] 166 | }, 167 | "execution_count": 32, 168 | "metadata": {}, 169 | "output_type": "execute_result" 170 | } 171 | ], 172 | "source": [ 173 | "np.sum(np.sum(populations[:, :, None, None]*C_spatial, axis=0), axis=1)/np.sum(populations, axis=0)" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "This is indeed the overall contact matrix" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": {}, 187 | "outputs": [], 188 | "source": [] 189 | } 190 | ], 191 | "metadata": { 192 | "kernelspec": { 193 | "display_name": "Python 3", 194 | "language": "python", 195 | "name": "python3" 196 | }, 197 | "language_info": { 198 | "codemirror_mode": { 199 | "name": "ipython", 200 | "version": 3 201 | }, 202 | "file_extension": ".py", 203 | "mimetype": "text/x-python", 204 | "name": "python", 205 | "nbconvert_exporter": "python", 206 | "pygments_lexer": "ipython3", 207 | "version": "3.7.7" 208 | } 209 | }, 210 | "nbformat": 4, 211 | "nbformat_minor": 4 212 | } 213 | -------------------------------------------------------------------------------- /pyross/deterministic.pxd: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | cimport numpy as np 3 | cimport cython 4 | 5 | ctypedef np.float_t DTYPE_t 6 | 7 | cdef class CommonMethods: 8 | cdef: 9 | readonly int N, M, kI, kE, nClass 10 | readonly double gIh, gIc, fh, ep, gI 11 | readonly double gIsp, gIcp, gIhp 12 | readonly np.ndarray rp0, Ni, dxdt, CM, FM 13 | readonly np.ndarray population, sa, iaa, hh, cc, mm, alpha 14 | readonly dict paramList, readData 15 | 16 | cpdef set_contactMatrix(self, double t, contactMatrix) 17 | 18 | 19 | 20 | 21 | @cython.wraparound(False) 22 | @cython.boundscheck(False) 23 | @cython.cdivision(True) 24 | @cython.nonecheck(False) 25 | cdef class SIR(CommonMethods): 26 | """ 27 | Susceptible, Infected, Removed (SIR) 28 | 29 | * Ia: asymptomatic 30 | * Is: symptomatic 31 | """ 32 | 33 | cdef: 34 | readonly np.ndarray beta, gIa, gIs, fsa 35 | 36 | cpdef rhs(self, rp, tt) 37 | 38 | 39 | 40 | 41 | @cython.wraparound(False) 42 | @cython.boundscheck(False) 43 | @cython.cdivision(True) 44 | @cython.nonecheck(False) 45 | cdef class SIRS(CommonMethods): 46 | """ 47 | Susceptible, Infected, Removed, Susceptible (SIRS) 48 | 49 | * Ia: asymptomatic 50 | * Is: symptomatic 51 | """ 52 | cdef: 53 | readonly double beta, gIa, gIs, fsa 54 | cpdef rhs(self, rp, tt) 55 | 56 | 57 | 58 | 59 | @cython.wraparound(False) 60 | @cython.boundscheck(False) 61 | @cython.cdivision(True) 62 | @cython.nonecheck(False) 63 | cdef class SEIR(CommonMethods): 64 | """ 65 | Susceptible, Exposed, Infected, Removed (SEIR) 66 | 67 | * Ia: asymptomatic 68 | * Is: symptomatic 69 | """ 70 | cdef: 71 | readonly np.ndarray beta, gIa, gIs, gE, fsa 72 | cpdef rhs(self, rp, tt) 73 | 74 | 75 | 76 | 77 | 78 | @cython.wraparound(False) 79 | @cython.boundscheck(False) 80 | @cython.cdivision(True) 81 | @cython.nonecheck(False) 82 | cdef class SEkIkR(CommonMethods): 83 | """ 84 | Susceptible, Infected, Removed (SIkR). Method of k-stages of I 85 | See: Lloyd, Theoretical Population Biology 60, 59􏰈71 (2001), doi:10.1006􏰅tpbi.2001.1525. 86 | """ 87 | cdef: 88 | readonly double beta, gE, gIa, gIs, fsa 89 | cpdef rhs(self, rp, tt) 90 | 91 | 92 | 93 | 94 | @cython.wraparound(False) 95 | @cython.boundscheck(False) 96 | @cython.cdivision(True) 97 | @cython.nonecheck(False) 98 | cdef class SIkR(CommonMethods): 99 | """ 100 | Susceptible, Infected, Removed (SIkR). Method of k-stages of I 101 | """ 102 | cdef: 103 | readonly double beta, gIa, gIs, fsa 104 | cpdef rhs(self, rp, tt) 105 | 106 | 107 | 108 | 109 | 110 | @cython.wraparound(False) 111 | @cython.boundscheck(False) 112 | @cython.cdivision(True) 113 | @cython.nonecheck(False) 114 | cdef class SEAIRQ(CommonMethods): 115 | """ 116 | Susceptible, Exposed, Asymptomatic and infected, Infected, Removed, Quarantined (SEAIRQ) 117 | 118 | * Ia: asymptomatic 119 | * Is: symptomatic 120 | * E: exposed 121 | * A: Asymptomatic and infectious 122 | * R: removed (recovered or deceased) 123 | * Q: quarantined 124 | """ 125 | 126 | cdef: 127 | readonly np.ndarray beta, gE, gA, gIs, gIa, fsa 128 | readonly np.ndarray tS, tE, tA, tIa, tIs 129 | cpdef rhs(self, rp, tt) 130 | 131 | 132 | 133 | 134 | @cython.wraparound(False) 135 | @cython.boundscheck(False) 136 | @cython.cdivision(True) 137 | @cython.nonecheck(False) 138 | cdef class SEAIRQ_testing(CommonMethods): 139 | """ 140 | Susceptible, Exposed, Asymptomatic and infected, Infected, Removed, Quarantined (SEAIRQ) 141 | 142 | * Ia: asymptomatic 143 | * Is: symptomatic 144 | * E: exposed 145 | * A: Asymptomatic and infectious 146 | * R: removed (recovered or deceased) 147 | * Q: quarantined 148 | """ 149 | 150 | cdef: 151 | readonly np.ndarray beta, gE, gA, gIa, gIs, fsa 152 | readonly np.ndarray ars, kapE 153 | readonly object testRate 154 | cpdef rhs(self, rp, tt) 155 | cpdef set_testRate(self, testRate) 156 | 157 | 158 | 159 | 160 | @cython.wraparound(False) 161 | @cython.boundscheck(True) 162 | @cython.cdivision(False) 163 | @cython.nonecheck(True) 164 | cdef class Model(CommonMethods): 165 | """ 166 | Given a model specification, the Model class generates a custome-made compartment epidemic model. 167 | """ 168 | 169 | cdef: 170 | readonly int constant_CM 171 | readonly np.ndarray constant_terms, linear_terms, infection_terms, finres_terms, resource_list 172 | readonly np.ndarray parameters 173 | readonly np.ndarray parameters_length 174 | readonly list param_keys 175 | readonly dict param_dict 176 | readonly dict class_index_dict 177 | readonly np.ndarray _lambdas 178 | readonly object time_dep_param_mapping 179 | readonly np.ndarray finres_pop 180 | readonly np.ndarray nonzero_index_n 181 | 182 | cpdef rhs(self, rp, tt) 183 | 184 | @cython.wraparound(False) 185 | @cython.boundscheck(True) 186 | @cython.cdivision(False) 187 | @cython.nonecheck(True) 188 | cdef class Spp(Model): 189 | """ 190 | Given a model specification, the Spp class generates a custome-made compartment epidemic model with default susceptible class. 191 | """ 192 | 193 | 194 | @cython.wraparound(False) 195 | @cython.boundscheck(True) 196 | @cython.cdivision(False) 197 | @cython.nonecheck(True) 198 | cdef class SppSparse(Spp): 199 | """ 200 | Given a model specification, the Spp class generates a custome-made compartment epidemic model. 201 | """ 202 | 203 | cdef: 204 | readonly int intCounter 205 | readonly np.ndarray interactingMP 206 | 207 | 208 | @cython.wraparound(False) 209 | @cython.boundscheck(True) 210 | @cython.cdivision(False) 211 | @cython.nonecheck(True) 212 | cdef class SppQ(Spp): 213 | """ 214 | Given a model specification, the SppQ class generates a custome-made model just like Spp, but automatically adds a quarantined version of every compartment 215 | """ 216 | 217 | cdef: 218 | readonly dict full_model_spec 219 | readonly object input_time_dep_param_mapping 220 | readonly object testRate 221 | 222 | cpdef set_testRate(self, testRate) 223 | cpdef full_time_dep_param_mapping(self, input_parameters, t) 224 | 225 | 226 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/ex01-SIR.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import numpy as np\n", 17 | "import pyross" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 2, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# Get individual contact matrices\n", 27 | "CH, CW, CS, CO = pyross.contactMatrix.UK()" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 3, 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "# Generate class with contact matrix for SIR model with UK contact structure\n", 37 | "generator = pyross.contactMatrix.ContactMatrixFunction(CH, CW, CS, CO)" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 4, 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "# get constant contact matrix function (this is plug-and-play for model.simulate)\n", 47 | "C = generator.constant_contactMatrix()" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 5, 53 | "metadata": {}, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "True" 59 | ] 60 | }, 61 | "execution_count": 5, 62 | "metadata": {}, 63 | "output_type": "execute_result" 64 | } 65 | ], 66 | "source": [ 67 | "# compare: Does the constant contact matrix function yield the sum of the individual contact matrices?\n", 68 | "(CH + CW + CS + CO == C(123)).all()" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "## Create matrix for temporal intervention" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 6, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "times= [1, 2, 3] # temporal boundaries between different contact-behaviour\n", 85 | "# prefactors for CW, CS, CO:\n", 86 | "interventions = [[0.9,0.9,0.8], # before first time\n", 87 | " [0.5,0.4,0.3], # between first and second time\n", 88 | " [0.8,0.7,0.6], # between second and third time\n", 89 | " [0.9,0.3,0.5]] # for times larger than third time\n", 90 | "\n", 91 | "# generate corresponding contact matrix function\n", 92 | "C = generator.interventions_temporal(times=times,interventions=interventions)" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 7, 98 | "metadata": {}, 99 | "outputs": [ 100 | { 101 | "name": "stdout", 102 | "output_type": "stream", 103 | "text": [ 104 | "True\n", 105 | "True\n", 106 | "True\n", 107 | "True\n", 108 | "True\n" 109 | ] 110 | } 111 | ], 112 | "source": [ 113 | "# Check: Does the contact matrix function give what it should?\n", 114 | "\n", 115 | "# times at which to evaluate contact matrix function\n", 116 | "test_times = [-0.1, 0.5, 1.1, 2.9, 5]\n", 117 | "# for each time, we here enter the corresponding row from the \"interventions\" matrix by hand\n", 118 | "test_indices = [0, 0, 1, 2, 3]\n", 119 | " \n", 120 | "for i,t in enumerate(test_times):\n", 121 | " j = test_indices[i]\n", 122 | " lhs = CH + interventions[j][0]**2*CW + interventions[j][1]**2*CS + interventions[j][2]**2*CO\n", 123 | " rhs = C(t) \n", 124 | " print(np.allclose(lhs, rhs))" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "## Create matrix for population-threshold driven intervention" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": 8, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "# For the SIR model, we have 3*M population numbers (S,Ia,Is)\n", 141 | "# We now consider M = 1\n", 142 | "# (Possible extension: Include class R)\n", 143 | "\n", 144 | "# thresholds for switching\n", 145 | "thresholds = np.array([ [0,20,0],\n", 146 | " [0,40,0],\n", 147 | " [0, 100, 0]])\n", 148 | "# interventions\n", 149 | "interventions = [[0.5,0.2,0.3], # before first time\n", 150 | " [0.2,0.1,0.1], # between first and second time\n", 151 | " [0.4,0.5,0.2], # between second and third time\n", 152 | " [0.7,0.1,0.1]] # for times larger than third time\n", 153 | "\n", 154 | "# generate contact matrix function\n", 155 | "C = generator.interventions_threshold(thresholds=thresholds,interventions=interventions)\n", 156 | "\n", 157 | "# Note that this contact matrix function now takes 4 arguments!\n", 158 | "# C == C(t, S, Ia, Is)" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 9, 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "# Check: Does the contact matrix function give what it should?\n", 168 | "\n", 169 | "test_populations = [ [ 10,10,10] ,\n", 170 | " [0, 10, 10],\n", 171 | " [10, 50,100],\n", 172 | " [100,200,0]]\n", 173 | "\n", 174 | "# The function is written so that for a \"population vector\" state = (S,Ia,Is),\n", 175 | "# the intervention with the largest index i such that\n", 176 | "# state[j] >= thresholds[index,j] for all j\n", 177 | "# is chosen. \n", 178 | "# Put differently, we look for the first row (from above) in the matrix \"thresholds\" such that\n", 179 | "# all population numbers exceed the threshold.\n", 180 | "\n", 181 | "# for each time, we here enter the corresponding row from the \"interventions\" matrix by hand\n", 182 | "test_indices = [0, 0, 2, 3]" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [] 191 | } 192 | ], 193 | "metadata": { 194 | "kernelspec": { 195 | "display_name": "Python 3 (ipykernel)", 196 | "language": "python", 197 | "name": "python3" 198 | }, 199 | "language_info": { 200 | "codemirror_mode": { 201 | "name": "ipython", 202 | "version": 3 203 | }, 204 | "file_extension": ".py", 205 | "mimetype": "text/x-python", 206 | "name": "python", 207 | "nbconvert_exporter": "python", 208 | "pygments_lexer": "ipython3", 209 | "version": "3.10.9" 210 | } 211 | }, 212 | "nbformat": 4, 213 | "nbformat_minor": 4 214 | } 215 | -------------------------------------------------------------------------------- /pyross/hybrid.pyx: -------------------------------------------------------------------------------- 1 | # distutils: language = c++ 2 | # distutils: extra_compile_args = -std=c++11 3 | 4 | import numpy as np 5 | cimport numpy as np 6 | cimport cpython 7 | #from cython.parallel import prange 8 | DTYPE = np.float64 9 | ctypedef np.float_t DTYPE_t 10 | 11 | import pyross.stochastic as stochastic 12 | import pyross.deterministic as deterministic 13 | 14 | cdef class SIR: 15 | """ 16 | Susceptible, Infected, Removed (SIR) 17 | Ia: asymptomatic 18 | Is: symptomatic 19 | 20 | ... 21 | 22 | Parameters 23 | ---------- 24 | parameters: dict 25 | Contains the following keys: 26 | alpha: float, np.array (M,) 27 | fraction of infected who are asymptomatic. 28 | beta: float 29 | rate of spread of infection. 30 | gIa: float 31 | rate of removal from asymptomatic individuals. 32 | gIs: float 33 | rate of removal from symptomatic individuals. 34 | fsa: float 35 | fraction by which symptomatic individuals do not self-isolate. 36 | M: int 37 | Number of compartments of individual for each class. 38 | I.e len(contactMatrix) 39 | Ni: np.array(3*M, ) 40 | Initial number in each compartment and class 41 | 42 | Methods 43 | ------- 44 | simulate 45 | """ 46 | cdef: 47 | readonly int N, M, 48 | readonly double alpha, beta, gIa, gIs, fsa 49 | readonly np.ndarray Ni 50 | readonly dict parameters 51 | 52 | def __init__(self, parameters, M, Ni): 53 | 54 | self.M = M 55 | self.Ni = np.zeros( self.M, dtype=DTYPE) 56 | self.Ni = Ni 57 | self.parameters = parameters 58 | 59 | cdef below_threshold(self,populations,thresholds): 60 | cdef: 61 | int M = self.M 62 | for i in range(3): 63 | for j in range(M): 64 | if (populations[i][j] < thresholds[i][j]): 65 | return True 66 | return False 67 | 68 | cdef find_passing_index(self,trajectory,thresholds): 69 | cdef: 70 | int min_index = 0 71 | int length_of_traj = len(trajectory) 72 | int M = self.M 73 | for i in range(length_of_traj-1): 74 | for j in range(3): 75 | for k in range(M): 76 | product = (trajectory[i,j*M + k] - thresholds[j][k])*(trajectory[i+1,j*M + k] - thresholds[j][k]) 77 | if product < 0: 78 | return min_index+i+1 # index of first datapoint past threshold 79 | return min_index 80 | 81 | 82 | cpdef simulate(self, S0, Ia0, Is0, contactMatrix, long Tf, 83 | dict thresholds, 84 | double dt_stoch = 20,double dt_det = 300, 85 | method='gillespie', 86 | int nc = 30, double epsilon = 0.03, 87 | int tau_update_frequency = 1, 88 | ): 89 | cdef: 90 | int M=self.M 91 | tuple thresholds_from_below = thresholds.get('from_below') 92 | tuple thresholds_from_above = thresholds.get('from_above') 93 | tuple cur_populations = (S0, Ia0, Is0) 94 | int cur_t = 0 95 | long dt, cur_Tf, cur_Nt 96 | 97 | t_arr = np.arange(Tf+1,dtype=int) 98 | trajectory = np.zeros([Tf+1,3*M], 99 | dtype=long) 100 | trajectory[0] = np.concatenate((S0,Ia0,Is0)) 101 | 102 | # initialize both stochastic and deterministic simulations 103 | model_stoch = stochastic.SIR(self.parameters, M, self.Ni) 104 | model_det = deterministic.SIR(self.parameters, M, self.Ni) 105 | # check if initially we are above or below the threshold (from below) 106 | below = self.below_threshold(cur_populations,thresholds_from_below) 107 | 108 | while (cur_t < Tf): 109 | # run simulation 110 | if below: 111 | dt = long(np.round(dt_stoch)) 112 | else: 113 | dt = long(np.round(dt_det)) 114 | # duration of simulation 115 | cur_Tf = long( np.round( np.min([dt,(Tf-cur_t)]) ) ) 116 | cur_Nt = long( np.round(cur_Tf+1 ) ) 117 | # 118 | 119 | if below: 120 | cur_result = model_stoch.simulate(*cur_populations, 121 | contactMatrix, 122 | cur_Tf, cur_Nt, 123 | method=method,epsilon=epsilon, 124 | tau_update_frequency=tau_update_frequency, 125 | ) 126 | cur_traj = cur_result['X'] 127 | else: 128 | cur_result = model_det.simulate(*cur_populations, 129 | contactMatrix, 130 | cur_Tf, cur_Nt) 131 | cur_traj = np.array(np.round(cur_result['X']),dtype=int) 132 | 133 | # check if we passed the threshold 134 | if below: 135 | passing_index = self.find_passing_index(cur_traj,thresholds_from_below) 136 | else: 137 | passing_index = self.find_passing_index(cur_traj,thresholds_from_above) 138 | if passing_index == 0: # means we have not passed through the threshold 139 | trajectory[cur_t+1:cur_t+cur_Nt] = cur_traj[1:] 140 | cur_t += cur_Tf 141 | cur_populations = ( cur_traj[-1,:M,], 142 | cur_traj[-1,M:2*M], 143 | cur_traj[-1,2*M:] ) 144 | else: # means we passed through the threshold 145 | if below: # this means we came from below 146 | below = False # now we are above 147 | else: # this means we came from above 148 | below = True # now we are below 149 | trajectory[cur_t+1:cur_t+passing_index+1] = cur_traj[1:passing_index+1] 150 | # Note that the zero-th element of cur_traj is 151 | # the last datapoint from the previous simulation 152 | cur_t += passing_index 153 | cur_populations = ( cur_traj[passing_index,:M], 154 | cur_traj[passing_index,M:2*M], 155 | cur_traj[passing_index,2*M:] ) 156 | out_dict = {'X':trajectory, 't':t_arr, 157 | 'Ni':self.Ni, 'M':self.M, 158 | 'alpha':self.alpha, 'beta':self.beta, 159 | 'gIa':self.gIa, 'gIs':self.gIs, 160 | 'from_below':thresholds_from_below, 161 | 'from_above':thresholds_from_above, 162 | 'dt_det':dt_det,'dt_stoch':dt_stoch} 163 | return out_dict 164 | -------------------------------------------------------------------------------- /tests/notebook_test.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import os 3 | import re 4 | import subprocess 5 | import sys 6 | import unittest 7 | import argparse 8 | import time 9 | 10 | 11 | 12 | 13 | def run_notebook_tests(path, recursive=False): 14 | """ 15 | Runs Jupyter notebook tests. Exits if they fail. 16 | """ 17 | basepath = os.path.dirname(__file__) 18 | nbpath = os.path.abspath(os.path.join(basepath, "..", path)) 19 | 20 | ''' 21 | Ignore notebooks which take longer or have deliberate errors, 22 | but check they still exists 23 | ''' 24 | os.chdir('../examples/') 25 | 26 | cwd =os.getcwd() 27 | ignore_list = [os.path.join(cwd, 'control/ex04-SIR-optimal_control.ipynb'), 28 | os.path.join(cwd, 'inference/ex06_inference_latent_SEIR.ipynb'), 29 | os.path.join(cwd, 'inference/ex07-latent-hessian-and-sensitivity.ipynb'), 30 | os.path.join(cwd, 'inference/ex08-optimal_design.ipynb'), 31 | os.path.join(cwd, 'inference/ex09a_calibration_SIR.ipynb'), 32 | os.path.join(cwd, 'inference/ex09b_calibration_latent_SIR.ipynb'), 33 | os.path.join(cwd, 'inference/ex11-evidence.ipynb'), 34 | os.path.join(cwd, 'inference/ex12-fastest-growing-mode-inference.ipynb'), 35 | os.path.join(cwd, 'stochastic/ex05-SEAIRQ.ipynb'), 36 | os.path.join(cwd, 'stochastic/ex03-SIkR.ipynb'), 37 | os.path.join(cwd, 'stochastic/ex07-Spp-overdispersion.ipynb'), 38 | ] 39 | 40 | for ignored_book in ignore_list: 41 | if not os.path.isfile(ignored_book): 42 | raise Exception('Ignored notebook not found: ' + ignored_book) 43 | 44 | # Scan and run 45 | print('Testing notebooks') 46 | ok = True 47 | for notebook, cwd in list_notebooks(nbpath, recursive, ignore_list): 48 | os.chdir(cwd) # necessary for relative imports in notebooks 49 | ok &= test_notebook(notebook) 50 | # print(notebook) 51 | if not ok: 52 | print('\nErrors encountered in notebooks') 53 | sys.exit(1) 54 | print('\nOK') 55 | 56 | 57 | 58 | 59 | def list_notebooks(root, recursive=False, ignore_list=None, notebooks=None): 60 | """ 61 | Returns a list of all notebooks in a directory. 62 | """ 63 | if notebooks is None: 64 | notebooks = [] 65 | if ignore_list is None: 66 | ignore_list = [] 67 | try: 68 | for filename in os.listdir(root): 69 | path = os.path.join(root, filename) 70 | cwd = os.path.dirname(path) 71 | if path in ignore_list: 72 | print('Skipping ignored notebook: ' + path) 73 | continue 74 | 75 | # Add notebooks 76 | if os.path.splitext(path)[1] == '.ipynb': 77 | notebooks.append((path,cwd)) 78 | 79 | # Recurse into subdirectories 80 | elif recursive and os.path.isdir(path): 81 | # Ignore hidden directories 82 | if filename[:1] == '.': 83 | continue 84 | list_notebooks(path, recursive, ignore_list, notebooks) 85 | except NotADirectoryError: 86 | path = root 87 | cwd = os.path.dirname(path) 88 | return [(path,cwd)] 89 | 90 | return notebooks 91 | 92 | 93 | 94 | 95 | def test_notebook(path): 96 | """ 97 | Tests a notebook in a subprocess, exists if it doesn't finish. 98 | """ 99 | import nbconvert 100 | print('Running ' + path + ' ... ', end='') 101 | sys.stdout.flush() 102 | 103 | # Load notebook, convert to python 104 | e = nbconvert.exporters.PythonExporter() 105 | code, __ = e.from_filename(path) 106 | 107 | # Remove coding statement, if present 108 | ipylines = ['ipython', 'show('] 109 | code = '\n'.join([x for x in code.splitlines() if not 'ipython' in x]) 110 | for x in code.splitlines(): 111 | if not any(s in ipylines for s in x): 112 | code += '\n'.join([x]) 113 | # print(code) 114 | 115 | # Tell matplotlib not to produce any figures 116 | env = os.environ.copy() 117 | env['MPLBACKEND'] = 'Template' 118 | 119 | # Run in subprocess 120 | start = time.time() 121 | cmd = [sys.executable, '-c', code] 122 | try: 123 | p = subprocess.Popen( 124 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env 125 | ) 126 | stdout, stderr = p.communicate() 127 | # TODO: Use p.communicate(timeout=3600) if Python3 only 128 | if p.returncode != 0: 129 | # Show failing code, output and errors before returning 130 | print('ERROR') 131 | # print('-- script ' + '-' * (79 - 10)) 132 | # for i, line in enumerate(code.splitlines()): 133 | # j = str(1 + i) 134 | # print(j + ' ' * (5 - len(j)) + line) 135 | print('-- stdout ' + '-' * (79 - 10)) 136 | print(stdout) 137 | print('-- stderr ' + '-' * (79 - 10)) 138 | print(stderr) 139 | print('-' * 79) 140 | return False 141 | except KeyboardInterrupt: 142 | p.terminate() 143 | stop = time.time() 144 | print('ABORTED after', round(stop-start,4), "s") 145 | sys.exit(1) 146 | 147 | # Successfully run 148 | stop = time.time() 149 | print('ok. Run took ', round(stop-start,4), "s") 150 | return True 151 | 152 | 153 | 154 | 155 | def export_notebook(ipath, opath): 156 | """ 157 | Exports the notebook at `ipath` to a python file at `opath`. 158 | """ 159 | import nbconvert 160 | from traitlets.config import Config 161 | 162 | # Create nbconvert configuration to ignore text cells 163 | c = Config() 164 | c.TemplateExporter.exclude_markdown = True 165 | 166 | # Load notebook, convert to python 167 | e = nbconvert.exporters.PythonExporter(config=c) 168 | code, __ = e.from_filename(ipath) 169 | 170 | # Remove "In [1]:" comments 171 | r = re.compile(r'(\s*)# In\[([^]]*)\]:(\s)*') 172 | code = r.sub('\n\n', code) 173 | 174 | # Store as executable script file 175 | with open(opath, 'w') as f: 176 | f.write('#!/usr/bin/env python') 177 | f.write(code) 178 | os.chmod(opath, 0o775) 179 | 180 | 181 | 182 | 183 | if __name__ == '__main__': 184 | # Set up argument parsing 185 | def str2bool(v): 186 | if isinstance(v, bool): 187 | return v 188 | if v.lower() in ('yes', 'true', 't', 'y', '1'): 189 | return True 190 | elif v.lower() in ('no', 'false', 'f', 'n', '0'): 191 | return False 192 | else: 193 | raise argparse.ArgumentTypeError('Boolean value expected.') 194 | parser = argparse.ArgumentParser( 195 | description='Run notebook unit tests for PyRoss.', 196 | ) 197 | # Unit tests 198 | parser.add_argument( 199 | '--path', default = '.', 200 | help='Run specific notebook or folder containing notebooks',) 201 | parser.add_argument( 202 | '--recursive', default = True, type=str2bool, 203 | help='Wheither or not subfolders are searched',) 204 | 205 | # Parse! 206 | args = parser.parse_args() 207 | print(args) 208 | run_notebook_tests(args.path, recursive=args.recursive) 209 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/ex12-SEIR-fastest-growing-mode.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pyross\n", 10 | "import numpy as np\n", 11 | "import matplotlib.pyplot as plt\n", 12 | "plt.rcParams.update({'font.size': 12})" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "#########################################\n", 22 | "## Population Numbers ##\n", 23 | "#########################################\n", 24 | "\n", 25 | "M=16 ## number of age classes\n", 26 | "Ni = pyross.utils.getPopulation(country='UK', M=M)\n", 27 | "min_age = 2.5; max_age = 77.5; age = np.linspace(min_age,max_age, M)\n", 28 | "N = np.sum(Ni)\n", 29 | "\n", 30 | "#########################################\n", 31 | "## Contact Matrices ##\n", 32 | "#########################################\n", 33 | "\n", 34 | "# Get individual contact matrices\n", 35 | "CH, CW, CS, CO = pyross.contactMatrix.UK()\n", 36 | "def contactMatrix(t):\n", 37 | "# if t > 3000 and t < 90:\n", 38 | "# return CH + 0.1*CW + 0.1*CO\n", 39 | "# else:\n", 40 | " return CH + CW + CS + CO" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "####################################\n", 50 | "## ##\n", 51 | "## Disease Characteristics ##\n", 52 | "## ##\n", 53 | "####################################\n", 54 | "\n", 55 | "## All rates defined in units of 1/day ##\n", 56 | "\n", 57 | "beta = 0.0192 # infection rate constant\n", 58 | "gE = 1/2.72 # rate constant: Exposed to asymptomatic\n", 59 | "gA = 1/3.12 # rate constant: Activated to Infected\n", 60 | "gIa = 1/7 # rate constant: Asymptomatic to Recovery\n", 61 | "gIs = 1/7 \n", 62 | "\n", 63 | "\n", 64 | "#######################\n", 65 | "## Splitters ###\n", 66 | "#######################\n", 67 | "\n", 68 | "## Splitters are age-structured using the fitted form suggested by Jakub ##\n", 69 | "\n", 70 | "alpha = 0.66*np.exp(-age/50.5) # fraction of Activated that follow asymptomatic branch \n", 71 | "\n", 72 | "\n", 73 | "#######################\n", 74 | "## Modulators ##\n", 75 | "#######################\n", 76 | "\n", 77 | "fsa = 1.0 # Fraction by which symptomatic individuals do not self isolate" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "Nf = 1200\n", 87 | "Tf = 600\n", 88 | "\n", 89 | "S0 = Ni\n", 90 | "Ia0 = np.zeros((M))\n", 91 | "Ia0[2] += 5\n", 92 | "S0[2] -= 5\n", 93 | "\n", 94 | "Is0 = np.zeros((M))\n", 95 | "E0 = np.zeros((M))\n", 96 | "\n", 97 | "# instantiate model\n", 98 | "parameters = {'alpha':alpha,'beta':beta, 'gIa':gIa,'gIs':gIs,\n", 99 | " 'gE':gE, 'fsa':fsa} \n", 100 | "model = pyross.deterministic.SEIR(parameters, M, Ni)\n", 101 | "data = model.simulate(S0, E0, Ia0, Is0, contactMatrix, Tf, Nf)\n", 102 | "\n", 103 | "## Plot Results ##\n", 104 | "\n", 105 | "Infectious = np.sum((model.Is(data) + model.Ia(data)), axis=1) \n", 106 | "R = np.sum(model.R(data), axis=1)\n", 107 | "\n", 108 | "plt.figure(figsize=(12, 4)); plt.subplot(121) \n", 109 | "plt.semilogy(data['t'], Infectious/N, color = \"#A60628\", label = 'Infectious' ,lw = 2)\n", 110 | "plt.semilogy(data['t'], R/N, color = 'green', label = 'Recovered' ,lw = 2)\n", 111 | "plt.xlabel('time (days)'); \n", 112 | "plt.xlim(0,Tf); \n", 113 | "plt.ylim(1e-7,2)\n", 114 | "plt.ylabel('Fraction of compartment value'); \n", 115 | "plt.legend()\n", 116 | "plt.show() " 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": {}, 123 | "outputs": [], 124 | "source": [ 125 | "Nf = 1200\n", 126 | "Tf = 600\n", 127 | " \n", 128 | "# Initialise the model and find the fastest growing linear mode \n", 129 | "parameters = {'alpha':alpha,'beta':beta, 'gIa':gIa,'gIs':gIs,\n", 130 | " 'gE':gE, 'fsa':fsa} \n", 131 | "estimator = pyross.inference.SEIR(parameters, M, Ni)\n", 132 | "\n", 133 | "# Sets the contact matrix \n", 134 | "estimator.set_contact_matrix(contactMatrix)\n", 135 | "v = estimator.find_fastest_growing_lin_mode(0)\n", 136 | "\n", 137 | "# Find the coefficient of the fastest growing linear \n", 138 | "pert = np.zeros((M*4))\n", 139 | "pert[:M] = - (E0+Ia0+Is0)\n", 140 | "pert[M:2*M] = E0\n", 141 | "pert[2*M:3*M] = Ia0 \n", 142 | "pert[3*M:4*M] = Is0\n", 143 | "coeff = np.linalg.norm(pert, ord=1)\n", 144 | "\n", 145 | "\n", 146 | "# Find the Kreiss constant (good approximation when initial growth state is not yet reached)\n", 147 | "from scipy import sparse\n", 148 | "J = estimator.J_mat[M:, M:]\n", 149 | "eigval = sparse.linalg.eigs(J, k=1, which='LR')\n", 150 | "eigval = np.real(eigval[0])\n", 151 | "Jp = J - eigval*np.identity(J.shape[0])\n", 152 | "res = pyross.contactMatrix.characterise_transient(Jp, ord=1)\n", 153 | "K = np.real(res[2])\n", 154 | "\n", 155 | "# simulate with only the fastest growing linear mode \n", 156 | "zero_state = np.zeros((M*4))\n", 157 | "zero_state[:M] = Ni\n", 158 | "x0_approx = zero_state + coeff*v*K\n", 159 | "\n", 160 | "estimator.set_det_model(parameters)\n", 161 | "x = estimator.integrate(x0_approx, 0, Tf, Nf)\n", 162 | "\n", 163 | "\n", 164 | "# Plot Results \n", 165 | "\n", 166 | "x = np.array(x).reshape((Nf, 4, M))\n", 167 | "\n", 168 | "Infectious_approx = np.sum(np.sum(x[:, 2:, :], axis=1), axis=1)\n", 169 | "R_approx = np.sum(Ni - np.sum(x, axis=1), axis=1)\n", 170 | "\n", 171 | "print(R[-1] - R_approx[-1])\n", 172 | "\n", 173 | "plt.figure(figsize=(12, 4)); plt.subplot(121) \n", 174 | "plt.semilogy(data['t'], Infectious_approx/N, color = \"#A60628\", label = 'Approx I' ,lw = 2)\n", 175 | "plt.semilogy(data['t'], Infectious/N, label='I')\n", 176 | "plt.semilogy(data['t'], R_approx/N, color = 'green', label = 'Approx R' ,lw = 2)\n", 177 | "plt.semilogy(data['t'], R/N, label='R')\n", 178 | "plt.xlabel('time (days)') \n", 179 | "plt.xlim(0,Tf)\n", 180 | "plt.ylim(1e-7,2)\n", 181 | "plt.ylabel('Fraction of compartment value')\n", 182 | "plt.legend()\n", 183 | "plt.show() " 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": {}, 190 | "outputs": [], 191 | "source": [] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": null, 196 | "metadata": {}, 197 | "outputs": [], 198 | "source": [] 199 | } 200 | ], 201 | "metadata": { 202 | "kernelspec": { 203 | "display_name": "Python 3 (ipykernel)", 204 | "language": "python", 205 | "name": "python3" 206 | }, 207 | "language_info": { 208 | "codemirror_mode": { 209 | "name": "ipython", 210 | "version": 3 211 | }, 212 | "file_extension": ".py", 213 | "mimetype": "text/x-python", 214 | "name": "python", 215 | "nbconvert_exporter": "python", 216 | "pygments_lexer": "ipython3", 217 | "version": "3.10.9" 218 | } 219 | }, 220 | "nbformat": 4, 221 | "nbformat_minor": 4 222 | } 223 | -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/Population.csv: -------------------------------------------------------------------------------- 1 | Name,Pop 2 | E06000047,526980 3 | E06000005,106566 4 | E06000001,93242 5 | E06000002,140545 6 | E06000057,320274 7 | E06000003,136718 8 | E06000004,197213 9 | E11000007,1136371 10 | E08000037,202508 11 | E08000021,300196 12 | E08000022,205985 13 | E08000023,150265 14 | E08000024,277417 15 | E12000002,7292093 16 | E06000008,148942 17 | E06000009,139305 18 | E06000049,380790 19 | E06000050,340502 20 | E06000006,128432 21 | E06000007,209547 22 | E10000006,498888 23 | E07000026,97527 24 | E07000027,67137 25 | E07000028,108387 26 | E07000029,68424 27 | E07000030,52881 28 | E07000031,104532 29 | E11000001,2812569 30 | E08000001,285372 31 | E08000002,190108 32 | E08000003,547627 33 | E08000004,235623 34 | E08000005,220001 35 | E08000006,254408 36 | E08000007,291775 37 | E08000008,225197 38 | E08000009,236370 39 | E08000010,326088 40 | E10000017,1210053 41 | E07000117,88527 42 | E07000118,116821 43 | E07000119,79770 44 | E07000120,80815 45 | E07000121,144246 46 | E07000122,91405 47 | E07000123,141818 48 | E07000124,60057 49 | E07000125,70895 50 | E07000126,110527 51 | E07000127,113949 52 | E07000128,111223 53 | E11000002,1423065 54 | E08000011,149571 55 | E08000012,494814 56 | E08000014,275396 57 | E08000013,180049 58 | E08000015,323235 59 | E12000003,5479615 60 | E06000011,339614 61 | E06000010,260645 62 | E06000012,159821 63 | E06000013,172005 64 | E06000014,209893 65 | E10000023,614505 66 | E07000163,56832 67 | E07000164,91134 68 | E07000165,160533 69 | E07000166,53244 70 | E07000167,54920 71 | E07000168,108736 72 | E07000169,89106 73 | E11000003,1402918 74 | E08000016,245199 75 | E08000017,310542 76 | E08000018,264671 77 | E08000019,582506 78 | E11000006,2320214 79 | E08000032,537173 80 | E08000033,210082 81 | E08000034,438727 82 | E08000035,789194 83 | E08000036,345038 84 | E12000004,4804149 85 | E06000015,257174 86 | E06000016,355218 87 | E06000018,331069 88 | E06000017,39697 89 | E10000007,796142 90 | E07000032,126678 91 | E07000033,79530 92 | E07000034,104628 93 | E07000035,71977 94 | E07000036,115490 95 | E07000037,92221 96 | E07000038,101125 97 | E07000039,104493 98 | E10000018,698268 99 | E07000129,100421 100 | E07000130,182643 101 | E07000131,92499 102 | E07000132,112423 103 | E07000133,51100 104 | E07000134,102126 105 | E07000135,57056 106 | E10000019,755833 107 | E07000136,69366 108 | E07000137,140741 109 | E07000138,99039 110 | E07000139,115985 111 | E07000140,93980 112 | E07000141,141853 113 | E07000142,94869 114 | E10000021,747622 115 | E07000150,70827 116 | E07000151,84484 117 | E07000152,93906 118 | E07000153,101266 119 | E07000154,225146 120 | E07000155,92515 121 | E07000156,79478 122 | E10000024,823126 123 | E07000170,127151 124 | E07000171,116839 125 | E07000172,113272 126 | E07000173,117786 127 | E07000174,108841 128 | E07000175,121566 129 | E07000176,117671 130 | E12000005,5900757 131 | E06000019,192107 132 | E06000051,320274 133 | E06000021,255833 134 | E06000020,177799 135 | E10000028,875219 136 | E07000192,100109 137 | E07000193,118574 138 | E07000194,103965 139 | E07000195,129490 140 | E07000196,112126 141 | E07000197,135880 142 | E07000198,98397 143 | E07000199,76678 144 | E10000031,571010 145 | E07000218,64850 146 | E07000219,128902 147 | E07000220,107194 148 | E07000221,127580 149 | E07000222,142484 150 | E11000005,2916458 151 | E08000025,1141374 152 | E08000026,366785 153 | E08000027,320626 154 | E08000028,327378 155 | E08000029,214909 156 | E08000030,283378 157 | E08000031,262008 158 | E10000034,592057 159 | E07000234,98662 160 | E07000235,78113 161 | E07000236,84989 162 | E07000237,101891 163 | E07000238,127340 164 | E07000239,101062 165 | E12000006,6201214 166 | E06000055,171623 167 | E06000056,283606 168 | E06000032,214109 169 | E06000031,201041 170 | E06000033,182463 171 | E06000034,172525 172 | E10000003,651482 173 | E07000008,125758 174 | E07000009,89362 175 | E07000010,101491 176 | E07000011,177352 177 | E07000012,157519 178 | E10000012,1477764 179 | E07000066,185862 180 | E07000067,151561 181 | E07000068,76550 182 | E07000069,90070 183 | E07000070,177079 184 | E07000071,192523 185 | E07000072,131137 186 | E07000073,86594 187 | E07000074,64425 188 | E07000075,86981 189 | E07000076,145803 190 | E07000077,89179 191 | E10000015,1184365 192 | E07000095,96876 193 | E07000096,154280 194 | E07000242,148105 195 | E07000098,104205 196 | E07000099,133214 197 | E07000240,147373 198 | E07000243,87754 199 | E07000102,93045 200 | E07000103,96767 201 | E07000241,122746 202 | E10000020,903680 203 | E07000143,139329 204 | E07000144,129464 205 | E07000145,99370 206 | E07000146,151811 207 | E07000147,104552 208 | E07000148,141137 209 | E07000149,138017 210 | E10000029,758556 211 | E07000200,91401 212 | E07000244,248249 213 | E07000202,137532 214 | E07000203,102493 215 | E07000245,178881 216 | E12000007,8908081 217 | E09000007,262226 218 | E09000001,8706 219 | E09000012,279665 220 | E09000013,185426 221 | E09000014,270624 222 | E09000019,239142 223 | E09000020,156197 224 | E09000022,325917 225 | E09000023,303536 226 | E09000025,352005 227 | E09000028,317256 228 | E09000030,317705 229 | E09000032,326474 230 | E09000033,255324 231 | E09000002,211998 232 | E09000003,392140 233 | E09000004,247258 234 | E09000005,330795 235 | E09000006,331096 236 | E09000008,385346 237 | E09000009,341982 238 | E09000010,333869 239 | E09000011,286186 240 | E09000015,250149 241 | E09000016,257810 242 | E09000017,304824 243 | E09000018,270782 244 | E09000021,175470 245 | E09000024,206186 246 | E09000026,303858 247 | E09000027,196904 248 | E09000029,204525 249 | E09000031,276700 250 | E12000008,9133625 251 | E06000036,121676 252 | E06000043,290395 253 | E06000046,141538 254 | E06000035,277855 255 | E06000042,268607 256 | E06000044,215133 257 | E06000038,163203 258 | E06000039,149112 259 | E06000045,252796 260 | E06000037,158527 261 | E06000040,150906 262 | E06000041,167979 263 | E10000002,540059 264 | E07000004,199448 265 | E07000005,95927 266 | E07000006,70043 267 | E07000007,174641 268 | E10000011,554590 269 | E07000061,103160 270 | E07000062,92855 271 | E07000063,102744 272 | E07000064,95656 273 | E07000065,160175 274 | E10000014,1376316 275 | E07000084,175729 276 | E07000085,120681 277 | E07000086,131819 278 | E07000087,116339 279 | E07000088,85283 280 | E07000089,96293 281 | E07000090,125813 282 | E07000091,179753 283 | E07000092,95142 284 | E07000093,125169 285 | E07000094,124295 286 | E10000016,1568623 287 | E07000105,129281 288 | E07000106,164553 289 | E07000107,109709 290 | E07000108,116969 291 | E07000112,112578 292 | E07000109,106385 293 | E07000110,169955 294 | E07000111,120293 295 | E07000113,148519 296 | E07000114,141819 297 | E07000115,130508 298 | E07000116,118054 299 | E10000025,687524 300 | E07000177,149161 301 | E07000178,154327 302 | E07000179,140504 303 | E07000180,133732 304 | E07000181,109800 305 | E10000030,1189934 306 | E07000207,136626 307 | E07000208,79928 308 | E07000209,147889 309 | E07000210,87253 310 | E07000211,147757 311 | E07000212,88000 312 | E07000213,99334 313 | E07000214,88874 314 | E07000215,87496 315 | E07000216,125610 316 | E07000217,101167 317 | E10000032,858852 318 | E07000223,63869 319 | E07000224,159827 320 | E07000225,120750 321 | E07000226,112448 322 | E07000227,142217 323 | E07000228,149716 324 | E07000229,110025 325 | E12000009,5599735 326 | E06000022,192106 327 | E06000058,395784 328 | E06000023,463405 329 | E06000052,565968 330 | E06000059,376484 331 | E06000053,2242 332 | E06000024,213919 333 | E06000026,263100 334 | E06000025,282644 335 | E06000030,221996 336 | E06000027,135780 337 | E06000054,498064 338 | E10000008,795286 339 | E07000040,144317 340 | E07000041,130428 341 | E07000042,81695 342 | E07000043,96110 343 | E07000044,86221 344 | E07000045,132844 345 | E07000046,68143 346 | E07000047,55528 347 | E10000013,633558 348 | E07000078,117090 349 | E07000079,89022 350 | E07000080,86543 351 | E07000081,129285 352 | E07000082,119019 353 | E07000083,92599 354 | E10000027,559399 355 | E07000187,114881 356 | E07000188,122791 357 | E07000246,153866 358 | E07000189,167861 359 | W92000004,3138631 360 | W06000001,69961 361 | W06000002,124178 362 | W06000003,117181 363 | W06000004,95330 364 | W06000005,155593 365 | W06000006,136126 366 | W06000023,132447 367 | W06000008,72992 368 | W06000009,125055 369 | W06000010,187568 370 | W06000011,246466 371 | W06000012,142906 372 | W06000013,144876 373 | W06000014,132165 374 | W06000015,364248 375 | W06000016,240131 376 | W06000024,60183 377 | W06000018,181019 378 | W06000019,69713 379 | W06000020,93049 380 | W06000021,94142 381 | W06000022,153302 382 | S92000003,5438100 383 | S12000033,227560 384 | S12000034,261470 385 | S12000041,116040 386 | S12000035,86260 387 | S12000036,518500 388 | S12000005,51400 389 | S12000006,148790 390 | S12000042,148750 391 | S12000008,121840 392 | S12000045,108330 393 | S12000010,105790 394 | S12000011,95170 395 | S12000014,160340 396 | S12000047,371910 397 | S12000049,626410 398 | S12000017,235540 399 | S12000018,78150 400 | S12000019,91340 401 | S12000020,95520 402 | S12000013,26830 403 | S12000021,135280 404 | S12000050,340180 405 | S12000023,22190 406 | S12000048,151290 407 | S12000038,177790 408 | S12000026,115270 409 | S12000027,22990 410 | S12000028,112550 411 | S12000029,319020 412 | S12000030,94330 413 | S12000039,89130 414 | S12000040,182140 415 | -------------------------------------------------------------------------------- /examples/deterministic/contactMatrix/ex09_custom_temporal_protocol.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import numpy as np\n", 10 | "import pyross\n", 11 | "from matplotlib import pyplot as plt " 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 3, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# Get individual contact matrices\n", 21 | "CH, CW, CS, CO = pyross.contactMatrix.UK()\n", 22 | "\n", 23 | "# Generate class with contact matrix for SIR model with UK contact structure\n", 24 | "generator = pyross.contactMatrix.ContactMatrixFunction(CH, CW, CS, CO)" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 13, 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "data": { 34 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8li6FKAAASMElEQVR4nO3df4wcZR3H8d3etUiLenf2NNhebU0qUo0gHgV/o6i0YKwaE1tUlGiaRqpoTKTGqDH+ZfwRfxWaBiv+IDQGCFY8rUZR/jBor4qVUotnEVqL9vB6BXsoPTp+vstzcVx292avszfzPM/7lXwzu7Nz15ne3qdPn535TjVJkgoAwH9zit4BAEA+CHQACASBDgCBINABIBAEOgAEoruoP3jhwoXJ0qVLi/rjAcBLu3fvflhnJ/aXKtAtzIeHh4v64wHAS9Vq9YFmrzHlAgCBINABIBAEOgAEgkAHgEAQ6AAQS6DrE9VtqiOqe5q8br6mGlHtUZ2X/24CAPIYod+gWtXi9dWq5a7Wq67L8D0BADmb9jx0ncB+p0bdra4AWqP6TvJkH967tG2P6kw9fSi3vUzZ//dHKz/ac7gT3xoRee1Z/ZWXPa+v6N0AcpXHhUWLVAdTzw+5dU8JdAW9jeCtKkuWLJnRHzZy5F+Vr98xMqOvBYwNPe46MFb5/oaX8xeCoOQR6NUG6xreNUOj9q1aWFUGBwdndGeNy15ypuqymXwpUPPBG3fX/qcHhCaPs1xsRD6Qer5YxZwISqt3/rzK+MSJoncDKGWg71Bd4c52uVCPj3Vq/hzIQ9+CeZWjE49XTp7k9ouIbMpFIX2TFhepFuqxjcY/o5prrym4t2gxpLpUZRPbE6orO7a3QA56NEK3LH/k3ydqj4GYznJZN83rNsy5Krc9Ajqsb0FtPKJROoGOsHClKKKcQzdjxx8veE+AfBHoiHIO3Rwl0BEYAh3RjtDtg1EgJAQ6otM7NUIn0BEYAh3RWTCvqzKva47m0DkXHWEh0BEdnX6r0xXnMoeO4BDoiPriIiAkBDqi/WCUQEdoCHREO0LnPHSEhkBHlGwOnQZdCA2BjijRoAshItAR7Rz6VIMuIBQEOqLU6xp0MY+OkBDoiPzyf0boCAeBjijRoAshItARdwtdLi5CQAh0RN2ga5xAR0AIdESJBl0IEYGOaBt02Zku3OQCISHQES36uSA0BDqiRaAjNAQ6okWDLoSGQEe0aje54MIiBIRAR9QjdDtt8aQ1dQECQKAjWjToQmgIdFRiv/yfBl0IBYGOqOfQDfPoCAWBjmjRoAuhIdARLRp0ITQEOiqxN+ji8n+EgkBHJfYGXcyhI6pAr1arq1T7VSOqTQ1ef6bqh6o/qPaqrsx/V4F80aAL0QW63vRdWmxWrVatUK3TOlumXaW6N0mSc7S8SPUlbfPk/2eBks+jc5MLxDRCX6kaUVgfUD2ux9tVa+q2sUvtnq4Qr2p5hmpMNZnrngIdCnRucoGYAn2R6mDq+SG3Lu0bqrNVh1V/VF2t8D9Z/42U9+tVw1ajo6Mz3GUgPzToQmyBbqPuevXNLy5R3a16rupc1TcU2s94yhclyVbVoFV/f3/bOwvkrXaTCxp0IaJAtxH5QOr5YjcST7MPQW9VUJsRPb5f9cJ8dhHo/JQLDboQS6DvUi3XiHuZ+6BzrWpH3TYPqi62B9rmOVqcpTqQ544CnUCDLoSke7oNNOKeVEhv1MOdKjvjZZvW2amJG9zrW7T4nOoGrfujm6K5Rusf7uB+A7k36OrRaB0IOtCNwnlIi6G6dRbkU49tCuZN+e4aMJsNuuwELsBvXCmKqP2vQdeJgvcEOHUEOqJGgy6EhEBH1Gihi5AQ6IjafBp0ISAEOqJGgy6EhEBH9GjQhVAQ6IieBTo3uUAICHREzz4Y5Tx0hIBAR/Ro0IVQEOiIXh8NuhAIAh3Rsx4uJ5NK5ZF/c7Uo/EagI3rpBl2Azwh0RK93qp8LDbrgOQId0et1HRfHaNAFzxHoiN5Ugy5G6PAdgY7o0aALoSDQEb1ag67uOZUx5tDhOQId0as16NI8+jhz6PAcgQ4IDboQAgIdmOrnwnno8ByBDggjdISAQAdcg67xCS79h98IdCDVoOsJa+oCeIpAB9INuh5jlA5/EehA+uIizkWHxwh0QGjQhRAQ6ICbQzc06ILPCHRAelzHRaZc4DMCHRAadCEEBDogNOhCNIFerVZXqfarRlSbmmxzkepu1V7Vr/LdTWB2GnRx+T981p3hjd6lxWbVG1WHVLu0bkeSJPemtunR4lrVKq1/UM+f3akdBjp5+f9RrhZF4CP0laoRBfUBld1Fd7tqTd02l6tutTC3J1oeyXc3gc6jQRdiCPRFqoOp54fcurQXqHo1Mv+larfqikbfSOvXq4atRkdHZ7bHQAfPRecmFwg90KsN1iUNpm5eprpMdYnqUwrtFzzli5Jkq2rQqr+/v+2dBTqpdpMLplwQ8hy6G5EPpJ4vVh1usM3DCurjWh5XmN+p5Tmq+3LZS2CWG3R1zWk0jgH8H6HvUi1XSC9T2eV0a1U76rb5gerVer1bNV+PL1Dty3dXgc5PudCgC0GP0DXqnlRIb9TDnSo742Wb1tmpiRvc61tU+/T8J3q6R3VSdb3W3dPJHQc6cZaLsXn0qd4uQGhTLhbaQ1oM1a3bUvf8C1pYAV6aCnGbdgF8xJWigEODLviOQAdSt6EzXC0KXxHoQN0cOh0X4SsCHXBo0AXfEehAqkGXzaMz5QJfEehA3Y0uaNAFXxHoQAoNuuAzAh1IoUEXfEagAync5AI+I9CBFPtQ9NhjJ2oNugDfEOhACg264DMCHaj7UNRwowv4iEAHUnrc1aI06IKPCHQghQZd8BmBDqTQoAs+I9CBJje5AHxDoAMNGnTRcRE+ItCBFBp0wWcEOtDo8v/jJ/h7gXcIdKDB5f+ctggfEehAHRp0wVcEOlCHm1zAVwQ60GjKhQZd8BCBDjSYckmSSuURhTrgEwIdqEODLviKQAeaNOjiZtHwDYEONGnQxc2i4RsCHahDgy74ikAH6jCHDl8R6ECd0+fSoAt+ItCBOjToQtCBrjf4KtV+1YhqU4vtzlc9oXpHfrsIzD4adCHIQFc4d2mxWbVatUK1TutWNNnu86qdee8kUMTVovRER4gj9JWqkSRJDqjsNi7bVWsabPch1S2qIznuH1DYCJ1AR4iBvkh1MPX8kFuXHp3b87eptrT6RtpuvWrYanR0tN19BWYNDboQaqBXG6xL6p5/RXWNRvBPtPpGen2ratCqv78/6z4ChYzQadAF33Rn2MZG5AOp54tVh+u2GVRtt7MDZKHqUj2eVHDflsteAgXMoU816LJwB0IJ9F2q5QroZVr+TbVWdXl6AwW3vVaj7W7Q4nbCHKFcXESgI5hAVzBPKqQ3urNX7EyWbVq3V+s2uNdbzpsDPupNN+hidhABjdAttIe0GKpb1zDItf59OewXUIpAH7NABzzBlaJAiwZd4xPc5AL+INCBBmjQBR8R6ECTBl2ndc/hJhfwCoEONGCn4No8OleLwicEOtAEDbrgGwIdaKJPH4wyQodPCHSgxc2iCXT4hEAHmqBBF3xDoANN0KALviHQgWkadB17jIuL4AcCHZjm4iLm0eELAh3I0qAL8ACBDkx3+T+BDk8Q6EATPZpDNzTogi8IdKAJGnTBNwQ60AQNuuAbAh2YpkEXc+jwBYEOTHNx0VFucgFPEOhACzTogk8IdKCFWk90TluEJwh0oAVucgGfEOhACzTogk8IdKCFPhp0wSMEOjDNCN1w6iJ8QKADGRp0jU/QoAvlR6ADLdCgCz4h0IEMDbroiQ4fEOhApptccNcilB+BDrRAgy74hEAHpmnQZaN0znJBMIGuN/Uq1X7ViGpTg9ffpdrj6teqc/LfVaAYPXb5P1MuCCHQFc5dWmxWrVatUK3TOlum3a96bZIkL9Hyc6qtee8oUBQadCGkEfpK1YjC+oDKTsbdrlqT3kDrf6066p7epVqc724CxaFBF0IK9EWqg6nnh9y6Zt6v+nGjFzSyX68athodHc2+l0CBaje54MIiBBLo1QbrkoYbVquvc4F+TaPXNYrfqhq06u/vz76XQMGX/x977ETliZMN3/aAV4FuI/KB1HObTjncIMxt/vx61RoF9j/z2T2geDToQkiBvku1XIG9TGVXWaxV7UhvoPVLtLhV9R6F+X357yZQHBp0wRfd022ggJ5UYG/Uw50qO+Nlm9bt1boN7vUtWnxa9SzVtXberkzatErndhuYPTToQjCBbhTOQ1oM1a2zIJ96/AEtrIDg0KALvuBKUSDjlAsNulB2BDowjV7XcXHsOA26UG4EOpCxQRc3uUDZEejANGjQBV8Q6EDWy/+5WhQlR6ADGfQumEvHRZQegQ5kQIMu+IBABzKo3eSCKReUHIEOZLzJBQ26UHYEOpABDbrgAwIdyIAGXfABgQ600aCLUxdRZgQ60EaDrqPH7S6MQDkR6EAGNOiCDwh0IIM+N+VCgy6UGYEOZHD6PBp0ofwIdKCdi4uYQ0eJEehARjToQtkR6EAbDboYoaPMCHSgjRH6+AR3LUJ5EehARjToQtkR6EAbI3QadKHMCHSgjZtFJ0mlFupAGRHoQEY06ELZEehAu/1cuNEFSopAB9rsuMipiygrAh1oc8plnBE6SopABzKiQRfKjkAH2mjQ9bS5c5hDR2kR6EC7/Vxo0IWSItCBNtCgC94HerVaXaXarxpRbWrwuvmae32P6rz8dxUoHi104XWgK5y7tNisWq1aoVqndbZMs9eWu1qvui7n/QRKoWf+XBp0obS6M2yzUjWSJMkBe6Iw367FGtW9qW3s+Xe0TaLlXdqmR3Wmnj6U+x4DBY/QHxibqLzxy7/i54AZe+f5A5UPvPr5M/76Uwn0RaqDqeeHVBdk2MbW/V+gK+Rt9G5VWbJkSbv7ChTu7ectrvxTH4o+OXYBZmbhGafN7AtzCPRqg3X17+Ys29gvwVYtrCqDg4P8RsA75w70VDZfzkdE8PdDURttD6SeL1YdnsE2AICCA32XarmmS5ap7NrntaodddvY8yvc2S4X6vEx5s8BYHZNO+WiYJ5USG/Uw50qO+Nlm9bt1boN7vUtWgypLlWNqCZUV3ZulwEAM51Dt9C2wB6qW2dBPvXY5sOvyvK9AACdwZWiABAIAh0AAkGgA0AgCHQACES1qCvedJbMqBYPzPDLF6oeznF3fMAxx4GfcxwWnkKGPU+53V+qQD/FfwyGtd+DRe/HbOKY48DPOQ7VDmUYUy4AEAgCHQAC4Wug1xp8RYZjjgM/5zhs7cQ39XIOHQAQzggdAFCHQAeAQMzx8HSfljesDoGOa0B1h2qfyjpbXu3W96l+pvqzW/YWva950vF0qX6vuj2S47VbNd6s+pP7Wb88gmP+qHtP36O6SfW00I65Wq1uUx1R3ZNa1/QY9fgTLs8s1y6JJtAz3rA6BJOqj+nzjbO1tP7yV7njtH/Afq71djPun7vnIbF/uPalnod+vF9V/UTH90Itz3HHHuwx6z1st6X8sGpQx/diLbvc/RVCO+YbVKvq1jU8Rvd7bX8HL3Jfc63LufADPX3DatXjejx1w+qg2M1BVL9zjx91v+iL3LF+221my7cWs4f505vY7nJ1mer61OqQj/cZWrxG9U17bu9n1XjIx5xq2X26jt+W892dzYI65iRJ7tRirG51s2O09dv1Nf9R3e/uKWE5F0WgN7sZdbD0xl+qxUtVv1E9Rz/02o233fLZRe5bzr6i+rjqZGpdyMdrt3y39hffctNM16sWhHzMOp6/afFF1YOqh9ydzX4a8jGnNDvGXDPNt0DPdDPqUOgX/AwtblF9RG+CR4renw4e55u1OKJj3F30vswiG6Ha3aav03HbP9jHA5hqaMnNG9uIdJnquaoFWvfuYvcqrEzzLdCjuRm13uhzXZjfqF/4W93qf2j9me51Wx4pav9y9krVW3RMf3XTaK/X4+8FfLxT7+VD+tna/7zMzS7gQz7mN6ju1zGPqk7osb2vXxH4MU9pdoy5ZppvgZ7lhtXe07FV3dzqPr3xv5x6yY71ve6xLX8w2/vWCTrGT6gWq5a6n+kv9PjdoR6v0fH9XYuD+lGf5VZdrLo35GN2Uy0X6pjnu/f4xe7zoZCPeUqzY7T1a/XXcZrlmh7bh6a/nfqimbyxvCp3M+r7VH9RfbLo/enQMb7KfjSqPaq7XdlxP8t9Qv5nt+wL8NgvUt3uHgd9vHKuatj9nG9T9UZwzJ9V/Ullp/R9V3VaaMcsN6lsnvyEG4G/v9Uxyiddnu1XrT6VP5tL/wEgEL5NuQAAmiDQASAQBDoABIJAB4BAEOgAEAgCHQACQaADQCD+C3UjBbpj5pDYAAAAAElFTkSuQmCC\n", 35 | "text/plain": [ 36 | "
" 37 | ] 38 | }, 39 | "metadata": { 40 | "needs_background": "light" 41 | }, 42 | "output_type": "display_data" 43 | } 44 | ], 45 | "source": [ 46 | "# Define a tanh protocol for aW, aS, aO \n", 47 | "def approx_tanh(t, width, loc):\n", 48 | " cond1 = (t < loc-width/2)\n", 49 | " cond2 = (t >= loc+width/2)\n", 50 | " cond3 = np.logical_and((t < loc+width/2), (t >= loc-width/2))\n", 51 | " cond_list = [cond1, cond2, cond3]\n", 52 | " fun_list = [-1, 1, lambda t: 2*(t-loc)/width]\n", 53 | " return np.piecewise(t, cond_list, fun_list)\n", 54 | " \n", 55 | "def intervention_fun(t, M, width=1, loc=0, aW_f=0, aS_f=0, aO_f=0):\n", 56 | " aW = (1-approx_tanh(t, width, loc))/2*(1-aW_f) + aW_f\n", 57 | " aS = (1-approx_tanh(t, width, loc))/2*(1-aS_f) + aS_f\n", 58 | " aO = (1-approx_tanh(t, width, loc))/2*(1-aO_f) + aO_f\n", 59 | " aW_full = np.full((2, M), aW)\n", 60 | " aS_full = np.full((2, M), aS)\n", 61 | " aO_full = np.full((2, M), aO)\n", 62 | " return aW_full, aS_full, aO_full\n", 63 | "\n", 64 | "width = 5\n", 65 | "loc = 50 \n", 66 | "time_points = np.linspace(0, 100, 1001)\n", 67 | "aW = np.empty((1001,), dtype='float')\n", 68 | "for (i, t) in enumerate(time_points): \n", 69 | " aW[i] = intervention_fun(t, 16, width=width, loc=loc)[0][0, 0]\n", 70 | "plt.plot(time_points, aW)\n", 71 | "plt.show()" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 15, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "contactMatrix = generator.intervention_custom_temporal(intervention_fun, width=width, loc=loc)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 16, 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/plain": [ 91 | "True" 92 | ] 93 | }, 94 | "execution_count": 16, 95 | "metadata": {}, 96 | "output_type": "execute_result" 97 | } 98 | ], 99 | "source": [ 100 | "# compare: initially, all contacts \n", 101 | "(CH + CW + CS + CO == contactMatrix(0)).all()" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 17, 107 | "metadata": {}, 108 | "outputs": [ 109 | { 110 | "data": { 111 | "text/plain": [ 112 | "True" 113 | ] 114 | }, 115 | "execution_count": 17, 116 | "metadata": {}, 117 | "output_type": "execute_result" 118 | } 119 | ], 120 | "source": [ 121 | "# compare: in the end, only home contacts \n", 122 | "(CH == contactMatrix(100)).all()" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "execution_count": null, 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [] 131 | } 132 | ], 133 | "metadata": { 134 | "kernelspec": { 135 | "display_name": "Python 3", 136 | "language": "python", 137 | "name": "python3" 138 | }, 139 | "language_info": { 140 | "codemirror_mode": { 141 | "name": "ipython", 142 | "version": 3 143 | }, 144 | "file_extension": ".py", 145 | "mimetype": "text/x-python", 146 | "name": "python", 147 | "nbconvert_exporter": "python", 148 | "pygments_lexer": "ipython3", 149 | "version": "3.7.7" 150 | } 151 | }, 152 | "nbformat": 4, 153 | "nbformat_minor": 4 154 | } 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Imagel](https://raw.githubusercontent.com/rajeshrinet/pyross/master/examples/others/banner.jpg) 2 | 3 | 4 | ## PyRoss: inference, forecasts, and optimised control for epidemiological models in Python [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/rajeshrinet/pyross/master?filepath=binder) ![CI](https://github.com/rajeshrinet/pyross/workflows/CI/badge.svg) ![Notebooks](https://github.com/rajeshrinet/pyross/workflows/Notebooks/badge.svg) [![PyPI](https://img.shields.io/pypi/v/pyross.svg)](https://pypi.python.org/pypi/pyross) [![Python Version](https://img.shields.io/pypi/pyversions/pyross)](https://pypi.org/project/pyross) [![Downloads](https://pepy.tech/badge/pyross)](https://pepy.tech/project/pyross) ![stars](https://img.shields.io/github/stars/rajeshrinet/pyross) ![forks](https://img.shields.io/github/forks/rajeshrinet/pyross) ![License](https://img.shields.io/github/license/rajeshrinet/pyross) 5 | 6 | 7 | [About](#about) | 8 | [Documentation](https://pyross.readthedocs.io/en/latest/) | 9 | [Examples](#examples) | 10 | [Installation](#installation) | 11 | [Publications ](#publications) | 12 | 13 | 14 | 15 | ## About 16 | 17 | [PyRoss](https://github.com/rajeshrinet/pyross) is a numerical library that offers an integrated platform for **inference**, **forecasts** and **non-pharmaceutical interventions** in structured epidemiological compartment models. 18 | 19 | **Compartment models** of arbitrary complexity can be **user-defined** through Python dictionaries. The most common epidemiological models, and several less common ones, come pre-defined with the library. Models can include **stages** to allow for non-exponentially distributed compartmental residence times. Currently, [pre-defined models](https://github.com/rajeshrinet/pyross/blob/master/docs/models.pdf) include ones with multiple disease states (exposed, asymptomatic, symptomatic, etc) and may be further divided by age, and by objective medical states (hospitalized, in ICU, etc). The compartment framework supports models for **disease surveillance** and **quarantine** and a variety of other processes of epidemiological relevance. 20 | 21 | **Generative processes** can be formulated **stochastically** (as Markov population processes) or **deterministically** (as systems of differential equations). Population processes are sampled exactly by the Doob-Gillespie algorithm or approximately by the tau-leaping algorithm while differential equations are integrated by both fixed and adaptive time-stepping. A **hybrid algorithm** transits dynamically between these depending on the magnitude of the compartmental fluctuations. 22 | 23 | **Bayesian inference** on pre-defined or user-defined models is performed using model-adapted **Gaussian processes** derived from **functional limit theorems** for Markov population process. Generative models are fitted to data through the surveillance model allowing for possibily **unobserved** compartments. The **MAP** estimates of parameters and their standard errors can be obtained rapidly by optimising, obviating the need for expensive Markov chain Monte Carlo. This enables the fast evaluation of the **model evidence**, through which competing models may be **objectively compared** and their forecasts combined by **Bayesian model averaging**. Forecasts of disease progression, then, can be **fully Bayesian**, convolving uncertainties in data, parameters and models. The sensitivity of these forecasts is estimated through the **Fisher information matrix**. 24 | 25 | **Non-pharmaceutical interventions** are implemented as modifications of the **contact structures** of the model. **Optimised control** of these structures, given **cost functions**, is possible. 26 | 27 | [PyRossGeo](https://github.com/lukastk/PyRossGeo) is a companion library that supports **spatially resolved compartment models** with explicit **commuting networks**. 28 | 29 | The libraries are named after [Sir Ronald Ross](https://en.wikipedia.org/wiki/Ronald_Ross), doctor, mathematician and poet. In 1898 he made "the great discovery" in his laboratory in Calcutta "that malaria is conveyed by the bite of a mosquito". He won the Nobel Prize in 1902 and laid the foundations of the mathematical modelling of infectious diseases. 30 | 31 | 32 | The library was developed as a part of [The Rapid Assistance in Modelling the Pandemic (RAMP)](https://royalsociety.org/news/2020/03/urgent-call-epidemic-modelling/) taskforce at the **University of Cambridge**. In alphabetical order, the authors are: 33 | [Ronojoy Adhikari](https://github.com/ronojoy), 34 | [Austen Bolitho](https://github.com/TakodaS), 35 | [Erik Brorson](https://github.com/erikbrorson), 36 | [Fernando Caballero](https://github.com/fcaballerop), 37 | [Michael Cates](http://www.damtp.cam.ac.uk/person/mec22), 38 | [Jakub Dolezal](https://github.com/JakubJDolezal), 39 | [Tim Ekeh](https://github.com/tekeh), 40 | [Jules Guioth](https://orcid.org/0000-0001-5644-3044), 41 | [Robert Jack](https://github.com/rljack2002), 42 | [Julian Kappler](https://github.com/juliankappler), 43 | [Lukas Kikuchi](https://github.com/lukastk), 44 | [Hideki Kobayashi](https://github.com/hidekb), 45 | [Irene Li](https://github.com/Irene-Li), 46 | [Joseph Peterson](https://github.com/jdpeterson3/), 47 | [Patrick Pietzonka](https://github.com/ppietzonka), 48 | [Benjamin Remez](https://github.com/BenjaminRemez), 49 | [Paul Rohrbach](https://github.com/prohrbach), 50 | [Rajesh Singh](https://github.com/rajeshrinet), 51 | and [Günther Turk](https://github.com/phi6GTurk). 52 | PyRoss development was also partially supported by a [Microsoft Research Award](https://www.microsoft.com/en-us/research/collaboration/studies-in-pandemic-preparedness/#!projects) for "Building an open platform for pandemic modelling". 53 | 54 | Please read the [PyRoss paper](https://arxiv.org/abs/2005.09625) and [PyRoss Wiki](https://github.com/rajeshrinet/pyross/wiki/) before you use PyRoss for your research. [Open an issue](https://github.com/rajeshrinet/pyross/issues), in preference to emailing us with queries. Join our [Slack channel](https://join.slack.com/t/pyross/shared_invite/zt-e8th6kcz-S4b_oJIZWPsGLruSPl3Zuw) for discussion. Please follow the [Contributor Covenant](https://www.contributor-covenant.org/version/2/0/code_of_conduct/) in all PyRoss fora. Thank you! 55 | 56 | ## Installation 57 | You can take PyRoss for a spin **without installation**: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/rajeshrinet/pyross/master?filepath=binder). Please be patient while [Binder](https://mybinder.org/v2/gh/rajeshrinet/pyross/master?filepath=binder) loads. 58 | 59 | ### From a checkout of PyRoss GitHub repository 60 | This is the recommended way as it downloads a whole suite of examples along with the package. 61 | 62 | #### Install PyRoss and an extended list of dependencies using 63 | 64 | ```bash 65 | >> git clone https://github.com/rajeshrinet/pyross.git 66 | >> cd pyross 67 | >> pip install -r requirements.txt 68 | >> python setup.py install 69 | ``` 70 | 71 | #### Install PyRoss and an extended list of dependencies, via [Anaconda](https://docs.conda.io/projects/continuumio-conda/en/latest/user-guide/install/index.html), in an [environment](https://github.com/rajeshrinet/pyross/blob/master/environment.yml) named `pyross`: 72 | 73 | ```bash 74 | >> git clone https://github.com/rajeshrinet/pyross.git 75 | >> cd pyross 76 | >> make env 77 | >> conda activate pyross 78 | >> make 79 | ``` 80 | 81 | ### Via pip 82 | 83 | Install the latest [PyPI](https://pypi.org/project/pyross) version 84 | 85 | ```bash 86 | >> pip install pyross 87 | ``` 88 | 89 | 90 | 91 | 92 | ### Testing 93 | Short test of initialisation and running 94 | 95 | ```bash 96 | >> make test 97 | ``` 98 | 99 | Long test of all example notebooks. Optionally can specify path and recursion 100 | to test a certain subset of notebooks 101 | 102 | ```bash 103 | >> make nbtest -e path=examples/deterministic/ 104 | ``` 105 | 106 | 107 | 108 | ## Examples 109 | 110 | PyRoss has model-agnostic, formulation-agnostic intuitive interface. Once a model is instantiated, stochastic, deterministic and hybrid simulations can be performed through the same interface. The example below shows how to set up a deterministic SIR simulation with three age-groups. 111 | 112 | ```Python 113 | # SIR with three age-groups (M=3) 114 | 115 | import numpy as np 116 | import pyross 117 | import matplotlib.pyplot as plt 118 | 119 | 120 | model_spec = { "classes" : ["S", "I"], 121 | 122 | "S" : {"infection" : [ ["I","S", "-beta"] ]}, ## the I class passes infection to S class 123 | "I" : { "linear" : [ ["I", "-gamma"] ], ## this is recovery process for I class 124 | "infection" : [ ["I", "S", "beta"]]} 125 | 126 | ## the recovered class R is internally determined by number conservation 127 | } 128 | 129 | 130 | parameters = {'beta' : 0.1, 131 | 'gamma' : 0.1, 132 | } 133 | 134 | M=3; Ni=1000*np.ones(M); N=np.sum(Ni) 135 | 136 | 137 | # Initial conditions as an array 138 | x0 = np.array([ 139 | 980, 980, 980, # S 140 | 20, 20, 20, # I 141 | ]) 142 | 143 | # Or initial conditions as a dictionary 144 | x0 = {'S': [n-20 for n in Ni], 'I': [20, 20, 20] } 145 | 146 | 147 | CM = np.array( [[1, 0.5, 0.1], 148 | [0.5, 1, 0.5], 149 | [0.1, 0.5, 1 ]], dtype=float) 150 | 151 | def contactMatrix(t): 152 | return CM 153 | 154 | 155 | # duration of simulation and data file 156 | Tf = 160; Nf=Tf+1; 157 | 158 | det_model = pyross.deterministic.Model(model_spec, parameters, M, Ni) 159 | 160 | # simulate model 161 | data = det_model.simulate(x0, contactMatrix, Tf, Nf) 162 | 163 | 164 | # plot the data and obtain the epidemic curve 165 | S = np.sum(det_model.model_class_data('S', data), axis=1) 166 | I = np.sum(det_model.model_class_data('I', data), axis=1) 167 | R = np.sum(det_model.model_class_data('R', data), axis=1) 168 | t = data['t'] 169 | 170 | fig = plt.figure(num=None, figsize=(10, 8), dpi=80, facecolor='w', edgecolor='k') 171 | plt.rcParams.update({'font.size': 22}) 172 | 173 | plt.fill_between(t, 0, S/N, color="#348ABD", alpha=0.3) 174 | plt.plot(t, S, '-', color="#348ABD", label='$S$', lw=4) 175 | 176 | plt.fill_between(t, 0, I/N, color='#A60628', alpha=0.3) 177 | plt.plot(t, I, '-', color='#A60628', label='$I$', lw=4) 178 | 179 | plt.fill_between(t, 0, R/N, color="dimgrey", alpha=0.3) 180 | plt.plot(t, R, '-', color="dimgrey", label='$R$', lw=4) 181 | 182 | plt.legend(fontsize=26); plt.grid() 183 | plt.autoscale(enable=True, axis='x', tight=True) 184 | plt.ylabel('Compartment value') 185 | plt.xlabel('Days'); 186 | ``` 187 | Read more in the [examples](https://github.com/rajeshrinet/pyross/tree/master/examples) folders. 188 | 189 | 190 | ## Publications 191 | * **Bayesian inference across multiple models suggests a strong increase in lethality of COVID-19 in late 2020 in the UK**. Patrick Pietzonka, Erik Brorson, William Bankes, Michael E. Cates, Robert L. Jack, R. Adhikari [medRxiv, 2021](https://doi.org/10.1101/2021.03.10.21253311) 192 | 193 | * **Efficient Bayesian inference of fully stochastic epidemiological models with applications to COVID-19**. Yuting I. Li, Günther Turk, Paul B. Rohrbach, Patrick Pietzonka, Julian Kappler, Rajesh Singh, Jakub Dolezal, Timothy Ekeh, Lukas Kikuchi, Joseph D. Peterson, Hideki Kobayashi, Michael E. Cates, R. Adhikari, Robert L. Jack, [arXiv:2010.11783, 2020](https://arxiv.org/abs/2010.11783) | [ResearchGate](https://www.researchgate.net/publication/344828080_Efficient_Bayesian_inference_of_fully_stochastic_epidemiological_models_with_applications_to_COVID-19) 194 | 195 | * **Efficient and flexible methods for time since infection models**, Joseph D. Peterson, R. Adhikari, [arXiv:2010.10955, 2020](https://arxiv.org/abs/2010.10955) 196 | 197 | * **Inference, prediction and optimization of non-pharmaceutical interventions using compartment models: the PyRoss library**. R. Adhikari, Austen Bolitho, Fernando Caballero, Michael E. Cates, 198 | Jakub Dolezal, Timothy Ekeh, Jules Guioth, Robert L. Jack, Julian Kappler, 199 | Lukas Kikuchi, Hideki Kobayashi, Yuting I. Li, Joseph D. Peterson, Patrick 200 | Pietzonka, Benjamin Remez, Paul B. Rohrbach, Rajesh Singh, and Günther Turk, [arXiv:2005.09625, 2020](https://arxiv.org/abs/2005.09625) | [ResearchGate](https://www.researchgate.net/publication/341496170_Inference_prediction_and_optimization_of_non-pharmaceutical_interventions_using_compartment_models_the_PyRoss_library). 201 | 202 | * **Age-structured impact of social distancing on the COVID-19 epidemic in India**. Rajesh Singh and R. Adhikari, [arXiv:2003.12055, 2020](https://arxiv.org/abs/2003.12055) | [ResearchGate](https://www.researchgate.net/publication/340209224_Age-structured_impact_of_social_distancing_on_the_COVID-19_epidemic_in_India_Updates_at_httpsgithubcomrajeshrinetpyrossa). 203 | 204 | 205 | ## License 206 | We believe that openness and sharing improves the practice of science and increases the reach of its benefits. This code is released under the [MIT license](http://opensource.org/licenses/MIT). Our choice is guided by the excellent article on [Licensing for the scientist-programmer](http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1002598). 207 | 208 | -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/CFR.csv: -------------------------------------------------------------------------------- 1 | ,AreaCode,CFR 2 | 0,E06000047,0.025857076854888635 3 | 1,E06000005,0.025562780899695742 4 | 2,E06000001,0.02475634616133196 5 | 3,E06000002,0.021632433798022106 6 | 4,E06000057,0.029343295355588404 7 | 5,E06000003,0.027305433613509233 8 | 6,E06000004,0.023695829946212717 9 | 7,E08000037,0.024933614113877 10 | 8,E08000021,0.019264482845992345 11 | 9,E08000022,0.02559745787369916 12 | 10,E08000023,0.025706126335995533 13 | 11,E08000024,0.02512104757972376 14 | 12,E06000008,0.019921473357870274 15 | 13,E06000009,0.025725151234829848 16 | 14,E06000049,0.02786610653831746 17 | 15,E06000050,0.02652861449504299 18 | 16,E06000006,0.023545070342083356 19 | 17,E06000007,0.024240958138382767 20 | 18,E07000026,0.029189618342554756 21 | 19,E07000027,0.02672628459823266 22 | 20,E07000028,0.026787555355308797 23 | 21,E07000029,0.027944434262270838 24 | 22,E07000030,0.0313759942136568 25 | 23,E07000031,0.0325632608509932 26 | 24,E08000001,0.022402753515367278 27 | 25,E08000002,0.023444178524557668 28 | 26,E08000003,0.014300932248272492 29 | 27,E08000004,0.021195431505219627 30 | 28,E08000005,0.021681705743733005 31 | 29,E08000006,0.0194639694336441 32 | 30,E08000007,0.025338621508104016 33 | 31,E08000008,0.023140896777257128 34 | 32,E08000009,0.02303618122118355 35 | 33,E08000010,0.02427945870267041 36 | 34,E07000117,0.023468790671404255 37 | 35,E07000118,0.025023278856121527 38 | 36,E07000119,0.03204273017978082 39 | 37,E07000120,0.023391979545579478 40 | 38,E07000121,0.024477243326096746 41 | 39,E07000122,0.023485594204110557 42 | 40,E07000123,0.020086656199743255 43 | 41,E07000124,0.02888506949946361 44 | 42,E07000125,0.02390493021810209 45 | 43,E07000126,0.026295539316138213 46 | 44,E07000127,0.026793084978564915 47 | 45,E07000128,0.03186301902759518 48 | 46,E08000011,0.02315779520234679 49 | 47,E08000012,0.020033163173923233 50 | 48,E08000014,0.02864343553721099 51 | 49,E08000013,0.0256492244373892 52 | 50,E08000015,0.02672287108321638 53 | 51,E06000011,0.03060652148567812 54 | 52,E06000010,0.02038347811621906 55 | 53,E06000012,0.02546570541772365 56 | 54,E06000013,0.02615382374093498 57 | 55,E06000014,0.02295352473396202 58 | 56,E07000163,0.03155014788700897 59 | 57,E07000164,0.030891442900646174 60 | 58,E07000165,0.028420168631037204 61 | 59,E07000166,0.0262790238075388 62 | 60,E07000167,0.0314318715099314 63 | 61,E07000168,0.031443014705833223 64 | 62,E07000169,0.02576608123929188 65 | 63,E08000016,0.0247647501855033 66 | 64,E08000017,0.024410035557156345 67 | 65,E08000018,0.024825860719872597 68 | 66,E08000019,0.021035484909150165 69 | 67,E08000032,0.020138398329645604 70 | 68,E08000033,0.024075737195102212 71 | 69,E08000034,0.022743108751096065 72 | 70,E08000035,0.020542296357225712 73 | 71,E08000036,0.024317422535128207 74 | 72,E06000015,0.021479822707296398 75 | 73,E06000016,0.016967138891774414 76 | 74,E06000018,0.01638500571050082 77 | 75,E06000017,0.029255531757641253 78 | 76,E07000032,0.02717482263348735 79 | 77,E07000033,0.025458599644989966 80 | 78,E07000034,0.02625214125321015 81 | 79,E07000035,0.03184589003920815 82 | 80,E07000036,0.0257169521878347 83 | 81,E07000037,0.026544536442982807 84 | 82,E07000038,0.02941225197075835 85 | 83,E07000039,0.02386613954142904 86 | 84,E07000129,0.02552207510587305 87 | 85,E07000130,0.022968635037814097 88 | 86,E07000131,0.02718710038395219 89 | 87,E07000132,0.026824480988221454 90 | 88,E07000133,0.027799862677074082 91 | 89,E07000134,0.025160049014831317 92 | 90,E07000135,0.02637350430856795 93 | 91,E07000136,0.025609406922936576 94 | 92,E07000137,0.03363720270763788 95 | 93,E07000138,0.019883769374430607 96 | 94,E07000139,0.028249787759002536 97 | 95,E07000140,0.028815214652739576 98 | 96,E07000141,0.027722428579865267 99 | 97,E07000142,0.029309580598458784 100 | 98,E07000150,0.020172414044860934 101 | 99,E07000151,0.02591834455164266 102 | 100,E07000152,0.02583852265637294 103 | 101,E07000153,0.023408686402876574 104 | 102,E07000154,0.020478736852664405 105 | 103,E07000155,0.025918357971415486 106 | 104,E07000156,0.02423650716344973 107 | 105,E07000170,0.024550554122126537 108 | 106,E07000171,0.027113015730898547 109 | 107,E07000172,0.02597306129029061 110 | 108,E07000173,0.026269573087020735 111 | 109,E07000174,0.024639622239274267 112 | 110,E07000175,0.026852481523620523 113 | 111,E07000176,0.02612543607957913 114 | 112,E06000019,0.029049743857167094 115 | 113,E06000051,0.029150951729415543 116 | 114,E06000021,0.022213683218459925 117 | 115,E06000020,0.02240367443572568 118 | 116,E07000192,0.024449682261989864 119 | 117,E07000193,0.024626495349529858 120 | 118,E07000194,0.028455382577030012 121 | 119,E07000195,0.025318678802063527 122 | 120,E07000196,0.02944233107798087 123 | 121,E07000197,0.027306046263391937 124 | 122,E07000198,0.029724435247132197 125 | 123,E07000199,0.023833904369010353 126 | 124,E07000218,0.026983332692418833 127 | 125,E07000219,0.024450810581970253 128 | 126,E07000220,0.024077858063919145 129 | 127,E07000221,0.03009651450538639 130 | 128,E07000222,0.02362477357632796 131 | 129,E08000025,0.018018216447774623 132 | 130,E08000026,0.01835460784252886 133 | 131,E08000027,0.025442670440959415 134 | 132,E08000028,0.020526232614075254 135 | 133,E08000029,0.026030812763457624 136 | 134,E08000030,0.022817177294638787 137 | 135,E08000031,0.021959824237694242 138 | 136,E07000234,0.02756618151041761 139 | 137,E07000235,0.032312216908004385 140 | 138,E07000236,0.023059647728000537 141 | 139,E07000237,0.022220809997278407 142 | 140,E07000238,0.029461553075536488 143 | 141,E07000239,0.02875228089253412 144 | 142,E06000055,0.023118775607091496 145 | 143,E06000056,0.023526924211166686 146 | 144,E06000032,0.017982125995198543 147 | 145,E06000031,0.02005382453109036 148 | 146,E06000033,0.02430915837592064 149 | 147,E06000034,0.019364530769015915 150 | 148,E07000008,0.017467667766711093 151 | 149,E07000009,0.0251776788074566 152 | 150,E07000010,0.02738856452840731 153 | 151,E07000011,0.02521751670162843 154 | 152,E07000012,0.02483402404084674 155 | 153,E07000066,0.02269814455295589 156 | 154,E07000067,0.025264357143880197 157 | 155,E07000068,0.025821154073885216 158 | 156,E07000069,0.029611950926094463 159 | 157,E07000070,0.024459538312168183 160 | 158,E07000071,0.02207627694266065 161 | 159,E07000072,0.025126249494524567 162 | 160,E07000073,0.02118014440191578 163 | 161,E07000074,0.02985646373646881 164 | 162,E07000075,0.028076709736604685 165 | 163,E07000076,0.03301043159132284 166 | 164,E07000077,0.02514631808707148 167 | 165,E07000095,0.023598106782760774 168 | 166,E07000096,0.02298590384428258 169 | 167,E07000242,0.02393800763782285 170 | 168,E07000098,0.0236094179611659 171 | 169,E07000099,0.024575626138416747 172 | 170,E07000240,0.02268764398838333 173 | 171,E07000243,0.02140192003659177 174 | 172,E07000102,0.023864919589870075 175 | 173,E07000103,0.018976534336882768 176 | 174,E07000241,0.020577176052173254 177 | 175,E07000143,0.029102461085787467 178 | 176,E07000144,0.03031911745902808 179 | 177,E07000145,0.02840572349521867 180 | 178,E07000146,0.030128807497046887 181 | 179,E07000147,0.036211825244870745 182 | 180,E07000148,0.01931730529884782 183 | 181,E07000149,0.02869868448637243 184 | 182,E07000200,0.030342827242017707 185 | 183,E07000244,0.031213480966032006 186 | 184,E07000202,0.021772959107031316 187 | 185,E07000203,0.029156604923986845 188 | 186,E07000245,0.025357727646244905 189 | 187,E09000007,0.017145568533211163 190 | 188,E09000001,0.023175302216609083 191 | 189,E09000012,0.01337677897224534 192 | 190,E09000013,0.016697593665392876 193 | 191,E09000014,0.01639485753897635 194 | 192,E09000019,0.014373607789635066 195 | 193,E09000020,0.021403420209999146 196 | 194,E09000022,0.014431885659475943 197 | 195,E09000023,0.015880777279328902 198 | 196,E09000025,0.013208666476738922 199 | 197,E09000028,0.01464756051658948 200 | 198,E09000030,0.011698936905275925 201 | 199,E09000032,0.015171416939305692 202 | 200,E09000033,0.018129856720446102 203 | 201,E09000002,0.014884038617266272 204 | 202,E09000003,0.01980678592776628 205 | 203,E09000004,0.022155168958577977 206 | 204,E09000005,0.01807630029701493 207 | 205,E09000006,0.023159587651696283 208 | 206,E09000008,0.019690554260160177 209 | 207,E09000009,0.018766552106685576 210 | 208,E09000010,0.019050436566148757 211 | 209,E09000011,0.01629010771028956 212 | 210,E09000015,0.021263820243863717 213 | 211,E09000016,0.023384906433787364 214 | 212,E09000017,0.01907338906025638 215 | 213,E09000018,0.01796169542958851 216 | 214,E09000021,0.0193356115731992 217 | 215,E09000024,0.018651805818493836 218 | 216,E09000026,0.018174471083655587 219 | 217,E09000027,0.02149915668349966 220 | 218,E09000029,0.021227800730236165 221 | 219,E09000031,0.016573231670134615 222 | 220,E06000036,0.02067785513332549 223 | 221,E06000043,0.018806160360476016 224 | 222,E06000046,0.03181302013743597 225 | 223,E06000035,0.021386282178823882 226 | 224,E06000042,0.019438479842760134 227 | 225,E06000044,0.019174409189492977 228 | 226,E06000038,0.017746964562752474 229 | 227,E06000039,0.01589556423809149 230 | 228,E06000045,0.018062861048469523 231 | 229,E06000037,0.024580101745767347 232 | 230,E06000040,0.02412489752614834 233 | 231,E06000041,0.023447429022861708 234 | 232,E07000004,0.0224731373724283 235 | 233,E07000005,0.02695595569862194 236 | 234,E07000006,0.02678367540092831 237 | 235,E07000007,0.023916762044687515 238 | 236,E07000061,0.028936403031109014 239 | 237,E07000062,0.024774091906250333 240 | 238,E07000063,0.029891152647465703 241 | 239,E07000064,0.03508533220938303 242 | 240,E07000065,0.030515623849095442 243 | 241,E07000084,0.022942241816990613 244 | 242,E07000085,0.02840334239633092 245 | 243,E07000086,0.024826658218604938 246 | 244,E07000087,0.028626560425170172 247 | 245,E07000088,0.025169594473069573 248 | 246,E07000089,0.025126824439470986 249 | 247,E07000090,0.028318517963247195 250 | 248,E07000091,0.0327682045527584 251 | 249,E07000092,0.020402182571173308 252 | 250,E07000093,0.026747792618665604 253 | 251,E07000094,0.026013644215524847 254 | 252,E07000105,0.024277416256942384 255 | 253,E07000106,0.024291548459032947 256 | 254,E07000107,0.020119304728238738 257 | 255,E07000108,0.028061763757178216 258 | 256,E07000112,0.0287012160068719 259 | 257,E07000109,0.022915562751854558 260 | 258,E07000110,0.02445925946195867 261 | 259,E07000111,0.02652900750132271 262 | 260,E07000113,0.024243395331742336 263 | 261,E07000114,0.027686843696001353 264 | 262,E07000115,0.024418508009740453 265 | 263,E07000116,0.024657250109803002 266 | 264,E07000177,0.02368861215741466 267 | 265,E07000178,0.016587583925824573 268 | 266,E07000179,0.026267452235604977 269 | 267,E07000180,0.025263996913610517 270 | 268,E07000181,0.026670277033282383 271 | 269,E07000207,0.023921872205411907 272 | 270,E07000208,0.023777481937803536 273 | 271,E07000209,0.021687016997866636 274 | 272,E07000210,0.02873328745152309 275 | 273,E07000211,0.02357192343876093 276 | 274,E07000212,0.0222178610496583 277 | 275,E07000213,0.024384119760568104 278 | 276,E07000214,0.02549996221487313 279 | 277,E07000215,0.026030553556689182 280 | 278,E07000216,0.02696401318103091 281 | 279,E07000217,0.022806924019998995 282 | 280,E07000223,0.028257100813953002 283 | 281,E07000224,0.032410187081727555 284 | 282,E07000225,0.031276668321984155 285 | 283,E07000226,0.01941481257978107 286 | 284,E07000227,0.0278190100384512 287 | 285,E07000228,0.025784879845248153 288 | 286,E07000229,0.027363582692292016 289 | 287,E06000022,0.023482666348049488 290 | 288,E06000058,0.026199496818807167 291 | 289,E06000023,0.01776110088465477 292 | 290,E06000052,0.02914204239826982 293 | 291,E06000059,0.03271710852066914 294 | 292,E06000053,0.029537898617392866 295 | 293,E06000024,0.02841298374610004 296 | 294,E06000026,0.023202716684136628 297 | 295,E06000025,0.024058466643599057 298 | 296,E06000030,0.02190016635006133 299 | 297,E06000027,0.030657107761692486 300 | 298,E06000054,0.026448312735889646 301 | 299,E07000040,0.03367881623744596 302 | 300,E07000041,0.020294353500327027 303 | 301,E07000042,0.0280924151542316 304 | 302,E07000043,0.029603516761013166 305 | 303,E07000044,0.03246519679814214 306 | 304,E07000045,0.030617179277427242 307 | 305,E07000046,0.031546844147898524 308 | 306,E07000047,0.03201743718269851 309 | 307,E07000078,0.02422329357305865 310 | 308,E07000079,0.030445280853932232 311 | 309,E07000080,0.029123307305481152 312 | 310,E07000081,0.022224837443255218 313 | 311,E07000082,0.027932613424878704 314 | 312,E07000083,0.026989636367759983 315 | 313,E07000187,0.027918470040068356 316 | 314,E07000188,0.028204691743244845 317 | 315,E07000246,0.029761239235453013 318 | 316,E07000189,0.029443893496169816 319 | 317,W06000001,0.029936519617691722 320 | 318,W06000002,0.026990650620718593 321 | 319,W06000003,0.03161400402409211 322 | 320,W06000004,0.028745343580037476 323 | 321,W06000005,0.025961009417320553 324 | 322,W06000006,0.024957416231906667 325 | 323,W06000023,0.03144093049389861 326 | 324,W06000008,0.028762645807975037 327 | 325,W06000009,0.030013394720023734 328 | 326,W06000010,0.028295964862915142 329 | 327,W06000011,0.024286292736807033 330 | 328,W06000012,0.025937753867466468 331 | 329,W06000013,0.02560628783116614 332 | 330,W06000014,0.02612814950096086 333 | 331,W06000015,0.019113579452648587 334 | 332,W06000016,0.024114184048444134 335 | 333,W06000024,0.024073602405594238 336 | 334,W06000018,0.024546736014741694 337 | 335,W06000019,0.025290672382779426 338 | 336,W06000020,0.025439503127553737 339 | 337,W06000021,0.029785158197313706 340 | 338,W06000022,0.02265179570649979 341 | 339,S12000033,0.021313582966283277 342 | 340,S12000034,0.024911270780687826 343 | 341,S12000041,0.028502224250683196 344 | 342,S12000035,0.030606886383864614 345 | 343,S12000036,0.0205467709540234 346 | 344,S12000005,0.025574089876060434 347 | 345,S12000006,0.030609079817251316 348 | 346,S12000042,0.022793980149106594 349 | 347,S12000008,0.025798101173254054 350 | 348,S12000045,0.027955091221287434 351 | 349,S12000010,0.02596690832974531 352 | 350,S12000011,0.025611649348985376 353 | 351,S12000014,0.024641007282399912 354 | 352,S12000047,0.02573774119170784 355 | 353,S12000049,0.01950677605494564 356 | 354,S12000017,0.027636122051565706 357 | 355,S12000018,0.02700672359695979 358 | 356,S12000019,0.02420833976883615 359 | 357,S12000020,0.026887445078978778 360 | 358,S12000013,0.03051844501046582 361 | 359,S12000021,0.0275838878578511 362 | 360,S12000050,0.02322879150183272 363 | 361,S12000023,0.029005564182599343 364 | 362,S12000048,0.028466805753873396 365 | 363,S12000038,0.02486104999081635 366 | 364,S12000026,0.02980876319613837 367 | 365,S12000027,0.02547593070308405 368 | 366,S12000028,0.030124669120804345 369 | 367,S12000029,0.025401507093729177 370 | 368,S12000030,0.024649250338531783 371 | 369,S12000039,0.024753550630945045 372 | 370,S12000040,0.02243999987818343 373 | -------------------------------------------------------------------------------- /examples/inference/UK Inference Data/out.csv: -------------------------------------------------------------------------------- 1 | ,E06000001,E06000002,E06000003,E06000004,E06000005,E06000006,E06000007,E06000008,E06000009,E06000010,E06000011,E06000012,E06000013,E06000014,E06000015,E06000016,E06000017,E06000018,E06000019,E06000020,E06000021,E06000022,E06000023,E06000024,E06000025,E06000026,E06000027,E06000030,E06000031,E06000032,E06000033,E06000034,E06000035,E06000036,E06000037,E06000038,E06000039,E06000040,E06000041,E06000042,E06000043,E06000044,E06000045,E06000046,E06000047,E06000049,E06000050,E06000051,E06000052,E06000053,E06000054,E06000055,E06000056,E06000057,E06000058,E06000059,E07000004,E07000005,E07000006,E07000007,E07000008,E07000009,E07000010,E07000011,E07000012,E07000026,E07000027,E07000028,E07000029,E07000030,E07000031,E07000032,E07000033,E07000034,E07000035,E07000036,E07000037,E07000038,E07000039,E07000040,E07000041,E07000042,E07000043,E07000044,E07000045,E07000046,E07000047,E07000061,E07000062,E07000063,E07000064,E07000065,E07000066,E07000067,E07000068,E07000069,E07000070,E07000071,E07000072,E07000073,E07000074,E07000075,E07000076,E07000077,E07000078,E07000079,E07000080,E07000081,E07000082,E07000083,E07000084,E07000085,E07000086,E07000087,E07000088,E07000089,E07000090,E07000091,E07000092,E07000093,E07000094,E07000095,E07000096,E07000098,E07000099,E07000102,E07000103,E07000105,E07000106,E07000107,E07000108,E07000109,E07000110,E07000111,E07000112,E07000113,E07000114,E07000115,E07000116,E07000117,E07000118,E07000119,E07000120,E07000121,E07000122,E07000123,E07000124,E07000125,E07000126,E07000127,E07000128,E07000129,E07000130,E07000131,E07000132,E07000133,E07000134,E07000135,E07000136,E07000137,E07000138,E07000139,E07000140,E07000141,E07000142,E07000143,E07000144,E07000145,E07000146,E07000147,E07000148,E07000149,E07000150,E07000151,E07000152,E07000153,E07000154,E07000155,E07000156,E07000163,E07000164,E07000165,E07000166,E07000167,E07000168,E07000169,E07000170,E07000171,E07000172,E07000173,E07000174,E07000175,E07000176,E07000177,E07000178,E07000179,E07000180,E07000181,E07000187,E07000188,E07000189,E07000192,E07000193,E07000194,E07000195,E07000196,E07000197,E07000198,E07000199,E07000200,E07000202,E07000203,E07000207,E07000208,E07000209,E07000210,E07000211,E07000212,E07000213,E07000214,E07000215,E07000216,E07000217,E07000218,E07000219,E07000220,E07000221,E07000222,E07000223,E07000224,E07000225,E07000226,E07000227,E07000228,E07000229,E07000234,E07000235,E07000236,E07000237,E07000238,E07000239,E07000240,E07000241,E07000242,E07000243,E07000244,E07000245,E07000246,E08000001,E08000002,E08000003,E08000004,E08000005,E08000006,E08000007,E08000008,E08000009,E08000010,E08000011,E08000012,E08000013,E08000014,E08000015,E08000016,E08000017,E08000018,E08000019,E08000021,E08000022,E08000023,E08000024,E08000025,E08000026,E08000027,E08000028,E08000029,E08000030,E08000031,E08000032,E08000033,E08000034,E08000035,E08000036,E08000037,E09000001,E09000002,E09000003,E09000004,E09000005,E09000006,E09000007,E09000008,E09000009,E09000010,E09000011,E09000012,E09000013,E09000014,E09000015,E09000016,E09000017,E09000018,E09000019,E09000020,E09000021,E09000022,E09000023,E09000024,E09000025,E09000026,E09000027,E09000028,E09000029,E09000030,E09000031,E09000032,E09000033,S12000005,S12000006,S12000008,S12000010,S12000011,S12000013,S12000014,S12000017,S12000018,S12000019,S12000020,S12000021,S12000023,S12000026,S12000027,S12000028,S12000029,S12000030,S12000033,S12000034,S12000035,S12000036,S12000038,S12000039,S12000040,S12000041,S12000042,S12000045,S12000047,S12000048,S12000049,S12000050,W06000001,W06000002,W06000003,W06000004,W06000005,W06000006,W06000008,W06000009,W06000010,W06000011,W06000012,W06000013,W06000014,W06000015,W06000016,W06000018,W06000019,W06000020,W06000021,W06000022,W06000023,W06000024 2 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 3 | 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 4 | 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 5 | 3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 6 | 4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 7 | 5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 8 | 6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 9 | 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 10 | 8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 11 | 9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 12 | 10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,1,2,0,1,0,0,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 13 | 11,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,2,0,0,2,0,0,1,2,1,0,0,2,0,0,0,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1,2,0,1,2,0,0,1,0,1,0,0,2,2,2,6,0,2,1,3,2,2,1,0,3,4,0,0,0,0,1,0,1,0,1,3,0,1,0,0,1,1,4,1,1,0,3,0,1,0,6,0,3,2,2,5,0,3,0,1,3,0,0,1,5,3,0,2,2,1,0,0,4,2,7,5,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0 14 | 12,2,0,0,1,0,1,0,0,0,0,1,1,0,0,5,2,0,3,0,1,1,1,4,0,2,0,2,0,0,2,3,0,1,1,2,0,6,4,1,2,0,4,2,0,3,6,0,1,2,0,1,1,1,0,0,1,2,3,4,1,0,0,0,0,0,0,0,5,0,1,3,1,0,0,1,1,0,0,2,0,2,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,2,0,0,0,0,0,1,1,3,0,0,5,1,0,2,1,1,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,2,0,0,1,0,1,1,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,1,1,0,1,2,1,0,1,0,0,2,0,0,0,1,1,2,1,0,1,1,0,1,0,0,0,0,2,0,0,2,4,1,0,1,0,1,0,2,0,0,1,0,0,0,0,1,2,2,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,4,3,2,4,6,1,4,2,1,1,4,0,2,3,0,0,0,2,4,0,2,3,18,5,4,6,0,6,15,0,0,2,2,1,0,1,5,9,2,20,5,3,10,16,4,7,5,5,2,15,6,10,12,1,2,4,9,5,6,11,11,5,13,1,10,5,14,7,3,12,3,2,5,0,6,7,18,5,0,10,0,13,1,4,12,11,2,4,4,17,15,16,8,2,8,7,9,4,46,28,0,1,0,0,0,0,0,0,1,2,1,2,0,2,0,4,1,2,0,3,2,0 15 | 13,2,20,7,6,4,5,3,3,2,5,8,6,1,4,19,12,0,9,8,3,6,10,16,2,10,5,4,2,2,21,12,6,19,4,9,6,10,10,6,16,12,13,8,3,30,13,12,20,23,0,19,14,19,15,6,11,4,10,9,9,2,0,2,3,6,8,12,11,8,4,18,9,4,4,5,6,2,8,5,4,3,0,0,3,5,0,2,5,1,6,2,5,8,1,8,5,8,2,20,2,2,6,10,3,3,5,5,5,4,1,6,6,7,14,7,4,8,3,3,4,6,8,7,22,4,0,0,3,3,3,3,5,6,9,1,6,4,5,3,1,1,1,1,5,5,9,0,1,4,7,1,6,7,6,5,1,5,3,1,0,0,0,4,2,0,2,4,1,9,3,0,4,0,5,5,6,9,2,1,3,4,5,4,1,3,1,8,0,6,5,8,5,3,4,6,1,6,4,2,3,0,7,13,6,5,11,3,4,3,3,5,3,8,7,3,14,13,4,4,1,9,5,4,3,10,7,7,4,1,3,5,6,7,7,3,8,2,3,4,7,13,3,16,6,3,13,5,2,10,15,12,20,29,40,23,21,14,11,5,41,3,18,21,9,4,6,22,9,8,6,15,79,22,38,24,8,32,40,16,8,14,35,15,12,0,28,93,21,60,44,19,57,33,30,29,40,22,37,65,32,40,32,27,26,9,51,41,22,51,42,13,42,20,27,43,35,39,3,9,10,21,15,0,17,6,29,11,2,15,2,15,4,15,44,12,12,21,7,61,26,17,15,8,21,9,31,9,97,46,0,3,1,3,5,1,2,0,2,11,2,2,10,19,12,18,7,8,9,14,4,1 16 | 14,7,32,13,7,4,15,27,12,10,10,17,2,5,14,42,39,1,24,9,9,18,13,17,12,26,6,8,20,7,34,23,16,20,9,14,19,14,17,20,35,17,14,15,4,69,44,37,14,25,0,36,7,27,30,19,21,11,22,8,11,5,4,7,5,3,13,11,10,9,7,29,11,3,7,3,16,11,16,13,2,8,4,2,1,5,2,2,8,2,8,3,8,24,17,9,10,17,10,27,17,7,10,11,10,13,5,4,19,9,9,18,4,2,14,6,6,11,10,4,4,7,17,24,33,14,13,19,9,10,10,9,13,14,7,7,11,10,5,5,14,13,12,4,13,10,13,4,1,9,15,7,6,12,2,10,9,15,9,7,6,2,11,3,4,1,6,4,8,9,7,1,2,5,8,16,6,13,9,5,10,10,16,2,4,5,2,18,5,11,10,16,11,8,11,10,10,28,13,1,3,1,12,16,21,12,14,14,8,9,4,11,9,16,13,8,11,34,11,14,4,8,10,4,4,22,7,10,11,1,5,8,9,7,15,4,19,8,11,6,12,13,17,18,19,1,20,1,5,43,21,47,28,23,51,41,27,12,24,13,116,20,52,52,26,22,24,33,31,7,14,44,217,58,58,54,37,53,51,32,17,37,49,37,30,2,30,88,41,81,40,31,75,64,86,46,45,35,58,53,55,54,37,33,22,14,51,72,35,65,42,19,54,31,40,44,31,32,4,10,14,21,14,0,16,9,26,16,0,13,0,7,1,26,44,11,18,25,12,64,33,17,8,12,29,12,39,10,95,46,1,9,5,6,15,2,2,7,11,13,11,18,15,55,29,24,8,18,8,31,5,11 17 | 15,17,33,18,21,18,26,37,14,19,14,28,8,6,21,68,30,2,35,10,20,15,18,53,10,26,13,6,38,11,45,38,27,38,10,22,29,27,27,22,39,25,16,32,9,109,73,54,20,40,0,56,25,38,37,26,26,23,16,2,22,10,13,9,15,13,11,14,15,8,5,31,16,6,14,12,12,22,20,12,5,11,0,7,1,3,5,2,12,3,17,6,17,41,15,19,18,28,19,32,17,5,16,20,7,42,11,11,22,20,21,18,13,10,14,13,12,21,21,8,8,13,16,15,39,11,18,34,15,15,21,11,18,7,20,13,21,25,7,8,8,20,10,11,15,13,12,4,8,15,16,13,7,19,8,7,5,10,9,3,7,6,11,8,8,2,10,8,11,24,7,2,8,9,8,14,8,40,7,9,11,11,21,3,3,13,7,18,9,14,22,14,17,10,27,20,18,29,16,5,8,12,15,24,25,24,19,12,8,18,8,23,9,20,18,11,15,33,9,19,8,8,15,7,15,18,8,22,18,6,11,12,13,14,27,7,24,6,6,8,16,14,33,10,16,11,32,9,3,50,43,90,67,41,74,55,40,38,59,33,133,40,47,88,33,28,57,88,47,22,18,89,273,53,45,86,57,71,49,78,22,57,115,66,46,0,36,93,53,119,57,32,100,107,78,55,51,36,64,93,60,54,37,25,31,27,53,53,51,68,72,34,45,43,51,53,49,38,4,3,11,15,13,0,25,8,17,14,2,11,0,3,0,17,50,5,15,23,14,71,40,18,12,19,27,18,33,13,122,33,1,9,5,9,25,7,0,3,10,41,18,15,19,62,62,34,17,9,12,23,16,12 18 | -------------------------------------------------------------------------------- /examples/inference/ex03_SppQ_latent_inference.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Simulating any compartmental model with testing and quarantine using the `SppQ` class\n", 8 | "\n" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "metadata": {}, 15 | "outputs": [], 16 | "source": [ 17 | "%matplotlib inline\n", 18 | "import numpy as np\n", 19 | "import pyross\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "#from matplotlib import rc; rc('text', usetex=True)" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "### The SIR model with quarantine\n", 29 | "\n", 30 | "Below you will find the model-specification dictionary for the SIR model with quarantined states" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "model_spec = {\n", 40 | " \"classes\" : [\"S\", \"I\"],\n", 41 | "\n", 42 | " \"S\" : {\n", 43 | " \"infection\" : [ [\"I\", \"-beta\"] ],\n", 44 | " },\n", 45 | "\n", 46 | " \"I\" : {\n", 47 | " \"linear\" : [ [\"I\", \"-gamma\"] ],\n", 48 | " \"infection\" : [ [\"I\", \"beta\"] ],\n", 49 | " },\n", 50 | " \n", 51 | " # S I R\n", 52 | " \"test_pos\" : [ \"p_falsepos\", \"p_truepos\", \"p_falsepos\"] ,\n", 53 | " \"test_freq\" : [ \"pi_RS\", \"pi_I\", \"pi_RS\"] \n", 54 | "}\n", 55 | "\n", 56 | "parameters = {\n", 57 | " 'beta' : 0.02,\n", 58 | " 'gamma' : 0.1, \n", 59 | " 'p_falsepos' : 0.01,\n", 60 | " 'p_truepos' : 0.9,\n", 61 | " 'pi_RS' : 0.1,\n", 62 | " 'pi_I' : 1\n", 63 | " \n", 64 | "}" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "This corresponds to\n", 72 | "\n", 73 | "$$\n", 74 | "\\begin{aligned}\n", 75 | "\\dot{S}_i & = - \\beta \\sum_j C_{ij} \\frac{I_j}{N_j} S_i - \\tau_S S_i; &\\dot{S}^Q_i & = \\tau_S S_i \\\\\n", 76 | "\\dot{I}_i & = \\beta \\sum_j C_{ij} \\frac{I_j}{N_j} S_i - \\gamma I_i - \\tau_I I_i;\n", 77 | "&\\dot{I}^Q_i & =- \\gamma I_i^Q+ \\tau_I I_i\\\\\n", 78 | "\\dot{R}_i & = \\gamma I_i- \\tau_R R_i; &\\dot{R}^Q_i & = \\gamma I^Q_i+ \\tau_R R_i;\n", 79 | "\\end{aligned}\n", 80 | "$$\n", 81 | "\n", 82 | "Each of the classes, `S`, `I` and `R`, have a quarantined version, `SQ`, `IQ` and `RQ`. The dynamics within the quarantined states is the same as for the un-quarantined states, but there are no infection terms (assuming perfect quarantine). Individuals are quarantined upon testing positive, hence the total number $N^Q=S^Q+I^Q+R^Q$ would be the reported number of confirmed cases. \n", 83 | "\n", 84 | "The transition rates $\\tau_S$, $\\tau_I$, $\\tau_R$ for irreversible transitions to the quarantined states are dependent on time and on other variables. They are determined by the overall testing rate $\\tau_{tot}(t)$ and the parameters specified in `\"test_pos\"` and `\"test_prob\"` (ordered such that they match to `S`, `I` and `R`). \n", 85 | "\n", 86 | "- `\"test_pos\"` specifies the probability $\\kappa_S$, $\\kappa_I$, $\\kappa_R$ that a test performed on an individual of a given class is positive. For classes $R$ and $S$, this is the conditional probability of false positives, for class $I$ the conditional probability of a true positive\n", 87 | "\n", 88 | "- `\"test_freq\"` characterises the frequency $\\pi_S$, $\\pi_I$, $\\pi_R$ of tests in a given class. The absolute values of these values does not matter, only their relative magnitudes. If we consider symptomatic testing and set $\\pi_I=1$, then $\\pi_R=\\pi_S$ is the fraction of people who would like to be tested because of symptoms of flu or cold among the population *not* infected with SARS-CoV-2. In models with several infected classes, this parameter can also be used to prioritise testing of patients with severe symptoms or elderly people\n", 89 | "\n", 90 | "- The rate of positive tests in each class is computed as\n", 91 | " $$ \\tau_X=\\tau_{tot}(t)\\pi_X \\kappa_X/\\mathcal{N} $$\n", 92 | " for $X\\in\\{S,I,R\\}$ with the normalisation constant\n", 93 | " $$ \\mathcal{N}=\\sum_X \\pi_X X$$" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "Next, we define the initial condition for all non-quarantined and quarantined states. $R$ is never specified but calculated from the total number. The initial value for $N^Q$ is specified for the auxiliary class `NiQ`. The (scalar) testing rate $\\tau_{tot}(t)$ is specified as a Python function, similar to the time dependent contact matrix. Here, we specify a rapid increase from 10 to 100 tests per day around day 40." 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 3, 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "M = 2 # the population has two age groups\n", 110 | "N = 5e4 # and this is the total population\n", 111 | "\n", 112 | "# set the age structure\n", 113 | "fi = np.array([0.25, 0.75]) # fraction of population in age age group\n", 114 | "Ni = N*fi\n", 115 | "\n", 116 | "# set the contact structure\n", 117 | "CM = np.array([[18., 9.], [3., 12.]])\n", 118 | "\n", 119 | "\n", 120 | "# Initial conditions as an array\n", 121 | "S0 = np.array([Ni[0]-10, Ni[1]-10])\n", 122 | "I0 = np.array([10, 10])\n", 123 | "\n", 124 | "x0 = np.array([\n", 125 | " S0[0], S0[1], # S\n", 126 | " I0[0], I0[1], # I\n", 127 | " 0, 0, # R\n", 128 | " 0, 0, # SQ\n", 129 | " 0, 0, # IQ\n", 130 | " 0, 0 # RQ\n", 131 | "])\n", 132 | "\n", 133 | "\n", 134 | "def contactMatrix(t): \n", 135 | " return CM\n", 136 | "\n", 137 | "# Tests performed per day\n", 138 | "def testRate(t):\n", 139 | " return (900.*(1.+np.tanh((t-30.)/10.))/2.+100.)\n", 140 | "\n", 141 | "# duration of simulation and data file\n", 142 | "Tf = 100; Nf=Tf+1; \n", 143 | "\n", 144 | "model = pyross.stochastic.SppQ(model_spec, parameters, M, Ni)\n", 145 | "data = model.simulate(x0, contactMatrix, testRate, Tf, Nf)\n", 146 | "data_array = data['X']\n", 147 | "\n", 148 | "det_model = pyross.deterministic.SppQ(model_spec, parameters, M, Ni)\n", 149 | "data_det = det_model.simulate(x0, contactMatrix, testRate, Tf, Nf)\n", 150 | "data_array_data = data_det['X']\n", 151 | "\n", 152 | "# non-quarantined version for comarpison\n", 153 | "model_specU = model_spec.copy()\n", 154 | "model_specU.pop('test_freq')\n", 155 | "model_specU.pop('test_pos')\n", 156 | "modelU = pyross.stochastic.Spp(model_specU, parameters, M, Ni)\n", 157 | "dataU = modelU.simulate(x0[0:(2*M)], contactMatrix, Tf, Nf)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "metadata": {}, 164 | "outputs": [], 165 | "source": [ 166 | "# plot the data and obtain the epidemic curve\n", 167 | "S = np.sum(model.model_class_data('S', data), axis=1)\n", 168 | "I = np.sum(model.model_class_data('I', data), axis=1)\n", 169 | "R = np.sum(model.model_class_data('R', data), axis=1)\n", 170 | "SQ = np.sum(model.model_class_data('SQ', data), axis=1)\n", 171 | "IQ = np.sum(model.model_class_data('IQ', data), axis=1)\n", 172 | "RQ = np.sum(model.model_class_data('RQ', data), axis=1)\n", 173 | "NQ = np.sum(model.model_class_data('NiQ', data), axis=1)\n", 174 | "\n", 175 | "NQ_det = np.sum(det_model.model_class_data('NiQ', data_det), axis=1)\n", 176 | "\n", 177 | "SU = np.sum(modelU.model_class_data('S', dataU), axis=1)\n", 178 | "IU = np.sum(modelU.model_class_data('I', dataU), axis=1)\n", 179 | "RU = np.sum(modelU.model_class_data('R', dataU), axis=1)\n", 180 | "\n", 181 | "t = data['t']\n", 182 | "\n", 183 | "fig = plt.figure(num=None, figsize=(16, 6), dpi=80, facecolor='w', edgecolor='k')\n", 184 | "plt.rcParams.update({'font.size': 18})\n", 185 | "\n", 186 | "plt.subplot(1, 2, 1)\n", 187 | "plt.plot(t, S, '-', color=\"#348ABD\", label='$S$', lw=3)\n", 188 | "plt.plot(t, I, '-', color='#A60628', label='$I$', lw=3)\n", 189 | "plt.plot(t, R, '-', color=\"dimgrey\", label='$R$', lw=3)\n", 190 | "plt.plot(t, SU, '--', color=\"#348ABD\", label='$S$ (w/o $Q$)', lw=2)\n", 191 | "plt.plot(t, IU, '--', color='#A60628', label='$I$ (w/o $Q$)', lw=2)\n", 192 | "plt.plot(t, RU, '--', color=\"dimgrey\", label='$R$ (w/o $Q$)', lw=2)\n", 193 | "\n", 194 | "plt.legend(fontsize=18); plt.grid() \n", 195 | "plt.autoscale(enable=True, axis='x', tight=True)\n", 196 | "plt.ylabel('Compartment value')\n", 197 | "plt.xlabel('Days');\n", 198 | "\n", 199 | "plt.subplot(1, 2, 2)\n", 200 | "tm = t[1:]-0.5\n", 201 | "plt.plot(tm, [testRate(tt) for tt in tm], '-', color=\"darkgreen\", label='daily total tests', lw=3)\n", 202 | "plt.plot(tm, np.diff(NQ), '-', color=\"#348ABD\", label='daily positive tests', lw=3)\n", 203 | "plt.plot(tm, np.diff(NQ_det), '--', color=\"#348ABD\", label='daily positive tests (deterministic)', lw=2)\n", 204 | "plt.plot(tm, np.diff(I+R+IQ+RQ), '-', color=\"#A60628\", label='true new cases', lw=3)\n", 205 | "\n", 206 | "plt.legend(fontsize=18); plt.grid() \n", 207 | "plt.autoscale(enable=True, axis='x', tight=True)\n", 208 | "plt.ylabel('Compartment value')\n", 209 | "plt.xlabel('Days');" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": {}, 215 | "source": [ 216 | "In this simple model, testing and quarantining has helped to eradicate the disease. It is interesting to evaluate how many infections have been confired anf how many have remained unconfirmed:" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "metadata": {}, 223 | "outputs": [], 224 | "source": [ 225 | "print(\"Confirmed cases:\", int(RQ[-1]))\n", 226 | "print(\"Confirmed cases (incl. false positives):\", int(NQ[-1]))\n", 227 | "print(\"Total cases:\", int(R[-1]+RQ[-1]))" 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": null, 233 | "metadata": {}, 234 | "outputs": [], 235 | "source": [ 236 | "# load the data and rescale to intensive variables \n", 237 | "Tf_inference = 30 # truncate to only getting the first few datapoints \n", 238 | "Nf_inference = Tf_inference+1\n", 239 | "x = (data_array[:Nf_inference]).astype('float')/N\n", 240 | "\n", 241 | "inference_parameters = parameters.copy()" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": null, 247 | "metadata": {}, 248 | "outputs": [], 249 | "source": [ 250 | "# a filter that sums over all the diagnosed people for each age group\n", 251 | "fltr = np.kron([0, 0, 0, 1, 1, 1],np.identity(M))\n", 252 | "print(fltr)\n", 253 | "\n", 254 | "# Compare the deterministic trajectory and the stochastic trajectory with the same \n", 255 | "# initial conditions and parameters \n", 256 | "obs=np.einsum('ij,kj->ki', fltr, x)\n", 257 | "x0=x[0]\n", 258 | "\n", 259 | "# initialise the estimator \n", 260 | "estimator = pyross.inference.SppQ(model_spec, inference_parameters, testRate, M, fi, Omega=N, lyapunov_method='euler')\n", 261 | "\n", 262 | "\n", 263 | "# compute -log_p for the original (correct) parameters \n", 264 | "logp = estimator.minus_logp_red(inference_parameters, x0, obs, fltr, Tf_inference, contactMatrix)\n", 265 | "print(logp) " 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": null, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "# make parameter guesses and set up bounds for each parameter \n", 275 | "eps=1e-4\n", 276 | "param_priors = {\n", 277 | " 'beta':{\n", 278 | " 'mean': 0.015, \n", 279 | " 'std': 0.015, \n", 280 | " 'bounds': (eps, 0.1)\n", 281 | " }, \n", 282 | " 'gamma':{\n", 283 | " 'mean': 0.08, \n", 284 | " 'std': 0.1, \n", 285 | " 'bounds': (eps, 1)\n", 286 | " }\n", 287 | "}\n", 288 | "\n", 289 | "# set up filter for initial conditions because they are constraint by the observed \n", 290 | "# note that this filter is different from the bulk of the trajectory, \n", 291 | "# because we know the initial value 0 holds for R all quarantined age groups\n", 292 | "obs0 = np.zeros(M*4)\n", 293 | "obs0[:M] = fi\n", 294 | "fltr0 = np.kron(([[1, 1, 1, 0, 0, 0],\n", 295 | " [0, 0, 0, 1, 0, 0],\n", 296 | " [0, 0, 0, 0, 1, 0],\n", 297 | " [0, 0, 0, 0, 0, 1]\n", 298 | " ]), np.identity(M))\n", 299 | "init_fltr = np.repeat([True, True, False, False, False, False], M)\n", 300 | "\n", 301 | "full_obs = np.array([obs0, *obs[1:]])\n", 302 | "full_fltrs = np.array([fltr0, *([fltr]*(Nf_inference-1))])\n", 303 | "\n", 304 | "I0_g = (I0)/N\n", 305 | "I_std = I0_g\n", 306 | "bounds_for_I = np.tile([0.1/N, 100/N], M).reshape(M, 2)\n", 307 | "\n", 308 | "S0_g = (S0)/N\n", 309 | "S_std = I_std*3 \n", 310 | "bounds_for_S = np.array([(1/N, f) for f in fi])\n", 311 | "\n", 312 | "init_priors = {\n", 313 | " 'independent':{\n", 314 | " 'fltr':init_fltr,\n", 315 | " 'mean':[*S0_g, *I0_g], \n", 316 | " 'std': [*S_std, *I_std], \n", 317 | " 'bounds': [*bounds_for_S, *bounds_for_I]\n", 318 | " }\n", 319 | "}\n", 320 | "\n", 321 | "# optimisation parameters \n", 322 | "ftol = 1e-5 # the relative tol in (-logp)\n", 323 | "res = estimator.latent_infer_parameters(full_obs, full_fltrs, Tf_inference, contactMatrix, \n", 324 | " param_priors, init_priors, \n", 325 | " global_max_iter=30, global_atol=10, \n", 326 | " verbose=True, ftol=ftol) " 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": null, 332 | "metadata": {}, 333 | "outputs": [], 334 | "source": [ 335 | "print(\"True parameters:\")\n", 336 | "print(inference_parameters)\n", 337 | "\n", 338 | "print(\"\\nInferred parameters:\")\n", 339 | "best_estimates = res['map_params_dict']\n", 340 | "print(best_estimates)\n", 341 | "\n", 342 | "print('\\n True initial conditions: ') \n", 343 | "print((x0*N).astype('int'))\n", 344 | "\n", 345 | "map_x0 = res['map_x0']\n", 346 | "print('\\n Inferred initial conditions: ') \n", 347 | "print((map_x0*N).astype('int'))\n", 348 | "\n", 349 | "# compute -log_p for the original (correct) parameters \n", 350 | "logp = estimator.minus_logp_red(inference_parameters, map_x0, obs, fltr, Tf_inference, contactMatrix)\n", 351 | "print(logp) " 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": null, 357 | "metadata": {}, 358 | "outputs": [], 359 | "source": [ 360 | "# plot the guessed trajectory and the true trajectory \n", 361 | "estimator.set_params(best_estimates)\n", 362 | "estimator.set_det_model(best_estimates)\n", 363 | "x_det = estimator.integrate(map_x0, 0, Tf, Nf)\n", 364 | "\n", 365 | "fig = plt.figure(num=None, figsize=(10, 8), dpi=80, facecolor='w', edgecolor='k')\n", 366 | "plt.rcParams.update({'font.size': 22})\n", 367 | "plt.plot(S/N, label='True S', ls='--', c='C1')\n", 368 | "plt.plot(np.sum(x_det[:, 0*M:1*M],axis=1), label='Inferred S', c='C1')\n", 369 | "plt.plot(I/N, label='True I', ls='--', c='C2')\n", 370 | "plt.plot(np.sum(x_det[:, 1*M:2*M],axis=1), label='Inferred I', c='C2')\n", 371 | "plt.plot(NQ/N, label='True Q ($S^Q+I^Q+R^Q$)', ls='--', c='C3')\n", 372 | "plt.plot(np.sum(x_det[:, 3*M:6*M],axis=1), label='Inferred Q', c='C3')\n", 373 | "\n", 374 | "\n", 375 | "plt.axvspan(0, Tf_inference, \n", 376 | " label='Used for inference',\n", 377 | " alpha=0.3, color='dodgerblue')\n", 378 | "plt.xlim([0, Tf])\n", 379 | "plt.legend(fontsize=18); plt.grid() \n", 380 | "plt.autoscale(enable=True, axis='x', tight=True)\n", 381 | "plt.xlabel(\"time [days]\")\n", 382 | "plt.show()" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": null, 388 | "metadata": {}, 389 | "outputs": [], 390 | "source": [] 391 | } 392 | ], 393 | "metadata": { 394 | "kernelspec": { 395 | "display_name": "Python (pyross_env)", 396 | "language": "python", 397 | "name": "python-env" 398 | }, 399 | "language_info": { 400 | "codemirror_mode": { 401 | "name": "ipython", 402 | "version": 3 403 | }, 404 | "file_extension": ".py", 405 | "mimetype": "text/x-python", 406 | "name": "python", 407 | "nbconvert_exporter": "python", 408 | "pygments_lexer": "ipython3", 409 | "version": "3.7.6" 410 | } 411 | }, 412 | "nbformat": 4, 413 | "nbformat_minor": 4 414 | } 415 | -------------------------------------------------------------------------------- /tests/quick_test.py: -------------------------------------------------------------------------------- 1 | #!python 2 | """Unittesting for the pyross module. Run as python -m unittest pyross.test.""" 3 | import sys 4 | #remove pwd from path that tries to import .pyx files 5 | # for i in sys.path: 6 | # if 'pyross' in i or i == '': 7 | # sys.path.remove(i) 8 | # print(sys.path) 9 | import pyross 10 | import unittest 11 | import inspect 12 | import numpy as np 13 | import scipy as sp 14 | 15 | skip = ["Spp", "SppQ", "SEAIRQ_testing", "SIR_type", "Symbol", "SppSparse", "SppQ_old"] 16 | 17 | class DeterministicTest(unittest.TestCase): 18 | """testing deterministic.pyx.""" 19 | N = np.asarray([10000], dtype=np.float64) 20 | M = 1 21 | alpha = 0 22 | beta = 0.0071 23 | gIa = 0.008 24 | gIs = 0.008 25 | gI = 0.008 26 | gE = 0.007 27 | gIc = 0.1 28 | gIhp= 0.1 29 | gIsp= 0.1 30 | gIcp= 0.1 31 | gIh = 0.1 32 | gA = 0 33 | tE = 0 34 | tIa = 0 35 | tIs = 0 36 | Tf = 100 37 | Nf = 1000 38 | fsa = 0 39 | fh = 1 40 | sa = 0 41 | iaa = 0 42 | hh = 0 43 | cc = 0 44 | mm = 0 45 | tE = 0 46 | tA = 0 47 | tIa = 0 48 | tIs = 0 49 | kI = 1 50 | kE = 1 51 | k = 1 52 | ep = 0 53 | parameters = {'N': N, 'M': M, 'alpha': alpha, 54 | 'beta': beta, 'gIa': gIa, 'gIs': gIs, 55 | 'gIsp':gIsp,'gIhp':gIhp,'gIcp':gIcp, 56 | 'gI': gI, 'iaa': iaa, 57 | 'gE': gE, 'gA': gA, 'tE': tE, 58 | 'gIc': gIc, 'gIh': gIh, 'fh': fh, 59 | 'tIa': tIa, 'tIs': tIs, 'fsa': fsa, 60 | 'sa': sa, 'hh': hh, 'cc': cc, 61 | 'mm': mm, 'tA': tA, 'tE': tE, 62 | 'tIa': tIa, 'tIs': tIs, 'kI': kI, 63 | 'kE': kE, 'ep': ep, 'k': k} 64 | 65 | 66 | def __init__(self, *args, **kwargs): 67 | super(DeterministicTest, self).__init__(*args, **kwargs) 68 | # self.parameters = self.parameters 69 | 70 | def contactMatrix(self, t): return np.identity(self.M) 71 | 72 | def test_decay(self): 73 | """ 74 | Exponential decay from infected to recovered. Paths agree within .1%. 75 | """ 76 | SIR = pyross.deterministic.SIR(self.parameters, self.M, self.N) 77 | sim = SIR.simulate(np.zeros(1), np.zeros(1), self.N, 78 | self.contactMatrix, self.Tf, 79 | self.Nf, integrator='solve_ivp') 80 | time_points = np.linspace(0, self.Tf, self.Nf) 81 | exp_decay = sp.integrate.solve_ivp(lambda t, y: -self.gIs * y, 82 | (0, self.Tf), self.N, 83 | t_eval=time_points) 84 | diff = (sim['X'][:, 2] - exp_decay.y)/self.N 85 | self.assertTrue((diff < 0.001).all(), msg="paths differ > .1%") 86 | 87 | def test_integrators(self): 88 | """ 89 | All integration methods produce paths which agree within .1% 90 | """ 91 | integrators = ['solve_ivp', 'odeint'] 92 | paths = [] 93 | model = pyross.deterministic.SIR(self.parameters, self.M, self.N) 94 | for integrator in integrators: 95 | try: 96 | data = model.simulate(np.zeros(1), np.zeros(1), self.N, 97 | self.contactMatrix, self.Tf, 98 | self.Nf, integrator=integrator) 99 | except ImportError: 100 | print(f"{integrator} is not installed, skipping...") 101 | pass 102 | paths.append(data['X']) 103 | for i in range(len(paths)): 104 | for j in range(len(paths)): 105 | if i != j: 106 | diff = (paths[i]-paths[j])/self.N 107 | self.assertTrue((np.asarray(diff) < 0.001).all(), 108 | "path {i} not equal to path {j}") 109 | 110 | def test_SIRS(self): 111 | """Test to make sure SIRS collapses down to SIR""" 112 | self.parameters['ep'] = 0 113 | self.parameters['sa'] = 0 114 | self.parameters['iaa'] = 0 115 | SIR = pyross.deterministic.SIR(self.parameters, self.M, self.N) 116 | SIRS = pyross.deterministic.SIRS(self.parameters, self.M, self.N) 117 | SIRdata = SIR.simulate(self.N, np.ones(1), np.zeros(1), 118 | self.contactMatrix, self.Tf, 119 | self.Nf)['X'] 120 | SIRSdata = SIRS.simulate(self.N, np.ones(1), np.zeros(1), 121 | self.contactMatrix, self.Tf, 122 | self.Nf)['X'] 123 | self.assertTrue((SIRdata-SIRSdata[:, 0:3] < 0.001).all(), 124 | msg="paths differ > .1%") 125 | 126 | def test_init_models(self): 127 | """Test initialisation of deterministic models""" 128 | deterministic_models = dict(inspect.getmembers(pyross.deterministic, 129 | inspect.isclass)) 130 | for name, model in deterministic_models.items(): 131 | if name.startswith('S') and not name in skip: 132 | m = model(self.parameters, self.M, self.N) 133 | 134 | def test_run_models(self): 135 | """Runs all deterministic models""" 136 | deterministic_models = dict(inspect.getmembers(pyross.deterministic, 137 | inspect.isclass)) 138 | traj_dict={} 139 | for name, model in deterministic_models.items(): 140 | if name.startswith('S') and not name in skip: 141 | m = model(self.parameters, self.M, self.N) 142 | x0 = np.array([*self.N, *np.ones(self.M), 143 | *np.zeros(m.nClass-2)], dtype=np.float64).reshape((m.nClass,1)) 144 | traj_dict[name] = m.simulate(*x0, self.contactMatrix, 100, 100) 145 | 146 | 147 | class StochasticTest(unittest.TestCase): 148 | """testing stochastic.pyx""" 149 | nloops=10 150 | iinfec = 3000 151 | Tf = 10 152 | 153 | def __init__(self, *args, **kwargs): 154 | super(StochasticTest, self).__init__(*args, **kwargs) 155 | self.parameters = DeterministicTest.parameters 156 | self.stochastic_models = dict(inspect.getmembers(pyross.stochastic, 157 | inspect.isclass)) 158 | 159 | def contactMatrix(self, t): return np.identity(self.parameters['M']) 160 | 161 | def test_init_models(self): 162 | """Initializes all stochastic models""" 163 | traj_dict={} 164 | for name, model in self.stochastic_models.items(): 165 | if name.startswith('S') and not name in skip: 166 | params, M, N = self.parameters, self.parameters['M'], self.parameters['N'] 167 | m = model(params, M, N) 168 | # x0 = np.array([*self.N, *np.ones(self.M), 169 | # *np.zeros(m.nClass -2)], dtype=np.float64).reshape((m.nClass,1)) 170 | # traj_dict[name] = m.simulate(*x0, self.contactMatrix, 100, 100) 171 | 172 | def test_run_models(self): 173 | """Runs all stochastic models""" 174 | traj_dict={} 175 | for name, model in self.stochastic_models.items(): 176 | 177 | if name.startswith('S') and not name in skip: 178 | params, M, N = self.parameters, self.parameters['M'], self.parameters['N'] 179 | m = model(params, M, N + M*10) 180 | x0 = np.array([*self.parameters['N'], 181 | *np.ones(self.parameters['M'])*10, 182 | *np.zeros(m.nClass -2)], 183 | dtype=np.float64).reshape((m.nClass,1)) 184 | traj_dict[name] = m.simulate(*x0, self.contactMatrix, 100, 100) 185 | 186 | def test_stochastic_mean_gillespie(self): 187 | """Runs stochastic models a few times and compares mean to 188 | deterministic""" 189 | deterministic_models = dict(inspect.getmembers(pyross.deterministic, 190 | inspect.isclass)) 191 | params, M, N = self.parameters, self.parameters['M'], self.parameters['N'] 192 | for name, model in self.stochastic_models.items(): 193 | if name.startswith('S') and not name in skip: 194 | mS = model(params, M, N + M*self.iinfec) 195 | # print(mS.kk) 196 | mD = deterministic_models[name](params, M, N + M*self.iinfec) 197 | x0 = np.array([*self.parameters['N'], 198 | *np.ones(self.parameters['M'])*self.iinfec, 199 | *np.zeros(mS.nClass -2)], 200 | dtype=np.float64).reshape((mS.nClass,1)) 201 | trajectories = [] 202 | for i in range(self.nloops): 203 | traj = mS.simulate(*x0, self.contactMatrix, self.Tf, self.Tf)['X'] 204 | trajectories.append(traj) 205 | traj_mean = np.mean(trajectories, axis=0) 206 | mean = mD.simulate(*x0, self.contactMatrix, self.Tf, self.Tf)['X'] 207 | absdiff = np.abs(traj_mean -mean)/(N*self.Tf) 208 | # print(name, np.sum(absdiff[:,:-1])) 209 | self.assertTrue(np.sum(absdiff[:,:-1])<0.01, 210 | "{name} model disagreement") 211 | 212 | def test_stochastic_mean_tau(self): 213 | """Runs stochastic models a few times and compares mean to 214 | deterministic using tau leaping""" 215 | deterministic_models = dict(inspect.getmembers(pyross.deterministic, 216 | inspect.isclass)) 217 | params, M, N = self.parameters, self.parameters['M'], self.parameters['N'] 218 | for name, model in self.stochastic_models.items(): 219 | if name.startswith('S') and not name in skip: 220 | mS = model(params, M, N + M*self.iinfec) 221 | # print(mS.kk) 222 | mD = deterministic_models[name](params, M, N + M*self.iinfec) 223 | x0 = np.array([*self.parameters['N'], 224 | *np.ones(self.parameters['M'])*self.iinfec, 225 | *np.zeros(mS.nClass -2)], 226 | dtype=np.float64).reshape((mS.nClass,1)) 227 | trajectories = [] 228 | for i in range(self.nloops): 229 | traj = mS.simulate(*x0, self.contactMatrix, self.Tf, self.Tf, 230 | method='tau_leaping')['X'] 231 | trajectories.append(traj) 232 | traj_mean = np.mean(trajectories, axis=0) 233 | mean = mD.simulate(*x0, self.contactMatrix, self.Tf, self.Tf)['X'] 234 | absdiff = np.abs(traj_mean -mean)/(N*self.Tf) 235 | # print(name, np.sum(absdiff[:,:-1])) 236 | self.assertTrue(np.sum(absdiff[:,:-1])<0.01, 237 | "{name} model disagreement") 238 | 239 | def test_stochastic_integrators(self): 240 | """Compare tau leaping to Gillespie. 241 | This will fail because there is a problem with SIkR 242 | Also, difference is an order of magnitude greater than 243 | Gillespie from the mean. 244 | """ 245 | self.nloops=10 246 | params, M, N = self.parameters, self.parameters['M'], self.parameters['N'] 247 | for name, model in self.stochastic_models.items(): 248 | if name.startswith('S') and not name in skip: 249 | mS = model(params, M, N + M*self.iinfec) 250 | x0 = np.array([*self.parameters['N'], 251 | *np.ones(self.parameters['M'])*self.iinfec, 252 | *np.zeros(mS.nClass -2)], 253 | dtype=np.float64).reshape((mS.nClass,1)) 254 | gtraj = [] 255 | tautraj = [] 256 | for i in range(self.nloops): 257 | gtraj.append(mS.simulate(*x0, self.contactMatrix, self.Tf, self.Tf, 258 | method='gillespie')['X']) 259 | tautraj.append(mS.simulate(*x0, self.contactMatrix, self.Tf, self.Tf, 260 | method='tau_leaping', epsilon=1E-3)['X']) 261 | gmean = np.sum(gtraj, axis=0) 262 | taumean= np.sum(tautraj, axis=0) 263 | absdiff = np.abs(gmean - taumean)/(N*self.Tf) 264 | # print(name, np.sum(absdiff), np.shape(gmean), np.shape(taumean)) 265 | self.assertTrue(np.sum(absdiff)<.1, "{name} model disagreement") 266 | 267 | 268 | class ControlTest(unittest.TestCase): 269 | """testing control.pyx""" 270 | 271 | def __init__(self, *args, **kwargs): 272 | super(ControlTest, self).__init__(*args, **kwargs) 273 | self.parameters = DeterministicTest.parameters 274 | self.control_models = dict(inspect.getmembers(pyross.control, 275 | inspect.isclass)) 276 | 277 | def contactMatrix(self, t): return np.identity(self.parameters['M']) 278 | 279 | def test_init_models(self): 280 | """Initializes all control models""" 281 | for name, model in self.control_models.items(): 282 | if name.startswith('S') and not name in skip: 283 | params, M, N = self.parameters, self.parameters['M'], self.parameters['N'] 284 | m = model(params, M, N) 285 | 286 | 287 | class InferenceTest(unittest.TestCase): 288 | """testing inference.pyx""" 289 | 290 | def __init__(self, *args, **kwargs): 291 | super(InferenceTest, self).__init__(*args, **kwargs) 292 | self.parameters = DeterministicTest.parameters 293 | self.control_models = dict(inspect.getmembers(pyross.inference, 294 | inspect.isclass)) 295 | 296 | def contactMatrix(self, t): return np.identity(self.parameters['M']) 297 | 298 | def test_init_models(self): 299 | """Initializes all inference models""" 300 | for name, model in self.control_models.items(): 301 | if name.startswith('S') and not name in skip: 302 | params, M, Ni = self.parameters, self.parameters['M'], self.parameters['N'] 303 | N = int(np.sum(Ni)) 304 | fi = Ni/N 305 | steps = 10 306 | m = model(params, M, fi, N, steps) 307 | 308 | 309 | class ForecastTest(unittest.TestCase): 310 | """testing forcast.pyx""" 311 | 312 | def __init__(self, *args, **kwargs): 313 | super(ForecastTest, self).__init__(*args, **kwargs) 314 | self.parameters = DeterministicTest.parameters 315 | self.control_models = dict(inspect.getmembers(pyross.forecast, 316 | inspect.isclass)) 317 | self.parameters['cov'] = np.identity(2) 318 | 319 | def contactMatrix(self, t): return np.identity(self.parameters['M']) 320 | 321 | def test_init_models(self): 322 | """Initializes all forcast models""" 323 | for name, model in self.control_models.items(): 324 | if name.startswith('S') and not name in skip: 325 | params, M, Ni = self.parameters, self.parameters['M'], self.parameters['N'] 326 | N = int(np.sum(Ni)) 327 | fi = Ni/N 328 | m = model(params, M, Ni) 329 | 330 | 331 | class UtilsPythonTest(unittest.TestCase): 332 | """Testing the minimization function in utils_python.py""" 333 | 334 | def __init__(self, *args, **kwargs): 335 | super(UtilsPythonTest, self).__init__(*args, **kwargs) 336 | 337 | def test_minimization(self): 338 | """Test the minimization(...) function in utils_python.py with a few simple examples""" 339 | 340 | # A simple example 341 | f1 = lambda x, grad=0: 1 + np.linalg.norm(x)**3 342 | # A multi-modal example 343 | f2 = lambda x, grad=0: 1 + np.linalg.norm(x)**2 + 0.1*np.abs(np.sin(4*np.pi*np.linalg.norm(x))) 344 | 345 | # Test global optimisation 346 | guess = np.array([1.0, 1.0]) 347 | bounds = np.array([[-2.0, 2.0], [-2.0, 2.0]]) 348 | x, y = pyross.utils_python.minimization(f1, guess, bounds, enable_global=True, enable_local=False, 349 | ftol=1e-5, global_atol=1e-3, cma_random_seed=1, verbose=False) 350 | self.assertTrue(np.abs(y - 1.0) < 1e-3) 351 | 352 | x, y = pyross.utils_python.minimization(f2, guess, bounds, enable_global=True, enable_local=False, 353 | ftol=1e-5, global_atol=1e-3, verbose=False, cma_random_seed=2) 354 | self.assertTrue(np.abs(y - 1.0) < 1e-3) 355 | 356 | # Test local optimisation 357 | guess = np.array([2.0, 2.0]) 358 | bounds = np.array([[-5.0, 5.0], [-5.0, 5.0]]) 359 | x, y = pyross.utils_python.minimization(f1, guess, bounds, enable_global=False, enable_local=True, 360 | ftol=1e-5, verbose=False) 361 | self.assertTrue(np.abs(y - 1.0) < 1e-4) 362 | 363 | # And now combined 364 | x, y = pyross.utils_python.minimization(f2, guess, bounds, enable_global=True, enable_local=True, 365 | ftol=1e-5, global_atol=1e-3, verbose=False, cma_random_seed=4) 366 | self.assertTrue(np.abs(y - 1.0) < 1e-4) 367 | 368 | 369 | if __name__ == '__main__': 370 | unittest.main() 371 | --------------------------------------------------------------------------------