diff --git a/config/build/no_run.yaml b/config/build/no_run.yaml index 81649f7c..8741cec6 100644 --- a/config/build/no_run.yaml +++ b/config/build/no_run.yaml @@ -7,11 +7,6 @@ - GetDist # Cant get it to install, even in optional requirements. - Zeus # Test Model Iniitalization no good. - ZeusPlotter # Test Model Iniitalization no good. -- UltraNestPlotter # Test Model Iniitalization no good. - DynestyPlotter # Test Model Iniitalization no good. - start_point # bug https://github.com/rhayes777/PyAutoFit/issues/1017 - tutorial_8_astronomy_example # Requires dataset/howtofit/chapter_1/astro/simple/data.npy (not auto-generated) -- searches/mle/PySwarmsGlobal # PySwarms does not support JAX. -- searches/mle/PySwarmsLocal # PySwarms does not support JAX. -- searches/nest/UltraNest # UltraNest does not support JAX. -- plot/PySwarmsPlotter # PySwarms does not support JAX. diff --git a/config/non_linear/mle.yaml b/config/non_linear/mle.yaml index 365b911f..25c0be5f 100644 --- a/config/non_linear/mle.yaml +++ b/config/non_linear/mle.yaml @@ -2,53 +2,10 @@ # **PyAutoFit** supports the following maximum likelihood estimator (MLE) algorithms: -# - PySwarms: https://github.com/ljvmiranda921/pyswarms / https://pyswarms.readthedocs.io/en/latest/index.html # Settings in the [search], [run] and [options] entries are specific to each nested algorithm and should be # determined by consulting that method's own readthedocs. -PySwarmsGlobal: - run: - iters: 2000 - search: - cognitive: 0.5 - ftol: -.inf - inertia: 0.9 - n_particles: 50 - social: 0.3 - initialize: # The method used to generate where walkers are initialized in parameter space {prior | ball}. - method: ball # priors: samples are initialized by randomly drawing from each parameter's prior. ball: samples are initialized by randomly drawing unit values from a narrow uniform distribution. - ball_lower_limit: 0.49 # The lower limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - ball_upper_limit: 0.51 # The upper limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - parallel: - number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing. - printing: - silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter. - iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. - iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. - remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable). -PySwarmsLocal: - run: - iters: 2000 - search: - cognitive: 0.5 - ftol: -.inf - inertia: 0.9 - minkowski_p_norm: 2 - n_particles: 50 - number_of_k_neighbors: 3 - social: 0.3 - initialize: # The method used to generate where walkers are initialized in parameter space {prior | ball}. - method: ball # priors: samples are initialized by randomly drawing from each parameter's prior. ball: samples are initialized by randomly drawing unit values from a narrow uniform distribution. - ball_lower_limit: 0.49 # The lower limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - ball_upper_limit: 0.51 # The upper limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - parallel: - number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing. - printing: - silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter. - iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. - iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. - remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable). LBFGS: search: tol: null diff --git a/config/non_linear/nest.yaml b/config/non_linear/nest.yaml index c113fb30..ea0e1f47 100644 --- a/config/non_linear/nest.yaml +++ b/config/non_linear/nest.yaml @@ -4,7 +4,6 @@ # - Dynesty: https://github.com/joshspeagle/dynesty / https://dynesty.readthedocs.io/en/latest/index.html # - Nautilus https://https://github.com/johannesulf/nautilus / https://nautilus-sampler.readthedocs.io/en/stable/index.html -# - UltraNest: https://github.com/JohannesBuchner/UltraNest / https://johannesbuchner.github.io/UltraNest/readme.html # Settings in the [search] and [run] entries are specific to each nested algorithm and should be determined by # consulting that MCMC method's own readthedocs. @@ -94,52 +93,3 @@ Nautilus: force_x1_cpu: false # Force Dynesty to not use Python multiprocessing Pool, which can fix issues on certain operating systems. printing: silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter. - -UltraNest: - search: - draw_multiple: true - ndraw_max: 65536 - ndraw_min: 128 - num_bootstraps: 30 - num_test_samples: 2 - resume: true - run_num: null - storage_backend: hdf5 - vectorized: false - warmstart_max_tau: -1.0 - run: - cluster_num_live_points: 40 - dkl: 0.5 - dlogz: 0.5 - frac_remain: 0.01 - insertion_test_window: 10 - insertion_test_zscore_threshold: 2 - lepsilon: 0.001 - log_interval: null - max_iters: null - max_ncalls: null - max_num_improvement_loops: -1.0 - min_ess: 400 - min_num_live_points: 400 - show_status: true - update_interval_ncall: null - update_interval_volume_fraction: 0.8 - viz_callback: auto - stepsampler: - adaptive_nsteps: false - log: false - max_nsteps: 1000 - nsteps: 25 - region_filter: false - scale: 1.0 - stepsampler_cls: null - initialize: # The method used to generate where walkers are initialized in parameter space {prior}. - method: prior # priors: samples are initialized by randomly drawing from each parameter's prior. - parallel: - number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing. - printing: - silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter. - - iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. - iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. - remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable). \ No newline at end of file diff --git a/notebooks/plot/PySwarmsPlotter.ipynb b/notebooks/plot/PySwarmsPlotter.ipynb deleted file mode 100644 index a2aa855b..00000000 --- a/notebooks/plot/PySwarmsPlotter.ipynb +++ /dev/null @@ -1,234 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Plots: PySwarmsPlotter\n", - "======================\n", - "\n", - "This example illustrates how to plot visualization summarizing the results of a pyswarms non-linear search using\n", - "the `autofit.plot` module-level functions.\n", - "\n", - "__Contents__\n", - "\n", - "This script is split into the following sections:\n", - "\n", - "- **Notation**: How parameter labels and superscripts are customized for plots.\n", - "- **Plotting**: Using the plot functions to visualize PySwarms search results.\n", - "- **Search Specific Visualization**: Accessing the native PySwarms optimizer for custom visualizations." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "\n", - "%matplotlib inline\n", - "from pyprojroot import here\n", - "workspace_path = str(here())\n", - "%cd $workspace_path\n", - "print(f\"Working Directory has been set to `{workspace_path}`\")\n", - "\n", - "import matplotlib.pyplot as plt\n", - "from os import path\n", - "\n", - "import autofit as af" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, lets create a result via pyswarms by repeating the simple model-fit that is performed in \n", - "the `overview/simple/fit.py` example." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "dataset_path = path.join(\"dataset\", \"example_1d\", \"gaussian_x1\")" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Dataset Auto-Simulation__\n", - "\n", - "If the dataset does not already exist on your system, it will be created by running the corresponding\n", - "simulator script. This ensures that all example scripts can be run without manually simulating data first." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "if not path.exists(dataset_path):\n", - " import subprocess\n", - " import sys\n", - "\n", - " subprocess.run(\n", - " [sys.executable, \"scripts/simulators/simulators.py\"],\n", - " check=True,\n", - " )\n", - "\n", - "data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, \"data.json\"))\n", - "noise_map = af.util.numpy_array_from_json(\n", - " file_path=path.join(dataset_path, \"noise_map.json\")\n", - ")\n", - "\n", - "model = af.Model(af.ex.Gaussian)\n", - "\n", - "model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0)\n", - "model.normalization = af.UniformPrior(lower_limit=1e-2, upper_limit=1e2)\n", - "model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0)\n", - "\n", - "analysis = af.ex.Analysis(data=data, noise_map=noise_map)\n", - "\n", - "search = af.PySwarmsGlobal(\n", - " path_prefix=path.join(\"plot\"), name=\"MLEPlotter\", n_particles=50, iters=10\n", - ")\n", - "\n", - "result = search.fit(model=model, analysis=analysis)\n", - "\n", - "samples = result.samples" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Notation__\n", - "\n", - "Plot are labeled with short hand parameter names (e.g. the `centre` parameters are plotted using an `x`). \n", - "\n", - "The mappings of every parameter to its shorthand symbol for plots is specified in the `config/notation.yaml` file \n", - "and can be customized.\n", - "\n", - "Each label also has a superscript corresponding to the model component the parameter originates from. For example,\n", - "Gaussians are given the superscript `g`. This can also be customized in the `config/notation.yaml` file.\n", - "\n", - "__Plotting__\n", - "\n", - "We now use the `autofit.plot` module-level functions and pyswarms's in-built plotting libraries to\n", - "make figures.\n", - "\n", - "The pyswarms readthedocs describes fully all of the methods used below \n", - "\n", - " - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.utils.plotters.html\n", - " \n", - "In all the examples below, we use the `kwargs` of this function to pass in any of the input parameters that are \n", - "described in the API docs." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "# %%\n", - "'''\n", - "__Search Specific Visualization__\n", - "\n", - "PySwarms has bespoke in-built visualization tools that can be used to plot its results.\n", - "\n", - "The first time you run a search, the `search_internal` attribute will be available because it is passed ot the\n", - "result via memory. \n", - "\n", - "If you rerun the fit on a completed result, it will not be available in memory, and therefore\n", - "will be loaded from the `files/search_internal` folder. The `search_internal` entry of the `output.yaml` must be true \n", - "for this to be possible.\n", - "'''" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search_internal = result.search_internal" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `contour` method shows a 2D projection of the particle trajectories." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "from pyswarms.utils import plotters\n", - "\n", - "plotters.plot_contour(\n", - " pos_history=search_internal.pos_history,\n", - " canvas=None,\n", - " title=\"Trajectories\",\n", - " mark=None,\n", - " designer=None,\n", - " mesher=None,\n", - " animator=None,\n", - ")\n", - "plt.show()\n", - "\n", - "plotters.plot_cost_history(\n", - " cost_history=search_internal.cost_history,\n", - " ax=None,\n", - " title=\"Cost History\",\n", - " designer=None,\n", - ")\n", - "plt.show()" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finish." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [], - "outputs": [], - "execution_count": null - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/notebooks/plot/README.rst b/notebooks/plot/README.rst index 809285da..78e108e1 100644 --- a/notebooks/plot/README.rst +++ b/notebooks/plot/README.rst @@ -5,8 +5,7 @@ Files - ``DynestyPlotter.py``: Plots results of a Dynesty fit (e.g. corner). - ``MCMCPlotter.py``: Plots results of an Emcee fit (e.g. corner). -- ``MLEPlotter.py``: Plots results of a PySwarms fit (e.g. contour). -- ``UltraNest.py``: Plots results of an UltraNest fit (e.g. corner). +- ``MLEPlotter.py``: Plots results of an MLE fit (e.g. contour). - ``ZeusPlotter.py``: Plots results of a Zeus fit (e.g. corner). - ``GetDist.py``: Plot results of any MCMC / nested sampler non-linear search using the library GetDist. \ No newline at end of file diff --git a/notebooks/plot/UltraNestPlotter.ipynb b/notebooks/plot/UltraNestPlotter.ipynb deleted file mode 100644 index 5cad91aa..00000000 --- a/notebooks/plot/UltraNestPlotter.ipynb +++ /dev/null @@ -1,237 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Plots: DynestyPlotter\n", - "=======================\n", - "\n", - "This example illustrates how to plot visualization summarizing the results of a ultranest non-linear search using\n", - "the `autofit.plot` module-level functions.\n", - "\n", - "Installation\n", - "------------\n", - "\n", - "Because UltraNest is an optional library, you will likely have to install it manually via the command:\n", - "\n", - "`pip install ultranest`\n", - "\n", - "__Contents__\n", - "\n", - "This script is split into the following sections:\n", - "\n", - "- **Notation**: How parameter labels and superscripts are customized for plots.\n", - "- **Plotting**: Using the plot functions to visualize UltraNest search results.\n", - "- **Search Specific Visualization**: Accessing the native UltraNest sampler for custom visualizations.\n", - "- **Plots**: Producing UltraNest-specific diagnostic plots." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "\n", - "%matplotlib inline\n", - "from pyprojroot import here\n", - "workspace_path = str(here())\n", - "%cd $workspace_path\n", - "print(f\"Working Directory has been set to `{workspace_path}`\")\n", - "\n", - "from os import path\n", - "\n", - "import autofit as af\n", - "import autofit.plot as aplt" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, lets create a result via ultranest by repeating the simple model-fit that is performed in \n", - "the `overview/simple/fit.py` example." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "dataset_path = path.join(\"dataset\", \"example_1d\", \"gaussian_x1\")" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Dataset Auto-Simulation__\n", - "\n", - "If the dataset does not already exist on your system, it will be created by running the corresponding\n", - "simulator script. This ensures that all example scripts can be run without manually simulating data first." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "if not path.exists(dataset_path):\n", - " import subprocess\n", - " import sys\n", - "\n", - " subprocess.run(\n", - " [sys.executable, \"scripts/simulators/simulators.py\"],\n", - " check=True,\n", - " )\n", - "\n", - "data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, \"data.json\"))\n", - "noise_map = af.util.numpy_array_from_json(\n", - " file_path=path.join(dataset_path, \"noise_map.json\")\n", - ")\n", - "\n", - "model = af.Model(af.ex.Gaussian)\n", - "\n", - "analysis = af.ex.Analysis(data=data, noise_map=noise_map)\n", - "\n", - "search = af.UltraNest(path_prefix=\"plot\", name=\"NestPlotter\", max_ncalls=10)\n", - "\n", - "result = search.fit(model=model, analysis=analysis)\n", - "\n", - "samples = result.samples" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Notation__\n", - "\n", - "Plot are labeled with short hand parameter names (e.g. the `centre` parameters are plotted using an `x`). \n", - "\n", - "The mappings of every parameter to its shorthand symbol for plots is specified in the `config/notation.yaml` file \n", - "and can be customized.\n", - "\n", - "Each label also has a superscript corresponding to the model component the parameter originates from. For example,\n", - "Gaussians are given the superscript `g`. This can also be customized in the `config/notation.yaml` file.\n", - "\n", - "__Plotting__\n", - "\n", - "We now use the `autofit.plot` module-level functions to visualize the results.\n", - "\n", - "The ultranest readthedocs describes fully all of the methods used below \n", - "\n", - " - https://johannesbuchner.github.io/UltraNest/readme.html\n", - " - https://johannesbuchner.github.io/UltraNest/ultranest.html#module-ultranest.plot\n", - " \n", - "In all the examples below, we use the `kwargs` of this function to pass in any of the input parameters that are \n", - "described in the API docs." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "# %%\n", - "'''\n", - "The `corner_anesthetic` function produces a triangle of 1D and 2D PDF's of every parameter using the library `anesthetic`.\n", - "'''" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "aplt.corner_anesthetic(samples=samples)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `corner_cornerpy` function produces a triangle of 1D and 2D PDF's of every parameter using the library `corner.py`." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "aplt.corner_cornerpy(samples=samples)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Search Specific Visualization__\n", - "\n", - "The internal sampler can be used to plot the results of the non-linear search. \n", - "\n", - "We do this using the `search_internal` attribute which contains the sampler in its native form.\n", - "\n", - "The first time you run a search, the `search_internal` attribute will be available because it is passed ot the\n", - "result via memory. \n", - "\n", - "If you rerun the fit on a completed result, it will not be available in memory, and therefore\n", - "will be loaded from the `files/search_internal` folder. The `search_internal` entry of the `output.yaml` must be true \n", - "for this to be possible." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search_internal = result.search_internal" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Plots__\n", - "\n", - "UltraNest example plots are not shown explicitly below, so checkout their docs for examples!" - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [], - "outputs": [], - "execution_count": null - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/notebooks/searches/mle/PySwarmsGlobal.ipynb b/notebooks/searches/mle/PySwarmsGlobal.ipynb deleted file mode 100644 index 1eeb384a..00000000 --- a/notebooks/searches/mle/PySwarmsGlobal.ipynb +++ /dev/null @@ -1,279 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Searches: PySwarmsGlobal\n", - "========================\n", - "\n", - "This example illustrates how to use the particle swarm optimization algorithm PySwarmsGlobal.\n", - "\n", - "Information about PySwarms can be found at the following links:\n", - "\n", - " - https://github.com/ljvmiranda921/pyswarms\n", - " - https://pyswarms.readthedocs.io/en/latest/index.html\n", - " - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.global_best\n", - "\n", - "__Contents__\n", - "\n", - "This script is split into the following sections:\n", - "\n", - "- **Data**: Loading and plotting the 1D Gaussian dataset used to demonstrate the search.\n", - "- **Model + Analysis**: Setting up the model and analysis for the fitting example.\n", - "- **Search**: Configuring and running the PySwarmsGlobal particle swarm optimizer.\n", - "- **Result**: Inspecting the result and comparing the maximum log likelihood model to the data.\n", - "- **Search Internal**: Accessing the internal PySwarms optimizer for advanced use." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "\n", - "%matplotlib inline\n", - "from pyprojroot import here\n", - "workspace_path = str(here())\n", - "%cd $workspace_path\n", - "print(f\"Working Directory has been set to `{workspace_path}`\")\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from os import path\n", - "\n", - "import autofit as af" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Data__\n", - "\n", - "This example fits a single 1D Gaussian, we therefore load and plot data containing one Gaussian." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "dataset_path = path.join(\"dataset\", \"example_1d\", \"gaussian_x1\")" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Dataset Auto-Simulation__\n", - "\n", - "If the dataset does not already exist on your system, it will be created by running the corresponding\n", - "simulator script. This ensures that all example scripts can be run without manually simulating data first." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "if not path.exists(dataset_path):\n", - " import subprocess\n", - " import sys\n", - "\n", - " subprocess.run(\n", - " [sys.executable, \"scripts/simulators/simulators.py\"],\n", - " check=True,\n", - " )\n", - "\n", - "data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, \"data.json\"))\n", - "noise_map = af.util.numpy_array_from_json(\n", - " file_path=path.join(dataset_path, \"noise_map.json\")\n", - ")\n", - "\n", - "plt.errorbar(\n", - " x=range(data.shape[0]),\n", - " y=data,\n", - " yerr=noise_map,\n", - " linestyle=\"\",\n", - " color=\"k\",\n", - " ecolor=\"k\",\n", - " elinewidth=1,\n", - " capsize=2,\n", - ")\n", - "plt.show()\n", - "plt.close()" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Model + Analysis__\n", - "\n", - "We create the model and analysis, which in this example is a single `Gaussian` and therefore has dimensionality N=3." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "model = af.Model(af.ex.Gaussian)\n", - "\n", - "model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0)\n", - "model.normalization = af.UniformPrior(lower_limit=1e-2, upper_limit=1e2)\n", - "model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0)\n", - "\n", - "analysis = af.ex.Analysis(data=data, noise_map=noise_map)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Search__\n", - "\n", - "We now create and run the `PySwarmsGlobal` object which acts as our non-linear search. \n", - "\n", - "We manually specify all of the PySwarms settings, descriptions of which are provided at the following webpage:\n", - "\n", - " https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.global_best" - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search = af.PySwarmsGlobal(\n", - " path_prefix=\"searches\",\n", - " name=\"PySwarmsGlobal\",\n", - " n_particles=50,\n", - " iters=1000,\n", - " cognitive=0.5,\n", - " social=0.3,\n", - " inertia=0.9,\n", - " ftol=-np.inf,\n", - " iterations_per_full_update=100,\n", - " number_of_cores=1,\n", - ")\n", - "\n", - "result = search.fit(model=model, analysis=analysis)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Result__\n", - "\n", - "The result object returned by the fit provides information on the results of the non-linear search. Lets use it to\n", - "compare the maximum log likelihood `Gaussian` to the data." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "model_data = result.max_log_likelihood_instance.model_data_from(\n", - " xvalues=np.arange(data.shape[0])\n", - ")\n", - "\n", - "plt.errorbar(\n", - " x=range(data.shape[0]),\n", - " y=data,\n", - " yerr=noise_map,\n", - " linestyle=\"\",\n", - " color=\"k\",\n", - " ecolor=\"k\",\n", - " elinewidth=1,\n", - " capsize=2,\n", - ")\n", - "plt.plot(range(data.shape[0]), model_data, color=\"r\")\n", - "plt.title(\"PySwarmsGlobal model fit to 1D Gaussian dataset.\")\n", - "plt.xlabel(\"x values of profile\")\n", - "plt.ylabel(\"Profile normalization\")\n", - "plt.show()\n", - "plt.close()" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Search Internal__\n", - "\n", - "The result also contains the internal representation of the non-linear search.\n", - "\n", - "The internal representation of the non-linear search ensures that all sampling info is available in its native form.\n", - "This can be passed to functions which take it as input, for example if the sampling package has bespoke visualization \n", - "functions.\n", - "\n", - "For `PySwarms`, this is an instance of the `Sampler` object (`from pyswarms import GlobalBestPSO`)." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search_internal = result.search_internal\n", - "\n", - "print(search_internal)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The internal search is by default not saved to hard-disk, because it can often take up quite a lot of hard-disk space\n", - "(significantly more than standard output files).\n", - "\n", - "This means that the search internal will only be available the first time you run the search. If you rerun the code \n", - "and the search is bypassed because the results already exist on hard-disk, the search internal will not be available.\n", - "\n", - "If you are frequently using the search internal you can have it saved to hard-disk by changing the `search_internal`\n", - "setting in `output.yaml` to `True`. The result will then have the search internal available as an attribute, \n", - "irrespective of whether the search is re-run or not." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [], - "outputs": [], - "execution_count": null - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/notebooks/searches/mle/PySwarmsLocal.ipynb b/notebooks/searches/mle/PySwarmsLocal.ipynb deleted file mode 100644 index cec12ce1..00000000 --- a/notebooks/searches/mle/PySwarmsLocal.ipynb +++ /dev/null @@ -1,281 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Searches: PySwarmsLocal\n", - "========================\n", - "\n", - "This example illustrates how to use the particle swarm optimization algorithm PySwarmsLocal.\n", - "\n", - "Information about PySwarms can be found at the following links:\n", - "\n", - " - https://github.com/ljvmiranda921/pyswarms\n", - " - https://pyswarms.readthedocs.io/en/latest/index.html\n", - " - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.local_best\n", - "\n", - "__Contents__\n", - "\n", - "This script is split into the following sections:\n", - "\n", - "- **Data**: Loading and plotting the 1D Gaussian dataset used to demonstrate the search.\n", - "- **Model + Analysis**: Setting up the model and analysis for the fitting example.\n", - "- **Search**: Configuring and running the PySwarmsLocal particle swarm optimizer.\n", - "- **Result**: Inspecting the result and comparing the maximum log likelihood model to the data.\n", - "- **Search Internal**: Accessing the internal PySwarms optimizer for advanced use." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "\n", - "%matplotlib inline\n", - "from pyprojroot import here\n", - "workspace_path = str(here())\n", - "%cd $workspace_path\n", - "print(f\"Working Directory has been set to `{workspace_path}`\")\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from os import path\n", - "\n", - "import autofit as af" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Data__\n", - "\n", - "This example fits a single 1D Gaussian, we therefore load and plot data containing one Gaussian." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "dataset_path = path.join(\"dataset\", \"example_1d\", \"gaussian_x1\")" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Dataset Auto-Simulation__\n", - "\n", - "If the dataset does not already exist on your system, it will be created by running the corresponding\n", - "simulator script. This ensures that all example scripts can be run without manually simulating data first." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "if not path.exists(dataset_path):\n", - " import subprocess\n", - " import sys\n", - "\n", - " subprocess.run(\n", - " [sys.executable, \"scripts/simulators/simulators.py\"],\n", - " check=True,\n", - " )\n", - "\n", - "data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, \"data.json\"))\n", - "noise_map = af.util.numpy_array_from_json(\n", - " file_path=path.join(dataset_path, \"noise_map.json\")\n", - ")\n", - "\n", - "plt.errorbar(\n", - " x=range(data.shape[0]),\n", - " y=data,\n", - " yerr=noise_map,\n", - " linestyle=\"\",\n", - " color=\"k\",\n", - " ecolor=\"k\",\n", - " elinewidth=1,\n", - " capsize=2,\n", - ")\n", - "plt.show()\n", - "plt.close()" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Model + Analysis__\n", - "\n", - "We create the model and analysis, which in this example is a single `Gaussian` and therefore has dimensionality N=3." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "model = af.Model(af.ex.Gaussian)\n", - "\n", - "model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0)\n", - "model.normalization = af.UniformPrior(lower_limit=1e-2, upper_limit=1e2)\n", - "model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0)\n", - "\n", - "analysis = af.ex.Analysis(data=data, noise_map=noise_map)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Search__\n", - "\n", - "We now create and run the `PySwarmsLocal` object which acts as our non-linear search. \n", - "\n", - "We manually specify all of the PySwarms settings, descriptions of which are provided at the following webpage:\n", - "\n", - " https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.local_best" - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search = af.PySwarmsLocal(\n", - " path_prefix=\"searches\",\n", - " name=\"PySwarmsLocal\",\n", - " n_particles=50,\n", - " iters=1000,\n", - " cognitive=0.5,\n", - " social=0.3,\n", - " inertia=0.9,\n", - " number_of_k_neighbors=3,\n", - " minkowski_p_norm=2,\n", - " ftol=-np.inf,\n", - " iterations_per_full_update=1000,\n", - " number_of_cores=1,\n", - ")\n", - "\n", - "result = search.fit(model=model, analysis=analysis)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Result__\n", - "\n", - "The result object returned by the fit provides information on the results of the non-linear search. Lets use it to\n", - "compare the maximum log likelihood `Gaussian` to the data." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "model_data = result.max_log_likelihood_instance.model_data_from(\n", - " xvalues=np.arange(data.shape[0])\n", - ")\n", - "\n", - "plt.errorbar(\n", - " x=range(data.shape[0]),\n", - " y=data,\n", - " yerr=noise_map,\n", - " linestyle=\"\",\n", - " color=\"k\",\n", - " ecolor=\"k\",\n", - " elinewidth=1,\n", - " capsize=2,\n", - ")\n", - "plt.plot(range(data.shape[0]), model_data, color=\"r\")\n", - "plt.title(\"PySwarmsLocal model fit to 1D Gaussian dataset.\")\n", - "plt.xlabel(\"x values of profile\")\n", - "plt.ylabel(\"Profile normalization\")\n", - "plt.show()\n", - "plt.close()" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Search Internal__\n", - "\n", - "The result also contains the internal representation of the non-linear search.\n", - "\n", - "The internal representation of the non-linear search ensures that all sampling info is available in its native form.\n", - "This can be passed to functions which take it as input, for example if the sampling package has bespoke visualization \n", - "functions.\n", - "\n", - "For `PySwarms`, this is an instance of the `Sampler` object (`from pyswarms import LocalBestPSO`)." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search_internal = result.search_internal\n", - "\n", - "print(search_internal)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The internal search is by default not saved to hard-disk, because it can often take up quite a lot of hard-disk space\n", - "(significantly more than standard output files).\n", - "\n", - "This means that the search internal will only be available the first time you run the search. If you rerun the code \n", - "and the search is bypassed because the results already exist on hard-disk, the search internal will not be available.\n", - "\n", - "If you are frequently using the search internal you can have it saved to hard-disk by changing the `search_internal`\n", - "setting in `output.yaml` to `True`. The result will then have the search internal available as an attribute, \n", - "irrespective of whether the search is re-run or not." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [], - "outputs": [], - "execution_count": null - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/notebooks/searches/mle/README.rst b/notebooks/searches/mle/README.rst index 5165a691..898044f1 100644 --- a/notebooks/searches/mle/README.rst +++ b/notebooks/searches/mle/README.rst @@ -5,8 +5,6 @@ Files - ``drawer.py``: Fit a model using the in-built ``Drawer`` which simple draws samples from the priors. - ``LBFGS.py``: Fit a model using the scipy lbfgs optimizer. -- ``PySwarmsGlobal.py``: Fit a model using the optimizer algorithm PySwarms, using its global fitting method. -- ``PySwarmsLocal.py``: Fit a model using the optimizer algorithm PySwarms, using its local fitting method. - ``analysis.py``: Not an example, an ``Analysis`` class used in the examples. - ``model.py``: Not an example, defines the model component used in the examples. \ No newline at end of file diff --git a/notebooks/searches/nest/README.rst b/notebooks/searches/nest/README.rst index e27e6fd6..36262e6c 100644 --- a/notebooks/searches/nest/README.rst +++ b/notebooks/searches/nest/README.rst @@ -5,7 +5,6 @@ Files - ``DynestyDynamic.py``: Fit a model using the nested sampling algorithm Dynesty, using its dynamic sampler. - ``DynestStatic.py``: Fit a model using the nested sampling algorithm Dynesty, using its static sampler. -- ``UltraNest.py``: Fit a model using the nested sampling algorithm UltraNest, using its static sampler. - ``analysis.py``: Not an example, an ``Analysis`` class used in the examples. - ``model.py``: Not an example, defines the model component used in the examples. \ No newline at end of file diff --git a/notebooks/searches/nest/UltraNest.ipynb b/notebooks/searches/nest/UltraNest.ipynb deleted file mode 100644 index 7b4cb795..00000000 --- a/notebooks/searches/nest/UltraNest.ipynb +++ /dev/null @@ -1,255 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Searches: UltraNest\n", - "=======================\n", - "\n", - "This example illustrates how to use the nested sampling algorithm UltraNest.\n", - "\n", - "UltraNest is an optional requirement and must be installed manually via the command `pip install ultranest`.\n", - "It is optional as it has certain dependencies which are generally straight forward to install (e.g. Cython).\n", - "\n", - "Information about UltraNest can be found at the following links:\n", - "\n", - " - https://github.com/JohannesBuchner/UltraNest\n", - " - https://johannesbuchner.github.io/UltraNest/readme.html\n", - "\n", - "__Contents__\n", - "\n", - "This script is split into the following sections:\n", - "\n", - "- **Data**: Loading and plotting the 1D Gaussian dataset used to demonstrate the search.\n", - "- **Model + Analysis**: Setting up the model and analysis for the fitting example.\n", - "- **Search**: Configuring and running the UltraNest nested sampler.\n", - "- **Result**: Inspecting the result and comparing the maximum log likelihood model to the data." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "\n", - "%matplotlib inline\n", - "from pyprojroot import here\n", - "workspace_path = str(here())\n", - "%cd $workspace_path\n", - "print(f\"Working Directory has been set to `{workspace_path}`\")\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from os import path\n", - "\n", - "import autofit as af" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Data__\n", - "\n", - "This example fits a single 1D Gaussian, we therefore load and plot data containing one Gaussian." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "dataset_path = path.join(\"dataset\", \"example_1d\", \"gaussian_x1\")" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Dataset Auto-Simulation__\n", - "\n", - "If the dataset does not already exist on your system, it will be created by running the corresponding\n", - "simulator script. This ensures that all example scripts can be run without manually simulating data first." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "if not path.exists(dataset_path):\n", - " import subprocess\n", - " import sys\n", - "\n", - " subprocess.run(\n", - " [sys.executable, \"scripts/simulators/simulators.py\"],\n", - " check=True,\n", - " )\n", - "\n", - "data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, \"data.json\"))\n", - "noise_map = af.util.numpy_array_from_json(\n", - " file_path=path.join(dataset_path, \"noise_map.json\")\n", - ")\n", - "\n", - "plt.errorbar(\n", - " x=range(data.shape[0]),\n", - " y=data,\n", - " yerr=noise_map,\n", - " linestyle=\"\",\n", - " color=\"k\",\n", - " ecolor=\"k\",\n", - " elinewidth=1,\n", - " capsize=2,\n", - ")\n", - "plt.show()\n", - "plt.close()" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Model + Analysis__\n", - "\n", - "We create the model and analysis, which in this example is a single `Gaussian` and therefore has dimensionality N=3." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "model = af.Model(af.ex.Gaussian)\n", - "\n", - "model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0)\n", - "model.normalization = af.LogUniformPrior(lower_limit=1e-2, upper_limit=1e2)\n", - "model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0)\n", - "\n", - "analysis = af.ex.Analysis(data=data, noise_map=noise_map)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Search__\n", - "\n", - "We now create and run the `UltraNest` object which acts as our non-linear search. \n", - "\n", - "We manually specify all of the Dynesty settings, descriptions of which are provided at the following webpage:\n", - "\n", - "- https://johannesbuchner.github.io/UltraNest/readme.html\n", - "- https://johannesbuchner.github.io/UltraNest/ultranest.html#ultranest.integrator.ReactiveNestedSampler" - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "search = af.UltraNest(\n", - " path_prefix=\"searches\",\n", - " name=\"UltraNest\",\n", - " resume=True,\n", - " run_num=None,\n", - " num_test_samples=2,\n", - " draw_multiple=True,\n", - " num_bootstraps=30,\n", - " vectorized=False,\n", - " ndraw_min=128,\n", - " ndraw_max=65536,\n", - " storage_backend=\"hdf5\",\n", - " warmstart_max_tau=-1,\n", - " update_interval_volume_fraction=0.8,\n", - " update_interval_ncall=None,\n", - " log_interval=None,\n", - " show_status=True,\n", - " viz_callback=\"auto\",\n", - " dlogz=0.5,\n", - " dKL=0.5,\n", - " frac_remain=0.01,\n", - " Lepsilon=0.001,\n", - " min_ess=400,\n", - " max_iters=None,\n", - " max_ncalls=None,\n", - " max_num_improvement_loops=-1,\n", - " min_num_live_points=50,\n", - " cluster_num_live_points=40,\n", - " insertion_test_window=10,\n", - " insertion_test_zscore_threshold=2,\n", - " stepsampler_cls=\"RegionMHSampler\",\n", - " nsteps=11,\n", - " number_of_cores=1,\n", - ")\n", - "\n", - "result = search.fit(model=model, analysis=analysis)" - ], - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "__Result__\n", - "\n", - "The result object returned by the fit provides information on the results of the non-linear search. Lets use it to\n", - "compare the maximum log likelihood `Gaussian` to the data." - ] - }, - { - "cell_type": "code", - "metadata": {}, - "source": [ - "model_data = result.max_log_likelihood_instance.model_data_from(\n", - " xvalues=np.arange(data.shape[0])\n", - ")\n", - "\n", - "plt.errorbar(\n", - " x=range(data.shape[0]),\n", - " y=data,\n", - " yerr=noise_map,\n", - " linestyle=\"\",\n", - " color=\"k\",\n", - " ecolor=\"k\",\n", - " elinewidth=1,\n", - " capsize=2,\n", - ")\n", - "plt.plot(range(data.shape[0]), model_data, color=\"r\")\n", - "plt.title(\"UltraNest model fit to 1D Gaussian dataset.\")\n", - "plt.xlabel(\"x values of profile\")\n", - "plt.ylabel(\"Profile normalization\")\n", - "plt.show()\n", - "plt.close()\n" - ], - "outputs": [], - "execution_count": null - } - ], - "metadata": { - "anaconda-cloud": {}, - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/projects/cosmology/config/non_linear/nest.yaml b/projects/cosmology/config/non_linear/nest.yaml index 90016114..3977f09e 100644 --- a/projects/cosmology/config/non_linear/nest.yaml +++ b/projects/cosmology/config/non_linear/nest.yaml @@ -2,7 +2,7 @@ # - Dynesty: https://github.com/joshspeagle/dynesty / https://dynesty.readthedocs.io/en/latest/index.html # - Nautilus https://https://github.com/johannesulf/nautilus / https://nautilus-sampler.readthedocs.io/en/stable/index.html -# - UltraNest: https://github.com/JohannesBuchner/UltraNest / https://johannesbuchner.github.io/UltraNest/readme.html + # Settings in the [search] and [run] entries are specific to each nested algorithm and should be determined by # consulting that MCMC method's own readthedocs. @@ -72,50 +72,6 @@ DynestyDynamic: iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable). -UltraNest: - search: - draw_multiple: true - ndraw_max: 65536 - ndraw_min: 128 - num_bootstraps: 30 - num_test_samples: 2 - resume: true - run_num: null - storage_backend: hdf5 - vectorized: false - warmstart_max_tau: -1.0 - run: - cluster_num_live_points: 40 - dkl: 0.5 - dlogz: 0.5 - frac_remain: 0.01 - insertion_test_window: 10 - insertion_test_zscore_threshold: 2 - lepsilon: 0.001 - log_interval: null - max_iters: null - max_ncalls: null - max_num_improvement_loops: -1.0 - min_ess: 400 - min_num_live_points: 400 - show_status: true - update_interval_ncall: null - update_interval_volume_fraction: 0.8 - viz_callback: auto - stepsampler: - adaptive_nsteps: false - log: false - max_nsteps: 1000 - nsteps: 25 - region_filter: false - scale: 1.0 - stepsampler_cls: null - initialize: # The method used to generate where walkers are initialized in parameter space {prior}. - method: prior # priors: samples are initialized by randomly drawing from each parameter's prior. - parallel: - number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing. - printing: - silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter. iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. diff --git a/projects/cosmology/config/non_linear/optimize.yaml b/projects/cosmology/config/non_linear/optimize.yaml index 365b911f..3704cbc4 100644 --- a/projects/cosmology/config/non_linear/optimize.yaml +++ b/projects/cosmology/config/non_linear/optimize.yaml @@ -2,53 +2,9 @@ # **PyAutoFit** supports the following maximum likelihood estimator (MLE) algorithms: -# - PySwarms: https://github.com/ljvmiranda921/pyswarms / https://pyswarms.readthedocs.io/en/latest/index.html - -# Settings in the [search], [run] and [options] entries are specific to each nested algorithm and should be +# Settings in the [search], [run] and [options] entries are specific to each MLE algorithm and should be # determined by consulting that method's own readthedocs. -PySwarmsGlobal: - run: - iters: 2000 - search: - cognitive: 0.5 - ftol: -.inf - inertia: 0.9 - n_particles: 50 - social: 0.3 - initialize: # The method used to generate where walkers are initialized in parameter space {prior | ball}. - method: ball # priors: samples are initialized by randomly drawing from each parameter's prior. ball: samples are initialized by randomly drawing unit values from a narrow uniform distribution. - ball_lower_limit: 0.49 # The lower limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - ball_upper_limit: 0.51 # The upper limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - parallel: - number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing. - printing: - silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter. - iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. - iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. - remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable). -PySwarmsLocal: - run: - iters: 2000 - search: - cognitive: 0.5 - ftol: -.inf - inertia: 0.9 - minkowski_p_norm: 2 - n_particles: 50 - number_of_k_neighbors: 3 - social: 0.3 - initialize: # The method used to generate where walkers are initialized in parameter space {prior | ball}. - method: ball # priors: samples are initialized by randomly drawing from each parameter's prior. ball: samples are initialized by randomly drawing unit values from a narrow uniform distribution. - ball_lower_limit: 0.49 # The lower limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - ball_upper_limit: 0.51 # The upper limit of the uniform distribution unit values are drawn from when initializing walkers using the ball method. - parallel: - number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing. - printing: - silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter. - iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow. - iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit. - remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable). LBFGS: search: tol: null diff --git a/projects/cosmology/config/visualize.yaml b/projects/cosmology/config/visualize.yaml index 64cfa0d5..db85003b 100644 --- a/projects/cosmology/config/visualize.yaml +++ b/projects/cosmology/config/visualize.yaml @@ -12,15 +12,6 @@ plots_search: likelihood_series: true # Output likelihood series figure during a non-linear search fit? time_series: true # Output time series figure during a non-linear search fit? trajectories: true # Output trajectories figure during a non-linear search fit? - pyswarms: - contour: true # Output contour figure during a non-linear search fit? - cost_history: true # Output cost_history figure during a non-linear search fit? - time_series: true # Output time_series figure during a non-linear search fit? - trajectories: true # Output trajectories figure during a non-linear search fit? - ultranest: - corner: true # Output corner figure (using anestetic) during a non-linear search fit? - runplot: true # Output Ultranest runplot figure during a non-linear search fit? - traceplot: true # Output Ultranest traceplot figure during a non-linear search fit? zeus: corner: true # Output corner figure (using corner.py) during a non-linear search fit? likelihood_series: true # Output likelihood series figure during a non-linear search fit? diff --git a/scripts/cookbooks/search.py b/scripts/cookbooks/search.py index ec051153..eebcbb56 100644 --- a/scripts/cookbooks/search.py +++ b/scripts/cookbooks/search.py @@ -23,9 +23,6 @@ - Zeus (MCMC): The Zeus ensemble sampler MCMC. - DynestyDynamic (Nested Sampling): The Dynesty dynamic nested sampler. - DynestyStatic (Nested Sampling): The Dynesty static nested sampler. - - UltraNest (Nested Sampling): The UltraNest nested sampler. - - PySwarmsGlobal (Particle Swarm Optimization): The global PySwarms particle swarm optimization - - PySwarmsLocal (Particle Swarm Optimization): The local PySwarms particle swarm optimization. - LBFGS: The L-BFGS scipy optimization. """ @@ -384,96 +381,6 @@ max_move=100, ) -""" -__UltraNest (Nested Sampling)__ - -The UltraNest sampler is a Nested Sampling algorithm. It is a Python implementation of the -`Buchner `_ algorithm. - -UltraNest is an optional requirement and must be installed manually via the command `pip install ultranest`. -It is optional as it has certain dependencies which are generally straight forward to install (e.g. Cython). - -Information about UltraNest can be found at the following links: - - - https://github.com/JohannesBuchner/UltraNest - - https://johannesbuchner.github.io/UltraNest/readme.html -""" -search = af.UltraNest( - resume=True, - run_num=None, - num_test_samples=2, - draw_multiple=True, - num_bootstraps=30, - vectorized=False, - ndraw_min=128, - ndraw_max=65536, - storage_backend="hdf5", - warmstart_max_tau=-1, - update_interval_volume_fraction=0.8, - update_interval_ncall=None, - log_interval=None, - show_status=True, - viz_callback="auto", - dlogz=0.5, - dKL=0.5, - frac_remain=0.01, - Lepsilon=0.001, - min_ess=400, - max_iters=None, - max_ncalls=None, - max_num_improvement_loops=-1, - min_num_live_points=50, - cluster_num_live_points=40, - insertion_test_window=10, - insertion_test_zscore_threshold=2, - stepsampler_cls="RegionMHSampler", - nsteps=11, -) - -""" -__PySwarmsGlobal__ - -The PySwarmsGlobal sampler is a Global Optimization algorithm. It is a Python implementation of the -`Bratley `_ algorithm. - -Information about PySwarms can be found at the following links: - - - https://github.com/ljvmiranda921/pyswarms - - https://pyswarms.readthedocs.io/en/latest/index.html - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.global_best -""" -search = af.PySwarmsGlobal( - n_particles=50, - iters=1000, - cognitive=0.5, - social=0.3, - inertia=0.9, - ftol=-np.inf, -) - -""" -__PySwarmsLocal__ - -The PySwarmsLocal sampler is a Local Optimization algorithm. It is a Python implementation of the -`Bratley `_ algorithm. - -Information about PySwarms can be found at the following links: - - - https://github.com/ljvmiranda921/pyswarms - - https://pyswarms.readthedocs.io/en/latest/index.html - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.global_best -""" -search = af.PySwarmsLocal( - n_particles=50, - iters=1000, - cognitive=0.5, - social=0.3, - inertia=0.9, - number_of_k_neighbors=3, - minkowski_p_norm=2, - ftol=-np.inf, -) - """ __LBFGS__ diff --git a/scripts/features/interpolate.py b/scripts/features/interpolate.py index fd36da56..17d14772 100644 --- a/scripts/features/interpolate.py +++ b/scripts/features/interpolate.py @@ -168,7 +168,7 @@ __Search__ The model is fitted to the data using the nested sampling algorithm - Dynesty (https://johannesbuchner.github.io/UltraNest/readme.html). + Dynesty (https://dynesty.readthedocs.io/en/latest/). """ search = af.DynestyStatic( path_prefix=path.join("interpolate"), diff --git a/scripts/plot/PySwarmsPlotter.py b/scripts/plot/PySwarmsPlotter.py deleted file mode 100644 index a3793f10..00000000 --- a/scripts/plot/PySwarmsPlotter.py +++ /dev/null @@ -1,133 +0,0 @@ -""" -Plots: PySwarmsPlotter -====================== - -This example illustrates how to plot visualization summarizing the results of a pyswarms non-linear search using -the `autofit.plot` module-level functions. - -__Contents__ - -This script is split into the following sections: - -- **Notation**: How parameter labels and superscripts are customized for plots. -- **Plotting**: Using the plot functions to visualize PySwarms search results. -- **Search Specific Visualization**: Accessing the native PySwarms optimizer for custom visualizations. -""" - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - -import matplotlib.pyplot as plt -from os import path - -import autofit as af - -""" -First, lets create a result via pyswarms by repeating the simple model-fit that is performed in -the `overview/simple/fit.py` example. -""" -dataset_path = path.join("dataset", "example_1d", "gaussian_x1") - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -model = af.Model(af.ex.Gaussian) - -model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) -model.normalization = af.UniformPrior(lower_limit=1e-2, upper_limit=1e2) -model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0) - -analysis = af.ex.Analysis(data=data, noise_map=noise_map) - -search = af.PySwarmsGlobal( - path_prefix=path.join("plot"), name="MLEPlotter", n_particles=50, iters=10 -) - -result = search.fit(model=model, analysis=analysis) - -samples = result.samples - -""" -__Notation__ - -Plot are labeled with short hand parameter names (e.g. the `centre` parameters are plotted using an `x`). - -The mappings of every parameter to its shorthand symbol for plots is specified in the `config/notation.yaml` file -and can be customized. - -Each label also has a superscript corresponding to the model component the parameter originates from. For example, -Gaussians are given the superscript `g`. This can also be customized in the `config/notation.yaml` file. - -__Plotting__ - -We now use the `autofit.plot` module-level functions and pyswarms's in-built plotting libraries to -make figures. - -The pyswarms readthedocs describes fully all of the methods used below - - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.utils.plotters.html - -In all the examples below, we use the `kwargs` of this function to pass in any of the input parameters that are -described in the API docs. -""" -""" -__Search Specific Visualization__ - -PySwarms has bespoke in-built visualization tools that can be used to plot its results. - -The first time you run a search, the `search_internal` attribute will be available because it is passed ot the -result via memory. - -If you rerun the fit on a completed result, it will not be available in memory, and therefore -will be loaded from the `files/search_internal` folder. The `search_internal` entry of the `output.yaml` must be true -for this to be possible. -""" -search_internal = result.search_internal - -""" -The `contour` method shows a 2D projection of the particle trajectories. -""" -from pyswarms.utils import plotters - -plotters.plot_contour( - pos_history=search_internal.pos_history, - canvas=None, - title="Trajectories", - mark=None, - designer=None, - mesher=None, - animator=None, -) -plt.show() - -plotters.plot_cost_history( - cost_history=search_internal.cost_history, - ax=None, - title="Cost History", - designer=None, -) -plt.show() - -""" -Finish. -""" diff --git a/scripts/plot/README.rst b/scripts/plot/README.rst index 809285da..78e108e1 100644 --- a/scripts/plot/README.rst +++ b/scripts/plot/README.rst @@ -5,8 +5,7 @@ Files - ``DynestyPlotter.py``: Plots results of a Dynesty fit (e.g. corner). - ``MCMCPlotter.py``: Plots results of an Emcee fit (e.g. corner). -- ``MLEPlotter.py``: Plots results of a PySwarms fit (e.g. contour). -- ``UltraNest.py``: Plots results of an UltraNest fit (e.g. corner). +- ``MLEPlotter.py``: Plots results of an MLE fit (e.g. contour). - ``ZeusPlotter.py``: Plots results of a Zeus fit (e.g. corner). - ``GetDist.py``: Plot results of any MCMC / nested sampler non-linear search using the library GetDist. \ No newline at end of file diff --git a/scripts/plot/UltraNestPlotter.py b/scripts/plot/UltraNestPlotter.py deleted file mode 100644 index d07008d7..00000000 --- a/scripts/plot/UltraNestPlotter.py +++ /dev/null @@ -1,125 +0,0 @@ -""" -Plots: DynestyPlotter -======================= - -This example illustrates how to plot visualization summarizing the results of a ultranest non-linear search using -the `autofit.plot` module-level functions. - -Installation ------------- - -Because UltraNest is an optional library, you will likely have to install it manually via the command: - -`pip install ultranest` - -__Contents__ - -This script is split into the following sections: - -- **Notation**: How parameter labels and superscripts are customized for plots. -- **Plotting**: Using the plot functions to visualize UltraNest search results. -- **Search Specific Visualization**: Accessing the native UltraNest sampler for custom visualizations. -- **Plots**: Producing UltraNest-specific diagnostic plots. -""" - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - -from os import path - -import autofit as af -import autofit.plot as aplt - -""" -First, lets create a result via ultranest by repeating the simple model-fit that is performed in -the `overview/simple/fit.py` example. -""" -dataset_path = path.join("dataset", "example_1d", "gaussian_x1") - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -model = af.Model(af.ex.Gaussian) - -analysis = af.ex.Analysis(data=data, noise_map=noise_map) - -search = af.UltraNest(path_prefix="plot", name="NestPlotter", max_ncalls=10) - -result = search.fit(model=model, analysis=analysis) - -samples = result.samples - -""" -__Notation__ - -Plot are labeled with short hand parameter names (e.g. the `centre` parameters are plotted using an `x`). - -The mappings of every parameter to its shorthand symbol for plots is specified in the `config/notation.yaml` file -and can be customized. - -Each label also has a superscript corresponding to the model component the parameter originates from. For example, -Gaussians are given the superscript `g`. This can also be customized in the `config/notation.yaml` file. - -__Plotting__ - -We now use the `autofit.plot` module-level functions to visualize the results. - -The ultranest readthedocs describes fully all of the methods used below - - - https://johannesbuchner.github.io/UltraNest/readme.html - - https://johannesbuchner.github.io/UltraNest/ultranest.html#module-ultranest.plot - -In all the examples below, we use the `kwargs` of this function to pass in any of the input parameters that are -described in the API docs. -""" -""" -The `corner_anesthetic` function produces a triangle of 1D and 2D PDF's of every parameter using the library `anesthetic`. -""" -aplt.corner_anesthetic(samples=samples) - -""" -The `corner_cornerpy` function produces a triangle of 1D and 2D PDF's of every parameter using the library `corner.py`. -""" -aplt.corner_cornerpy(samples=samples) - -""" -__Search Specific Visualization__ - -The internal sampler can be used to plot the results of the non-linear search. - -We do this using the `search_internal` attribute which contains the sampler in its native form. - -The first time you run a search, the `search_internal` attribute will be available because it is passed ot the -result via memory. - -If you rerun the fit on a completed result, it will not be available in memory, and therefore -will be loaded from the `files/search_internal` folder. The `search_internal` entry of the `output.yaml` must be true -for this to be possible. -""" -search_internal = result.search_internal - -""" -__Plots__ - -UltraNest example plots are not shown explicitly below, so checkout their docs for examples! -""" diff --git a/scripts/searches/mle/Drawer.py b/scripts/searches/mle/Drawer.py index 9bbb9c2d..1fda8544 100644 --- a/scripts/searches/mle/Drawer.py +++ b/scripts/searches/mle/Drawer.py @@ -131,7 +131,7 @@ capsize=2, ) plt.plot(range(data.shape[0]), model_data, color="r") -plt.title("PySwarmsLocal model fit to 1D Gaussian dataset.") +plt.title("Drawer model fit to 1D Gaussian dataset.") plt.xlabel("x values of profile") plt.ylabel("Profile normalization") plt.show() diff --git a/scripts/searches/mle/LBFGS.py b/scripts/searches/mle/LBFGS.py index 2caec90f..ce23f63d 100644 --- a/scripts/searches/mle/LBFGS.py +++ b/scripts/searches/mle/LBFGS.py @@ -132,7 +132,7 @@ capsize=2, ) plt.plot(range(data.shape[0]), model_data, color="r") -plt.title("PySwarmsLocal model fit to 1D Gaussian dataset.") +plt.title("LBFGS model fit to 1D Gaussian dataset.") plt.xlabel("x values of profile") plt.ylabel("Profile normalization") plt.show() @@ -147,7 +147,7 @@ This can be passed to functions which take it as input, for example if the sampling package has bespoke visualization functions. -For `PySwarms`, this is an instance of the `Sampler` object (`from pyswarms import GlobalBestPSO`). +For `LBFGS`, this is an instance of the scipy `OptimizeResult` object. """ search_internal = result.search_internal diff --git a/scripts/searches/mle/PySwarmsGlobal.py b/scripts/searches/mle/PySwarmsGlobal.py deleted file mode 100644 index d43cc1ff..00000000 --- a/scripts/searches/mle/PySwarmsGlobal.py +++ /dev/null @@ -1,165 +0,0 @@ -""" -Searches: PySwarmsGlobal -======================== - -This example illustrates how to use the particle swarm optimization algorithm PySwarmsGlobal. - -Information about PySwarms can be found at the following links: - - - https://github.com/ljvmiranda921/pyswarms - - https://pyswarms.readthedocs.io/en/latest/index.html - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.global_best - -__Contents__ - -This script is split into the following sections: - -- **Data**: Loading and plotting the 1D Gaussian dataset used to demonstrate the search. -- **Model + Analysis**: Setting up the model and analysis for the fitting example. -- **Search**: Configuring and running the PySwarmsGlobal particle swarm optimizer. -- **Result**: Inspecting the result and comparing the maximum log likelihood model to the data. -- **Search Internal**: Accessing the internal PySwarms optimizer for advanced use. -""" - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - -import matplotlib.pyplot as plt -import numpy as np -from os import path - -import autofit as af - -""" -__Data__ - -This example fits a single 1D Gaussian, we therefore load and plot data containing one Gaussian. -""" -dataset_path = path.join("dataset", "example_1d", "gaussian_x1") - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -plt.errorbar( - x=range(data.shape[0]), - y=data, - yerr=noise_map, - linestyle="", - color="k", - ecolor="k", - elinewidth=1, - capsize=2, -) -plt.show() -plt.close() - -""" -__Model + Analysis__ - -We create the model and analysis, which in this example is a single `Gaussian` and therefore has dimensionality N=3. -""" -model = af.Model(af.ex.Gaussian) - -model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) -model.normalization = af.UniformPrior(lower_limit=1e-2, upper_limit=1e2) -model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0) - -analysis = af.ex.Analysis(data=data, noise_map=noise_map) - -""" -__Search__ - -We now create and run the `PySwarmsGlobal` object which acts as our non-linear search. - -We manually specify all of the PySwarms settings, descriptions of which are provided at the following webpage: - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.global_best -""" -search = af.PySwarmsGlobal( - path_prefix="searches", - name="PySwarmsGlobal", - n_particles=50, - iters=1000, - cognitive=0.5, - social=0.3, - inertia=0.9, - ftol=-np.inf, - iterations_per_full_update=100, - number_of_cores=1, -) - -result = search.fit(model=model, analysis=analysis) - -""" -__Result__ - -The result object returned by the fit provides information on the results of the non-linear search. Lets use it to -compare the maximum log likelihood `Gaussian` to the data. -""" -model_data = result.max_log_likelihood_instance.model_data_from( - xvalues=np.arange(data.shape[0]) -) - -plt.errorbar( - x=range(data.shape[0]), - y=data, - yerr=noise_map, - linestyle="", - color="k", - ecolor="k", - elinewidth=1, - capsize=2, -) -plt.plot(range(data.shape[0]), model_data, color="r") -plt.title("PySwarmsGlobal model fit to 1D Gaussian dataset.") -plt.xlabel("x values of profile") -plt.ylabel("Profile normalization") -plt.show() -plt.close() - -""" -__Search Internal__ - -The result also contains the internal representation of the non-linear search. - -The internal representation of the non-linear search ensures that all sampling info is available in its native form. -This can be passed to functions which take it as input, for example if the sampling package has bespoke visualization -functions. - -For `PySwarms`, this is an instance of the `Sampler` object (`from pyswarms import GlobalBestPSO`). -""" -search_internal = result.search_internal - -print(search_internal) - -""" -The internal search is by default not saved to hard-disk, because it can often take up quite a lot of hard-disk space -(significantly more than standard output files). - -This means that the search internal will only be available the first time you run the search. If you rerun the code -and the search is bypassed because the results already exist on hard-disk, the search internal will not be available. - -If you are frequently using the search internal you can have it saved to hard-disk by changing the `search_internal` -setting in `output.yaml` to `True`. The result will then have the search internal available as an attribute, -irrespective of whether the search is re-run or not. -""" diff --git a/scripts/searches/mle/PySwarmsLocal.py b/scripts/searches/mle/PySwarmsLocal.py deleted file mode 100644 index ced238f0..00000000 --- a/scripts/searches/mle/PySwarmsLocal.py +++ /dev/null @@ -1,167 +0,0 @@ -""" -Searches: PySwarmsLocal -======================== - -This example illustrates how to use the particle swarm optimization algorithm PySwarmsLocal. - -Information about PySwarms can be found at the following links: - - - https://github.com/ljvmiranda921/pyswarms - - https://pyswarms.readthedocs.io/en/latest/index.html - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.local_best - -__Contents__ - -This script is split into the following sections: - -- **Data**: Loading and plotting the 1D Gaussian dataset used to demonstrate the search. -- **Model + Analysis**: Setting up the model and analysis for the fitting example. -- **Search**: Configuring and running the PySwarmsLocal particle swarm optimizer. -- **Result**: Inspecting the result and comparing the maximum log likelihood model to the data. -- **Search Internal**: Accessing the internal PySwarms optimizer for advanced use. -""" - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - -import matplotlib.pyplot as plt -import numpy as np -from os import path - -import autofit as af - -""" -__Data__ - -This example fits a single 1D Gaussian, we therefore load and plot data containing one Gaussian. -""" -dataset_path = path.join("dataset", "example_1d", "gaussian_x1") - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -plt.errorbar( - x=range(data.shape[0]), - y=data, - yerr=noise_map, - linestyle="", - color="k", - ecolor="k", - elinewidth=1, - capsize=2, -) -plt.show() -plt.close() - -""" -__Model + Analysis__ - -We create the model and analysis, which in this example is a single `Gaussian` and therefore has dimensionality N=3. -""" -model = af.Model(af.ex.Gaussian) - -model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) -model.normalization = af.UniformPrior(lower_limit=1e-2, upper_limit=1e2) -model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0) - -analysis = af.ex.Analysis(data=data, noise_map=noise_map) - -""" -__Search__ - -We now create and run the `PySwarmsLocal` object which acts as our non-linear search. - -We manually specify all of the PySwarms settings, descriptions of which are provided at the following webpage: - - https://pyswarms.readthedocs.io/en/latest/api/pyswarms.single.html#module-pyswarms.single.local_best -""" -search = af.PySwarmsLocal( - path_prefix="searches", - name="PySwarmsLocal", - n_particles=50, - iters=1000, - cognitive=0.5, - social=0.3, - inertia=0.9, - number_of_k_neighbors=3, - minkowski_p_norm=2, - ftol=-np.inf, - iterations_per_full_update=1000, - number_of_cores=1, -) - -result = search.fit(model=model, analysis=analysis) - -""" -__Result__ - -The result object returned by the fit provides information on the results of the non-linear search. Lets use it to -compare the maximum log likelihood `Gaussian` to the data. -""" -model_data = result.max_log_likelihood_instance.model_data_from( - xvalues=np.arange(data.shape[0]) -) - -plt.errorbar( - x=range(data.shape[0]), - y=data, - yerr=noise_map, - linestyle="", - color="k", - ecolor="k", - elinewidth=1, - capsize=2, -) -plt.plot(range(data.shape[0]), model_data, color="r") -plt.title("PySwarmsLocal model fit to 1D Gaussian dataset.") -plt.xlabel("x values of profile") -plt.ylabel("Profile normalization") -plt.show() -plt.close() - -""" -__Search Internal__ - -The result also contains the internal representation of the non-linear search. - -The internal representation of the non-linear search ensures that all sampling info is available in its native form. -This can be passed to functions which take it as input, for example if the sampling package has bespoke visualization -functions. - -For `PySwarms`, this is an instance of the `Sampler` object (`from pyswarms import LocalBestPSO`). -""" -search_internal = result.search_internal - -print(search_internal) - -""" -The internal search is by default not saved to hard-disk, because it can often take up quite a lot of hard-disk space -(significantly more than standard output files). - -This means that the search internal will only be available the first time you run the search. If you rerun the code -and the search is bypassed because the results already exist on hard-disk, the search internal will not be available. - -If you are frequently using the search internal you can have it saved to hard-disk by changing the `search_internal` -setting in `output.yaml` to `True`. The result will then have the search internal available as an attribute, -irrespective of whether the search is re-run or not. -""" diff --git a/scripts/searches/mle/README.rst b/scripts/searches/mle/README.rst index 5165a691..898044f1 100644 --- a/scripts/searches/mle/README.rst +++ b/scripts/searches/mle/README.rst @@ -5,8 +5,6 @@ Files - ``drawer.py``: Fit a model using the in-built ``Drawer`` which simple draws samples from the priors. - ``LBFGS.py``: Fit a model using the scipy lbfgs optimizer. -- ``PySwarmsGlobal.py``: Fit a model using the optimizer algorithm PySwarms, using its global fitting method. -- ``PySwarmsLocal.py``: Fit a model using the optimizer algorithm PySwarms, using its local fitting method. - ``analysis.py``: Not an example, an ``Analysis`` class used in the examples. - ``model.py``: Not an example, defines the model component used in the examples. \ No newline at end of file diff --git a/scripts/searches/nest/README.rst b/scripts/searches/nest/README.rst index e27e6fd6..36262e6c 100644 --- a/scripts/searches/nest/README.rst +++ b/scripts/searches/nest/README.rst @@ -5,7 +5,6 @@ Files - ``DynestyDynamic.py``: Fit a model using the nested sampling algorithm Dynesty, using its dynamic sampler. - ``DynestStatic.py``: Fit a model using the nested sampling algorithm Dynesty, using its static sampler. -- ``UltraNest.py``: Fit a model using the nested sampling algorithm UltraNest, using its static sampler. - ``analysis.py``: Not an example, an ``Analysis`` class used in the examples. - ``model.py``: Not an example, defines the model component used in the examples. \ No newline at end of file diff --git a/scripts/searches/nest/UltraNest.py b/scripts/searches/nest/UltraNest.py deleted file mode 100644 index f6fc3f89..00000000 --- a/scripts/searches/nest/UltraNest.py +++ /dev/null @@ -1,163 +0,0 @@ -""" -Searches: UltraNest -======================= - -This example illustrates how to use the nested sampling algorithm UltraNest. - -UltraNest is an optional requirement and must be installed manually via the command `pip install ultranest`. -It is optional as it has certain dependencies which are generally straight forward to install (e.g. Cython). - -Information about UltraNest can be found at the following links: - - - https://github.com/JohannesBuchner/UltraNest - - https://johannesbuchner.github.io/UltraNest/readme.html - -__Contents__ - -This script is split into the following sections: - -- **Data**: Loading and plotting the 1D Gaussian dataset used to demonstrate the search. -- **Model + Analysis**: Setting up the model and analysis for the fitting example. -- **Search**: Configuring and running the UltraNest nested sampler. -- **Result**: Inspecting the result and comparing the maximum log likelihood model to the data. -""" - -# %matplotlib inline -# from pyprojroot import here -# workspace_path = str(here()) -# %cd $workspace_path -# print(f"Working Directory has been set to `{workspace_path}`") - -import matplotlib.pyplot as plt -import numpy as np -from os import path - -import autofit as af - -""" -__Data__ - -This example fits a single 1D Gaussian, we therefore load and plot data containing one Gaussian. -""" -dataset_path = path.join("dataset", "example_1d", "gaussian_x1") - -""" -__Dataset Auto-Simulation__ - -If the dataset does not already exist on your system, it will be created by running the corresponding -simulator script. This ensures that all example scripts can be run without manually simulating data first. -""" -if not path.exists(dataset_path): - import subprocess - import sys - - subprocess.run( - [sys.executable, "scripts/simulators/simulators.py"], - check=True, - ) - -data = af.util.numpy_array_from_json(file_path=path.join(dataset_path, "data.json")) -noise_map = af.util.numpy_array_from_json( - file_path=path.join(dataset_path, "noise_map.json") -) - -plt.errorbar( - x=range(data.shape[0]), - y=data, - yerr=noise_map, - linestyle="", - color="k", - ecolor="k", - elinewidth=1, - capsize=2, -) -plt.show() -plt.close() - -""" -__Model + Analysis__ - -We create the model and analysis, which in this example is a single `Gaussian` and therefore has dimensionality N=3. -""" -model = af.Model(af.ex.Gaussian) - -model.centre = af.UniformPrior(lower_limit=0.0, upper_limit=100.0) -model.normalization = af.LogUniformPrior(lower_limit=1e-2, upper_limit=1e2) -model.sigma = af.UniformPrior(lower_limit=0.0, upper_limit=30.0) - -analysis = af.ex.Analysis(data=data, noise_map=noise_map) - -""" -__Search__ - -We now create and run the `UltraNest` object which acts as our non-linear search. - -We manually specify all of the Dynesty settings, descriptions of which are provided at the following webpage: - -- https://johannesbuchner.github.io/UltraNest/readme.html -- https://johannesbuchner.github.io/UltraNest/ultranest.html#ultranest.integrator.ReactiveNestedSampler - -""" -search = af.UltraNest( - path_prefix="searches", - name="UltraNest", - resume=True, - run_num=None, - num_test_samples=2, - draw_multiple=True, - num_bootstraps=30, - vectorized=False, - ndraw_min=128, - ndraw_max=65536, - storage_backend="hdf5", - warmstart_max_tau=-1, - update_interval_volume_fraction=0.8, - update_interval_ncall=None, - log_interval=None, - show_status=True, - viz_callback="auto", - dlogz=0.5, - dKL=0.5, - frac_remain=0.01, - Lepsilon=0.001, - min_ess=400, - max_iters=None, - max_ncalls=None, - max_num_improvement_loops=-1, - min_num_live_points=50, - cluster_num_live_points=40, - insertion_test_window=10, - insertion_test_zscore_threshold=2, - stepsampler_cls="RegionMHSampler", - nsteps=11, - number_of_cores=1, -) - -result = search.fit(model=model, analysis=analysis) - -""" -__Result__ - -The result object returned by the fit provides information on the results of the non-linear search. Lets use it to -compare the maximum log likelihood `Gaussian` to the data. -""" -model_data = result.max_log_likelihood_instance.model_data_from( - xvalues=np.arange(data.shape[0]) -) - -plt.errorbar( - x=range(data.shape[0]), - y=data, - yerr=noise_map, - linestyle="", - color="k", - ecolor="k", - elinewidth=1, - capsize=2, -) -plt.plot(range(data.shape[0]), model_data, color="r") -plt.title("UltraNest model fit to 1D Gaussian dataset.") -plt.xlabel("x values of profile") -plt.ylabel("Profile normalization") -plt.show() -plt.close()