{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "tutorial:stats:sampling_srou",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "BulletList",
          "__tag": 4053,
          "ordered": false,
          "start": 1,
          "children": [
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Required: PDF, area under PDF if different from 1"
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Optional: mode, CDF at mode"
                    }
                  ]
                }
              ]
            },
            {
              "__type": "ListItem",
              "__tag": 4054,
              "children": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Speed:"
                    }
                  ]
                },
                {
                  "__type": "BulletList",
                  "__tag": 4053,
                  "ordered": false,
                  "start": 1,
                  "children": [
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": "Set-up: fast"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "__type": "ListItem",
                      "__tag": 4054,
                      "children": [
                        {
                          "__type": "Paragraph",
                          "__tag": 4045,
                          "children": [
                            {
                              "__type": "Text",
                              "__tag": 4046,
                              "value": "Sampling: slow"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "SROU is based on the ratio-of-uniforms method that uses universal inequalities to construct a (universal) bounding rectangle. It works for T-concave distributions with  "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "T(x) = -1/\\sqrt{x}"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> import numpy as np\n>>> from scipy.stats.sampling import SimpleRatioUniforms",
              "execution_status": null,
              "out": ""
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Suppose we have the normal distribution:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> class StdNorm:\n...     def pdf(self, x):\n...         return np.exp(-0.5 * x**2)",
              "execution_status": null,
              "out": ""
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Notice that the PDF does not integrate to 1. We can either pass the exact area under the PDF during initialization of the generator or an upper bound to the exact area under the PDF. Also, it is recommended to pass the mode of the distribution to speed up the setup:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> urng = np.random.default_rng()\n>>> dist = StdNorm()\n>>> rng = SimpleRatioUniforms(dist, mode=0,\n...                           pdf_area=np.sqrt(2*np.pi),\n...                           random_state=urng)",
              "execution_status": null,
              "out": ""
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Now, we can use the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "rvs",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " method to generate samples from the distribution:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> rvs = rng.rvs(10)",
              "execution_status": null,
              "out": ""
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "If the CDF at the mode is available, it can be set to improve the performance of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "rvs",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> from scipy.stats import norm\n>>> rng = SimpleRatioUniforms(dist, mode=0,\n...                           pdf_area=np.sqrt(2*np.pi),\n...                           cdf_at_mode=norm.cdf(0),\n...                           random_state=urng)\n>>> rvs = rng.rvs(1000)",
              "execution_status": null,
              "out": ""
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "We can check that the samples are from the given distribution by visualizing its histogram:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> from scipy.stats.sampling import SimpleRatioUniforms\n>>> from scipy.stats import norm\n>>> import matplotlib.pyplot as plt\n>>> class StdNorm:\n...     def pdf(self, x):\n...         return np.exp(-0.5 * x**2)\n... \n>>> urng = np.random.default_rng()\n>>> dist = StdNorm()\n>>> rng = SimpleRatioUniforms(dist, mode=0,\n...                           pdf_area=np.sqrt(2*np.pi),\n...                           cdf_at_mode=norm.cdf(0),\n...                           random_state=urng)\n>>> rvs = rng.rvs(1000)\n>>> x = np.linspace(rvs.min()-0.1, rvs.max()+0.1, 1000)\n>>> fx = 1/np.sqrt(2*np.pi) * dist.pdf(x)\n>>> fig, ax = plt.subplots()\n>>> ax.plot(x, fx, 'r-', lw=2, label='true distribution')\n>>> ax.hist(rvs, bins=10, density=True, alpha=0.8, label='random variates')\n>>> ax.set_xlabel('x')\n>>> ax.set_ylabel('PDF(x)')\n>>> ax.set_title('Simple Ratio-of-Uniforms Samples')\n>>> ax.legend()\n>>> plt.show()",
          "execution_status": null,
          "out": ""
        },
        {
          "__type": "Figure",
          "__tag": 4024,
          "value": {
            "__type": "RefInfo",
            "__tag": 4000,
            "module": "scipy",
            "version": "2.0.0.dev0+git20260907.41eeb59",
            "kind": "assets",
            "path": "fig-plot-48.png"
          }
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The main advantage of the method is a fast setup. This can be beneficial when one repeatedly needs to generate small to moderate samples of a distribution with different shape parameters. In such a situation, the setup step of "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "sampling.NumericalInverseHermite",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " or "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "sampling.NumericalInversePolynomial",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " will lead to poor performance. As an example, assume we are interested to generate 100 samples for the Gamma distribution with 1000 different shape parameters given by "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "np.linspace(1.5, 5, 1000)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> import math\n>>> import warnings\n>>> class GammaDist:\n...     def __init__(self, p):\n...         self.p = p\n...     def pdf(self, x):\n...         return x**(self.p-1) * np.exp(-x)\n...\n>>> urng = np.random.default_rng()\n>>> p = np.linspace(1.5, 5, 1000)\n>>> res = np.empty((1000, 100))\n>>> for i in range(1000):\n...     dist = GammaDist(p[i])\n...     rng = SimpleRatioUniforms(dist, mode=p[i]-1,\n...                               pdf_area=math.gamma(p[i]),\n...                               random_state=urng)\n...     with warnings.catch_warnings():\n...         warnings.filterwarnings(\"ignore\", RuntimeWarning, \"invalid value encountered in double_scalars\")\n...         warnings.filterwarnings(\"ignore\", RuntimeWarning, \"overflow encountered in exp\")\n...         res[i] = rng.rvs(100)",
              "execution_status": null,
              "out": ""
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "See "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "2"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", and "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "3"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for more details."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Simple Ratio-of-Uniforms (SROU)"
        }
      ],
      "level": 0,
      "target": "sampling-srou"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Footnote",
          "__tag": 4067,
          "label": "1",
          "children": [
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "UNU.RAN reference manual, Section 5.3.16,        \"SROU - Simple Ratio-of-Uniforms method\",        http://statmath.wu.ac.at/software/unuran/doc/unuran.html#SROU"
                }
              ]
            }
          ]
        },
        {
          "__type": "Footnote",
          "__tag": 4067,
          "label": "2",
          "children": [
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "Leydold, Josef. \"A simple universal generator for continuous and        discrete univariate T-concave distributions.\" ACM Transactions on        Mathematical Software (TOMS) 27.1 (2001): 66-82"
                }
              ]
            }
          ]
        },
        {
          "__type": "Footnote",
          "__tag": 4067,
          "label": "3",
          "children": [
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "Leydold, Josef. \"Short universal generators via generalized ratio-of-uniforms        method.\" Mathematics of Computation 72.243 (2003): 1453-1471"
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "References"
        }
      ],
      "level": 1,
      "target": null
    }
  ],
  "local_refs": []
}