├── .DS_Store ├── .Rbuildignore ├── .github ├── .gitignore └── workflows │ ├── coverage.yaml │ ├── develop_build.yaml │ ├── master_build.yaml │ └── readme_render.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── R ├── .DS_Store ├── .Rapp.history ├── RcppExports.R ├── assertions_v13.R ├── cpp_template.R ├── data.R ├── diagnostic.R ├── drjacoby.R ├── drjacoby_output.R ├── main.R ├── plot.R ├── samples.R └── sysdata.rda ├── README.Rmd ├── README.md ├── R_ignore ├── .DS_Store ├── deploy.R └── images │ ├── Sunglasses.png │ ├── create_hex.R │ ├── dependence_table.png │ ├── infographic_coupling.png │ ├── loglady.jpg │ └── logo3.png ├── _pkgdown.yml ├── data └── population_data.rda ├── docs ├── .DS_Store ├── 404.html ├── LICENSE-text.html ├── LICENSE.html ├── articles │ ├── blocks.html │ ├── blocks_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ ├── figure-html │ │ │ ├── unnamed-chunk-8-1.png │ │ │ └── unnamed-chunk-9-1.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── checks_double_well.html │ ├── checks_double_well_files │ │ ├── figure-html │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ ├── unnamed-chunk-8-1.png │ │ │ ├── unnamed-chunk-8-2.png │ │ │ └── unnamed-chunk-9-1.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── checks_multilevel_blocks.html │ ├── checks_multilevel_blocks_files │ │ ├── figure-html │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-5-2.png │ │ │ ├── unnamed-chunk-5-3.png │ │ │ ├── unnamed-chunk-5-4.png │ │ │ └── unnamed-chunk-5-5.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── checks_normal_model.html │ ├── checks_normal_model_files │ │ ├── figure-html │ │ │ └── unnamed-chunk-5-1.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── checks_return_prior.html │ ├── checks_return_prior_files │ │ ├── figure-html │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-5-2.png │ │ │ ├── unnamed-chunk-5-3.png │ │ │ └── unnamed-chunk-5-4.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── example.html │ ├── example_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ ├── figure-html │ │ │ ├── unnamed-chunk-10-1.png │ │ │ ├── unnamed-chunk-10-2.png │ │ │ ├── unnamed-chunk-13-1.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ ├── unnamed-chunk-7-2.png │ │ │ ├── unnamed-chunk-8-1.png │ │ │ ├── unnamed-chunk-8-2.png │ │ │ ├── unnamed-chunk-9-1.png │ │ │ └── unnamed-chunk-9-2.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── getting_model_fits.html │ ├── getting_model_fits_files │ │ ├── figure-html │ │ │ ├── unnamed-chunk-3-1.png │ │ │ └── unnamed-chunk-8-1.png │ │ └── header-attrs-2.10 │ │ │ └── header-attrs.js │ ├── index.html │ ├── installation.html │ ├── installation_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ ├── figure-html │ │ │ ├── unnamed-chunk-1-1.png │ │ │ └── unnamed-chunk-1-2.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── metropolis_coupling.html │ ├── metropolis_coupling_files │ │ ├── accessible-code-block-0.0.1 │ │ │ └── empty-anchor.js │ │ ├── anchor-sections-1.0 │ │ │ ├── anchor-sections.css │ │ │ └── anchor-sections.js │ │ ├── figure-html │ │ │ ├── unnamed-chunk-1-1.png │ │ │ ├── unnamed-chunk-10-1.png │ │ │ ├── unnamed-chunk-10-2.png │ │ │ ├── unnamed-chunk-11-1.png │ │ │ ├── unnamed-chunk-11-2.png │ │ │ ├── unnamed-chunk-5-1.png │ │ │ ├── unnamed-chunk-6-1.png │ │ │ ├── unnamed-chunk-7-1.png │ │ │ ├── unnamed-chunk-8-1.png │ │ │ ├── unnamed-chunk-9-1.png │ │ │ └── unnamed-chunk-9-2.png │ │ ├── header-attrs-2.10 │ │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ │ └── header-attrs.js │ ├── parallel.html │ └── parallel_files │ │ ├── accessible-code-block-0.0.1 │ │ └── empty-anchor.js │ │ ├── anchor-sections-1.0 │ │ ├── anchor-sections.css │ │ └── anchor-sections.js │ │ ├── figure-html │ │ ├── unnamed-chunk-1-1.png │ │ ├── unnamed-chunk-1-2.png │ │ ├── unnamed-chunk-10-1.png │ │ └── unnamed-chunk-4-1.png │ │ ├── header-attrs-2.10 │ │ └── header-attrs.js │ │ └── header-attrs-2.9 │ │ └── header-attrs.js ├── authors.html ├── bootstrap-toc.css ├── bootstrap-toc.js ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── Rplot001.png │ ├── acf_data.html │ ├── check_drjacoby_loaded.html │ ├── check_likelihood_compilation.html │ ├── check_prior_compilation.html │ ├── cpp_function_get.html │ ├── cpp_template.html │ ├── define_default.html │ ├── define_params.html │ ├── drjacoby.html │ ├── drjacoby_cols.html │ ├── drjacoby_file.html │ ├── dummy1.html │ ├── ess.html │ ├── gelman_rubin.html │ ├── get_theta_rungs.html │ ├── index.html │ ├── plot_autocorrelation.html │ ├── plot_contour.html │ ├── plot_cor.html │ ├── plot_cor_mat.html │ ├── plot_credible.html │ ├── plot_mc_acceptance.html │ ├── plot_pairs.html │ ├── plot_par.html │ ├── plot_rung_loglike.html │ ├── plot_scatter.html │ ├── plot_trace.html │ ├── population_data.html │ ├── run_mcmc.html │ ├── sample_chains.html │ └── set_rhat.html └── sitemap.xml ├── drjacoby.Rproj ├── index.md ├── inst ├── .DS_Store ├── extdata │ ├── .DS_Store │ ├── blocks_loglike_logprior.cpp │ ├── checks │ │ ├── doublewell_loglike_logprior.cpp │ │ ├── multilevel_loglike_logprior.cpp │ │ ├── normal_loglike_logprior.cpp │ │ └── returnprior_loglike_logprior.cpp │ ├── coupling_loglike_logprior.cpp │ ├── example_loglike_logprior.cpp │ └── getting_model_fits_data.rds └── templates │ └── cpp_template.cpp ├── man ├── acf_data.Rd ├── check_drjacoby_loaded.Rd ├── cpp_template.Rd ├── define_params.Rd ├── drjacoby.Rd ├── gelman_rubin.Rd ├── plot_autocorrelation.Rd ├── plot_cor_mat.Rd ├── plot_credible.Rd ├── plot_density.Rd ├── plot_mc_acceptance.Rd ├── plot_pairs.Rd ├── plot_rung_loglike.Rd ├── plot_scatter.Rd ├── plot_trace.Rd ├── population_data.Rd ├── run_mcmc.Rd └── sample_chains.Rd ├── src ├── .DS_Store ├── .gitignore ├── Particle.cpp ├── Particle.h ├── RcppExports.cpp ├── System.cpp ├── System.h ├── main.cpp ├── main.h ├── misc.cpp └── misc.h ├── tests ├── .DS_Store ├── testthat.R └── testthat │ ├── .DS_Store │ ├── test-Inf_checks_work.R │ ├── test-assertions_v13.R │ ├── test-cpp_template.R │ ├── test-diagnostic.R │ ├── test-mcmc-with-cpp-likelihood-and-prior.R │ ├── test-mcmc-with-r-likelihood-and-prior.R │ ├── test-mcmc-wth-mixed-likelihood-and-prior.R │ ├── test-mcmc_with_multi_function_cpp.R │ ├── test-plot.R │ └── test_input_files │ ├── loglike_logprior.cpp │ └── multi_loglike_logprior.cpp └── vignettes ├── .gitignore ├── blocks.Rmd ├── checks_double_well.Rmd ├── checks_multilevel_blocks.Rmd ├── checks_normal_model.Rmd ├── checks_return_prior.Rmd ├── example.Rmd ├── getting_model_fits.Rmd ├── installation.Rmd ├── metropolis_coupling.Rmd └── parallel.Rmd /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/.DS_Store -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^data-raw$ 2 | ^Meta$ 3 | ^doc$ 4 | ^docs$ 5 | ^_pkgdown\.yml$ 6 | ^codecov\.yml$ 7 | ^.*\.Rproj$ 8 | ^\.Rproj\.user$ 9 | ignore/ 10 | R_ignore/ 11 | ^index.md 12 | ^\.github$ 13 | ^README\.Rmd$ 14 | test_scripts/ 15 | LICENSE.md 16 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | pull_request: 4 | 5 | name: test-coverage 6 | 7 | jobs: 8 | test-coverage: 9 | runs-on: macOS-latest 10 | env: 11 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - uses: r-lib/actions/setup-r@master 16 | 17 | - uses: r-lib/actions/setup-pandoc@master 18 | 19 | - name: Query dependencies 20 | run: | 21 | install.packages('remotes') 22 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 23 | shell: Rscript {0} 24 | 25 | - name: Cache R packages 26 | uses: actions/cache@v1 27 | with: 28 | path: ${{ env.R_LIBS_USER }} 29 | key: macOS-r-4.0-1-${{ hashFiles('.github/depends.Rds') }} 30 | restore-keys: macOS-r-4.0-1- 31 | 32 | - name: Install dependencies 33 | run: | 34 | install.packages(c("remotes")) 35 | remotes::install_deps(dependencies = TRUE) 36 | remotes::install_cran("covr") 37 | shell: Rscript {0} 38 | 39 | - name: Test coverage 40 | run: covr::codecov() 41 | shell: Rscript {0} 42 | -------------------------------------------------------------------------------- /.github/workflows/develop_build.yaml: -------------------------------------------------------------------------------- 1 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 2 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | pull_request: 8 | branches: 9 | - develop 10 | 11 | name: develop_build 12 | 13 | jobs: 14 | R-CMD-check: 15 | runs-on: ${{ matrix.config.os }} 16 | 17 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 18 | 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | config: 23 | - {os: windows-latest, r: 'release'} 24 | - {os: macOS-latest, r: 'release'} 25 | - {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} 26 | 27 | env: 28 | R_REMOTES_NO_ERRORS_FROM_WARNINGS: true 29 | RSPM: ${{ matrix.config.rspm }} 30 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | 35 | - uses: r-lib/actions/setup-r@v2 36 | with: 37 | r-version: ${{ matrix.config.r }} 38 | 39 | - uses: r-lib/actions/setup-pandoc@v1 40 | 41 | - name: Query dependencies 42 | run: | 43 | install.packages('remotes') 44 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 45 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 46 | shell: Rscript {0} 47 | 48 | - name: Cache R packages 49 | if: runner.os != 'Windows' 50 | uses: actions/cache@v2 51 | with: 52 | path: ${{ env.R_LIBS_USER }} 53 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 54 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 55 | 56 | - name: Install system dependencies 57 | if: runner.os == 'Linux' 58 | run: | 59 | while read -r cmd 60 | do 61 | eval sudo $cmd 62 | done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') 63 | 64 | - name: Install dependencies 65 | run: | 66 | remotes::install_deps(dependencies = TRUE) 67 | remotes::install_cran("rcmdcheck") 68 | shell: Rscript {0} 69 | 70 | - name: Check 71 | env: 72 | _R_CHECK_CRAN_INCOMING_REMOTE_: false 73 | run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 74 | shell: Rscript {0} 75 | 76 | - name: Upload check results 77 | if: failure() 78 | uses: actions/upload-artifact@main 79 | with: 80 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 81 | path: check 82 | -------------------------------------------------------------------------------- /.github/workflows/master_build.yaml: -------------------------------------------------------------------------------- 1 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 2 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | name: master_build 12 | 13 | jobs: 14 | R-CMD-check: 15 | runs-on: ${{ matrix.config.os }} 16 | 17 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 18 | 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | config: 23 | - {os: windows-latest, r: 'release'} 24 | - {os: macOS-latest, r: 'release'} 25 | - {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest"} 26 | 27 | env: 28 | R_REMOTES_NO_ERRORS_FROM_WARNINGS: true 29 | RSPM: ${{ matrix.config.rspm }} 30 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 31 | 32 | steps: 33 | - uses: actions/checkout@v2 34 | 35 | - uses: r-lib/actions/setup-r@v2 36 | with: 37 | r-version: ${{ matrix.config.r }} 38 | 39 | - uses: r-lib/actions/setup-pandoc@v1 40 | 41 | - name: Query dependencies 42 | run: | 43 | install.packages('remotes') 44 | saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) 45 | writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") 46 | shell: Rscript {0} 47 | 48 | - name: Cache R packages 49 | if: runner.os != 'Windows' 50 | uses: actions/cache@v2 51 | with: 52 | path: ${{ env.R_LIBS_USER }} 53 | key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} 54 | restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- 55 | 56 | - name: Install system dependencies 57 | if: runner.os == 'Linux' 58 | run: | 59 | while read -r cmd 60 | do 61 | eval sudo $cmd 62 | done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') 63 | 64 | - name: Install dependencies 65 | run: | 66 | remotes::install_deps(dependencies = TRUE) 67 | remotes::install_cran("rcmdcheck") 68 | shell: Rscript {0} 69 | 70 | - name: Check 71 | env: 72 | _R_CHECK_CRAN_INCOMING_REMOTE_: false 73 | run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") 74 | shell: Rscript {0} 75 | 76 | - name: Upload check results 77 | if: failure() 78 | uses: actions/upload-artifact@main 79 | with: 80 | name: ${{ runner.os }}-r${{ matrix.config.r }}-results 81 | path: check 82 | -------------------------------------------------------------------------------- /.github/workflows/readme_render.yaml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | paths: 4 | - README.Rmd 5 | 6 | name: Render README 7 | 8 | jobs: 9 | render: 10 | name: Render README 11 | runs-on: macOS-latest 12 | env: 13 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 14 | steps: 15 | - uses: actions/checkout@v2 16 | - uses: r-lib/actions/setup-r@v1 17 | - uses: r-lib/actions/setup-pandoc@v1 18 | - name: Install rmarkdown, remotes, and the local package 19 | run: | 20 | install.packages("remotes") 21 | remotes::install_local(".") 22 | remotes::install_cran("rmarkdown") 23 | shell: Rscript {0} 24 | - name: Render README 25 | run: Rscript -e 'rmarkdown::render("README.Rmd")' 26 | - name: Commit results 27 | run: | 28 | git config --local user.email "actions@github.com" 29 | git config --local user.name "GitHub Actions" 30 | git commit README.md -m 'Re-build README.Rmd' || echo "No changes to commit" 31 | git push origin || echo "No changes to commit" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Meta 2 | doc 3 | inst/doc 4 | .Rproj.user 5 | .Rhistory 6 | .RData 7 | .Ruserdata 8 | ignore/ 9 | test_scripts/ 10 | /doc/ 11 | /Meta/ 12 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: drjacoby 2 | Type: Package 3 | Title: Flexible Markov Chain Monte Carlo via Reparameterization 4 | Version: 1.5.4 5 | Authors@R: c( 6 | person("Bob", "Verity", email = "r.verity@imperial.ac.uk", role = c("aut", "cre")), 7 | person("Pete", "Winskill", email = "p.winskill@imperial.ac.uk", role = c("aut")) 8 | ) 9 | Description: drjacoby is an R package for performing Bayesian inference via 10 | Markov chain monte carlo (MCMC). In addition to being highly flexible it 11 | implements some advanced techniques that can improve mixing in tricky 12 | situations. 13 | License: MIT + file LICENSE 14 | Encoding: UTF-8 15 | LazyData: true 16 | RoxygenNote: 7.3.1 17 | LinkingTo: 18 | Rcpp 19 | Imports: 20 | Rcpp, 21 | coda, 22 | parallel, 23 | ggplot2, 24 | usethis, 25 | tools, 26 | rlang, 27 | cowplot, 28 | dplyr, 29 | magrittr, 30 | GGally, 31 | tidyr 32 | Suggests: 33 | testthat, 34 | covr, 35 | knitr, 36 | rmarkdown, 37 | microbenchmark, 38 | gridExtra 39 | BugReports: https://github.com/mrc-ide/drjacoby/issues 40 | VignetteBuilder: knitr 41 | Depends: R (>= 3.1.0) 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2024 2 | COPYRIGHT HOLDER: MRC Centre for Outbreak Analysis and Modelling 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 MRC Centre for Outbreak Analysis and Modelling 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 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(print,drjacoby_output) 4 | S3method(summary,drjacoby_output) 5 | export(check_drjacoby_loaded) 6 | export(cpp_template) 7 | export(define_params) 8 | export(plot_autocorrelation) 9 | export(plot_cor_mat) 10 | export(plot_credible) 11 | export(plot_density) 12 | export(plot_mc_acceptance) 13 | export(plot_pairs) 14 | export(plot_rung_loglike) 15 | export(plot_scatter) 16 | export(plot_trace) 17 | export(run_mcmc) 18 | export(sample_chains) 19 | import(dplyr) 20 | import(ggplot2) 21 | importFrom(GGally,ggpairs) 22 | importFrom(GGally,wrap) 23 | importFrom(Rcpp,sourceCpp) 24 | importFrom(coda,geweke.diag) 25 | importFrom(coda,mcmc) 26 | importFrom(grDevices,grey) 27 | importFrom(magrittr,"%>%") 28 | importFrom(stats,cor) 29 | importFrom(stats,pnorm) 30 | importFrom(stats,quantile) 31 | importFrom(stats,runif) 32 | importFrom(stats,setNames) 33 | importFrom(stats,var) 34 | importFrom(tidyr,pivot_longer) 35 | importFrom(utils,setTxtProgressBar) 36 | importFrom(utils,txtProgressBar) 37 | useDynLib(drjacoby, .registration = TRUE) 38 | -------------------------------------------------------------------------------- /R/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R/.DS_Store -------------------------------------------------------------------------------- /R/.Rapp.history: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R/.Rapp.history -------------------------------------------------------------------------------- /R/RcppExports.R: -------------------------------------------------------------------------------- 1 | # Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | main_cpp <- function(args) { 5 | .Call(`_drjacoby_main_cpp`, args) 6 | } 7 | 8 | -------------------------------------------------------------------------------- /R/cpp_template.R: -------------------------------------------------------------------------------- 1 | #' Create template for cpp 2 | #' 3 | #' @param save_as Path of (.cpp) file to create, relative to root of active project. 4 | #' 5 | #' @export 6 | cpp_template <- function (save_as){ 7 | assert_single_string(save_as) 8 | ext <- tools::file_ext(save_as) 9 | if(ext != "cpp"){ 10 | stop("File must be .cpp") 11 | } 12 | usethis::use_template( 13 | template = "cpp_template.cpp", 14 | save_as = save_as, 15 | open = rlang::is_interactive(), 16 | package = "drjacoby" 17 | ) 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /R/data.R: -------------------------------------------------------------------------------- 1 | #' Population data. 2 | #' 3 | #' Example population growth data. 4 | #' 5 | #' @format A data frame with 20 rows and 2 variables: 6 | #' \describe{ 7 | #' \item{pop}{population size} 8 | #' \item{time}{time} 9 | #' ... 10 | #' } 11 | "population_data" 12 | -------------------------------------------------------------------------------- /R/diagnostic.R: -------------------------------------------------------------------------------- 1 | #------------------------------------------------ 2 | #' Gelman-Rubin statistic 3 | #' 4 | #' Estimate sthe Gelman-Rubin (rhat) convergence statistic for a single parameter 5 | #' across multiple chains. Basic method, assuming all chains are of equal length 6 | #' 7 | #' @references Gelman, A., and D. B. Rubin. 1992. 8 | #' Inference from Iterative Simulation Using Multiple Sequences. 9 | #' Statistical Science 7: 457–511. 10 | #' @references \url{https://astrostatistics.psu.edu/RLectures/diagnosticsMCMC.pdf} 11 | #' 12 | #' @param par_matrix Matrix (interations x chains) 13 | #' @param chains number of chains 14 | #' @param samples number of samples 15 | #' 16 | #' @return Gelman-Rubin statistic 17 | gelman_rubin <- function(par_matrix, chains, samples){ 18 | 19 | # Check that >1 chains and >1 samples 20 | assert_gr(chains, 1) 21 | assert_gr(samples, 1) 22 | 23 | # Coerce to matrix 24 | par_matrix <- as.data.frame(par_matrix) 25 | 26 | # Mean over all samples 27 | all_mean <- mean(par_matrix[,2]) 28 | 29 | # Mean of each chain 30 | chain_mean <- tapply(par_matrix[,2], par_matrix[,1], mean) 31 | 32 | # Variance of each chain 33 | chain_var <- tapply(par_matrix[,2], par_matrix[,1], stats::var) 34 | W <- (1 / chains) * sum(chain_var) 35 | B <- samples / (chains - 1) * sum((chain_mean - all_mean)^2) 36 | V <- (1 - 1 / samples) * W + (1 / samples) * B 37 | round(sqrt(V / W), 4) 38 | } 39 | 40 | #------------------------------------------------ 41 | #' @title Estimate autocorrelation 42 | #' 43 | #' @inheritParams plot_autocorrelation 44 | #' @param x Single chain. 45 | acf_data <- function(x, lag){ 46 | stats::acf(x, plot = FALSE, lag.max = lag)$acf 47 | } 48 | 49 | #------------------------------------------------ 50 | # check that geweke p-value non-significant at alpha significance level on 51 | # values x[1:n] 52 | #' @importFrom coda mcmc 53 | #' @noRd 54 | test_convergence <- function(x, n, alpha = 0.01) { 55 | 56 | # check inputs 57 | assert_vector_numeric(x) 58 | assert_single_pos_int(n) 59 | assert_single_bounded(alpha) 60 | 61 | # fail if n = 1 62 | if (n == 1) { 63 | return(FALSE) 64 | } 65 | 66 | # fail if ESS too small 67 | ESS <- try(coda::effectiveSize(x[1:n]), silent = TRUE) 68 | if (inherits(ESS, "try-error")) { 69 | return(FALSE) 70 | } 71 | if (ESS < 10) { 72 | return(FALSE) 73 | } 74 | 75 | # fail if geweke p-value < threshold 76 | g <- geweke_pvalue(mcmc(x[1:n])) 77 | ret <- (g > alpha) 78 | 79 | # return 80 | return(ret) 81 | } 82 | 83 | #------------------------------------------------ 84 | # geweke_pvalue 85 | # return p-value of Geweke's diagnostic convergence statistic, estimated from 86 | # package coda 87 | #' @importFrom stats pnorm 88 | #' @importFrom coda geweke.diag 89 | #' @noRd 90 | geweke_pvalue <- function(x) { 91 | ret <- 2*pnorm(abs(coda::geweke.diag(x)$z), lower.tail = FALSE) 92 | return(ret) 93 | } 94 | 95 | -------------------------------------------------------------------------------- /R/drjacoby.R: -------------------------------------------------------------------------------- 1 | #------------------------------------------------ 2 | #' @title Flexible Markov Chain Monte Carlo via Reparameterization 3 | #' 4 | #' @description Flexible Markov chain monte carlo via reparameterization using 5 | #' the Jacobean matrix. 6 | #' 7 | #' _PACKAGE 8 | #' @name drjacoby 9 | NULL 10 | 11 | #------------------------------------------------ 12 | #' @useDynLib drjacoby, .registration = TRUE 13 | #' @importFrom Rcpp sourceCpp 14 | #' @importFrom magrittr %>% 15 | NULL 16 | 17 | #------------------------------------------------ 18 | # unload DLL when package is unloaded 19 | #' @noRd 20 | .onUnload <- function(libpath) { 21 | library.dynam.unload("drjacoby", libpath) # nocov 22 | } 23 | -------------------------------------------------------------------------------- /R/drjacoby_output.R: -------------------------------------------------------------------------------- 1 | 2 | #------------------------------------------------ 3 | # custom print output 4 | #' @method print drjacoby_output 5 | #' @export 6 | print.drjacoby_output <- function(x, ...) { 7 | 8 | # print summary 9 | summary(x) 10 | 11 | # return invisibly 12 | invisible(x) 13 | } 14 | 15 | #------------------------------------------------ 16 | # custom summary output 17 | #' @method summary drjacoby_output 18 | #' @export 19 | summary.drjacoby_output <- function(object, ...) { 20 | 21 | # print summary 22 | message("drjacoby output:") 23 | message(sprintf("%s chains", object$parameters$chains)) 24 | message(sprintf("%s rungs", object$parameters$rungs)) 25 | message(sprintf("%s burn-in iterations", object$parameters$burnin)) 26 | message(sprintf("%s sampling iterations", object$parameters$samples)) 27 | message(sprintf("%s parameters", length(object$parameters$df_params$name))) 28 | 29 | # return invisibly 30 | invisible(object) 31 | } 32 | -------------------------------------------------------------------------------- /R/samples.R: -------------------------------------------------------------------------------- 1 | #------------------------------------------------ 2 | # return 95% quantile 3 | #' @importFrom stats quantile 4 | #' @noRd 5 | quantile_95 <- function(x) { 6 | ret <- quantile(x, probs = c(0.025, 0.5, 0.975)) 7 | names(ret) <- c("Q2.5", "Q50", "Q97.5") 8 | return(ret) 9 | } 10 | 11 | #------------------------------------------------ 12 | #' Sample posterior draws from all available chains 13 | #' 14 | #' @param x an object of class \code{drjacoby_output}. 15 | #' @param sample_n An integer number of samples. 16 | #' @param keep_chain_index if \code{TRUE} then the column giving the chain is 17 | #' retained. 18 | #' 19 | #' @return A data.frame of posterior samples 20 | #' @export 21 | sample_chains <- function(x, sample_n, keep_chain_index = FALSE) { 22 | 23 | # avoid "no visible binding" note 24 | phase <- chain <- iteration <- logprior <- loglikelihood <- NULL 25 | 26 | # check inputs 27 | assert_class(x, "drjacoby_output") 28 | assert_pos_int(sample_n, zero_allowed = FALSE) 29 | assert_single_logical(keep_chain_index) 30 | 31 | # join chains 32 | all_chains <- x$output |> 33 | filter(phase == "sampling") |> 34 | select(-c(iteration, phase, logprior, loglikelihood)) 35 | if (!keep_chain_index) { 36 | all_chains <- all_chains |> 37 | select(-chain) 38 | } 39 | assert_leq(sample_n, nrow(all_chains), message = sprintf("sample_n cannot exceed the total number of samples over all chains (%s)", nrow(all_chains))) 40 | 41 | # sample chains 42 | sampled_chains <- all_chains[seq.int(1, nrow(all_chains), length.out = sample_n),, drop = FALSE] 43 | sampled_chains$sample <- 1:nrow(sampled_chains) 44 | 45 | return(sampled_chains) 46 | } 47 | 48 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R/sysdata.rda -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | 16 | DrJacoby 17 | =================================================== 18 | 19 | 20 | [![master build](https://github.com/mrc-ide/drjacoby/workflows/master_build/badge.svg)](https://github.com/mrc-ide/drjacoby/actions) 21 | [![develop build](https://github.com/mrc-ide/drjacoby/workflows/develop_build/badge.svg)](https://github.com/mrc-ide/drjacoby/actions) 22 | [![Coverage status](https://codecov.io/gh/mrc-ide/drjacoby/branch/master/graph/badge.svg)](https://codecov.io/github/mrc-ide/drjacoby?branch=master) 23 | 24 | 25 | *drjacoby* is an R package for performing Bayesian inference via Markov chain monte carlo (MCMC). In addition to being highly flexible it implements some advanced techniques that can improve mixing in tricky situations. Full details can be found on the drjacoby [website](https://mrc-ide.github.io/drjacoby/). 26 | 27 | So far, *drjacoby* has been used in the following projects: 28 | 29 | * The paper [Estimates of the severity of coronavirus disease 2019: a model-based analysis](https://doi.org/10.1016/S1473-3099(20)30243-7) used *drjacoby* **version 1.0.1** 30 | * The report [COVID-19 Infection Fatality Ratio: Estimates from Seroprevalence](https://www.imperial.ac.uk/mrc-global-infectious-disease-analysis/covid-19/report-34-ifr/) used *drjacoby* **version 1.2.0** 31 | 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # DrJacoby 5 | 6 | 7 | 8 | [![master 9 | build](https://github.com/mrc-ide/drjacoby/workflows/master_build/badge.svg)](https://github.com/mrc-ide/drjacoby/actions) 10 | [![develop 11 | build](https://github.com/mrc-ide/drjacoby/workflows/develop_build/badge.svg)](https://github.com/mrc-ide/drjacoby/actions) 12 | [![Coverage 13 | status](https://codecov.io/gh/mrc-ide/drjacoby/branch/master/graph/badge.svg)](https://codecov.io/github/mrc-ide/drjacoby?branch=master) 14 | 15 | 16 | *drjacoby* is an R package for performing Bayesian inference via Markov 17 | chain monte carlo (MCMC). In addition to being highly flexible it 18 | implements some advanced techniques that can improve mixing in tricky 19 | situations. Full details can be found on the drjacoby 20 | [website](https://mrc-ide.github.io/drjacoby/). 21 | 22 | So far, *drjacoby* has been used in the following projects: 23 | 24 | - The paper [Estimates of the severity of coronavirus disease 2019: a 25 | model-based analysis](https://doi.org/10.1016/S1473-3099(20)30243-7) 26 | used *drjacoby* **version 1.0.1** 27 | - The report [COVID-19 Infection Fatality Ratio: Estimates from 28 | Seroprevalence](https://www.imperial.ac.uk/mrc-global-infectious-disease-analysis/covid-19/report-34-ifr/) 29 | used *drjacoby* **version 1.2.0** 30 | -------------------------------------------------------------------------------- /R_ignore/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R_ignore/.DS_Store -------------------------------------------------------------------------------- /R_ignore/deploy.R: -------------------------------------------------------------------------------- 1 | 2 | # deploy.R 3 | # 4 | # Author: Bob Verity 5 | # Date: 2024-06-19 6 | # 7 | # Purpose: 8 | # Test package functions. 9 | 10 | # ------------------------------------------------------------------ 11 | 12 | library(tidyverse) 13 | 14 | # define R loglike function 15 | r_loglike <- function(params, data, misc) { 16 | sum(dnorm(data$x, mean = params["mu"], sd = params["sigma"], log = TRUE)) 17 | } 18 | 19 | # define R logprior function 20 | r_logprior <- function(params, misc) { 21 | dunif(params["mu"], -10, 10, log = TRUE) + dnorm(params["sigma"], 0, 1, log = TRUE) 22 | } 23 | 24 | # source C++ likelihood and prior 25 | #cpp11::cpp_source("ignore/source/normal_model.cpp") 26 | 27 | 28 | # ------------------------------------------------------------------ 29 | 30 | set.seed(1) 31 | 32 | # define data 33 | x <- rnorm(1e2, mean = 1, sd = 4) 34 | 35 | # define parameters dataframe 36 | df_params <- define_params(name = "mu", min = -10, max = 10, 37 | name = "sigma", min = 0, max = Inf) 38 | 39 | 40 | mcmc <- run_mcmc(data = list(x = x), 41 | df_params = df_params, 42 | loglike = r_loglike, 43 | logprior = r_logprior, 44 | burnin = 1e3, 45 | samples = 1e3) 46 | 47 | plot_trace(mcmc, show = "mu", phase = "burnin") 48 | 49 | plot_density(mcmc) 50 | -------------------------------------------------------------------------------- /R_ignore/images/Sunglasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R_ignore/images/Sunglasses.png -------------------------------------------------------------------------------- /R_ignore/images/create_hex.R: -------------------------------------------------------------------------------- 1 | # Create package hex image. 2 | path_image <- "R_ignore/images/Sunglasses.png" 3 | s <- hexSticker::sticker(subplot = path_image, 4 | package = "Dr Jacoby", p_size = 80, p_color = "darkred", 5 | s_x = 1, s_y = 0.8, s_width = 0.8, s_height = 0.8, 6 | h_fill = "white", 7 | h_color = "black", 8 | dpi = 1000, 9 | filename = "R_ignore/images/logo3.png", 10 | white_around_sticker = F) 11 | -------------------------------------------------------------------------------- /R_ignore/images/dependence_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R_ignore/images/dependence_table.png -------------------------------------------------------------------------------- /R_ignore/images/infographic_coupling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R_ignore/images/infographic_coupling.png -------------------------------------------------------------------------------- /R_ignore/images/loglady.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R_ignore/images/loglady.jpg -------------------------------------------------------------------------------- /R_ignore/images/logo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/R_ignore/images/logo3.png -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | 2 | title: drjacoby 3 | template: 4 | params: 5 | bootswatch: flatly 6 | 7 | navbar: 8 | title: "drjacoby" 9 | left: 10 | - text: "Vignettes" 11 | menu: 12 | - text: "Installation" 13 | href: articles/installation.html 14 | - text: "Basic Example" 15 | href: articles/example.html 16 | - text: "Parallel Tempering" 17 | href: articles/metropolis_coupling.html 18 | - text: "Running Parallel Chains" 19 | href: articles/parallel.html 20 | - text: "Getting Model Fits" 21 | href: articles/getting_model_fits.html 22 | - text: "Using Likelihood Blocks" 23 | href: articles/blocks.html 24 | - text: "Checks" 25 | menu: 26 | - text: "Return prior" 27 | href: articles/checks_return_prior.html 28 | - text: "Normal model" 29 | href: articles/checks_normal_model.html 30 | - text: "Double well" 31 | href: articles/checks_double_well.html 32 | - text: "Multilevel blocks" 33 | href: articles/checks_multilevel_blocks.html 34 | - text: "Functions" 35 | href: reference/index.html 36 | right: 37 | - icon: fa-github 38 | href: https://github.com/mrc-ide/drjacoby 39 | -------------------------------------------------------------------------------- /data/population_data.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/data/population_data.rda -------------------------------------------------------------------------------- /docs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/.DS_Store -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • drjacoby 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 |
24 |
106 | 107 | 108 | 109 | 110 |
111 |
112 | 115 | 116 | Content not found. Please use links in the navbar. 117 | 118 |
119 | 120 | 124 | 125 |
126 | 127 | 128 | 129 | 140 |
141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docs/LICENSE-text.html: -------------------------------------------------------------------------------- 1 | 2 | License • drjacoby 6 | 7 | 8 |
9 |
81 | 82 | 83 | 84 |
85 |
86 | 89 | 90 |
YEAR: 2024
 91 | COPYRIGHT HOLDER: MRC Centre for Outbreak Analysis and Modelling
 92 | 
