{"id":32199442,"url":"https://github.com/prdm0/acceptreject","last_synced_at":"2025-10-22T03:16:03.696Z","repository":{"id":232238777,"uuid":"783807680","full_name":"prdm0/AcceptReject","owner":"prdm0","description":"Acceptance and rejection method","archived":false,"fork":false,"pushed_at":"2024-05-22T16:03:24.000Z","size":29578,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-11T01:45:42.044Z","etag":null,"topics":["monte-carlo","monte-carlo-simulation","package","r","rejection-sampling","rstats","statistics-library"],"latest_commit_sha":null,"homepage":"https://prdm0.github.io/AcceptReject/","language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prdm0.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-08T15:57:59.000Z","updated_at":"2025-09-19T03:23:18.000Z","dependencies_parsed_at":"2025-09-08T16:33:54.227Z","dependency_job_id":null,"html_url":"https://github.com/prdm0/AcceptReject","commit_stats":null,"previous_names":["prdm0/acceptreject"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/prdm0/AcceptReject","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prdm0%2FAcceptReject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prdm0%2FAcceptReject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prdm0%2FAcceptReject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prdm0%2FAcceptReject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prdm0","download_url":"https://codeload.github.com/prdm0/AcceptReject/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prdm0%2FAcceptReject/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280371890,"owners_count":26319523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-22T02:00:06.515Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["monte-carlo","monte-carlo-simulation","package","r","rejection-sampling","rstats","statistics-library"],"created_at":"2025-10-22T03:16:01.566Z","updated_at":"2025-10-22T03:16:03.681Z","avatar_url":"https://github.com/prdm0.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# AcceptReject \u003cimg src=\"logo.png\" align=\"right\" width=\"250\"/\u003e\n\n[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/AcceptReject)](https://cran.r-project.org/package=AcceptReject) [![R-CMD-check](https://github.com/prdm0/AcceptReject/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/prdm0/AcceptReject/actions/workflows/R-CMD-check.yaml) [![r-universe](https://prdm0.r-universe.dev/badges/AcceptReject)](https://prdm0.r-universe.dev) [![Licence](https://img.shields.io/badge/licence-GPL--3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html) [![Downloads](https://cranlogs.r-pkg.org/badges/grand-total/AcceptReject)](https://cran.r-project.org/package=AcceptReject)\n\nGenerating pseudo-random observations from a probability distribution is a common task in statistics. Being able to generate pseudo-random observations from a probability distribution is useful for simulating scenarios, in [Monte-Carlo](https://en.wikipedia.org/wiki/Monte_Carlo_method) methods, which are useful for evaluating various statistical models.\n\nThe acceptance-rejection method was developed by [John von Neumann](https://pt.wikipedia.org/wiki/John_von_Neumann) in 1951 and is a well-known technique present in various computational statistics books. The original reference can be found at the link below:\n\n💎 [Neumann V (1951). “Various techniques used in connection with random digits.” Notes by GE Forsythe, pp. 36–38.](https://mcnp.lanl.gov/pdf_files/InBook_Computing_1961_Neumann_JohnVonNeumannCollectedWorks_VariousTechniquesUsedinConnectionwithRandomDigits.pdf)\n\nThe inversion method is a common way to do this, but it is not always possible to find a closed-form formula for the inverse function of the cumulative distribution function of a random variable $X$, that is, $q(u) = F^{-1}(u) = x$ (quantile function), where $F$ is the cumulative distribution function of $X$ and $u$ is a uniformly distributed random variable in the interval $(0, 1)$.\n\nWhenever possible, it is preferable to use the inversion method to generate pseudo-random observations from a probability distribution. However, when it is not possible to find a closed-form formula for the inverse function of the cumulative distribution function of a random variable, it is necessary to resort to other methods. One way to do this is through the [acceptance-rejection method](https://en.wikipedia.org/wiki/Rejection_sampling), which is a Monte-Carlo procedure. This package aims to provide a function that implements the Acceptance and Rejection method for generating pseudo-random observations from probability distributions that are difficult to sample directly.\n\nThe package [AcceptReject](https://github.com/prdm0/AcceptReject) provides the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function, in addition to other functions, that implements the acceptance-rejection method in an optimized manner to generate pseudo-random observations for discrete or continuous random variables. The [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function operates in parallel on Unix-based operating systems such as Linux and MacOS and operates sequentially on Windows-based operating systems; however, it still exhibits good performance. By default, on Unix-based systems, observations are generated sequentially, but it is possible to generate observations in parallel if desired, by using the `parallel = TRUE` argument.\n\nThe [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function, by default, attempts to maximize the probability of acceptance of the pseudo-random observations generated. Suppose $X$ and $Y$ are random variables with probability density function (pdf) or probability function (pf) $f$ and $g$, respectively. Furthermore, suppose there exists a constant $c$ such that\n\n$$\\frac{f_X(x)}{g_Y(y)} \\leq c.$$\n\nBy default, the accept_reject function attempts to find the value of $c$ that maximizes the probability of acceptance of the pseudo-random observations generated. However, it is possible to provide a value of $c$ to the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function through the argument `c`, where $Y$ is a random variable for which we know how to generate observations. For the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function, it is not necessary to specify the probability function or probability density function of $Y$ to generate observations of $X$ for discrete and continuous cases, respectively. For the discrete and continuous cases, $Y$ follows the discrete uniform distribution function and continuous uniform distribution function, respectively.\n\nSince the probability of acceptance is $1/c$, the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function attempts to find the minimum value of $c$ that satisfies the description above. Unless you have compelling reasons to provide a value for the `c` argument of the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function, it is recommended to use `c = NULL` (default), allowing a value of $c$ to be automatically determined.\n\n## 💻 Installation\n\nThe package is being versioned on GitHub. You can install the development version of [AcceptReject](https://github.com/prdm0/AcceptReject), and to do this, you must first install the [remotes](https://CRAN.R-project.org/package=remotes) package and then run the following command:\n\n``` r\n# install.packages(\"remotes\")\n# or remotes::install_github(\"prdm0/AcceptReject\", force = TRUE)\nlibrary(AcceptReject)\n```\n\nThe `force = TRUE` argument is not necessary. It is only needed in situations where you have already installed the package and want to reinstall it to have a new version.\n\nYou can also install the package version available on [Comprehensive R Archive Network - CRAN](https://cran.r-project.org/web/packages/available_packages_by_name.html):\n\n```{r message=FALSE, warning=FALSE, eval = FALSE, echo = TRUE}\ninstall.packages(\"AcceptReject\")\n```\n\n## 📚 Examples\n\nPlease note the examples below on how to use the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function to generate pseudo-random observations of discrete and continuous random variables. For further details, refer to the function's documentation [**Reference**](https://prdm0.github.io/AcceptReject/reference/) and the [**Vignette**](https://prdm0.github.io/AcceptReject/articles/accept_reject.html).\n\nIn the examples, we use well-known distributions, but it's important to note that the accept-reject method can be used to generate observations from probability distributions for which we don't know how to generate observations directly. Thus, if you need to generate observations from a random variable with a distribution for which there are no built-in functions in R that you can use to generate observations (such as functions like `rnorm()`, `rgamma()`, `rweibull()`, `rchisq()`, among others), the [AcceptReject](https://prdm0.github.io/AcceptReject/) package might be what you need. 🎉\n\n### Generating discrete observations\n\nAs an example, let $X \\sim Poisson(\\lambda = 0.7)$. We will generate $n = 1000$ observations of $X$ using the acceptance-rejection method, using the `accept_reject()` function. Note that it is necessary to provide the `xlim` argument. Try to set an upper limit value for which the probability of $X$ assuming that value is zero or very close to zero. In this case, we choose `xlim = c(0, 6)`, where `dpois(x = 6, lambda = 0.7)` is very close to zero (`r dpois(x = 6, lambda = 0.7)`).\n\n```{r}\nlibrary(AcceptReject)\nlibrary(cowplot) # install.packages(\"cowplot\")\n\n# Ensuring Reproducibility\nset.seed(0) \n\nsimulation \u003c- function(n){\n  AcceptReject::accept_reject(\n    n = n,\n    f = dpois,\n    continuous = FALSE,\n    args_f = list(lambda = 0.7),\n    xlim = c(0, 6),\n    parallel = TRUE\n  )\n}\n\na \u003c- simulation(25L)\nb \u003c- simulation(250L)\nc \u003c- simulation(2500L)\nd \u003c- simulation(25000L)\n\n# Plots\np1 \u003c- plot(a)\np2 \u003c- plot(b)\np3 \u003c- plot(c)\np4 \u003c- plot(d)\n\nplot_grid(p1, p2, p3, p4, nrow = 2L, labels = c(\"a\", \"b\", \"c\", \"d\"))\n\n# QQ-Plots\nq1 \u003c- qqplot(a, size_points = 2)\nq2 \u003c- qqplot(b, size_points = 2)\nq3 \u003c- qqplot(c, size_points = 2)\nq4 \u003c- qqplot(d, size_points = 2)\n\nplot_grid(q1, q2, q3, q4, nrow = 2L, labels = c(\"a\", \"b\", \"c\", \"d\"))\n```\n\n## Generating continuous observations\n\nTo expand beyond examples of generating pseudo-random observations of discrete random variables, consider now that we want to generate observations from a random variable $X \\sim \\mathcal{N}(\\mu = 0, \\sigma^2 = 1)$. We chose the normal distribution because we are familiar with its form, but you can choose another distribution if desired.\n\n```{r}\nlibrary(AcceptReject)\nlibrary(cowplot) # install.packages(\"cowplot\")\n\n# Ensuring reproducibility\nset.seed(0) \n\nsimulation \u003c- function(n){\n  AcceptReject::accept_reject(\n    n = n,\n    f = dnorm,\n    continuous = TRUE,\n    args_f = list(mean = 0, sd = 1),\n    xlim = c(-4, 4),\n    parallel = TRUE\n  )\n}\n\na \u003c- simulation(n = 100L)\nb \u003c- simulation(n = 150L)\nc \u003c- simulation(n = 250L)\nd \u003c- simulation(n = 2500L)\n\n# Plots\np1 \u003c- plot(a)\np2 \u003c- plot(b)\np3 \u003c- plot(c)\np4 \u003c- plot(d)\n\nplot_grid(p1, p2, p3, p4, nrow = 2L, labels = c(\"a\", \"b\", \"c\", \"d\"))\n\n# QQ-plots\nq1 \u003c- qqplot(a)\nq2 \u003c- qqplot(b)\nq3 \u003c- qqplot(c)\nq4 \u003c- qqplot(d)\n\nplot_grid(q1, q2, q3, q4, nrow = 2L, labels = c(\"a\", \"b\", \"c\", \"d\"))\n```\n\nThe [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function supports, **for the continuous case**, specifying a base probability density function if you don't want to use the continuous uniform distribution as the default base.\n\nWhen choosing to specify another probability density function different from the uniform one, it's necessary to specify the following arguments:\n\n-   `f_base`: base probability density function;\n-   `random_base`: sampling from the base probability density function;\n-   `args_f_base`: list with the parameters of the base density.\n\nBy default, all of them are `NULL`, and the continuous uniform distribution in `xlim` is used as the base. If at least one of these arguments is not specified, no error will occur, and the continuous uniform distribution in `xlim` will still be used as the base.\n\nFor the discrete case, if the user mistakenly specifies any of these arguments, i.e., when `continuous = FALSE`, the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function will ignore these arguments and use the discrete uniform distribution as the base.\n\nIf you choose to specify a base density, it's convenient to inspect it by comparing the base density function with the theoretical probability density function. The [`inspect()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function facilitates this task. The [`inspect()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function will plot the base probability density function and the theoretical probability density function, find the intersection between the densities, and display the value of the intersection area on the plot. These are important pieces of information to decide if the base probability density function specified in the `args_f_base` argument and the value of `c` (default is 1) are appropriate.\n\nAnother example, considering $X \\sim Beta(\\alpha = 2, \\beta = 2)$:\n\n```{r}\nlibrary(AcceptReject)\nlibrary(cowplot)\n\n# Ensuring reproducibility\nset.seed(0)\n\nx \u003c- accept_reject(\n  n = 100000L,\n  f = dbeta,\n  continuous = TRUE,\n  args_f = list(shape1 = 2, shape2 = 2),\n  xlim = c(0, 1)\n)\nprint(x)\na \u003c- plot(x)\nb \u003c- qqplot(x)\nplot_grid(a, b, nrow = 2L, labels = c(\"a\", \"b\"))\n\n# Inspecting the estimated value of c by accept_reject()\n# Note that c = 1.5 indeed causes the base density,\n# which in this case was the default (uniform), to overlap the # density of the beta:\ninspect(\n  f = dbeta,\n  args_f = list(shape1 = 2, shape2 = 2),\n  f_base = dunif,\n  args_f_base = c(min = 0, max = 1),\n  xlim = c(0, 1),\n  c = attr(x, \"c\")\n)\n```\n\nNote that `c` is an attribute of `x`. To access all attributes, you can use `attributes(x)`. Most likely, you won't need to access these attributes. They are useful for plotting methods.\n\n## 🕵️‍♀️ Example of inspection\n\n```{r}\nlibrary(AcceptReject)\nlibrary(cowplot) # install.packages(\"cowplot\")\n\n# Ensuring reproducibility\nset.seed(0)\n\n# Inspecting\n# Case a\na \u003c- inspect(\n  f = dweibull,\n  args_f = list(shape = 2.1, scale = 2.2),\n  f_base = dgamma,\n  args_f_base = list(shape = 2.8, rate = 1.2),\n  xlim = c(0, 6),\n  c = 1.2\n)\n\n# Inspecting\n# Case b\nb \u003c- inspect(\n  f = dweibull,\n  args_f = list(shape = 2.1, scale = 2.2),\n  f_base = dgamma,\n  args_f_base = list(shape = 2.9, rate = 2.5),\n  xlim = c(0, 6),\n  c = 1.4\n)\n\nplot_grid(a, b, nrow = 2L, labels = c(\"a\", \"b\"))\n```\n\nNotice that considering the distribution in scenario \"a\" in the code above is more convenient. Note that the area is approximately 1, the base probability density function with parameters `shape = 2.8` and `rate = 1.2` provides a shape close to the theoretical distribution, and `c = 1.2` ensures that the base density function upper bounds the theoretical probability density function. Therefore, considering `f_base` with $\\Gamma(\\alpha = 2.8, \\beta = 1.2)$ and `c = 1.2` is a reasonable choice for a base distribution.\n\nTherefore, passing arguments to `f_base = dgamma`, `args_f_base = list(shape = 2.8, rate = 1.2)`, and `c = 1.2` to the [`accept_reject()`](https://prdm0.github.io/AcceptReject/reference/accept_reject.html) function will lead us to an even more efficient code.\n\n```{r}\nlibrary(AcceptReject)\nlibrary(tictoc) # install.packages(\"tictoc\")\n\n# Ensuring reproducibility\nset.seed(0)\n\n# Not specifying the base probability density function\ntic()\ncase_1 \u003c- accept_reject(\n  n = 2000,\n  continuous = TRUE,\n  f = dweibull,\n  args_f = list(shape = 2.1, scale = 2.2),\n  xlim = c(0, 6)\n)\ntoc()\n\n# Specifying the base probability density function\ntic()\ncase_2 \u003c- accept_reject(\n  n = 2000,\n  continuous = TRUE,\n  f = dweibull,\n  args_f = list(shape = 2.1, scale = 2.2),\n  f_base = dgamma,\n  random_base = rgamma,\n  args_f_base = list(shape = 2.8, rate = 1.2),\n  xlim = c(0, 6),\n  c = 1.2\n)\ntoc()\n\n# Visualizing the results\np1 \u003c- plot(case_1)\np2 \u003c- plot(case_2)\n\nplot_grid(p1, p2, nrow = 2L)\n\n# QQ-plot\nq1 \u003c- qqplot(case_1)\nq2 \u003c- qqplot(case_2)\nplot_grid(q1, q2, nrow = 1L)\n```\n\nNotice that the results were very close in a graphical analysis. However, the execution time specifying a convenient base density was lower for a very large sample.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprdm0%2Facceptreject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprdm0%2Facceptreject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprdm0%2Facceptreject/lists"}