{
    "nbformat": 4,
    "nbformat_minor": 5,
    "metadata": {
        "kernelspec": {
            "display_name": "Python",
            "language": "python",
            "name": "python"
        },
        "language_info": {
            "name": "python"
        }
    },
    "cells": [
        {
            "id": "bc45d8af",
            "cell_type": "markdown",
            "source": "<div class='alert alert-warning'>\n\nSciPy's interactive examples with Jupyterlite are experimental and may not always work as expected. Execution of cells containing imports may result in large downloads (up to 60MB of content for the first import from SciPy). Load times when importing from SciPy may take roughly 10-20 seconds. If you notice any problems, feel free to open an [issue](https://github.com/scipy/scipy/issues/new/choose).\n\n</div>",
            "metadata": {}
        },
        {
            "id": "fe20751a",
            "cell_type": "markdown",
            "source": "Generate a 2D sample using a `radius` of 0.2.\n",
            "metadata": {}
        },
        {
            "id": "bfa1ae30",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "import numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.collections import PatchCollection\nfrom scipy.stats import qmc\n\nrng = np.random.default_rng()\nradius = 0.2\nengine = qmc.PoissonDisk(d=2, radius=radius, rng=rng)\nsample = engine.random(20)",
            "outputs": []
        },
        {
            "id": "5a3547a8",
            "cell_type": "markdown",
            "source": "Visualizing the 2D sample and showing that no points are closer than\n`radius`. ``radius/2`` is used to visualize non-intersecting circles.\nIf two samples are exactly at `radius` from each other, then their circle\nof radius ``radius/2`` will touch.\n",
            "metadata": {}
        },
        {
            "id": "3493752b",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "fig, ax = plt.subplots()\n_ = ax.scatter(sample[:, 0], sample[:, 1])\ncircles = [plt.Circle((xi, yi), radius=radius/2, fill=False)\n           for xi, yi in sample]\ncollection = PatchCollection(circles, match_original=True)\nax.add_collection(collection)\n_ = ax.set(aspect='equal', xlabel=r'$x_1$', ylabel=r'$x_2$',\n           xlim=[0, 1], ylim=[0, 1])\nplt.show()",
            "outputs": []
        },
        {
            "id": "7a692875",
            "cell_type": "markdown",
            "source": "Such visualization can be seen as circle packing: how many circle can\nwe put in the space. It is a np-hard problem. The method `fill_space`\ncan be used to add samples until no more samples can be added. This is\na hard problem and parameters may need to be adjusted manually. Beware of\nthe dimension: as the dimensionality increases, the number of samples\nrequired to fill the space increases exponentially\n(curse-of-dimensionality).\n",
            "metadata": {}
        }
    ]
}