93 | 94 |
95 | 96 | 99 | 100 |
101 | 102 | 103 | 104 |
113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/articles/blocks_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/blocks_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/blocks_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/blocks_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/blocks_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/blocks_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/blocks_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/blocks_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/blocks_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_double_well_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_double_well_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_double_well_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/figure-html/unnamed-chunk-8-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_double_well_files/figure-html/unnamed-chunk-8-2.png -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_double_well_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_double_well_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-2.png -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-3.png -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-4.png -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_multilevel_blocks_files/figure-html/unnamed-chunk-5-5.png -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_multilevel_blocks_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_normal_model_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_normal_model_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/checks_normal_model_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_normal_model_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-2.png -------------------------------------------------------------------------------- /docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-3.png -------------------------------------------------------------------------------- /docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/checks_return_prior_files/figure-html/unnamed-chunk-5-4.png -------------------------------------------------------------------------------- /docs/articles/checks_return_prior_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/checks_return_prior_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/example_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/example_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/example_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-10-2.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-13-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-13-1.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-8-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-8-2.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/example_files/figure-html/unnamed-chunk-9-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/example_files/figure-html/unnamed-chunk-9-2.png -------------------------------------------------------------------------------- /docs/articles/example_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/example_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/getting_model_fits_files/figure-html/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/getting_model_fits_files/figure-html/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /docs/articles/getting_model_fits_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/getting_model_fits_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/getting_model_fits_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/installation_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/installation_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/installation_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/installation_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/installation_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/installation_files/figure-html/unnamed-chunk-1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/installation_files/figure-html/unnamed-chunk-1-2.png -------------------------------------------------------------------------------- /docs/articles/installation_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/installation_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-10-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-10-2.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-11-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-11-2.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-9-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/metropolis_coupling_files/figure-html/unnamed-chunk-9-2.png -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/metropolis_coupling_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/parallel_files/accessible-code-block-0.0.1/empty-anchor.js: -------------------------------------------------------------------------------- 1 | // Hide empty tag within highlighted CodeBlock for screen reader accessibility (see https://github.com/jgm/pandoc/issues/6352#issuecomment-626106786) --> 2 | // v0.0.1 3 | // Written by JooYoung Seo (jooyoung@psu.edu) and Atsushi Yasumoto on June 1st, 2020. 4 | 5 | document.addEventListener('DOMContentLoaded', function() { 6 | const codeList = document.getElementsByClassName("sourceCode"); 7 | for (var i = 0; i < codeList.length; i++) { 8 | var linkList = codeList[i].getElementsByTagName('a'); 9 | for (var j = 0; j < linkList.length; j++) { 10 | if (linkList[j].innerHTML === "") { 11 | linkList[j].setAttribute('aria-hidden', 'true'); 12 | } 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /docs/articles/parallel_files/anchor-sections-1.0/anchor-sections.css: -------------------------------------------------------------------------------- 1 | /* Styles for section anchors */ 2 | a.anchor-section {margin-left: 10px; visibility: hidden; color: inherit;} 3 | a.anchor-section::before {content: '#';} 4 | .hasAnchor:hover a.anchor-section {visibility: visible;} 5 | -------------------------------------------------------------------------------- /docs/articles/parallel_files/anchor-sections-1.0/anchor-sections.js: -------------------------------------------------------------------------------- 1 | // Anchor sections v1.0 written by Atsushi Yasumoto on Oct 3rd, 2020. 2 | document.addEventListener('DOMContentLoaded', function() { 3 | // Do nothing if AnchorJS is used 4 | if (typeof window.anchors === 'object' && anchors.hasOwnProperty('hasAnchorJSLink')) { 5 | return; 6 | } 7 | 8 | const h = document.querySelectorAll('h1, h2, h3, h4, h5, h6'); 9 | 10 | // Do nothing if sections are already anchored 11 | if (Array.from(h).some(x => x.classList.contains('hasAnchor'))) { 12 | return null; 13 | } 14 | 15 | // Use section id when pandoc runs with --section-divs 16 | const section_id = function(x) { 17 | return ((x.classList.contains('section') || (x.tagName === 'SECTION')) 18 | ? x.id : ''); 19 | }; 20 | 21 | // Add anchors 22 | h.forEach(function(x) { 23 | const id = x.id || section_id(x.parentElement); 24 | if (id === '') { 25 | return null; 26 | } 27 | let anchor = document.createElement('a'); 28 | anchor.href = '#' + id; 29 | anchor.classList = ['anchor-section']; 30 | x.classList.add('hasAnchor'); 31 | x.appendChild(anchor); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /docs/articles/parallel_files/figure-html/unnamed-chunk-1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/parallel_files/figure-html/unnamed-chunk-1-1.png -------------------------------------------------------------------------------- /docs/articles/parallel_files/figure-html/unnamed-chunk-1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/parallel_files/figure-html/unnamed-chunk-1-2.png -------------------------------------------------------------------------------- /docs/articles/parallel_files/figure-html/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/parallel_files/figure-html/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/articles/parallel_files/figure-html/unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/articles/parallel_files/figure-html/unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/articles/parallel_files/header-attrs-2.10/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/articles/parallel_files/header-attrs-2.9/header-attrs.js: -------------------------------------------------------------------------------- 1 | // Pandoc 2.9 adds attributes on both header and div. We remove the former (to 2 | // be compatible with the behavior of Pandoc < 2.8). 3 | document.addEventListener('DOMContentLoaded', function(e) { 4 | var hs = document.querySelectorAll("div.section[class*='level'] > :first-child"); 5 | var i, h, a; 6 | for (i = 0; i < hs.length; i++) { 7 | h = hs[i]; 8 | if (!/^h[1-6]$/i.test(h.tagName)) continue; // it should be a header h1-h6 9 | a = h.attributes; 10 | while (a.length > 0) h.removeAttribute(a[0].name); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | 6 | /* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ 7 | 8 | /* All levels of nav */ 9 | nav[data-toggle='toc'] .nav > li > a { 10 | display: block; 11 | padding: 4px 20px; 12 | font-size: 13px; 13 | font-weight: 500; 14 | color: #767676; 15 | } 16 | nav[data-toggle='toc'] .nav > li > a:hover, 17 | nav[data-toggle='toc'] .nav > li > a:focus { 18 | padding-left: 19px; 19 | color: #563d7c; 20 | text-decoration: none; 21 | background-color: transparent; 22 | border-left: 1px solid #563d7c; 23 | } 24 | nav[data-toggle='toc'] .nav > .active > a, 25 | nav[data-toggle='toc'] .nav > .active:hover > a, 26 | nav[data-toggle='toc'] .nav > .active:focus > a { 27 | padding-left: 18px; 28 | font-weight: bold; 29 | color: #563d7c; 30 | background-color: transparent; 31 | border-left: 2px solid #563d7c; 32 | } 33 | 34 | /* Nav: second level (shown on .active) */ 35 | nav[data-toggle='toc'] .nav .nav { 36 | display: none; /* Hide by default, but at >768px, show it */ 37 | padding-bottom: 10px; 38 | } 39 | nav[data-toggle='toc'] .nav .nav > li > a { 40 | padding-top: 1px; 41 | padding-bottom: 1px; 42 | padding-left: 30px; 43 | font-size: 12px; 44 | font-weight: normal; 45 | } 46 | nav[data-toggle='toc'] .nav .nav > li > a:hover, 47 | nav[data-toggle='toc'] .nav .nav > li > a:focus { 48 | padding-left: 29px; 49 | } 50 | nav[data-toggle='toc'] .nav .nav > .active > a, 51 | nav[data-toggle='toc'] .nav .nav > .active:hover > a, 52 | nav[data-toggle='toc'] .nav .nav > .active:focus > a { 53 | padding-left: 28px; 54 | font-weight: 500; 55 | } 56 | 57 | /* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ 58 | nav[data-toggle='toc'] .nav > .active > ul { 59 | display: block; 60 | } 61 | -------------------------------------------------------------------------------- /docs/bootstrap-toc.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | (function() { 6 | 'use strict'; 7 | 8 | window.Toc = { 9 | helpers: { 10 | // return all matching elements in the set, or their descendants 11 | findOrFilter: function($el, selector) { 12 | // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ 13 | // http://stackoverflow.com/a/12731439/358804 14 | var $descendants = $el.find(selector); 15 | return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); 16 | }, 17 | 18 | generateUniqueIdBase: function(el) { 19 | var text = $(el).text(); 20 | var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); 21 | return anchor || el.tagName.toLowerCase(); 22 | }, 23 | 24 | generateUniqueId: function(el) { 25 | var anchorBase = this.generateUniqueIdBase(el); 26 | for (var i = 0; ; i++) { 27 | var anchor = anchorBase; 28 | if (i > 0) { 29 | // add suffix 30 | anchor += '-' + i; 31 | } 32 | // check if ID already exists 33 | if (!document.getElementById(anchor)) { 34 | return anchor; 35 | } 36 | } 37 | }, 38 | 39 | generateAnchor: function(el) { 40 | if (el.id) { 41 | return el.id; 42 | } else { 43 | var anchor = this.generateUniqueId(el); 44 | el.id = anchor; 45 | return anchor; 46 | } 47 | }, 48 | 49 | createNavList: function() { 50 | return $(''); 51 | }, 52 | 53 | createChildNavList: function($parent) { 54 | var $childList = this.createNavList(); 55 | $parent.append($childList); 56 | return $childList; 57 | }, 58 | 59 | generateNavEl: function(anchor, text) { 60 | var $a = $(''); 61 | $a.attr('href', '#' + anchor); 62 | $a.text(text); 63 | var $li = $('
  • '); 64 | $li.append($a); 65 | return $li; 66 | }, 67 | 68 | generateNavItem: function(headingEl) { 69 | var anchor = this.generateAnchor(headingEl); 70 | var $heading = $(headingEl); 71 | var text = $heading.data('toc-text') || $heading.text(); 72 | return this.generateNavEl(anchor, text); 73 | }, 74 | 75 | // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). 76 | getTopLevel: function($scope) { 77 | for (var i = 1; i <= 6; i++) { 78 | var $headings = this.findOrFilter($scope, 'h' + i); 79 | if ($headings.length > 1) { 80 | return i; 81 | } 82 | } 83 | 84 | return 1; 85 | }, 86 | 87 | // returns the elements for the top level, and the next below it 88 | getHeadings: function($scope, topLevel) { 89 | var topSelector = 'h' + topLevel; 90 | 91 | var secondaryLevel = topLevel + 1; 92 | var secondarySelector = 'h' + secondaryLevel; 93 | 94 | return this.findOrFilter($scope, topSelector + ',' + secondarySelector); 95 | }, 96 | 97 | getNavLevel: function(el) { 98 | return parseInt(el.tagName.charAt(1), 10); 99 | }, 100 | 101 | populateNav: function($topContext, topLevel, $headings) { 102 | var $context = $topContext; 103 | var $prevNav; 104 | 105 | var helpers = this; 106 | $headings.each(function(i, el) { 107 | var $newNav = helpers.generateNavItem(el); 108 | var navLevel = helpers.getNavLevel(el); 109 | 110 | // determine the proper $context 111 | if (navLevel === topLevel) { 112 | // use top level 113 | $context = $topContext; 114 | } else if ($prevNav && $context === $topContext) { 115 | // create a new level of the tree and switch to it 116 | $context = helpers.createChildNavList($prevNav); 117 | } // else use the current $context 118 | 119 | $context.append($newNav); 120 | 121 | $prevNav = $newNav; 122 | }); 123 | }, 124 | 125 | parseOps: function(arg) { 126 | var opts; 127 | if (arg.jquery) { 128 | opts = { 129 | $nav: arg 130 | }; 131 | } else { 132 | opts = arg; 133 | } 134 | opts.$scope = opts.$scope || $(document.body); 135 | return opts; 136 | } 137 | }, 138 | 139 | // accepts a jQuery object, or an options object 140 | init: function(opts) { 141 | opts = this.helpers.parseOps(opts); 142 | 143 | // ensure that the data attribute is in place for styling 144 | opts.$nav.attr('data-toggle', 'toc'); 145 | 146 | var $topContext = this.helpers.createChildNavList(opts.$nav); 147 | var topLevel = this.helpers.getTopLevel(opts.$scope); 148 | var $headings = this.helpers.getHeadings(opts.$scope, topLevel); 149 | this.helpers.populateNav($topContext, topLevel, $headings); 150 | } 151 | }; 152 | 153 | $(function() { 154 | $('nav[data-toggle="toc"]').each(function(i, el) { 155 | var $nav = $(el); 156 | Toc.init($nav); 157 | }); 158 | }); 159 | })(); 160 | -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('[data-toggle="tooltip"]').tooltip(); 13 | 14 | var cur_path = paths(location.pathname); 15 | var links = $("#navbar ul li a"); 16 | var max_length = -1; 17 | var pos = -1; 18 | for (var i = 0; i < links.length; i++) { 19 | if (links[i].getAttribute("href") === "#") 20 | continue; 21 | // Ignore external links 22 | if (links[i].host !== location.host) 23 | continue; 24 | 25 | var nav_path = paths(links[i].pathname); 26 | 27 | var length = prefix_length(nav_path, cur_path); 28 | if (length > max_length) { 29 | max_length = length; 30 | pos = i; 31 | } 32 | } 33 | 34 | // Add class to parent
  • , and enclosing
  • if in dropdown 35 | if (pos >= 0) { 36 | var menu_anchor = $(links[pos]); 37 | menu_anchor.parent().addClass("active"); 38 | menu_anchor.closest("li.dropdown").addClass("active"); 39 | } 40 | }); 41 | 42 | function paths(pathname) { 43 | var pieces = pathname.split("/"); 44 | pieces.shift(); // always starts with / 45 | 46 | var end = pieces[pieces.length - 1]; 47 | if (end === "index.html" || end === "") 48 | pieces.pop(); 49 | return(pieces); 50 | } 51 | 52 | // Returns -1 if not found 53 | function prefix_length(needle, haystack) { 54 | if (needle.length > haystack.length) 55 | return(-1); 56 | 57 | // Special case for length-0 haystack, since for loop won't run 58 | if (haystack.length === 0) { 59 | return(needle.length === 0 ? 0 : -1); 60 | } 61 | 62 | for (var i = 0; i < haystack.length; i++) { 63 | if (needle[i] != haystack[i]) 64 | return(i); 65 | } 66 | 67 | return(haystack.length); 68 | } 69 | 70 | /* Clipboard --------------------------*/ 71 | 72 | function changeTooltipMessage(element, msg) { 73 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 74 | element.setAttribute('data-original-title', msg); 75 | $(element).tooltip('show'); 76 | element.setAttribute('data-original-title', tooltipOriginalTitle); 77 | } 78 | 79 | if(ClipboardJS.isSupported()) { 80 | $(document).ready(function() { 81 | var copyButton = ""; 82 | 83 | $("div.sourceCode").addClass("hasCopyButton"); 84 | 85 | // Insert copy buttons: 86 | $(copyButton).prependTo(".hasCopyButton"); 87 | 88 | // Initialize tooltips: 89 | $('.btn-copy-ex').tooltip({container: 'body'}); 90 | 91 | // Initialize clipboard: 92 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 93 | text: function(trigger) { 94 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 95 | } 96 | }); 97 | 98 | clipboardBtnCopies.on('success', function(e) { 99 | changeTooltipMessage(e.trigger, 'Copied!'); 100 | e.clearSelection(); 101 | }); 102 | 103 | clipboardBtnCopies.on('error', function() { 104 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 105 | }); 106 | }); 107 | } 108 | })(window.jQuery || window.$) 109 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 3.1.11 2 | pkgdown: 2.0.9 3 | pkgdown_sha: ~ 4 | articles: 5 | blocks: blocks.html 6 | checks_double_well: checks_double_well.html 7 | checks_multilevel_blocks: checks_multilevel_blocks.html 8 | checks_normal_model: checks_normal_model.html 9 | checks_return_prior: checks_return_prior.html 10 | example: example.html 11 | getting_model_fits: getting_model_fits.html 12 | installation: installation.html 13 | metropolis_coupling: metropolis_coupling.html 14 | parallel: parallel.html 15 | last_built: 2024-06-26T00:19Z 16 | 17 | -------------------------------------------------------------------------------- /docs/reference/Rplot001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/docs/reference/Rplot001.png -------------------------------------------------------------------------------- /docs/reference/define_default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Replace with default values — define_default • drjacoby 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | 54 |
    55 |
    56 | 90 | 91 | 92 |
    93 | 94 |
    95 |
    96 | 101 | 102 |
    103 | 104 |

    If NULL then replace with chosen value, otherwise keep original 105 | value.

    106 | 107 |
    108 | 109 |
    define_default(x, default)
    110 | 111 |

    Arguments

    112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
    x

    object to define default.

    default

    default value.

    123 | 124 | 125 |
    126 | 133 |
    134 | 135 |
    136 | 139 | 140 |
    141 |

    Site built with pkgdown 1.3.0.

    142 |
    143 |
    144 |
    145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /docs/reference/drjacoby_cols.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Series of standard colours used within the drjacoby package — drjacoby_cols • drjacoby 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
    64 |
    65 | 119 | 120 | 121 | 122 |
    123 | 124 |
    125 |
    126 | 131 | 132 |
    133 |

    Returns a series of standard colours used within the drjacoby 134 | package.

    135 |
    136 | 137 |
    drjacoby_cols()
    138 | 139 | 140 | 141 |
    142 | 147 |
    148 | 149 | 150 |
    151 | 154 | 155 |
    156 |

    Site built with pkgdown 1.5.1.

    157 |
    158 | 159 |
    160 |
    161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/reference/ess.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Effective sample size — ess • drjacoby 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 56 |
    57 |
    58 | 113 | 114 | 115 |
    116 | 117 |
    118 |
    119 | 124 | 125 |
    126 | 127 |

    Estimates effective sample size. 128 | Note 1: Lag is trunctaed at when autocorrelation < 0.05, 129 | if -ve autocorrelation occurs it is possible to get ess > N. 130 | Note 2: ESS estimates will be too optimistic for chains that haven’t mixed.

    131 | 132 |
    133 | 134 |
    ess(x)
    135 | 136 |

    Arguments

    137 | 138 | 139 | 140 | 141 | 142 | 143 |
    x

    chain

    144 | 145 |

    Value

    146 | 147 |

    The effective sample size of a chain

    148 | 149 | 150 |
    151 | 160 |
    161 | 162 |
    163 | 166 | 167 |
    168 |

    Site built with pkgdown 1.3.0.

    169 |
    170 |
    171 |
    172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /404.html 5 | 6 | 7 | /LICENSE-text.html 8 | 9 | 10 | /LICENSE.html 11 | 12 | 13 | /articles/blocks.html 14 | 15 | 16 | /articles/checks_double_well.html 17 | 18 | 19 | /articles/checks_multilevel_blocks.html 20 | 21 | 22 | /articles/checks_normal_model.html 23 | 24 | 25 | /articles/checks_return_prior.html 26 | 27 | 28 | /articles/example.html 29 | 30 | 31 | /articles/getting_model_fits.html 32 | 33 | 34 | /articles/index.html 35 | 36 | 37 | /articles/installation.html 38 | 39 | 40 | /articles/metropolis_coupling.html 41 | 42 | 43 | /articles/parallel.html 44 | 45 | 46 | /authors.html 47 | 48 | 49 | /index.html 50 | 51 | 52 | /reference/acf_data.html 53 | 54 | 55 | /reference/check_drjacoby_loaded.html 56 | 57 | 58 | /reference/check_likelihood_compilation.html 59 | 60 | 61 | /reference/check_prior_compilation.html 62 | 63 | 64 | /reference/cpp_function_get.html 65 | 66 | 67 | /reference/cpp_template.html 68 | 69 | 70 | /reference/define_default.html 71 | 72 | 73 | /reference/define_params.html 74 | 75 | 76 | /reference/drjacoby.html 77 | 78 | 79 | /reference/drjacoby_cols.html 80 | 81 | 82 | /reference/drjacoby_file.html 83 | 84 | 85 | /reference/dummy1.html 86 | 87 | 88 | /reference/ess.html 89 | 90 | 91 | /reference/gelman_rubin.html 92 | 93 | 94 | /reference/get_theta_rungs.html 95 | 96 | 97 | /reference/index.html 98 | 99 | 100 | /reference/plot_autocorrelation.html 101 | 102 | 103 | /reference/plot_contour.html 104 | 105 | 106 | /reference/plot_cor.html 107 | 108 | 109 | /reference/plot_cor_mat.html 110 | 111 | 112 | /reference/plot_credible.html 113 | 114 | 115 | /reference/plot_mc_acceptance.html 116 | 117 | 118 | /reference/plot_pairs.html 119 | 120 | 121 | /reference/plot_par.html 122 | 123 | 124 | /reference/plot_rung_loglike.html 125 | 126 | 127 | /reference/plot_scatter.html 128 | 129 | 130 | /reference/plot_trace.html 131 | 132 | 133 | /reference/population_data.html 134 | 135 | 136 | /reference/run_mcmc.html 137 | 138 | 139 | /reference/sample_chains.html 140 | 141 | 142 | /reference/set_rhat.html 143 | 144 | 145 | -------------------------------------------------------------------------------- /drjacoby.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | 17 | BuildType: Package 18 | PackageUseDevtools: Yes 19 | PackageInstallArgs: --no-multiarch --with-keep.source 20 | PackageRoxygenize: rd,collate,namespace 21 | -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | 2 |

    Dr. Jacoby

    3 | 4 | [![master build](https://github.com/mrc-ide/drjacoby/workflows/master_build/badge.svg)](https://github.com/mrc-ide/drjacoby/actions) 5 | [![develop build](https://github.com/mrc-ide/drjacoby/workflows/develop_build/badge.svg)](https://github.com/mrc-ide/drjacoby/actions) 6 | [![Coverage status](https://codecov.io/gh/mrc-ide/drjacoby/branch/master/graph/badge.svg)](https://codecov.io/github/mrc-ide/drjacoby?branch=master) 7 | 8 |
    9 | 10 | *drjacoby* is a package for running flexible Markov chain Monte Carlo (MCMC) with minimal fiddling required by the user. The likelihood and the priors that go into the model can be written as either R or C++ functions, with the latter typically being much faster to run. Outputs are produced in a standardised format, and can be explored using a range of built in diagnostic plots and statistics. 11 | 12 |

    13 |

    *drjacoby* uses parallel tempering to "melt" the target distribution,
    thereby allowing information to pass between well-separated peaks.

    14 | 15 | There are many MCMC programs out there, including more far-reaching programs such as WinBUGS, JAGS, greta, STAN, and many more. These programs contain a wide variety of options for specifying complex models, and often run different flavours of MCMC such as Hamiltonian Monte Carlo (HMC). In contrast, *drjacoby* is tailored to a specific type of MCMC problem: those that **mix poorly due to highly correlated and/or multi-modal posteriors**, which can occur in both simple and complex models. If the posterior is particularly peaky then even methods like HMC may fail, meaning (unfortunately) no amount of STAN iterations will get us to the right answer. There are techniques available for dealing with this sort of problem, but they tend to be fairly advanced and tricky to implement. The aim of *drjacoby* is to bring these methods within reach of a non-specialist MCMC user, so that reliable results can be obtained without the need to code a custom MCMC program from scratch. 16 | 17 | After [installing](https://mrc-ide.github.io/drjacoby/articles/installation.html) *drjacoby*, please take at look at the first [example application](https://mrc-ide.github.io/drjacoby/articles/example.html) to get up and running. 18 | -------------------------------------------------------------------------------- /inst/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/inst/.DS_Store -------------------------------------------------------------------------------- /inst/extdata/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/inst/extdata/.DS_Store -------------------------------------------------------------------------------- /inst/extdata/blocks_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | 7 | // unpack parameters 8 | int pi = 0; 9 | std::vector mu(6); 10 | for (int i = 0; i < 6; ++i) { 11 | mu[i] = params[pi++]; 12 | } 13 | double sigma = params["sigma"]; 14 | double phi = params["phi"]; 15 | double tau = params["tau"]; 16 | 17 | // get current update block 18 | int block = misc["block"]; 19 | 20 | // distinct method for first 6 blocks, vs 7th 21 | double ret = 0.0; 22 | if (block == 7) { // likelihood for the global parameters 23 | 24 | // calculate likelihood component 25 | for (int i = 0; i < 6; ++i) { 26 | ret += R::dnorm(mu[i], phi, tau, true); 27 | } 28 | 29 | } else { // likelihood for each of the 6 data groups 30 | 31 | // get data for this group 32 | NumericVector x = data[block - 1]; 33 | 34 | // calculate likelihood component 35 | for (int i = 0; i < x.size(); ++i) { 36 | ret += R::dnorm(x[i], mu[block - 1], sigma, true); 37 | } 38 | 39 | } 40 | 41 | return Rcpp::wrap(ret); 42 | } 43 | 44 | // [[Rcpp::export]] 45 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 46 | 47 | // unpack parameters 48 | double sigma = params["sigma"]; 49 | double phi = params["phi"]; 50 | double tau = params["tau"]; 51 | 52 | // apply priors 53 | double ret = R::dgamma(sigma, 0.01, 100.0, true) + 54 | R::dnorm(phi, 0, 1000, true) + 55 | R::dgamma(tau, 0.01, 100.0, true); 56 | 57 | return Rcpp::wrap(ret); 58 | } 59 | 60 | // [[Rcpp::export]] 61 | SEXP create_xptr(std::string function_name) { 62 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 63 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 64 | 65 | if (function_name == "loglike"){ 66 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 67 | } 68 | if (function_name == "logprior"){ 69 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 70 | } 71 | 72 | stop("cpp function %i not found", function_name); 73 | } 74 | -------------------------------------------------------------------------------- /inst/extdata/checks/doublewell_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | double mu = params["mu"]; 7 | double gamma = params["gamma"]; 8 | double ret = -gamma*(mu*mu - 1.0)*(mu*mu - 1.0); 9 | 10 | return Rcpp::wrap(ret); 11 | } 12 | 13 | // [[Rcpp::export]] 14 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 15 | return Rcpp::wrap(0.0); 16 | } 17 | 18 | // [[Rcpp::export]] 19 | SEXP create_xptr(std::string function_name) { 20 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 21 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 22 | 23 | if (function_name == "loglike"){ 24 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 25 | } 26 | if (function_name == "logprior"){ 27 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 28 | } 29 | 30 | stop("cpp function %i not found", function_name); 31 | } 32 | -------------------------------------------------------------------------------- /inst/extdata/checks/multilevel_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | 7 | int pi = 0; 8 | std::vector mu(5); 9 | for (int i = 0; i < 5; ++i) { 10 | mu[i] = params[pi++]; 11 | } 12 | 13 | int block = misc["block"]; 14 | 15 | double ret = 0.0; 16 | if (block == 6) { // likelihood for the global parameters 17 | for (int i = 0; i < 5; ++i) { 18 | ret += R::dnorm(mu[i], 0, 1.0, true); 19 | } 20 | } else { // likelihood for each of the 6 data groups 21 | NumericVector x = data[block - 1]; 22 | for (int i = 0; i < x.size(); ++i) { 23 | ret += R::dnorm(x[i], mu[block - 1], 1.0, true); 24 | } 25 | } 26 | 27 | return Rcpp::wrap(ret); 28 | } 29 | 30 | // [[Rcpp::export]] 31 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 32 | return Rcpp::wrap(0.0); 33 | } 34 | 35 | // [[Rcpp::export]] 36 | SEXP create_xptr(std::string function_name) { 37 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 38 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 39 | 40 | if (function_name == "loglike"){ 41 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 42 | } 43 | if (function_name == "logprior"){ 44 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 45 | } 46 | 47 | stop("cpp function %i not found", function_name); 48 | } 49 | -------------------------------------------------------------------------------- /inst/extdata/checks/normal_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | 7 | std::vector x = Rcpp::as< std::vector >(data["x"]); 8 | 9 | double ret = 0.0; 10 | for (unsigned int i = 0; i < x.size(); ++i) { 11 | ret += R::dnorm(x[i], params["mu"], 1.0, true); 12 | } 13 | 14 | return Rcpp::wrap(ret); 15 | } 16 | 17 | // [[Rcpp::export]] 18 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 19 | return Rcpp::wrap(0.0); 20 | } 21 | 22 | // [[Rcpp::export]] 23 | SEXP create_xptr(std::string function_name) { 24 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 25 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 26 | 27 | if (function_name == "loglike"){ 28 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 29 | } 30 | 31 | if (function_name == "logprior"){ 32 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 33 | } 34 | 35 | stop("cpp function %i not found", function_name); 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /inst/extdata/checks/returnprior_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | return Rcpp::wrap(0.0); 7 | } 8 | 9 | // [[Rcpp::export]] 10 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 11 | 12 | double ret = R::dnorm(params["real_line"], 0.0, 1.0, true) + 13 | R::dgamma(-params["neg_line"], 5.0, 5.0, true) + 14 | R::dgamma(params["pos_line"], 5.0, 5.0, true) + 15 | R::dbeta(params["unit_interval"], 3.0, 3.0, true); 16 | 17 | return Rcpp::wrap(ret); 18 | } 19 | 20 | // [[Rcpp::export]] 21 | SEXP create_xptr(std::string function_name) { 22 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 23 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 24 | 25 | if (function_name == "loglike"){ 26 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 27 | } 28 | if (function_name == "logprior"){ 29 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 30 | } 31 | 32 | stop("cpp function %i not found", function_name); 33 | } 34 | -------------------------------------------------------------------------------- /inst/extdata/coupling_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | 7 | // unpack data 8 | std::vector x = Rcpp::as< std::vector >(data["x"]); 9 | 10 | // unpack parameters 11 | double alpha = params["alpha"]; 12 | double beta = params["beta"]; 13 | double epsilon = params["epsilon"]; 14 | 15 | // sum log-likelihood over all data 16 | double mean = alpha*alpha*beta + epsilon; 17 | double ret = 0.0; 18 | for (unsigned int i = 0; i < x.size(); ++i) { 19 | ret += R::dnorm(x[i], mean, 1.0, true); 20 | } 21 | 22 | // return as SEXP 23 | return Rcpp::wrap(ret); 24 | } 25 | 26 | // [[Rcpp::export]] 27 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 28 | 29 | // unpack parameters 30 | double epsilon = params["epsilon"]; 31 | 32 | // calculate logprior 33 | double ret = -log(20.0) - log(10.0) + R::dnorm(epsilon, 0.0, 1.0, true); 34 | 35 | // return as SEXP 36 | return Rcpp::wrap(ret); 37 | } 38 | 39 | // [[Rcpp::export]] 40 | SEXP create_xptr(std::string function_name) { 41 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 42 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 43 | 44 | if (function_name == "loglike"){ 45 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 46 | } 47 | if (function_name == "logprior"){ 48 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 49 | } 50 | 51 | stop("cpp function %i not found", function_name); 52 | } 53 | -------------------------------------------------------------------------------- /inst/extdata/example_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | 7 | // extract parameters 8 | double mu = params["mu"]; 9 | double sigma = params["sigma"]; 10 | 11 | // unpack data 12 | std::vector x = Rcpp::as< std::vector >(data["x"]); 13 | 14 | // sum log-likelihood over all data 15 | double ret = 0.0; 16 | for (unsigned int i = 0; i < x.size(); ++i) { 17 | ret += R::dnorm(x[i], mu, sigma, true); 18 | } 19 | 20 | // return as SEXP 21 | return Rcpp::wrap(ret); 22 | } 23 | 24 | // [[Rcpp::export]] 25 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 26 | 27 | // extract parameters 28 | double sigma = params["sigma"]; 29 | 30 | // calculate logprior 31 | double ret = -log(20.0) + R::dlnorm(sigma, 0.0, 1.0, true); 32 | 33 | // return as SEXP 34 | return Rcpp::wrap(ret); 35 | } 36 | 37 | // [[Rcpp::export]] 38 | SEXP create_xptr(std::string function_name) { 39 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 40 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 41 | 42 | if (function_name == "loglike"){ 43 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 44 | } 45 | if (function_name == "logprior"){ 46 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 47 | } 48 | 49 | stop("cpp function %i not found", function_name); 50 | } 51 | -------------------------------------------------------------------------------- /inst/extdata/getting_model_fits_data.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/inst/extdata/getting_model_fits_data.rds -------------------------------------------------------------------------------- /inst/templates/cpp_template.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // [[Rcpp::export]] 5 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 6 | // Insert loglikelihood code here: 7 | 8 | double loglikelihood = 0.0; 9 | return Rcpp::wrap(loglikelihood); 10 | } 11 | 12 | // [[Rcpp::export]] 13 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 14 | // Insert loglikelihood code here: 15 | 16 | double logprior = 0.0; 17 | return Rcpp::wrap(logprior); 18 | } 19 | 20 | 21 | // NOTE: Do not edit this function name 22 | // [[Rcpp::export]] 23 | SEXP create_xptr(std::string function_name) { 24 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 25 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 26 | 27 | // NOTE: If your loglikelihood function is not called "loglike" please edit: 28 | if (function_name == "loglike"){ 29 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 30 | } 31 | // NOTE: If your logprior function is not called "logprior" please edit: 32 | if (function_name == "logprior"){ 33 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 34 | } 35 | 36 | stop("cpp function %i not found", function_name); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /man/acf_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostic.R 3 | \name{acf_data} 4 | \alias{acf_data} 5 | \title{Estimate autocorrelation} 6 | \usage{ 7 | acf_data(x, lag) 8 | } 9 | \arguments{ 10 | \item{x}{Single chain.} 11 | 12 | \item{lag}{maximum lag. Must be an integer between 1 and 500.} 13 | } 14 | \description{ 15 | Estimate autocorrelation 16 | } 17 | -------------------------------------------------------------------------------- /man/check_drjacoby_loaded.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/main.R 3 | \name{check_drjacoby_loaded} 4 | \alias{check_drjacoby_loaded} 5 | \title{Check that drjacoby package has loaded successfully} 6 | \usage{ 7 | check_drjacoby_loaded() 8 | } 9 | \description{ 10 | Simple function to check that drjacoby package has loaded 11 | successfully. Prints "drjacoby loaded successfully!" if so. 12 | } 13 | -------------------------------------------------------------------------------- /man/cpp_template.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cpp_template.R 3 | \name{cpp_template} 4 | \alias{cpp_template} 5 | \title{Create template for cpp} 6 | \usage{ 7 | cpp_template(save_as) 8 | } 9 | \arguments{ 10 | \item{save_as}{Path of (.cpp) file to create, relative to root of active project.} 11 | } 12 | \description{ 13 | Create template for cpp 14 | } 15 | -------------------------------------------------------------------------------- /man/define_params.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/main.R 3 | \name{define_params} 4 | \alias{define_params} 5 | \title{Define parameters dataframe} 6 | \usage{ 7 | define_params(...) 8 | } 9 | \arguments{ 10 | \item{...}{a series of named input arguments.} 11 | } 12 | \description{ 13 | Provides a convenient way of defining parameters in the format 14 | required by \code{run_mcmc()}. Each parameter must have the following three 15 | elements, defined in order: 16 | \itemize{ 17 | \item \code{name} - the parameter name. 18 | \item \code{min} - the minimum value of the parameter. \code{-Inf} is 19 | allowed. 20 | \item \code{max} - the maximum value of the parameter. \code{Inf} is 21 | allowed. 22 | } 23 | There following arguments are also optional: 24 | \itemize{ 25 | \item \code{init} - the initial value of the parameter. If running 26 | multiple chains a vector of initial values can be used to specify distinct 27 | values for each chain. 28 | \item \code{block} - which likelihood block(s) this parameter belongs to. 29 | See vignettes for instructions on using likelihood blocks. 30 | } 31 | } 32 | \examples{ 33 | define_params(name = "mu", min = -10, max = 10, init = 0, 34 | name = "sigma", min = 0, max = 5, init = c(1, 2)) 35 | 36 | define_params(name = "mu1", min = -10, max = 10, init = 0, block = 1, 37 | name = "mu2", min = -10, max = 10, init = 0, block = 2, 38 | name = "sigma", min = 0, max = 5, init = 1, block = c(1, 2)) 39 | } 40 | -------------------------------------------------------------------------------- /man/drjacoby.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/drjacoby.R 3 | \name{drjacoby} 4 | \alias{drjacoby} 5 | \title{Flexible Markov Chain Monte Carlo via Reparameterization} 6 | \description{ 7 | Flexible Markov chain monte carlo via reparameterization using 8 | the Jacobean matrix. 9 | 10 | _PACKAGE 11 | } 12 | -------------------------------------------------------------------------------- /man/gelman_rubin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostic.R 3 | \name{gelman_rubin} 4 | \alias{gelman_rubin} 5 | \title{Gelman-Rubin statistic} 6 | \usage{ 7 | gelman_rubin(par_matrix, chains, samples) 8 | } 9 | \arguments{ 10 | \item{par_matrix}{Matrix (interations x chains)} 11 | 12 | \item{chains}{number of chains} 13 | 14 | \item{samples}{number of samples} 15 | } 16 | \value{ 17 | Gelman-Rubin statistic 18 | } 19 | \description{ 20 | Estimate sthe Gelman-Rubin (rhat) convergence statistic for a single parameter 21 | across multiple chains. Basic method, assuming all chains are of equal length 22 | } 23 | \references{ 24 | Gelman, A., and D. B. Rubin. 1992. 25 | Inference from Iterative Simulation Using Multiple Sequences. 26 | Statistical Science 7: 457–511. 27 | 28 | \url{https://astrostatistics.psu.edu/RLectures/diagnosticsMCMC.pdf} 29 | } 30 | -------------------------------------------------------------------------------- /man/plot_autocorrelation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_autocorrelation} 4 | \alias{plot_autocorrelation} 5 | \title{Plot autocorrelation} 6 | \usage{ 7 | plot_autocorrelation(x, lag = 20, par = NULL, chain = 1, phase = "sampling") 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}} 11 | 12 | \item{lag}{maximum lag. Must be an integer between 1 and 500.} 13 | 14 | \item{par}{vector of parameter names. If \code{NULL} all parameters are 15 | plotted.} 16 | 17 | \item{chain}{which chain to plot.} 18 | 19 | \item{phase}{which phase to plot. Must be either "burnin" or "sampling".} 20 | } 21 | \description{ 22 | Plot autocorrelation for specified parameters 23 | } 24 | -------------------------------------------------------------------------------- /man/plot_cor_mat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_cor_mat} 4 | \alias{plot_cor_mat} 5 | \title{Plot posterior correlation matrix} 6 | \usage{ 7 | plot_cor_mat(x, show = NULL, phase = "sampling", param_names = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}} 11 | 12 | \item{show}{Vector of parameter names to plot.} 13 | 14 | \item{phase}{which phase to plot. Must be either "burnin" or "sampling".} 15 | 16 | \item{param_names}{Optional vector of names to replace the default parameter names.} 17 | } 18 | \description{ 19 | Produces a matrix showing the correlation between all parameters 20 | from posterior draws. 21 | } 22 | -------------------------------------------------------------------------------- /man/plot_credible.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_credible} 4 | \alias{plot_credible} 5 | \title{Plot 95\% credible intervals} 6 | \usage{ 7 | plot_credible(x, show = NULL, phase = "sampling", param_names = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}} 11 | 12 | \item{show}{vector of parameter names to plot.} 13 | 14 | \item{phase}{which phase to plot. Must be either "burnin" or "sampling".} 15 | 16 | \item{param_names}{optional vector of names to replace the default parameter names.} 17 | } 18 | \description{ 19 | Plots posterior 95\% credible intervals over specified set of 20 | parameters (defauls to all parameters). 21 | } 22 | -------------------------------------------------------------------------------- /man/plot_density.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_density} 4 | \alias{plot_density} 5 | \title{Produce density plots} 6 | \usage{ 7 | plot_density(x, show = NULL, hide = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}} 11 | 12 | \item{show}{optional vector of parameter names to plot. Parameters matching 13 | show will be included.} 14 | 15 | \item{hide}{optional vector of parameter names to filter out. Parameters 16 | matching hide will be hidden.} 17 | } 18 | \description{ 19 | Density plots of all parameters. Use \code{show} and \code{hide} 20 | to be more specific about which parameters to plot. 21 | } 22 | -------------------------------------------------------------------------------- /man/plot_mc_acceptance.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_mc_acceptance} 4 | \alias{plot_mc_acceptance} 5 | \title{Plot Metropolis coupling acceptance rates} 6 | \usage{ 7 | plot_mc_acceptance(x, chain = NULL, phase = "sampling", x_axis_type = 1) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}} 11 | 12 | \item{chain}{which chain to plot. If \code{NULL} then plot all chains.} 13 | 14 | \item{phase}{which phase to plot. Must be either "burnin" or "sampling".} 15 | 16 | \item{x_axis_type}{how to format the x-axis. 1 = integer rungs, 2 = values of 17 | the thermodynamic power.} 18 | } 19 | \description{ 20 | Plot Metropolis coupling acceptance rates between all rungs. 21 | } 22 | -------------------------------------------------------------------------------- /man/plot_pairs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_pairs} 4 | \alias{plot_pairs} 5 | \title{Produce scatterplots between multiple parameters} 6 | \usage{ 7 | plot_pairs(x, show = NULL, hide = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}} 11 | 12 | \item{show}{optional vector of parameter names to plot. Parameters matching 13 | show will be included.} 14 | 15 | \item{hide}{optional vector of parameter names to filter out. Parameters 16 | matching hide will be hidden.} 17 | } 18 | \description{ 19 | Uses \code{ggpairs} function from the \code{GGally} package to 20 | produce scatterplots between all named parameters. 21 | } 22 | -------------------------------------------------------------------------------- /man/plot_rung_loglike.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_rung_loglike} 4 | \alias{plot_rung_loglike} 5 | \title{Plot loglikelihood 95\% credible intervals} 6 | \usage{ 7 | plot_rung_loglike( 8 | x, 9 | chain = 1, 10 | phase = "sampling", 11 | x_axis_type = 1, 12 | y_axis_type = 1 13 | ) 14 | } 15 | \arguments{ 16 | \item{x}{an object of class \code{drjacoby_output}} 17 | 18 | \item{chain}{which chain to plot.} 19 | 20 | \item{phase}{which phase to plot. Must be either "burnin" or "sampling".} 21 | 22 | \item{x_axis_type}{how to format the x-axis. 1 = integer rungs, 2 = values of 23 | the thermodynamic power.} 24 | 25 | \item{y_axis_type}{how to format the y-axis. 1 = raw values, 2 = truncated at 26 | auto-chosen lower limit. 3 = double-log scale.} 27 | } 28 | \description{ 29 | Plot loglikelihood 95\% credible intervals. 30 | } 31 | -------------------------------------------------------------------------------- /man/plot_scatter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_scatter} 4 | \alias{plot_scatter} 5 | \title{Produce bivariate scatterplot} 6 | \usage{ 7 | plot_scatter( 8 | x, 9 | parameter1, 10 | parameter2, 11 | downsample = TRUE, 12 | phase = "sampling", 13 | chain = NULL 14 | ) 15 | } 16 | \arguments{ 17 | \item{x}{an object of class \code{drjacoby_output}} 18 | 19 | \item{parameter1}{name of parameter first parameter.} 20 | 21 | \item{parameter2}{name of parameter second parameter.} 22 | 23 | \item{downsample}{whether to downsample output to 200 values max to speed up 24 | plotting.} 25 | 26 | \item{phase}{which phase to plot. Must be either "burnin" or "sampling".} 27 | 28 | \item{chain}{which chain to plot.} 29 | } 30 | \description{ 31 | Produces scatterplot between two named parameters. 32 | } 33 | -------------------------------------------------------------------------------- /man/plot_trace.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot_trace} 4 | \alias{plot_trace} 5 | \title{Plot parameter trace} 6 | \usage{ 7 | plot_trace( 8 | x, 9 | show = NULL, 10 | hide = NULL, 11 | lag = 20, 12 | downsample = TRUE, 13 | phase = "sampling", 14 | chain = NULL, 15 | display = TRUE 16 | ) 17 | } 18 | \arguments{ 19 | \item{x}{an object of class \code{drjacoby_output}} 20 | 21 | \item{show}{optional vector of parameter names to plot. Parameters matching 22 | show will be included.} 23 | 24 | \item{hide}{optional vector of parameter names to filter out. Parameters 25 | matching hide will be hidden.} 26 | 27 | \item{lag}{maximum lag. Must be an integer between 1 and 500.} 28 | 29 | \item{downsample}{boolean. Whether to downsample chain to make plotting more 30 | efficient.} 31 | 32 | \item{phase}{which phase to plot. Must be either "burnin", "sampling" or "both".} 33 | 34 | \item{chain}{which chain to plot.} 35 | 36 | \item{display}{boolean. Whether to show plots, if \code{FALSE} then plotting 37 | objects are returned without displaying.} 38 | } 39 | \description{ 40 | Produce a series of plots corresponding to each parameter, 41 | including the raw trace, the posterior histogram and an autocorrelation 42 | plot. Plotting objects can be cycled through interactively, or can be 43 | returned as an object allowing them to be viewed/edited by the user. 44 | } 45 | -------------------------------------------------------------------------------- /man/population_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{population_data} 5 | \alias{population_data} 6 | \title{Population data.} 7 | \format{ 8 | A data frame with 20 rows and 2 variables: 9 | \describe{ 10 | \item{pop}{population size} 11 | \item{time}{time} 12 | ... 13 | } 14 | } 15 | \usage{ 16 | population_data 17 | } 18 | \description{ 19 | Example population growth data. 20 | } 21 | \keyword{datasets} 22 | -------------------------------------------------------------------------------- /man/run_mcmc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/main.R 3 | \name{run_mcmc} 4 | \alias{run_mcmc} 5 | \title{Run drjacoby MCMC} 6 | \usage{ 7 | run_mcmc( 8 | data, 9 | df_params, 10 | misc = list(), 11 | loglike, 12 | logprior, 13 | burnin = 1000, 14 | samples = 10000, 15 | rungs = 1, 16 | chains = 5, 17 | beta_manual = NULL, 18 | alpha = 1, 19 | target_acceptance = 0.44, 20 | cluster = NULL, 21 | coupling_on = TRUE, 22 | pb_markdown = FALSE, 23 | save_data = TRUE, 24 | save_hot_draws = FALSE, 25 | silent = FALSE 26 | ) 27 | } 28 | \arguments{ 29 | \item{data}{a named list or data frame or data values.} 30 | 31 | \item{df_params}{a data.frame of parameters (see \code{?define_params}).} 32 | 33 | \item{misc}{optional list object passed to likelihood and prior. This can be 34 | useful for passing values that are not strictly data, for example passing a 35 | lookup table to the prior function.} 36 | 37 | \item{loglike, logprior}{the log-likelihood and log-prior functions used in 38 | the MCMC. Can either be passed in as R functions (not in quotes), or as 39 | character strings naming compiled C++ functions (in quotes).} 40 | 41 | \item{burnin}{the number of burn-in iterations. Automatic tuning of proposal 42 | standard deviations is only active during the burn-in period.} 43 | 44 | \item{samples}{the number of sampling iterations.} 45 | 46 | \item{rungs}{the number of temperature rungs used in the parallel tempering 47 | method. By default, \eqn{\beta} values are equally spaced between 0 and 1, 48 | i.e. \eqn{\beta[i]=}\code{(i-1)/(rungs-1)} for \code{i} in \code{1:rungs}. 49 | The likelihood for the \out{ith} heated chain is raised to the 50 | power \eqn{\beta[i]^\alpha}, meaning we can use the \eqn{\alpha} parameter 51 | to concentrate rungs towards the start or the end of the interval (see the 52 | \code{alpha} argument).} 53 | 54 | \item{chains}{the number of independent replicates of the MCMC to run. If a 55 | \code{cluster} object is defined then these chains are run in parallel, 56 | otherwise they are run in serial.} 57 | 58 | \item{beta_manual}{vector of manually defined \eqn{\beta} values used in the 59 | parallel tempering approach. If defined, this overrides the spacing defined 60 | by \code{rungs}. Note that even manually defined \eqn{\beta} values are 61 | raised to the power \eqn{\alpha} internally, hence you should set 62 | \code{alpha = 1} if you want to fix \eqn{\beta} values exactly.} 63 | 64 | \item{alpha}{the likelihood for the \out{ith} heated chain is 65 | raised to the power \eqn{\beta[i]^\alpha}, meaning we can use the 66 | \eqn{\alpha} parameter to concentrate rungs towards the start or the end of 67 | the temperature scale.} 68 | 69 | \item{target_acceptance}{Target acceptance rate. Should be between 0 and 1. 70 | Default of 0.44, set as optimum for unvariate proposal distributions.} 71 | 72 | \item{cluster}{option to pass in a cluster environment, allowing chains to be 73 | run in parallel (see package "parallel").} 74 | 75 | \item{coupling_on}{whether to implement Metropolis-coupling over temperature 76 | rungs. The option of deactivating coupling has been retained for general 77 | interest and debugging purposes only. If this parameter is \code{FALSE} 78 | then parallel tempering will have no impact on MCMC mixing.} 79 | 80 | \item{pb_markdown}{whether to run progress bars in markdown mode, meaning 81 | they are only updated when they reach 100\% to avoid large amounts of output 82 | being printed to markdown files.} 83 | 84 | \item{save_data}{if \code{TRUE} (the default) the raw input data is stored 85 | for reference in the project output. This allows complete reproducibility 86 | from a project, but may be undesirable when datasets are very large.} 87 | 88 | \item{save_hot_draws}{if \code{TRUE} the parameter draws relating to the hot 89 | chains are also stored inside the \code{pt} element of the project output. 90 | If \code{FALSE} (the default) only log-likelihoods and log-priors are 91 | stored from heated chains.} 92 | 93 | \item{silent}{whether to suppress all console output.} 94 | } 95 | \description{ 96 | Run MCMC either with or without parallel tempering turned on. 97 | Minimum inputs include a data object, a data.frame of parameters, a 98 | log-likelihood function and a log-prior function. Produces an object of 99 | class \code{drjacoby_output}, which contains all MCMC output along with 100 | some diagnostics and a record of inputs. 101 | } 102 | \details{ 103 | Note that both \code{data} and \code{misc} are passed into 104 | log-likelihood/log-prior functions *by reference*. This means if you modify 105 | these objects inside the functions then any changes will persist. 106 | } 107 | -------------------------------------------------------------------------------- /man/sample_chains.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/samples.R 3 | \name{sample_chains} 4 | \alias{sample_chains} 5 | \title{Sample posterior draws from all available chains} 6 | \usage{ 7 | sample_chains(x, sample_n, keep_chain_index = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{an object of class \code{drjacoby_output}.} 11 | 12 | \item{sample_n}{An integer number of samples.} 13 | 14 | \item{keep_chain_index}{if \code{TRUE} then the column giving the chain is 15 | retained.} 16 | } 17 | \value{ 18 | A data.frame of posterior samples 19 | } 20 | \description{ 21 | Sample posterior draws from all available chains 22 | } 23 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/src/.DS_Store -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/Particle.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Particle.h" 3 | 4 | using namespace std; 5 | 6 | //------------------------------------------------ 7 | // initialise/reset particle 8 | void Particle::init(System &s, double beta_raised) { 9 | 10 | // pointer to system object 11 | this->s_ptr = &s; 12 | 13 | // local copies of some parameters for convenience 14 | d = s_ptr->d; 15 | 16 | // thermodynamic power 17 | this->beta_raised = beta_raised; 18 | 19 | // theta is the parameter vector in natural space 20 | theta = Rcpp::clone(s_ptr->theta_vector); 21 | theta_prop = Rcpp::clone(theta); 22 | 23 | // phi is a vector of transformed parameters 24 | phi = Rcpp::NumericVector(d); 25 | theta_to_phi(); 26 | phi_prop = Rcpp::NumericVector(d); 27 | 28 | // proposal parameters 29 | bw = vector(d, 1.0); 30 | bw_index = vector(d, 1); 31 | bw_stepsize = 1.0; 32 | 33 | // likelihoods and priors 34 | loglike_block = vector(s_ptr->n_block); 35 | loglike_prop_block = vector(s_ptr->n_block); 36 | loglike = 0; 37 | loglike_prop = 0; 38 | logprior = 0; 39 | logprior_prop = 0; 40 | 41 | // acceptance rates 42 | accept_count = 0; 43 | 44 | } 45 | 46 | //------------------------------------------------ 47 | // propose new value of phi[i] from univariate normal distribution 48 | void Particle::propose_phi(int i) { 49 | phi_prop[i] = R::rnorm(phi[i], bw[i]); 50 | } 51 | 52 | //------------------------------------------------ 53 | // transform phi_prop to theta_prop. See main.R for a key to transformation 54 | // types 55 | void Particle::phi_prop_to_theta_prop(int i) { 56 | 57 | switch(s_ptr->trans_type[i]) { 58 | case 0: 59 | theta_prop[i] = phi_prop[i]; 60 | break; 61 | case 1: 62 | theta_prop[i] = s_ptr->theta_max[i] - exp(phi_prop[i]); 63 | break; 64 | case 2: 65 | theta_prop[i] = exp(phi_prop[i]) + s_ptr->theta_min[i]; 66 | break; 67 | case 3: 68 | theta_prop[i] = (s_ptr->theta_max[i]*exp(phi_prop[i]) + s_ptr->theta_min[i]) / (1 + exp(phi_prop[i])); 69 | break; 70 | default: 71 | Rcpp::stop("trans_type invalid"); 72 | } 73 | 74 | } 75 | 76 | //------------------------------------------------ 77 | // transform theta to phi. See main.R for a key to transformation types 78 | void Particle::theta_to_phi() { 79 | 80 | for (int i = 0; i < d; ++i) { 81 | switch(s_ptr->trans_type[i]) { 82 | case 0: 83 | phi[i] = theta[i]; 84 | break; 85 | case 1: 86 | phi[i] = log(s_ptr->theta_max[i] - theta[i]); 87 | break; 88 | case 2: 89 | phi[i] = log(theta[i] - s_ptr->theta_min[i]); 90 | break; 91 | case 3: 92 | phi[i] = log(theta[i] - s_ptr->theta_min[i]) - log(s_ptr->theta_max[i] - theta[i]); 93 | break; 94 | default: 95 | Rcpp::stop("trans_type invalid"); 96 | } 97 | } 98 | 99 | } 100 | 101 | //------------------------------------------------ 102 | // get adjustment factor to account for reparameterisation 103 | double Particle::get_adjustment(int i) { 104 | 105 | double ret = 0; 106 | switch(s_ptr->trans_type[i]) { 107 | case 0: 108 | // (no adjustment needed) 109 | break; 110 | case 1: 111 | ret = log(s_ptr->theta_max[i] - theta_prop[i]) - log(s_ptr->theta_max[i] - theta[i]); 112 | break; 113 | case 2: 114 | ret = log(theta_prop[i] - s_ptr->theta_min[i]) - log(theta[i] - s_ptr->theta_min[i]); 115 | break; 116 | case 3: 117 | ret = log(s_ptr->theta_max[i] - theta_prop[i]) + log(theta_prop[i] - s_ptr->theta_min[i]) - log(s_ptr->theta_max[i] - theta[i]) - log(theta[i] - s_ptr->theta_min[i]); 118 | break; 119 | default: 120 | Rcpp::stop("trans_type invalid"); 121 | } 122 | return ret; 123 | 124 | } 125 | 126 | -------------------------------------------------------------------------------- /src/Particle.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "System.h" 5 | #include "misc.h" 6 | 7 | #include 8 | 9 | //------------------------------------------------ 10 | // class defining MCMC particle 11 | class Particle { 12 | 13 | public: 14 | // PUBLIC OBJECTS 15 | 16 | // pointer to system object 17 | System * s_ptr; 18 | 19 | // local copies of some parameters for convenience 20 | int d; 21 | 22 | // thermodynamic power 23 | double beta_raised; 24 | 25 | // theta is the parameter vector in natural space 26 | Rcpp::NumericVector theta; 27 | Rcpp::NumericVector theta_prop; 28 | 29 | // phi is a vector of transformed parameters 30 | Rcpp::NumericVector phi; 31 | Rcpp::NumericVector phi_prop; 32 | 33 | // proposal parameters 34 | std::vector bw; 35 | std::vector bw_index; 36 | double bw_stepsize; 37 | 38 | // likelihoods and priors 39 | std::vector loglike_block; 40 | std::vector loglike_prop_block; 41 | double loglike; 42 | double loglike_prop; 43 | double logprior; 44 | double logprior_prop; 45 | 46 | // store acceptance rates 47 | int accept_count; 48 | 49 | 50 | // PUBLIC FUNCTIONS 51 | 52 | // constructors 53 | Particle() {}; 54 | 55 | // initialise everything except for likelihood and prior values 56 | void init(System &s, double beta_raised); 57 | 58 | // initialise likelihood and prior values 59 | template 60 | void init_like(TYPE1 get_loglike, TYPE2 get_logprior) { 61 | PutRNGstate(); 62 | for (int i = 0; i < d; ++i) { 63 | for (unsigned int j = 0; j < s_ptr->block[i].size(); ++j) { 64 | int this_block = s_ptr->block[i][j]; 65 | s_ptr->misc["block"] = this_block; 66 | loglike_block[this_block - 1] = Rcpp::as(get_loglike(theta, s_ptr->x, s_ptr->misc)); 67 | } 68 | } 69 | loglike = sum(loglike_block); 70 | 71 | logprior = Rcpp::as(get_logprior(theta, s_ptr->misc)); 72 | GetRNGstate(); 73 | 74 | // Catch for -Inf in likelihood or prior given init theta 75 | if(loglike == R_NegInf || logprior == R_NegInf){ 76 | Rcpp::Rcerr << "\n Current theta " << theta << std::endl; 77 | Rcpp::stop("Starting values result in -Inf in likelihood or prior. Consider setting inital values in the parameters data.frame."); 78 | } 79 | } 80 | 81 | // update theta[i] via univariate Metropolis-Hastings 82 | template 83 | void update(TYPE1 get_loglike, TYPE2 get_logprior) { 84 | 85 | // set theta_prop and phi_prop to current values of theta and phi 86 | theta_prop = Rcpp::clone(theta); 87 | phi_prop = Rcpp::clone(phi); 88 | 89 | // loop through parameters 90 | for (int i = 0; i < d; ++i) { 91 | if (s_ptr->skip_param[i]) { 92 | continue; 93 | } 94 | 95 | // generate new phi_prop[i] 96 | propose_phi(i); 97 | 98 | // transform phi_prop[i] to theta_prop[i] 99 | phi_prop_to_theta_prop(i); 100 | 101 | // calculate adjustment factor, taking into account forwards and backwards 102 | // moves 103 | double adj = get_adjustment(i); 104 | 105 | // calculate loglikelihood in each block 106 | PutRNGstate(); 107 | loglike_prop_block = loglike_block; 108 | for (unsigned int j = 0; j < s_ptr->block[i].size(); ++j) { 109 | int this_block = s_ptr->block[i][j]; 110 | s_ptr->misc["block"] = this_block; 111 | loglike_prop_block[this_block - 1] = Rcpp::as(get_loglike(theta_prop, s_ptr->x, s_ptr->misc)); 112 | } 113 | 114 | // calculate overall likelihood and prior of proposed theta 115 | loglike_prop = sum(loglike_prop_block); 116 | 117 | logprior_prop = Rcpp::as(get_logprior(theta_prop, s_ptr->misc)); 118 | GetRNGstate(); 119 | 120 | // Check for NA/NaN/Inf in likelihood or prior 121 | if(R_IsNaN(loglike_prop) || loglike_prop == R_PosInf || R_IsNA(loglike_prop)){ 122 | Rcpp::Rcerr << "\n Current theta " << theta_prop << std::endl; 123 | Rcpp::stop("NA, NaN or Inf in likelihood"); 124 | } 125 | if(R_IsNaN(logprior_prop) || logprior_prop == R_PosInf || R_IsNA(logprior_prop)){ 126 | Rcpp::Rcerr << "\n Current theta " << theta_prop << std::endl; 127 | Rcpp::stop("NA, NaN or Inf in prior"); 128 | } 129 | 130 | // calculate Metropolis-Hastings ratio 131 | double MH; 132 | if(beta_raised == 0.0){ 133 | MH = (logprior_prop - logprior) + adj; 134 | } else { 135 | MH = beta_raised*(loglike_prop - loglike) + (logprior_prop - logprior) + adj; 136 | } 137 | 138 | // accept or reject move 139 | bool MH_accept = (log(R::runif(0,1)) < MH); 140 | 141 | // implement changes 142 | if (MH_accept) { 143 | // update theta and phi 144 | theta[i] = theta_prop[i]; 145 | phi[i] = phi_prop[i]; 146 | 147 | // update likelihoods 148 | loglike_block = loglike_prop_block; 149 | loglike = loglike_prop; 150 | logprior = logprior_prop; 151 | 152 | // Robbins-Monro positive update (on the log scale) 153 | bw[i] = exp(log(bw[i]) + bw_stepsize*(1 - s_ptr->target_acceptance) / sqrt(bw_index[i])); 154 | bw_index[i]++; 155 | 156 | // add to acceptance rate count 157 | accept_count++; 158 | 159 | } else { 160 | // reset theta_prop and phi_prop 161 | theta_prop[i] = theta[i]; 162 | phi_prop[i] = phi[i]; 163 | 164 | // Robbins-Monro negative update (on the log scale) 165 | bw[i] = exp(log(bw[i]) - bw_stepsize*s_ptr->target_acceptance / sqrt(bw_index[i])); 166 | bw_index[i]++; 167 | 168 | } // end MH step 169 | } // end loop over parameters 170 | 171 | } // end update_univar function 172 | 173 | // other public methods 174 | void propose_phi(int i); 175 | void phi_prop_to_theta_prop(int i); 176 | void theta_to_phi(); 177 | double get_adjustment(int i); 178 | 179 | }; 180 | -------------------------------------------------------------------------------- /src/RcppExports.cpp: -------------------------------------------------------------------------------- 1 | // Generated by using Rcpp::compileAttributes() -> do not edit by hand 2 | // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 3 | 4 | #include 5 | 6 | using namespace Rcpp; 7 | 8 | #ifdef RCPP_USE_GLOBAL_ROSTREAM 9 | Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); 10 | Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); 11 | #endif 12 | 13 | // main_cpp 14 | Rcpp::List main_cpp(Rcpp::List args); 15 | RcppExport SEXP _drjacoby_main_cpp(SEXP argsSEXP) { 16 | BEGIN_RCPP 17 | Rcpp::RObject rcpp_result_gen; 18 | Rcpp::RNGScope rcpp_rngScope_gen; 19 | Rcpp::traits::input_parameter< Rcpp::List >::type args(argsSEXP); 20 | rcpp_result_gen = Rcpp::wrap(main_cpp(args)); 21 | return rcpp_result_gen; 22 | END_RCPP 23 | } 24 | 25 | static const R_CallMethodDef CallEntries[] = { 26 | {"_drjacoby_main_cpp", (DL_FUNC) &_drjacoby_main_cpp, 1}, 27 | {NULL, NULL, 0} 28 | }; 29 | 30 | RcppExport void R_init_drjacoby(DllInfo *dll) { 31 | R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); 32 | R_useDynamicSymbols(dll, FALSE); 33 | } 34 | -------------------------------------------------------------------------------- /src/System.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "System.h" 3 | #include "misc.h" 4 | 5 | using namespace std; 6 | 7 | void System::load(Rcpp::List args) { 8 | 9 | // split argument lists 10 | Rcpp::List args_params = args["args_params"]; 11 | Rcpp::List args_functions = args["args_functions"]; 12 | Rcpp::List args_progress = args["args_progress"]; 13 | Rcpp::List args_progress_burnin = args_progress["pb_burnin"]; 14 | 15 | // data 16 | x = args_params["x"]; 17 | 18 | // misc 19 | misc = args_params["misc"]; 20 | 21 | // model parameters 22 | theta_vector = args_params["theta_vector"]; 23 | theta_min = rcpp_to_vector_double(args_params["theta_min"]); 24 | theta_max = rcpp_to_vector_double(args_params["theta_max"]); 25 | block = rcpp_to_matrix_int(args_params["block"]); 26 | n_block = rcpp_to_int(args_params["n_block"]); 27 | trans_type = rcpp_to_vector_int(args_params["trans_type"]); 28 | skip_param = rcpp_to_vector_bool(args_params["skip_param"]); 29 | d = int(theta_min.size()); 30 | target_acceptance = rcpp_to_double(args_params["target_acceptance"]); 31 | 32 | // MCMC parameters 33 | burnin = rcpp_to_int(args_params["burnin"]); 34 | samples = rcpp_to_int(args_params["samples"]); 35 | rungs = rcpp_to_int(args_params["rungs"]); 36 | coupling_on = rcpp_to_bool(args_params["coupling_on"]); 37 | beta_raised = rcpp_to_vector_double(args_params["beta_raised"]); 38 | chain = rcpp_to_int(args_params["chain"]); 39 | 40 | // misc parameters 41 | save_hot_draws = rcpp_to_bool(args_params["save_hot_draws"]); 42 | pb_markdown = rcpp_to_bool(args_params["pb_markdown"]); 43 | silent = rcpp_to_bool(args_params["silent"]); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/System.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | 6 | #include 7 | 8 | //------------------------------------------------ 9 | // class holding all data, parameters and functions 10 | class System { 11 | 12 | public: 13 | // PUBLIC OBJECTS 14 | 15 | // data 16 | Rcpp::List x; 17 | 18 | // misc object 19 | Rcpp::List misc; 20 | 21 | // model parameters 22 | Rcpp::NumericVector theta_vector; 23 | std::vector theta_min; 24 | std::vector theta_max; 25 | std::vector> block; 26 | int n_block; 27 | std::vector trans_type; 28 | std::vector skip_param; 29 | int d; 30 | 31 | // MCMC parameters 32 | int burnin; 33 | int samples; 34 | int rungs; 35 | bool coupling_on; 36 | std::vector beta_raised; 37 | int chain; 38 | double target_acceptance; 39 | 40 | // misc parameters 41 | bool save_hot_draws; 42 | bool pb_markdown; 43 | bool silent; 44 | 45 | // PUBLIC FUNCTIONS 46 | 47 | // constructors 48 | System() {}; 49 | 50 | // public methods 51 | void load(Rcpp::List args); 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | 2 | #include "System.h" 3 | #include "Particle.h" 4 | 5 | #include 6 | 7 | 8 | //------------------------------------------------ 9 | // main Rcpp function, deployed from R 10 | // [[Rcpp::export]] 11 | Rcpp::List main_cpp(Rcpp::List args); 12 | 13 | //------------------------------------------------ 14 | // run MCMC 15 | template 16 | Rcpp::List run_mcmc(Rcpp::List args, TYPE1 get_loglike, TYPE2 get_logprior); 17 | 18 | //------------------------------------------------ 19 | // Metropolis-coupling over temperature rungs 20 | void coupling(std::vector &particle_vec, std::vector &mc_accept); 21 | -------------------------------------------------------------------------------- /tests/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/tests/.DS_Store -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(drjacoby) 3 | 4 | test_check("drjacoby") 5 | -------------------------------------------------------------------------------- /tests/testthat/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mrc-ide/drjacoby/edfea6339eb5a828410a0109bc9fef70c22ee210/tests/testthat/.DS_Store -------------------------------------------------------------------------------- /tests/testthat/test-cpp_template.R: -------------------------------------------------------------------------------- 1 | test_that("template works", { 2 | expect_error(cpp_template(NULL)) 3 | expect_error(cpp_template(1)) 4 | expect_error(cpp_template(save_as = "foo")) 5 | expect_error(cpp_template(save_as = "foo.csv")) 6 | }) 7 | 8 | -------------------------------------------------------------------------------- /tests/testthat/test-diagnostic.R: -------------------------------------------------------------------------------- 1 | #------------------------------------------------ 2 | test_that("gelman_rubin works", { 3 | 4 | # create dummy posterior draws matrix 5 | m <- cbind(chain = rep(1:2, each = 1e2), mu = rnorm(2e2)) 6 | 7 | # expect error when running with single chain or sample 8 | expect_error(gelman_rubin(m, 1, 10)) 9 | expect_error(gelman_rubin(m, 2, 1)) 10 | 11 | # expect no warnings when run with correct parameters 12 | expect_silent(gelman_rubin(m, 2, 10)) 13 | }) 14 | 15 | #------------------------------------------------ 16 | test_that("test_convergence works", { 17 | 18 | set.seed(1) 19 | 20 | # FALSE if single value 21 | x <- rnorm(1e2) 22 | expect_false(test_convergence(x, n = 1)) 23 | 24 | # FALSE if ESS gives warning 25 | x <- rep(1e100, 100) 26 | #coda::effectiveSize(x) 27 | expect_false(test_convergence(x, n = 10)) 28 | 29 | # FALSE if ESS too small 30 | x <- rep(0, 100) 31 | #coda::effectiveSize(x) 32 | expect_false(test_convergence(x, n = 100)) 33 | 34 | # expect TRUE when run with appropriate values 35 | x <- rnorm(1e2) 36 | expect_true(test_convergence(x, n = 100)) 37 | 38 | }) 39 | 40 | #------------------------------------------------ 41 | test_that("geweke_pvalue works", { 42 | 43 | # NaN if coda's geweke.diag() cannot calculate valid output 44 | expect_true(is.nan(geweke_pvalue(rep(0, 10)))) 45 | 46 | # expect no warnings when run with appropriate values 47 | expect_silent(geweke_pvalue(rnorm(10))) 48 | 49 | }) 50 | 51 | -------------------------------------------------------------------------------- /tests/testthat/test-mcmc-with-cpp-likelihood-and-prior.R: -------------------------------------------------------------------------------- 1 | context("test-mcmc-with-cpp-likelihood-and-prior") 2 | 3 | test_that("Cpp likelihood and prior", { 4 | set.seed(1) 5 | 6 | # define true parameter values 7 | mu_true <- 3 8 | sigma_true <- 2 9 | 10 | # draw example data 11 | x <- rnorm(1000, mean = mu_true, sd = sigma_true) 12 | data_list <- list(x = x) 13 | 14 | # define parameters dataframe 15 | df_params <- define_params(name = "mu", min = -10, max = 10, init = 5, 16 | name = "sigma", min = 0, max = 10, init = 1) 17 | 18 | # Source Rcpp likehood and prior functions 19 | Rcpp::sourceCpp("test_input_files/loglike_logprior.cpp") 20 | # run MCMC 21 | cpp_mcmc_null <- run_mcmc(data = data_list, 22 | df_params = df_params, 23 | loglike = "loglikenull", 24 | logprior = "logprior", 25 | burnin = 1e3, 26 | samples = 1e3, 27 | chains = 1, 28 | silent = TRUE) 29 | 30 | # subset output 31 | pe <- dplyr::filter(cpp_mcmc_null$output, phase == "sampling") %>% 32 | dplyr::select(mu, sigma) 33 | 34 | # check posterior estimates 35 | posterior_estimate <- apply(pe, 2, median) 36 | expect_lt(posterior_estimate["mu"] - 6, 0.1) # should approximately follow the values in logprior_strong 37 | expect_lt(posterior_estimate["sigma"] - 1, 0.1) # should approximately follow the values in logprior_strong 38 | 39 | # run MCMC with null prior 40 | cpp_mcmc_data <- run_mcmc(data = data_list, 41 | df_params = df_params, 42 | loglike = "loglike", 43 | logprior = "logpriornull", 44 | burnin = 1e3, 45 | samples = 1e4, 46 | silent = TRUE) 47 | 48 | # subset output 49 | pe <- dplyr::filter(cpp_mcmc_data$output, phase == "sampling") %>% 50 | dplyr::select(mu, sigma) 51 | 52 | # check posterior estimates 53 | posterior_estimate2 <- apply(pe, 2, median) 54 | expect_lt(posterior_estimate2["mu"] - mu_true, 0.1) 55 | expect_lt(posterior_estimate2["sigma"] - sigma_true, 0.1) 56 | 57 | ## Multiple chains 58 | cpp_mcmc_chains <- run_mcmc(data = data_list, 59 | df_params = df_params, 60 | loglike = "loglike", 61 | logprior = "logpriornull", 62 | chains = 2, 63 | burnin = 1e3, 64 | samples = 1e4, 65 | silent = TRUE) 66 | expect_length(cpp_mcmc_chains, 4) 67 | 68 | # subset output to chain1 and check posterior estimates 69 | pe <- dplyr::filter(cpp_mcmc_chains$output, phase == "sampling", chain == 1) %>% 70 | dplyr::select(mu, sigma) 71 | posterior_estimate3a <- apply(pe, 2, median) 72 | expect_lt(posterior_estimate3a["mu"] - mu_true, 0.1) 73 | expect_lt(posterior_estimate3a["sigma"] - sigma_true, 0.1) 74 | 75 | # subset output to chain2 and check posterior estimates 76 | pe <- dplyr::filter(cpp_mcmc_chains$output, phase == "sampling", chain == 2) %>% 77 | dplyr::select(mu, sigma) 78 | posterior_estimate3b <- apply(pe, 2, median) 79 | expect_lt(posterior_estimate3b["mu"] - mu_true, 0.1) 80 | expect_lt(posterior_estimate3b["sigma"] - sigma_true, 0.1) 81 | 82 | ## Metropolis coupling 83 | mcmc_out_MC <- run_mcmc(data = data_list, 84 | df_params = df_params, 85 | loglike = "loglike", 86 | logprior = "logpriornull", 87 | burnin = 1e3, 88 | samples = 1e4, 89 | rungs = 4, 90 | silent = TRUE) 91 | 92 | # subset output 93 | pe <- dplyr::filter(mcmc_out_MC$output, phase == "sampling") %>% 94 | dplyr::select(mu, sigma) 95 | 96 | # check posterior estimates 97 | posterior_estimate4 <- apply(pe, 2, median) 98 | expect_lt(posterior_estimate4["mu"] - mu_true, 0.1) 99 | expect_lt(posterior_estimate4["sigma"] - sigma_true, 0.1) 100 | }) 101 | -------------------------------------------------------------------------------- /tests/testthat/test-mcmc-wth-mixed-likelihood-and-prior.R: -------------------------------------------------------------------------------- 1 | context("test-mcmc-with-mixed-likelihood-and-prior") 2 | 3 | test_that("Cpp likelihood and R prior, and vice versa", { 4 | set.seed(1) 5 | 6 | # define true parameter values 7 | mu_true <- 3 8 | sigma_true <- 2 9 | 10 | # draw example data 11 | x <- rnorm(1000, mean = mu_true, sd = sigma_true) 12 | data_list <- list(x = x) 13 | 14 | # define parameters dataframe 15 | df_params <- define_params(name = "mu", min = -10, max = 10, init = 5, 16 | name = "sigma", min = 0, max = 10, init = 1) 17 | # Source Rcpp likehood and prior functions 18 | Rcpp::sourceCpp("test_input_files/loglike_logprior.cpp") 19 | 20 | # R likelihood and prior 21 | r_loglike_null <- function(params, data, misc) { 22 | return(0) 23 | } 24 | r_logprior_null <- function(params, misc) { 25 | return(0) 26 | } 27 | 28 | # expect no warnings when run MCMC with both combinations of prior and 29 | # likelihood 30 | expect_silent(run_mcmc(data = data_list, 31 | df_params = df_params, 32 | loglike = "loglikenull", 33 | logprior = r_logprior_null, 34 | burnin = 1e2, 35 | samples = 1e2, 36 | chains = 1, 37 | silent = TRUE)) 38 | 39 | expect_silent(run_mcmc(data = data_list, 40 | df_params = df_params, 41 | loglike = r_loglike_null, 42 | logprior = "logpriornull", 43 | burnin = 1e2, 44 | samples = 1e2, 45 | chains = 1, 46 | silent = TRUE)) 47 | 48 | }) 49 | -------------------------------------------------------------------------------- /tests/testthat/test-mcmc_with_multi_function_cpp.R: -------------------------------------------------------------------------------- 1 | test_that("Multi function cpp likelihood and prior", { 2 | set.seed(1) 3 | 4 | # define true parameter values 5 | mu_true <- 3 6 | sigma_true <- 2 7 | 8 | # draw example data 9 | x <- rnorm(1000, mean = mu_true, sd = sigma_true) 10 | data_list <- list(x = x) 11 | 12 | # define parameters dataframe 13 | df_params <- define_params(name = "mu", min = -10, max = 10, init = 5, 14 | name = "sigma", min = 0, max = 10, init = 1) 15 | 16 | # Source Rcpp likehood and prior functions 17 | Rcpp::sourceCpp("test_input_files/multi_loglike_logprior.cpp") 18 | 19 | mcmc <- run_mcmc(data = data_list, 20 | df_params = df_params, 21 | loglike = "loglike", 22 | logprior = "logprior", 23 | burnin = 1e3, 24 | samples = 1e3, 25 | chains = 1, 26 | silent = TRUE) 27 | 28 | # subset output 29 | pe <- dplyr::filter(mcmc$output, phase == "sampling") %>% 30 | dplyr::select(mu, sigma) 31 | 32 | # check posterior estimates 33 | posterior_estimate <- apply(pe, 2, median) 34 | expect_lt(posterior_estimate["mu"] - mu_true, 0.1) 35 | expect_lt(posterior_estimate["sigma"] - sigma_true, 0.1) 36 | }) 37 | -------------------------------------------------------------------------------- /tests/testthat/test-plot.R: -------------------------------------------------------------------------------- 1 | 2 | #------------------------------------------------ 3 | test_that("plots do not produce errors", { 4 | 5 | # define example data 6 | # (use small series so that loglikelihood comes back +ve in some cases, which 7 | # forces down a particular path in some plotting functions) 8 | data_list <- list(x = (1:10)*1e-2) 9 | 10 | # define parameters dataframe 11 | df_params <- rbind.data.frame(list("mu", -10, 10, 5), 12 | list("sigma", 0, 20, 1)) 13 | names(df_params) <- c("name", "min", "max", "init") 14 | 15 | # log likelihood 16 | r_loglike <- function(params, data, misc) { 17 | sum(dnorm(data$x, mean = params["mu"], sd = params["sigma"], log = TRUE)) 18 | } 19 | 20 | # log prior 21 | r_logprior <- function(params, misc) { 22 | dnorm(params["mu"], log = TRUE) + dlnorm(params["sigma"]) 23 | } 24 | 25 | # run MCMC 26 | mcmc_out <- run_mcmc(data = data_list, 27 | df_params = df_params, 28 | loglike = r_loglike, 29 | logprior = r_logprior, 30 | burnin = 1e2, 31 | samples = 3e3, 32 | rungs = 2, 33 | chains = 2, 34 | silent = TRUE) 35 | 36 | # expect no output (messages or warnings) in all standard plotting functions 37 | expect_silent(plot_autocorrelation(mcmc_out)) 38 | 39 | expect_silent(plot_mc_acceptance(mcmc_out)) 40 | expect_silent(plot_mc_acceptance(mcmc_out, chain = 1)) 41 | expect_silent(plot_mc_acceptance(mcmc_out, x_axis_type = 2)) 42 | 43 | expect_silent(plot_trace(mcmc_out, display = FALSE)) 44 | expect_silent(plot_trace(mcmc_out, show = "mu", display = FALSE)) 45 | expect_silent(plot_trace(mcmc_out, hide = "mu", display = FALSE)) 46 | expect_silent(plot_trace(mcmc_out, phase = "both", display = FALSE)) 47 | 48 | expect_silent(plot_scatter(mcmc_out, parameter1 = "mu", parameter2 = "sigma")) 49 | expect_silent(plot_scatter(mcmc_out, parameter1 = "mu", parameter2 = "sigma", phase = "both")) 50 | 51 | expect_silent(plot_cor_mat(mcmc_out)) 52 | expect_silent(plot_cor_mat(mcmc_out, show = c("mu", "sigma"))) 53 | expect_silent(plot_cor_mat(mcmc_out, phase = "both")) 54 | 55 | expect_silent(plot_credible(mcmc_out)) 56 | expect_silent(plot_credible(mcmc_out, show = "mu")) 57 | expect_silent(plot_credible(mcmc_out, phase = "both")) 58 | 59 | expect_silent(plot_rung_loglike(mcmc_out)) 60 | expect_silent(plot_rung_loglike(mcmc_out, x_axis_type = 2)) 61 | expect_silent(plot_rung_loglike(mcmc_out, y_axis_type = 2)) 62 | expect_silent(plot_rung_loglike(mcmc_out, y_axis_type = 3)) 63 | 64 | # repeat run with single rung 65 | mcmc_out <- run_mcmc(data = data_list, 66 | df_params = df_params, 67 | loglike = r_loglike, 68 | logprior = r_logprior, 69 | burnin = 1e2, 70 | samples = 3e3, 71 | rungs = 1, 72 | chains = 2, 73 | silent = TRUE) 74 | 75 | # further tests 76 | expect_error(plot_mc_acceptance(mcmc_out)) 77 | 78 | }) 79 | -------------------------------------------------------------------------------- /tests/testthat/test_input_files/loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // Log likelihood 5 | // [[Rcpp::export]] 6 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 7 | 8 | // unpack data 9 | std::vector x = Rcpp::as< std::vector >(data["x"]); 10 | 11 | // unpack params 12 | double mu = params["mu"]; 13 | double sigma = params["sigma"]; 14 | 15 | // calculate log-likelihood 16 | double ret = 0.0; 17 | for (unsigned int i = 0; i < x.size(); ++i) { 18 | ret += R::dnorm(x[i], mu, sigma, 1); 19 | } 20 | 21 | // catch underflow 22 | if (!std::isfinite(ret)) { 23 | const double OVERFLO_DOUBLE = DBL_MAX/100.0; 24 | ret = -OVERFLO_DOUBLE; 25 | } 26 | 27 | return Rcpp::wrap(ret); 28 | } 29 | 30 | // Log prior 31 | // [[Rcpp::export]] 32 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 33 | 34 | // unpack params 35 | double mu = params["mu"]; 36 | double sigma = params["sigma"]; 37 | 38 | // calculate logprior 39 | double ret = R::dnorm(mu, 6, 0.1, 1) + R::dnorm(sigma, 1, 0.1, 1); 40 | 41 | // catch underflow 42 | if (!std::isfinite(ret)) { 43 | const double OVERFLO_DOUBLE = DBL_MAX/100.0; 44 | ret = -OVERFLO_DOUBLE; 45 | } 46 | 47 | // return as SEXP 48 | return Rcpp::wrap(ret); 49 | } 50 | 51 | // Null log likelihood 52 | // [[Rcpp::export]] 53 | SEXP loglikenull(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 54 | return Rcpp::wrap(0.0); 55 | } 56 | 57 | // Null log prior 58 | // [[Rcpp::export]] 59 | SEXP logpriornull(Rcpp::NumericVector params, Rcpp::List misc) { 60 | return Rcpp::wrap(0.0); 61 | } 62 | 63 | 64 | // [[Rcpp::export]] 65 | SEXP create_xptr(std::string function_name) { 66 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 67 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 68 | 69 | if (function_name == "loglike"){ 70 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 71 | } 72 | if (function_name == "loglikenull"){ 73 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglikenull))) ; 74 | } 75 | if (function_name == "logprior"){ 76 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 77 | } 78 | if (function_name == "logpriornull"){ 79 | return(Rcpp::XPtr(new funcPtr_prior(&logpriornull))) ; 80 | } 81 | 82 | stop("cpp function %i not found", function_name); 83 | } 84 | -------------------------------------------------------------------------------- /tests/testthat/test_input_files/multi_loglike_logprior.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace Rcpp; 3 | 4 | // Silly example so we can show that our loglike function can call others internally 5 | double none(){ 6 | double x = 0.0; 7 | return x; 8 | } 9 | 10 | // Log likelihood 11 | // [[Rcpp::export]] 12 | SEXP loglike(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc) { 13 | 14 | // unpack data 15 | std::vector x = Rcpp::as< std::vector >(data["x"]); 16 | 17 | // unpack params 18 | double mu = params["mu"]; 19 | double sigma = params["sigma"]; 20 | 21 | // calculate log-likelihood 22 | double ret = 0.0; 23 | for (unsigned int i = 0; i < x.size(); ++i) { 24 | ret += R::dnorm(x[i], mu, sigma, 1) + none(); 25 | } 26 | 27 | // catch underflow 28 | if (!std::isfinite(ret)) { 29 | const double OVERFLO_DOUBLE = DBL_MAX/100.0; 30 | ret = -OVERFLO_DOUBLE; 31 | } 32 | 33 | return Rcpp::wrap(ret); 34 | } 35 | 36 | // Log prior 37 | // [[Rcpp::export]] 38 | SEXP logprior(Rcpp::NumericVector params, Rcpp::List misc) { 39 | 40 | // unpack params 41 | double mu = params["mu"]; 42 | double sigma = params["sigma"]; 43 | 44 | // calculate logprior 45 | double ret = none(); 46 | 47 | // return as SEXP 48 | return Rcpp::wrap(ret); 49 | } 50 | 51 | // [[Rcpp::export]] 52 | SEXP create_xptr(std::string function_name) { 53 | typedef SEXP (*funcPtr_likelihood)(Rcpp::NumericVector params, Rcpp::List data, Rcpp::List misc); 54 | typedef SEXP (*funcPtr_prior)(Rcpp::NumericVector params, Rcpp::List misc); 55 | 56 | if (function_name == "loglike"){ 57 | return(Rcpp::XPtr(new funcPtr_likelihood(&loglike))); 58 | } 59 | if (function_name == "logprior"){ 60 | return(Rcpp::XPtr(new funcPtr_prior(&logprior))); 61 | } 62 | 63 | stop("cpp function %i not found", function_name); 64 | } 65 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/checks_double_well.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Double well" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Double well} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include=FALSE} 13 | knitr::opts_chunk$set(echo = TRUE) 14 | ``` 15 | 16 | ```{r, echo = FALSE} 17 | # set random seed 18 | set.seed(1) 19 | 20 | # load the drjacoby package 21 | library(drjacoby) 22 | ``` 23 | 24 | **Purpose:** to compare *drjacoby* results for a challenging problem involving a multimodal posterior, both with and without temperature rungs. 25 | 26 | ## Model 27 | 28 | We assume a single parameter `mu` drawn from a double well potential distribution, defined by the formula: 29 | 30 | $$ 31 | \begin{aligned} 32 | \mu &\propto exp\left(-\gamma(\mu^2 - 1)^2\right) 33 | \end{aligned} 34 | $$ 35 | where $\gamma$ is a parameter that defines the strength of the well (higher $\gamma$ leads to a deeper valley and hence more challenging problem). NB, there is no data in this example, as the likelihood is defined exactly by these parameters. 36 | 37 | Likelihood and prior: 38 | 39 | ```{r, echo = FALSE, comment = ''} 40 | Rcpp::sourceCpp(system.file("extdata/checks/", "doublewell_loglike_logprior.cpp", package = 'drjacoby', mustWork = TRUE)) 41 | ``` 42 | 43 | Parameters dataframe: 44 | 45 | ```{r} 46 | L <- 2 47 | gamma <- 30 48 | df_params <- define_params(name = "mu", min = -L, max = L, 49 | name = "gamma", min = gamma, max = gamma) 50 | ``` 51 | 52 | 53 | ## Single temperature rung (no Metropolis coupling) 54 | 55 | ```{r} 56 | mcmc <- run_mcmc(data = list(x = -1), 57 | df_params = df_params, 58 | loglike = "loglike", 59 | logprior = "logprior", 60 | burnin = 1e3, 61 | samples = 1e5, 62 | chains = 1, 63 | rungs = 1, 64 | silent = TRUE) 65 | ``` 66 | 67 | ```{r} 68 | # trace plot 69 | plot_trace(mcmc, show = "mu") 70 | ``` 71 | 72 | ```{r} 73 | # extract posterior draws 74 | output_sub <- subset(mcmc$output, phase == "sampling") 75 | mu_draws <- output_sub$mu 76 | 77 | # get analytical solution 78 | x <- seq(-L, L, l = 1001) 79 | fx <- exp(-gamma*(x^2 - 1)^2) 80 | fx <- fx / sum(fx) * 1/(x[2]-x[1]) 81 | 82 | # overlay plots 83 | hist(mu_draws, breaks = seq(-L, L, l = 201), probability = TRUE, main = "", col = "black") 84 | lines(x, fx, col = 2, lwd = 2) 85 | ``` 86 | 87 | 88 | ## Multiple temperature rungs 89 | 90 | ```{r} 91 | mcmc <- run_mcmc(data = list(x = -1), 92 | df_params = df_params, 93 | loglike = "loglike", 94 | logprior = "logprior", 95 | burnin = 1e3, 96 | samples = 1e5, 97 | chains = 1, 98 | rungs = 11, 99 | alpha = 2, 100 | pb_markdown = TRUE) 101 | ``` 102 | 103 | ```{r, fig.width=6, fig.height=5} 104 | # trace plot 105 | plot_trace(mcmc, show = "mu") 106 | 107 | # coupling acceptance plot 108 | plot_mc_acceptance(mcmc) 109 | ``` 110 | 111 | ```{r, fig.width=6, fig.height=5} 112 | # extract posterior draws 113 | output_sub <- subset(mcmc$output, phase == "sampling") 114 | mu_draws <- output_sub$mu 115 | 116 | # overlay plots 117 | hist(mu_draws, breaks = seq(-L, L, l = 201), probability = TRUE, main = "", col = "black") 118 | lines(x, fx, col = 2, lwd = 2) 119 | ``` 120 | -------------------------------------------------------------------------------- /vignettes/checks_multilevel_blocks.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Multilevel example with blocks" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Multilevel example with blocks} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include=FALSE} 13 | knitr::opts_chunk$set(echo = TRUE) 14 | ``` 15 | 16 | ```{r, echo = FALSE} 17 | # set random seed 18 | set.seed(1) 19 | 20 | # load the drjacoby package 21 | library(drjacoby) 22 | ``` 23 | 24 | **Purpose:** to compare *drjacoby* infered posterior distribution against the exact analytical solution in a multi-level model implemented via likelihood blocks. 25 | 26 | ## Model 27 | 28 | There are `g` groups with means `mu_1` to `mu_g`. These component means are drawn from a normal distribution with mean 0 and sd 1.0. Within each group there are `n` observations drawn around each component mean from normal disribution with sd 1.0. 29 | 30 | 31 | ```{r} 32 | g <- 5 33 | mu <- rnorm(g) 34 | 35 | n <- 5 36 | data_list <- list() 37 | for (i in 1:g) { 38 | data_list[[i]] <- rnorm(n, mean = mu[i]) 39 | } 40 | names(data_list) <- sprintf("group%s", 1:g) 41 | ``` 42 | 43 | Likelihood and prior: 44 | 45 | ```{r, echo = FALSE, comment = ''} 46 | Rcpp::sourceCpp(system.file("extdata/checks/", "multilevel_loglike_logprior.cpp", package = 'drjacoby', mustWork = TRUE)) 47 | ``` 48 | 49 | Parameters dataframe: 50 | 51 | ```{r} 52 | L <- 5 53 | df_params <- define_params(name = "mu_1", min = -L, max = L, block = c(1, 6), 54 | name = "mu_2", min = -L, max = L, block = c(2, 6), 55 | name = "mu_3", min = -L, max = L, block = c(3, 6), 56 | name = "mu_4", min = -L, max = L, block = c(4, 6), 57 | name = "mu_5", min = -L, max = L, block = c(5, 6)) 58 | ``` 59 | 60 | ## MCMC 61 | 62 | ```{r cars} 63 | mcmc <- run_mcmc(data = data_list, 64 | df_params = df_params, 65 | loglike = "loglike", 66 | logprior = "logprior", 67 | burnin = 1e3, 68 | samples = 1e5, 69 | chains = 10, 70 | silent = TRUE) 71 | ``` 72 | 73 | ## Plots 74 | 75 | Black = posterior draws 76 | 77 | Red = analytical solution to multi-level model 78 | 79 | Green = analytical solution assuming independent groups (no second level) 80 | 81 | ```{r, fig.width=6, fig.height=5} 82 | # extract sampling draws 83 | output_sub <- subset(mcmc$output, phase == "sampling") 84 | 85 | for (i in 1:5) { 86 | # get posterior draws 87 | mu_draws <- output_sub[[sprintf("mu_%s", i)]] 88 | 89 | # get analytical solution for this group 90 | x <- seq(-L, L, l = 1001) 91 | m <- mean(data_list[[i]]) 92 | fx <- dnorm(x, mean = m * n/(n + 1), sd = sqrt(1/(n + 1))) 93 | 94 | # get analytical solution if no multi-level model 95 | fx2 <- dnorm(x, mean = m, sd = sqrt(1/n)) 96 | 97 | # overlay plots 98 | hist(mu_draws, breaks = seq(-L, L, l = 1001), probability = TRUE, col = "black", 99 | main = sprintf("mu_%s", i)) 100 | lines(x, fx, col = 2, lwd = 4) 101 | lines(x, fx2, col = 3, lwd = 4) 102 | } 103 | ``` 104 | -------------------------------------------------------------------------------- /vignettes/checks_normal_model.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Normal model" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Normal model} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include=FALSE} 13 | knitr::opts_chunk$set(echo = TRUE) 14 | ``` 15 | 16 | ```{r, echo = FALSE} 17 | # set random seed 18 | set.seed(1) 19 | 20 | # load the drjacoby package 21 | library(drjacoby) 22 | ``` 23 | 24 | **Purpose:** to compare *drjacoby* infered posterior distribution against the exact analytical solution for a very simple model. 25 | 26 | ## Model 27 | 28 | A vector of data `x` drawn from a normal distribution with unknown mean `mu` and known variance of 1.0. 29 | 30 | ```{r} 31 | n <- 1e2 32 | data_list <- list(x = rnorm(n)) 33 | ``` 34 | 35 | Likelihood and prior: 36 | 37 | ```{r, echo = FALSE, comment = ''} 38 | Rcpp::sourceCpp(system.file("extdata/checks/", "normal_loglike_logprior.cpp", package = 'drjacoby', mustWork = TRUE)) 39 | ``` 40 | 41 | Parameters dataframe: 42 | 43 | ```{r} 44 | df_params <- define_params(name = "mu", min = -1, max = 1) 45 | ``` 46 | 47 | ## MCMC 48 | 49 | ```{r cars} 50 | mcmc <- run_mcmc(data = data_list, 51 | df_params = df_params, 52 | loglike = "loglike", 53 | logprior = "logprior", 54 | burnin = 1e3, 55 | samples = 1e5, 56 | chains = 10, 57 | silent = TRUE) 58 | ``` 59 | 60 | ## Posterior plots 61 | 62 | ```{r, fig.width=6, fig.height=5} 63 | # extract sampling draws 64 | mu_draws <- subset(mcmc$output, phase = "sampling")$mu 65 | 66 | # calculate analytical solution 67 | x <- seq(-1, 1, l = 1001) 68 | fx <- dnorm(x, mean = mean(data_list$x), sd = sqrt(1/n)) 69 | 70 | # histogram and overlay analytical 71 | hist(mu_draws, breaks = seq(-1, 1, 0.01), probability = TRUE, col = "black") 72 | lines(x, fx, col = 2, lwd = 4) 73 | ``` 74 | -------------------------------------------------------------------------------- /vignettes/checks_return_prior.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Return prior" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Return prior} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include=FALSE} 13 | knitr::opts_chunk$set(echo = TRUE) 14 | ``` 15 | 16 | ```{r, echo = FALSE} 17 | # set random seed 18 | set.seed(1) 19 | 20 | # load the drjacoby package 21 | library(drjacoby) 22 | ``` 23 | **Purpose:** to check that *drjacoby* returns the prior distribution when no likelihood is used. 24 | 25 | ## Model 26 | 27 | Four parameters, each representing a different one of the four possible parameter transformations internally. Each parameter is given a suitable informative prior over it's domain. 28 | 29 | Parameters dataframe: 30 | 31 | ```{r} 32 | df_params <- define_params(name = "real_line", min = -Inf, max = Inf, 33 | name = "neg_line", min = -Inf, max = 0, 34 | name = "pos_line", min = 0, max = Inf, 35 | name = "unit_interval", min = 0, max = 1) 36 | ``` 37 | 38 | Likelihood and prior: 39 | 40 | ```{r, echo = FALSE, comment = ''} 41 | Rcpp::sourceCpp(system.file("extdata/checks/", "returnprior_loglike_logprior.cpp", package = 'drjacoby', mustWork = TRUE)) 42 | ``` 43 | 44 | ## Run MCMC 45 | 46 | ```{r} 47 | mcmc <- run_mcmc(data = list(x = -1), 48 | df_params = df_params, 49 | loglike = "loglike", 50 | logprior = "logprior", 51 | burnin = 1e3, 52 | samples = 1e5, 53 | chains = 10, 54 | silent = TRUE) 55 | ``` 56 | 57 | ## Plots 58 | 59 | ```{r, fig.width=6, fig.height=5} 60 | output_sub <- subset(mcmc$output, phase == "sampling") 61 | 62 | # real_line 63 | hist(output_sub$real_line, breaks = 100, probability = TRUE, col = "black", main = "real_line") 64 | x <- seq(-5, 5, l = 1001) 65 | lines(x, dnorm(x), col = 2, lwd = 2) 66 | 67 | # neg_line 68 | hist(output_sub$neg_line, breaks = 100, probability = TRUE, col = "black", main = "neg_line") 69 | x <- seq(-100, 0, l = 1001) 70 | lines(x, dgamma(-x, shape = 5, scale = 5), col = 2, lwd = 2) 71 | 72 | # pos_line 73 | hist(output_sub$pos_line, breaks = 100, probability = TRUE, col = "black", main = "pos_line") 74 | x <- seq(0, 100, l = 1001) 75 | lines(x, dgamma(x, shape = 5, scale = 5), col = 2, lwd = 2) 76 | 77 | # unit_interval 78 | hist(output_sub$unit_interval, breaks = seq(0, 1, 0.01), probability = TRUE, col = "black", main = "unit_interval") 79 | x <- seq(0, 10, l = 1001) 80 | lines(x, dbeta(x, shape1 = 3, shape2 = 3), col = 2, lwd = 2) 81 | ``` 82 | -------------------------------------------------------------------------------- /vignettes/getting_model_fits.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Getting Model Fits" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Getting Model Fits} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>" 16 | ) 17 | ``` 18 | 19 | ```{r, echo = FALSE} 20 | # set random seed 21 | set.seed(1) 22 | 23 | # load the drjacoby package 24 | library(drjacoby) 25 | 26 | # load other packages 27 | library(ggplot2) 28 | ``` 29 | 30 | Sometimes our likelihood function involves calculating a series of intermediate values. A good example is when we have a model that describes our fit to the data, which may be combined with an error term to capture random noise around this prediction. Once the MCMC has finished, we may want to extract this model fit so that we can see how good it really is. Having already written down the code for calculating the model fit once within the likelihood, we don't want to have to write it down again when visualising results as this duplication of work is not only a waste of time but also can introduce errors. 31 | 32 | This vignette demonstrates how intermediate values can be obtained from MCMC output using a single likelihood function. 33 | 34 | 35 | ## A simple model of population growth 36 | 37 | For this example we will use some data on population growth and we will attempt to fit a simple curve through these points. The data can be loaded directly from within the *drjacoby* package, and takes the form of a simple data.frame of sampling times and population sizes: 38 | 39 | ```{r, width = 10, height = 5} 40 | # load example data 41 | data("population_data") 42 | head(population_data) 43 | 44 | # plot points 45 | plot(population_data$time, population_data$pop, ylim = c(0, 120), pch = 20, 46 | xlab = "Time (days)", ylab = "Population size") 47 | ``` 48 | 49 | For our model we will assume a discrete-time logistic growth model, in which the population starts at size $N_0$ and grows at a rate $r$ each timestep, but also experiences density-dependent death causing it to plateau out at a maximum population size $N_{max}$. If we use $N_t$ to denote the population size at time $t$ then we can write this model as follows: 50 | 51 | $$ 52 | \begin{align} 53 | N_{t+1} = rN_t(1 - N_t / K), \hspace{10mm} \mbox{where } K = N_{\mbox{max}}\left(\frac{r}{r-1}\right). 54 | \end{align} 55 | $$ 56 | 57 | There are three parameters in this model, and so our parameters dataframe should contain the three variables with suitable ranges as follows: 58 | 59 | ```{r} 60 | # define parameters dataframe 61 | df_params <- define_params(name = "N_0", min = 1, max = 100, 62 | name = "r", min = 1, max = 2, 63 | name = "N_max", min = 50, max = 200) 64 | ``` 65 | 66 | Within our likelihood function we need to calculate our expected population growth curve. This curve is perfectly smooth, but the real data is noisy so we will use a Poisson distribution to link the data to the model. 67 | 68 | Crucially, when defining the likelihood function we will create an option to return the model prediction, rather than the log-likelihood. We use the `misc` input to the function to control whether this option is active or not. If we set `misc$output_type = 1` then we will obtain the log-likelihood, but if we set `misc$output_type = 2` then we will obtain the complete curve of model-predicted values: 69 | 70 | ```{r} 71 | # define log-likelihood function 72 | loglike <- function(params, data, misc) { 73 | 74 | # extract parameter values 75 | N_0 <- params["N_0"] 76 | r <- params["r"] 77 | N_max <- params["N_max"] 78 | 79 | # calculate expected population growth 80 | K <- N_max * r / (r - 1) 81 | x <- rep(0, 100) 82 | x[1] <- N_0 83 | for (i in 2:length(x)) { 84 | x[i] <- r * x[i-1] * (1 - x[i-1] / K) 85 | } 86 | 87 | # option to return model prediction rather than log-likelihood 88 | if (misc$output_type == 2) { 89 | return(x) 90 | } 91 | 92 | # calculate log-likelihood 93 | ret <- sum(dpois(data$pop, lambda = x[data$time], log = TRUE)) 94 | 95 | # return 96 | return(ret) 97 | } 98 | 99 | # define R logprior function 100 | logprior <- function(params, misc) { 101 | dunif(params["N_0"], 1, 100, log = TRUE) + 102 | dunif(params["r"], 1, 2, log = TRUE) + 103 | dunif(params["N_max"], 50, 200, log = TRUE) 104 | } 105 | ``` 106 | 107 | When running the MCMC we want to make sure `misc$output_type = 1`: 108 | 109 | ```{r} 110 | # run MCMC 111 | mcmc <- run_mcmc(data = population_data, 112 | df_params = df_params, 113 | misc = list(output_type = 1), 114 | loglike = loglike, 115 | logprior = logprior, 116 | burnin = 1e3, 117 | samples = 1e4, 118 | chains = 3, 119 | pb_markdown = TRUE) 120 | ``` 121 | 122 | Once we have MCMC output we should perform our usual checks to make sure that everything has converged nicely (we will skip this step here in the interest of time). Assuming everything is OK, we can move on to exploring model fits. We will do this by running the same likelihood function but with `misc$output_type = 2`, using the posterior parameter draws as inputs. We may not want to use every posterior parameter draw, in which case we can use the `sample_chains()` function to sub-sample the output down as needed: 123 | 124 | ```{r} 125 | # sample from posterior 126 | param_draws <- sample_chains(mcmc, 1000) 127 | 128 | # get matrix of model predictions 129 | model_matrix <- apply(param_draws, 1, function(x) { 130 | loglike(params = x, data = population_data, misc = list(output_type = 2)) 131 | }) 132 | ``` 133 | 134 | Plotting these against the data we can see that - reassuringly - the posterior model fits make a smooth curve through the data points: 135 | 136 | ```{r} 137 | matplot(model_matrix, type = 'l', lty = 1, col = "#99000010", ylim = c(0, 120), 138 | xlab = "Time (days)", ylab = "Population size") 139 | points(population_data$time, population_data$pop, pch = 20) 140 | ``` 141 | 142 | Notice that we only had to define the model fitting computation once in this pipeline, as the same likelihood function was used for both inference and obtaining the fit. There are more complicated versions of this approach that may be useful in some settings, for example using `switch` functions or multiple `if` statements to allow for several different types of output from the likelihood function, or even varying aspects of the core model such as the error distribution using flags contained in `misc`. 143 | -------------------------------------------------------------------------------- /vignettes/installation.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Installing drjacoby" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Installing drjacoby} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>" 16 | ) 17 | ``` 18 | 19 | ## Installing Rcpp 20 | 21 | *drjacoby* relies on the [Rcpp](https://cran.r-project.org/web/packages/Rcpp/index.html) package, which requires the following OS-specific steps: 22 | 23 | * Windows 24 | - Download and install the appropriate version of [Rtools](https://cran.rstudio.com/bin/windows/Rtools/) for your version of R. On installation, ensure you check the box to arrange your system PATH as recommended by Rtools 25 | * Mac OS X 26 | - Download and install [XCode](http://itunes.apple.com/us/app/xcode/id497799835?mt=12) 27 | - Within XCode go to Preferences : Downloads and install the Command Line Tools 28 | * Linux (Debian/Ubuntu) 29 | - Install g++ with 30 | 31 | ```{} 32 | sudo apt-get update 33 | sudo apt-get install g++ 34 | ``` 35 | 36 | Irrespective of which system you use above, you should then install and load Rcpp with 37 | 38 | ```{r, eval = FALSE} 39 | install.packages("Rcpp") 40 | library(Rcpp) 41 | ``` 42 | 43 | You can check the version number to make sure it has properly installed 44 | ```{r, eval = FALSE} 45 | packageVersion("Rcpp") 46 | ``` 47 | 48 | 49 | ## Installing and loading *drjacoby* 50 | 51 | Next, in R, ensure that you have the [devtools](https://www.rstudio.com/products/rpackages/devtools/) package installed by running 52 | 53 | ```{r, eval = FALSE} 54 | install.packages("devtools", repos='http://cran.us.r-project.org') 55 | ``` 56 | 57 | Then install the *drjacoby* package directly from GitHub by running 58 | 59 | ```{r, eval = FALSE} 60 | devtools::install_github("mrc-ide/drjacoby") 61 | ``` 62 | 63 | If you have any problems installing then please [raise an issue](https://github.com/mrc-ide/drjacoby/issues) on github. 64 | 65 | Assuming everything installed correctly, we need to load the package: 66 | 67 | ```{r} 68 | library(drjacoby) 69 | ``` 70 | 71 | You can test that the package is loaded and working by running the following command, which should produce this output: 72 | 73 | ```{r} 74 | check_drjacoby_loaded() 75 | ``` 76 | 77 | 78 | -------------------------------------------------------------------------------- /vignettes/parallel.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Running in Parallel" 3 | author: "Bob Verity and Pete Winskill" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Running in Parallel} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | ```{r setup, include = FALSE} 13 | knitr::opts_chunk$set( 14 | collapse = TRUE, 15 | comment = "#>" 16 | ) 17 | ``` 18 | 19 | ```{r, echo = FALSE} 20 | # set random seed 21 | set.seed(1) 22 | 23 | # load the drjacoby package 24 | library(drjacoby) 25 | ``` 26 | 27 | Running multiple chains is a good way of checking that our MCMC is working well. Each chain is completely independent of all others, and so this qualifies as an [embarrassingly parallel](https://en.wikipedia.org/wiki/Embarrassingly_parallel) problem. 28 | 29 | This vignette will demonstrate how to run *drjacoby* with multiple chains, first in serial and then in parallel over multiple cores. 30 | 31 | ## Setup 32 | 33 | As always, we require some data, some parameters, and some functions to work with (see [earlier examples](https://mrc-ide.github.io/drjacoby/articles/example.html)). The underlying model is not our focus here, so we will use a very basic setup 34 | 35 | 36 | ```{r} 37 | # define data 38 | data_list <- list(x = rnorm(10)) 39 | 40 | # define parameters dataframe 41 | df_params <- data.frame(name = "mu", min = -10, max = 10, init = 0) 42 | 43 | # define loglike function 44 | r_loglike <- function(params, data, misc) { 45 | sum(dnorm(data$x, mean = params["mu"], sd = 1.0, log = TRUE)) 46 | } 47 | 48 | # define logprior function 49 | r_logprior <- function(params, misc) { 50 | dunif(params["mu"], min = -10, max = 10, log = TRUE) 51 | } 52 | ``` 53 | 54 | ## Running multiple chains 55 | 56 | Whenever the input argument `cluster` is `NULL`, chains will run in serial. This is true by default, so running multiple chains in serial is simply a case of specifying the `chains` argument: 57 | 58 | ```{r} 59 | # run MCMC in serial 60 | mcmc <- run_mcmc(data = data_list, 61 | df_params = df_params, 62 | loglike = r_loglike, 63 | logprior = r_logprior, 64 | burnin = 1e3, 65 | samples = 1e3, 66 | chains = 2, 67 | pb_markdown = TRUE) 68 | ``` 69 | 70 | When we look at our MCMC output (using the `plot_trace()` function) we can see that there are 2 chains, each of which contains a series of draws from the posterior. If we used multiple [temperature rungs](https://mrc-ide.github.io/drjacoby/articles/metropolis_coupling.html) then these would also be duplicated over chains. 71 | 72 | ```{r, fig.width=10, fig.height=4} 73 | # summarise output 74 | mcmc 75 | 76 | # compare mu over both chains 77 | plot_trace(mcmc, "mu", phase = "both") 78 | ``` 79 | 80 | Running in parallel is only slightly more complex. Before running anything we need to know how many cores our machine has. You may know this number already, but if you don't then the `parallel` package has a handy function for detecting the number of cores for you: 81 | 82 | ```{r, eval = FALSE} 83 | cores <- parallel::detectCores() 84 | ``` 85 | 86 | Next we make a cluster object, which creates multiple copies of R running in parallel over different cores. Here we are using all available cores, but if you want to hold some back for other intensive tasks then simply use a smaller number of cores when specifying this cluster. 87 | 88 | ```{r, eval = FALSE} 89 | cl <- parallel::makeCluster(cores) 90 | ``` 91 | 92 | We then run the usual `run_mcmc()` function, this time passing in the cluster object as an argument. This causes *drjacoby* to use a `clusterApplyLB()` call rather than an ordinary `lapply()` call over different chains. Each chain is added to a queue over the specified number of cores - when the first job completes, the next job is placed on the node that has become available and this continues until all jobs are complete. 93 | 94 | Note that output is supressed when running in parallel to avoid sending print commands to multiple cores, so you will not see the usual progress bars. 95 | 96 | ```{r, eval = FALSE} 97 | # run MCMC in parallel 98 | mcmc <- run_mcmc(data = data_list, 99 | df_params = df_params, 100 | loglike = r_loglike, 101 | logprior = r_logprior, 102 | burnin = 1e3, 103 | samples = 1e3, 104 | chains = 2, 105 | cluster = cl, 106 | pb_markdown = TRUE) 107 | ``` 108 | 109 | Finally, it is good practice to shut down the workers once we are finished: 110 | 111 | ```{r, eval = FALSE} 112 | parallel::stopCluster(cl) 113 | ``` 114 | 115 | 116 | ## Running multiple chains using C++ log likelihood or log prior functions 117 | 118 | To run the MCMC in parallel with C++ log-likelihood or log-prior functions there is on additional step to take when setting up 119 | the cluster. Each node must be able to access a version of the compiled C++ functions, so after initialising the cluster with: 120 | 121 | ```{r, eval = FALSE} 122 | cl <- parallel::makeCluster(cores) 123 | ``` 124 | 125 | we must also make the C++ functions accessible, by running the Rcpp::sourceCPP command for our C++ file for each node: 126 | 127 | ```{r, eval = FALSE} 128 | cl_cpp <- parallel::clusterEvalQ(cl, Rcpp::sourceCpp("my_cpp.cpp")) 129 | ``` 130 | 131 | After which we can run the mcmc in the same way: 132 | 133 | ```{r, eval = FALSE} 134 | # run MCMC in parallel 135 | mcmc <- run_mcmc(data = data_list, 136 | df_params = df_params, 137 | loglike = "loglike", 138 | logprior = "logprior", 139 | burnin = 1e3, 140 | samples = 1e3, 141 | chains = 2, 142 | cluster = cl, 143 | pb_markdown = TRUE) 144 | parallel::stopCluster(cl) 145 | ``` 146 | 147 | --------------------------------------------------------------------------------