All modules for which code is available
39 |- bayesquad.acquisition_functions 40 |
- bayesquad.batch_selection 41 |
- bayesquad.gps 42 |
- bayesquad.plotting 43 |
- bayesquad.priors 44 |
- bayesquad.quadrature 45 |
├── docs ├── .nojekyll ├── build │ ├── html │ │ ├── objects.inv │ │ ├── _static │ │ │ ├── down.png │ │ │ ├── file.png │ │ │ ├── plus.png │ │ │ ├── up.png │ │ │ ├── minus.png │ │ │ ├── comment.png │ │ │ ├── ajax-loader.gif │ │ │ ├── up-pressed.png │ │ │ ├── comment-bright.png │ │ │ ├── comment-close.png │ │ │ ├── down-pressed.png │ │ │ ├── documentation_options.js │ │ │ ├── pygments.css │ │ │ ├── classic.css │ │ │ ├── sidebar.js │ │ │ ├── doctools.js │ │ │ └── underscore.js │ │ ├── _sources │ │ │ ├── modules.rst.txt │ │ │ ├── bayesquad.gps.rst.txt │ │ │ ├── bayesquad.priors.rst.txt │ │ │ ├── bayesquad.plotting.rst.txt │ │ │ ├── bayesquad.quadrature.rst.txt │ │ │ ├── bayesquad.batch_selection.rst.txt │ │ │ ├── bayesquad.acquisition_functions.rst.txt │ │ │ ├── bayesquad.rst.txt │ │ │ └── index.rst.txt │ │ ├── .buildinfo │ │ ├── _modules │ │ │ ├── index.html │ │ │ └── bayesquad │ │ │ │ ├── plotting.html │ │ │ │ └── acquisition_functions.html │ │ ├── search.html │ │ ├── index.html │ │ ├── modules.html │ │ ├── bayesquad.plotting.html │ │ ├── bayesquad.acquisition_functions.html │ │ ├── bayesquad.html │ │ ├── py-modindex.html │ │ ├── searchindex.js │ │ ├── bayesquad.batch_selection.html │ │ └── bayesquad.priors.html │ └── doctrees │ │ ├── index.doctree │ │ ├── bayesquad.doctree │ │ ├── modules.doctree │ │ ├── environment.pickle │ │ ├── bayesquad.gps.doctree │ │ ├── bayesquad.priors.doctree │ │ ├── bayesquad.plotting.doctree │ │ ├── bayesquad.quadrature.doctree │ │ ├── bayesquad.batch_selection.doctree │ │ └── bayesquad.acquisition_functions.doctree ├── source │ ├── modules.rst │ ├── bayesquad.gps.rst │ ├── bayesquad.priors.rst │ ├── bayesquad.plotting.rst │ ├── bayesquad.quadrature.rst │ ├── bayesquad.batch_selection.rst │ ├── bayesquad.acquisition_functions.rst │ ├── bayesquad.rst │ ├── index.rst │ └── conf.py ├── index.html └── Makefile ├── requirements.txt ├── make-docs.sh ├── bayesquad ├── __init__.py ├── _util.py ├── plotting.py ├── _transformations.py ├── _decorators.py ├── acquisition_functions.py ├── _optimisation.py ├── _cache.py ├── priors.py ├── _maths_helpers.py ├── _kernel_gradients.py ├── quadrature.py └── batch_selection.py ├── setup.py ├── LICENSE ├── README.md ├── examples ├── example_2d.py └── example_1d.py └── .gitignore /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | scipy 2 | numpy 3 | matplotlib 4 | GPy 5 | multimethod 6 | -------------------------------------------------------------------------------- /docs/build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/objects.inv -------------------------------------------------------------------------------- /make-docs.sh: -------------------------------------------------------------------------------- 1 | sphinx-apidoc --separate --force -o docs/source/ bayesquad 2 | cd docs 3 | make html 4 | 5 | -------------------------------------------------------------------------------- /docs/build/html/_static/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/down.png -------------------------------------------------------------------------------- /docs/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/file.png -------------------------------------------------------------------------------- /docs/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/build/html/_static/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/up.png -------------------------------------------------------------------------------- /docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | bayesquad 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | bayesquad 8 | -------------------------------------------------------------------------------- /docs/build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/modules.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/modules.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/comment.png -------------------------------------------------------------------------------- /docs/build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/build/html/_sources/modules.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad 2 | ========= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | bayesquad 8 | -------------------------------------------------------------------------------- /docs/build/html/_static/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/ajax-loader.gif -------------------------------------------------------------------------------- /docs/build/html/_static/up-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/up-pressed.png -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.gps.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.gps.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/comment-bright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/comment-bright.png -------------------------------------------------------------------------------- /docs/build/html/_static/comment-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/comment-close.png -------------------------------------------------------------------------------- /docs/build/html/_static/down-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/html/_static/down-pressed.png -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.priors.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.priors.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.plotting.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.plotting.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.quadrature.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.quadrature.doctree -------------------------------------------------------------------------------- /bayesquad/__init__.py: -------------------------------------------------------------------------------- 1 | """A module for performing bayesian quadrature, supporting batch selection of points for evaluation and warped GP models 2 | """ 3 | -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.batch_selection.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.batch_selection.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/bayesquad.acquisition_functions.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OxfordML/bayesquad/HEAD/docs/build/doctrees/bayesquad.acquisition_functions.doctree -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/source/bayesquad.gps.rst: -------------------------------------------------------------------------------- 1 | bayesquad.gps module 2 | ==================== 3 | 4 | .. automodule:: bayesquad.gps 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/bayesquad.priors.rst: -------------------------------------------------------------------------------- 1 | bayesquad.priors module 2 | ======================= 3 | 4 | .. automodule:: bayesquad.priors 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.gps.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad.gps module 2 | ==================== 3 | 4 | .. automodule:: bayesquad.gps 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/bayesquad.plotting.rst: -------------------------------------------------------------------------------- 1 | bayesquad.plotting module 2 | ========================= 3 | 4 | .. automodule:: bayesquad.plotting 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.priors.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad.priors module 2 | ======================= 3 | 4 | .. automodule:: bayesquad.priors 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/bayesquad.quadrature.rst: -------------------------------------------------------------------------------- 1 | bayesquad.quadrature module 2 | =========================== 3 | 4 | .. automodule:: bayesquad.quadrature 5 | :members: 6 | :private-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.plotting.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad.plotting module 2 | ========================= 3 | 4 | .. automodule:: bayesquad.plotting 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.quadrature.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad.quadrature module 2 | =========================== 3 | 4 | .. automodule:: bayesquad.quadrature 5 | :members: 6 | :private-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/bayesquad.batch_selection.rst: -------------------------------------------------------------------------------- 1 | bayesquad.batch\_selection module 2 | ================================= 3 | 4 | .. automodule:: bayesquad.batch_selection 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.batch_selection.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad.batch\_selection module 2 | ================================= 3 | 4 | .. automodule:: bayesquad.batch_selection 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/source/bayesquad.acquisition_functions.rst: -------------------------------------------------------------------------------- 1 | bayesquad.acquisition\_functions module 2 | ======================================= 3 | 4 | .. automodule:: bayesquad.acquisition_functions 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 36f55e483e252199e5ae2354fe16e6a8 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.acquisition_functions.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad.acquisition\_functions module 2 | ======================================= 3 | 4 | .. automodule:: bayesquad.acquisition_functions 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt' 9 | }; -------------------------------------------------------------------------------- /docs/source/bayesquad.rst: -------------------------------------------------------------------------------- 1 | bayesquad package 2 | ================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | 9 | bayesquad.acquisition_functions 10 | bayesquad.batch_selection 11 | bayesquad.gps 12 | bayesquad.plotting 13 | bayesquad.priors 14 | bayesquad.quadrature 15 | 16 | Module contents 17 | --------------- 18 | 19 | .. automodule:: bayesquad 20 | :members: 21 | :undoc-members: 22 | :show-inheritance: 23 | -------------------------------------------------------------------------------- /docs/build/html/_sources/bayesquad.rst.txt: -------------------------------------------------------------------------------- 1 | bayesquad package 2 | ================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | .. toctree:: 8 | 9 | bayesquad.acquisition_functions 10 | bayesquad.batch_selection 11 | bayesquad.gps 12 | bayesquad.plotting 13 | bayesquad.priors 14 | bayesquad.quadrature 15 | 16 | Module contents 17 | --------------- 18 | 19 | .. automodule:: bayesquad 20 | :members: 21 | :undoc-members: 22 | :show-inheritance: 23 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup 4 | 5 | setup(name='bayesquad', 6 | version='0.1', 7 | description='Bayesian Quadrature Library', 8 | author='Ed Wagstaff', 9 | author_email='ed@robots.ox.ac.uk', 10 | url='https://github.com/OxfordML/bayesquad', 11 | packages=['bayesquad'], 12 | install_requires=['scipy', 'numpy', 'matplotlib', 'GPy', 'multimethod'], 13 | python_requires='>=3.5' 14 | ) 15 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Batch Bayesian quadrature documentation master file, created by 2 | sphinx-quickstart on Fri Aug 17 15:43:05 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Batch Bayesian quadrature's documentation! 7 | ===================================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. Batch Bayesian quadrature documentation master file, created by 2 | sphinx-quickstart on Fri Aug 17 15:43:05 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Batch Bayesian quadrature's documentation! 7 | ===================================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = BatchBayesianquadrature 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /bayesquad/_util.py: -------------------------------------------------------------------------------- 1 | """Miscellaneous utility functions""" 2 | 3 | import numpy as np 4 | from numpy import ndarray 5 | 6 | 7 | def validate_dimensions(x: ndarray, expected_dimensionality: int): 8 | """Checks that `x` represents data of dimensionality `expected_dimensions`. 9 | 10 | Raises 11 | ------ 12 | ValueError 13 | If `x` is not a 2D array, or if the second dimension of `x` does not have size `expected_dimensions`. 14 | """ 15 | array_dimensions = np.ndim(x) 16 | 17 | if array_dimensions != 2: 18 | raise ValueError("Expected a 2-dimensional array, but got a {}-dimensional array.".format(array_dimensions)) 19 | 20 | actual_dimensionality = np.size(x, 1) 21 | 22 | if actual_dimensionality != expected_dimensionality: 23 | raise ValueError("Expected data in {} dimensions, but got data in {} dimensions." 24 | .format(expected_dimensionality, actual_dimensionality)) 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Edward Wagstaff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bayesian Quadrature 2 | 3 | This library provides code for evaluating the integral of non-negative functions using Bayesian Quadrature, both serially and in a batched mode. 4 | 5 | For some background on Bayesian quadrature, see: 6 | 7 | - [Introductory slides by David Duvenaud](https://www.cs.toronto.edu/~duvenaud/talks/intro_bq.pdf), or [these slides by Roman Garnett](http://probabilistic-numerics.org/assets/pdf/nips2015_probint/roman_talk.pdf) 8 | 9 | And for gory detail: 10 | 11 | - [Sampling for Inference in Probabilistic Models with Fast Bayesian Quadrature, Gunter et al. 2014](https://papers.nips.cc/paper/5483-sampling-for-inference-in-probabilistic-models-with-fast-bayesian-quadrature.pdf) for details on the warped Gaussian Process model implemented here ("WSABI") 12 | - [Batch Selection for Parallelisation of Bayesian Quadrature](https://arxiv.org/abs/1812.01553) for details on our batch selection process 13 | 14 | ## Installation 15 | 16 | Check out this repository and run `pip install .` in the root directory of the repository (i.e. in the directory containing setup.py). You should then be able to run the example scripts. 17 | 18 | ## Documentation 19 | 20 | Documentation is still a work in progress, but some docs are available at https://OxfordML.github.io/bayesquad 21 | 22 | -------------------------------------------------------------------------------- /bayesquad/plotting.py: -------------------------------------------------------------------------------- 1 | """Functions to allow plotting code to be decoupled from the rest of the code.""" 2 | 3 | from functools import wraps 4 | from types import MappingProxyType 5 | from typing import Callable 6 | 7 | 8 | class _Registry: 9 | def __init__(self): 10 | self._callback_registry = {} 11 | 12 | def trigger_callbacks(self, identifier: str, func: Callable): 13 | if identifier not in self._callback_registry: 14 | return 15 | 16 | for callback in self._callback_registry[identifier]: 17 | callback(func) 18 | 19 | def add_callback(self, identifier: str, callback: Callable): 20 | if identifier not in self._callback_registry: 21 | self._callback_registry[identifier] = [] 22 | 23 | self._callback_registry[identifier].append(callback) 24 | 25 | 26 | _function_registry = _Registry() 27 | 28 | # Using a mutable object (e.g. an empty dict) as a default parameter can lead to undesirable behaviour, so we use this 29 | # read-only proxy. 30 | # 31 | # See: 32 | # The problem: https://stackoverflow.com/q/1132941 33 | # A solution: https://stackoverflow.com/a/30638022 34 | _EMPTY = MappingProxyType({}) 35 | 36 | 37 | def plottable(identifier: str, *, default_plotting_parameters=_EMPTY): 38 | def decorator(func: Callable): 39 | @wraps(func) 40 | def func_for_plotting(*args, **kwargs): 41 | # Merge default_plotting_parameters into kwargs 42 | kwargs = {**default_plotting_parameters, **kwargs} 43 | return func(*args, **kwargs) 44 | 45 | _function_registry.trigger_callbacks(identifier, func_for_plotting) 46 | 47 | return func 48 | return decorator 49 | 50 | 51 | def add_callback(identifier: str, callback: Callable): 52 | _function_registry.add_callback(identifier, callback) 53 | -------------------------------------------------------------------------------- /bayesquad/_transformations.py: -------------------------------------------------------------------------------- 1 | """Transform functions""" 2 | from functools import wraps 3 | from typing import Callable 4 | 5 | import numpy as np 6 | import numpy.ma as ma 7 | 8 | 9 | def log_of_function(original_function: Callable) -> Callable: 10 | """Given a function f and its Jacobian, return the log(f) and the Jacobian of log(f). 11 | 12 | f may evaluate to 0 in some places (e.g. due to numerical issues), so we set the log to be -1e10 where f is 0. 13 | Since it's not possible to evaluate the log Jacobian in this case, we set the Jacobian to be the Jacobian of the 14 | original function. 15 | 16 | Parameters 17 | ---------- 18 | original_function 19 | A function returning a tuple of arrays (f(x), Jac(f(x))). The second element of this tuple may be `None`. 20 | 21 | Returns 22 | ------- 23 | log_function : Callable 24 | A function returning a tuple of arrays (log(f(x)), Jac(log(f(x)))). If `original_function` returns `None` for 25 | Jac(f(x)), then Jac(log(f(x))) will also be `None`. 26 | """ 27 | @wraps(original_function) 28 | def log_function(x, *args, **kwargs): 29 | value, jacobian = original_function(x, *args, **kwargs) 30 | masked_value = ma.masked_equal(value, 0) 31 | 32 | log_value = ma.log(masked_value) 33 | log_value = ma.filled(log_value, -1e10) 34 | 35 | if jacobian is not None: 36 | # We need expand_dims here because value is lower-dimensional than jacobian, but they must have the same 37 | # dimensionality for numpy broadcasting to work here. 38 | masked_value = ma.filled(masked_value, 1) 39 | log_jacobian = jacobian / np.expand_dims(masked_value, -1) 40 | else: 41 | log_jacobian = None 42 | 43 | return log_value, log_jacobian 44 | 45 | return log_function 46 | -------------------------------------------------------------------------------- /bayesquad/_decorators.py: -------------------------------------------------------------------------------- 1 | """Decorators to modify function behaviour.""" 2 | from functools import wraps 3 | 4 | import numpy as np 5 | from numpy import ndarray 6 | 7 | 8 | def flexible_array_dimensions(func): 9 | """Modifies a function so that it can accept either 1D or 2D arrays, and return arrays of consistent dimension. 10 | 11 | This decorator allows a vectorised function to be evaluated at a single point, passed as a 1D array. It is intended 12 | to be applied to a function whose array arguments have first dimension ranging across data points, and whose return 13 | values are also arrays with first dimension ranging across data points. After this decorator has been applied, the 14 | function may be evaluated at a single point by passing a 1D array, and the trivial first axis will be removed from 15 | the returned arrays. Within a method which has this decorator applied, we may assume that all array arguments are 16 | 2D, with shape (num_points, num_dimensions). 17 | 18 | NB this means that a 1D array of length n will be interpreted as a single n-dimensional point, rather than n 19 | 1-dimensional points. 20 | """ 21 | @wraps(func) 22 | def transformed_function(*args, **kwargs): 23 | new_args = tuple(np.atleast_2d(arg) if isinstance(arg, ndarray) 24 | else arg 25 | for arg in args) 26 | 27 | values = func(*new_args, **kwargs) 28 | 29 | if all([arg is new_arg for arg, new_arg in zip(args, new_args)]): 30 | return values 31 | 32 | if isinstance(values, tuple): 33 | return tuple(np.squeeze(value, axis=0) if isinstance(value, ndarray) and np.size(value, 0) == 1 34 | else value 35 | for value in values) 36 | elif isinstance(values, ndarray) and np.size(values, 0) == 1: 37 | return np.squeeze(values, axis=0) 38 | else: 39 | return values 40 | 41 | return transformed_function 42 | -------------------------------------------------------------------------------- /bayesquad/acquisition_functions.py: -------------------------------------------------------------------------------- 1 | """Acquisition functions and related functions.""" 2 | import numpy as np 3 | 4 | from .plotting import plottable 5 | from .quadrature import IntegrandModel 6 | 7 | 8 | def model_variance(integrand_model: IntegrandModel): 9 | 10 | @plottable("Model variance", default_plotting_parameters={'calculate_jacobian': False}) 11 | def f(x, *, calculate_jacobian=True): 12 | """Evaluate the variance, and the Jacobian of the variance, for the given `IntegrandModel` at a point, or a set 13 | of points. 14 | 15 | Given an array of shape (num_points, num_dimensions), returns an array of shape (num_points) containing the 16 | function values and an array of shape (num_points, num_dimensions) containing the function Jacobians. 17 | 18 | Given an array of shape (num_dimensions), returns a 0D array containing the function value and an array of shape 19 | (num_dimensions) containing the function Jacobian. 20 | 21 | If the Jacobian is not required (e.g. for plotting), the relevant calculations can be disabled by setting 22 | `calculate_jacobian=False`. 23 | """ 24 | _, variance = integrand_model.posterior_mean_and_variance(x) 25 | 26 | if calculate_jacobian: 27 | variance_jacobian = integrand_model.posterior_variance_jacobian(x) 28 | else: 29 | variance_jacobian = None 30 | 31 | return variance, variance_jacobian 32 | 33 | return f 34 | 35 | 36 | def model_variance_norm_of_gradient_squared(integrand_model: IntegrandModel): 37 | 38 | @plottable("Gradient squared", default_plotting_parameters={'calculate_jacobian': False}) 39 | def f(x, *, calculate_jacobian=True): 40 | """Evaluate the squared norm of the gradient of the variance, and the Jacobian of this quantity, for the given 41 | `IntegrandModel` at a point, or a set of points. 42 | 43 | Given an array of shape (num_points, num_dimensions), returns an array of shape (num_points) containing the 44 | function values and an array of shape (num_points, num_dimensions) containing the function Jacobians. 45 | 46 | Given an array of shape (num_dimensions), returns a 0D array containing the function value and an array of shape 47 | (num_dimensions) containing the function Jacobian. 48 | 49 | If the Jacobian is not required (e.g. for plotting), the relevant calculations can be disabled by setting 50 | `calculate_jacobian=False`. 51 | """ 52 | variance_jacobian = integrand_model.posterior_variance_jacobian(x) 53 | 54 | # Inner product of the Jacobian with itself, for each point. 55 | gradient_squared = np.einsum('...i,...i->...', variance_jacobian, variance_jacobian, optimize=True) 56 | 57 | if calculate_jacobian: 58 | variance_hessian = integrand_model.posterior_variance_hessian(x) 59 | 60 | # Matrix product of Hessian and Jacobian, for each point. 61 | gradient_squared_jacobian = 2 * np.einsum('...ij,...j->...i', 62 | variance_hessian, 63 | variance_jacobian, 64 | optimize=True) 65 | else: 66 | gradient_squared_jacobian = None 67 | 68 | return gradient_squared, gradient_squared_jacobian 69 | 70 | return f 71 | -------------------------------------------------------------------------------- /examples/example_2d.py: -------------------------------------------------------------------------------- 1 | """Plot bayesian quadrature on a simple 2D test function.""" 2 | 3 | from typing import Dict, Any 4 | 5 | import GPy 6 | import matplotlib.pyplot as plt 7 | import numpy as np 8 | from matplotlib.image import AxesImage 9 | 10 | import bayesquad.plotting as plotting 11 | from bayesquad.batch_selection import select_batch, LOCAL_PENALISATION 12 | from bayesquad.gps import WsabiLGP 13 | from bayesquad.priors import Gaussian 14 | from bayesquad.quadrature import IntegrandModel 15 | 16 | 17 | # Set up test function and WSABI-L model. 18 | 19 | def true_function(x): 20 | x = np.atleast_2d(x) 21 | return np.atleast_2d((((np.sin(x) + 0.5 * np.cos(3 * x))**2)/((x/2)**2+0.3)).prod(axis=1)) 22 | 23 | 24 | initial_x = np.array([[0, 0]]) 25 | initial_y = np.sqrt(2 * true_function(initial_x)) 26 | 27 | k = GPy.kern.RBF(2, variance=2, lengthscale=2) 28 | lik = GPy.likelihoods.Gaussian(variance=1e-10) 29 | 30 | prior = Gaussian(mean=np.array([0, 0]), covariance=2*np.eye(2)) 31 | 32 | gpy_gp = GPy.core.GP(initial_x, initial_y, kernel=k, likelihood=lik) 33 | warped_gp = WsabiLGP(gpy_gp) 34 | model = IntegrandModel(warped_gp, prior) 35 | 36 | 37 | def true_integrand(x): 38 | return true_function(x) * prior(x) 39 | 40 | 41 | # Set up plotting. 42 | 43 | LOWER_LIMIT = -4 44 | UPPER_LIMIT = 4 45 | PLOTTING_RESOLUTION = 200 46 | COLOUR_MAP = 'summer' 47 | 48 | 49 | def get_plotting_domain(lower_limit, upper_limit, resolution): 50 | x = np.linspace(lower_limit, upper_limit, resolution) 51 | y = np.linspace(lower_limit, upper_limit, resolution) 52 | x_grid, y_grid = np.meshgrid(x, y) 53 | return np.concatenate(np.dstack([x_grid, y_grid])) 54 | 55 | 56 | figure = plt.figure(figsize=(18, 6)) 57 | images: Dict[Any, AxesImage] = {} 58 | PLOTTING_DOMAIN = get_plotting_domain(LOWER_LIMIT, UPPER_LIMIT, PLOTTING_RESOLUTION) 59 | 60 | 61 | def plot_data(data, subplot, title=""): 62 | data = data.reshape(PLOTTING_RESOLUTION, PLOTTING_RESOLUTION) 63 | 64 | if subplot in images: 65 | image = images[subplot] 66 | image.set_data(data) 67 | image.set_clim(vmin=data.min(), vmax=data.max()) 68 | else: 69 | axis = figure.add_subplot(subplot) 70 | image = axis.imshow(data, cmap=plt.get_cmap(COLOUR_MAP), vmin=data.min(), vmax=data.max(), 71 | extent=[LOWER_LIMIT, UPPER_LIMIT, LOWER_LIMIT, UPPER_LIMIT], 72 | interpolation='nearest', origin='lower') 73 | images[subplot] = image 74 | 75 | axis.set_title(title) 76 | 77 | plt.pause(0.01) 78 | 79 | 80 | def plot_true_function(): 81 | z = true_integrand(PLOTTING_DOMAIN) 82 | plot_data(z, 133, "True Integrand") 83 | 84 | 85 | def plot_integrand_posterior(integrand_model: IntegrandModel): 86 | z = integrand_model.posterior_mean_and_variance(PLOTTING_DOMAIN)[0] 87 | plot_data(z, 132, "Posterior Mean") 88 | 89 | 90 | def plotting_callback(func): 91 | z = np.exp(func(PLOTTING_DOMAIN)[0]) 92 | plot_data(z, 131, "Acquisition Function") 93 | 94 | 95 | plotting.add_callback("Soft penalised log acquisition function", plotting_callback) 96 | plot_true_function() 97 | 98 | 99 | # Run algorithm. 100 | 101 | BATCHES = 25 102 | BATCH_SIZE = 4 103 | BATCH_METHOD = LOCAL_PENALISATION 104 | 105 | for i in range(BATCHES): 106 | plot_integrand_posterior(model) 107 | batch = select_batch(model, BATCH_SIZE, BATCH_METHOD) 108 | 109 | X = np.array(batch) 110 | Y = true_function(X) 111 | model.update(X, Y) 112 | 113 | gpy_gp.optimize() 114 | 115 | print("Integral: {}".format(model.integral_mean())) 116 | 117 | plot_integrand_posterior(model) 118 | plt.show() 119 | -------------------------------------------------------------------------------- /bayesquad/_optimisation.py: -------------------------------------------------------------------------------- 1 | """Utility functions wrapping a scipy optimizer.""" 2 | 3 | from typing import Tuple, Callable 4 | 5 | import numpy as np 6 | import scipy.optimize 7 | from numpy import ndarray 8 | 9 | DEFAULT_GTOL = 1e-2 10 | 11 | DEFAULT_MINIMIZER_KWARGS = {'method': 'BFGS', 12 | 'jac': True, 13 | 'options': {'gtol': DEFAULT_GTOL}} 14 | 15 | 16 | def multi_start_maximise(objective_function: Callable, 17 | initial_points: ndarray, **kwargs) -> Tuple[ndarray, float]: 18 | """Run multi-start maximisation of the given objective function. 19 | 20 | Warnings 21 | -------- 22 | This is a hack to take advantage of fast vectorised computation and avoid expensive python loops. There may be some 23 | issues with this method! 24 | 25 | The objective function provided here must be a vectorised function. We take advantage of the fast computation of 26 | vectorised functions to view a multi-start optimisation as a single pass of a higher-dimensional optimisation, 27 | rather than several passes of a low-dimensional optimisation (which would require an expensive python loop). We 28 | simply concatenate all the points where the function is to be evaluated into a single high-dimensional vector, give 29 | the function value as the sum of all the individual function values, and give the Jacobian as the concatenation of 30 | all the individual Jacobians. In this way we can essentially perform many optimisations in parallel. Note that 31 | there is an issue here with the stopping condition: we can only consider all optimisations together, so even if most 32 | have come very close to an optimum, the process will continue as long as one is far away. However, this does seem to 33 | perform well in practice. 34 | 35 | Parameters 36 | ---------- 37 | objective_function 38 | Function to be maximised. Must return both the function value and the Jacobian. Must also accept a 2D array of 39 | points, returning a 1D array and a 2D array for the function values and Jacobians respectively. 40 | initial_points 41 | Points at which to begin the optimisation, as a 2D array of shape (num_points, num_dimensions). 42 | **kwargs 43 | Keyword arguments will be included in the 'options' dict passed to the underlying scipy optimiser. 44 | 45 | Returns 46 | ------- 47 | ndarray 48 | The location of the found maximum. 49 | float 50 | The value of the objective function at the found maximum. 51 | """ 52 | minimizer_kwargs = DEFAULT_MINIMIZER_KWARGS.copy() 53 | minimizer_kwargs['options'] = {**minimizer_kwargs['options'], **kwargs} # This merges the two dicts. 54 | 55 | num_points, num_dims = np.shape(initial_points) 56 | 57 | def function_to_minimise(x, *inner_args, **inner_kwargs): 58 | x = np.reshape(x, (num_points, num_dims)) 59 | 60 | value, jacobian = objective_function(x, *inner_args, **inner_kwargs) 61 | combined_value, combined_jacobian = -value.sum(), -jacobian.ravel() 62 | 63 | if not np.isfinite(combined_value) or not np.all(np.isfinite(combined_jacobian)): 64 | raise FloatingPointError("Objective function for multi-start optimisation returned NaN or infinity.") 65 | 66 | return combined_value, combined_jacobian 67 | 68 | maximum = scipy.optimize.minimize(function_to_minimise, initial_points, **minimizer_kwargs) 69 | maxima = maximum.x.reshape(num_points, num_dims) 70 | 71 | values, _ = objective_function(maxima) 72 | max_index = np.argmax(values) 73 | 74 | optimal_x = maxima[max_index, :] 75 | optimal_y = values[max_index] 76 | 77 | return optimal_x, optimal_y 78 | 79 | 80 | def _indices_where(array: ndarray) -> Tuple: 81 | """Returns the indices where the elements of `array` are True.""" 82 | return np.nonzero(array) 83 | -------------------------------------------------------------------------------- /bayesquad/_cache.py: -------------------------------------------------------------------------------- 1 | """Basic caching functionality.""" 2 | from functools import wraps 3 | 4 | _cache = {} 5 | 6 | 7 | def last_value_cache(func): 8 | """Cache the result of most recent invocation of this method. 9 | 10 | This decorator may be applied to a method which takes one argument (excluding `self`). If the method is called 11 | consecutively with the same argument, the method will immediately return the previous result rather than computing 12 | the result again. Note that by "the same argument" we mean the same object - two different but equal objects will 13 | not be regarded as the same by this decorator. 14 | 15 | The cache is not shared between different instances of the same class. 16 | 17 | Warnings 18 | -------- 19 | Instances of a class with at least one method using this decorator **must** have :func:`~clear_last_value_caches` 20 | called on them when they are destroyed (e.g. in the class's `__del__` method). If this is not done, a new instance 21 | with the same id may incorrectly share the destroyed instance's cache. 22 | 23 | Examples 24 | -------- 25 | >>> import numpy as np 26 | 27 | >>> class Foo: 28 | ... def __init__(self): 29 | ... self._count_invocations = 0 30 | ... 31 | ... def __del__(self): 32 | ... clear_last_value_caches(self) 33 | ... 34 | ... @last_value_cache 35 | ... def do_something_expensive(self, array): 36 | ... # Do something expensive here. 37 | ... 38 | ... self._count_invocations += 1 39 | ... 40 | ... def count_expensive_operations(self): 41 | ... return self._count_invocations 42 | 43 | >>> foo = Foo() 44 | >>> a = np.array(1) 45 | >>> b = np.array(1) 46 | 47 | `a` and `b` are distinct: 48 | 49 | >>> a is b 50 | False 51 | 52 | Passing `a` twice in succession will hit the cache: 53 | 54 | >>> foo.do_something_expensive(a) 55 | >>> foo.count_expensive_operations() 56 | 1 57 | 58 | >>> foo.do_something_expensive(a) 59 | >>> foo.count_expensive_operations() 60 | 1 61 | 62 | We get a cache miss when passing a different object: 63 | 64 | >>> foo.do_something_expensive(b) 65 | >>> foo.count_expensive_operations() 66 | 2 67 | 68 | Since only a single function call is cached, we get a cache miss when passing the original object again: 69 | 70 | >>> foo.do_something_expensive(a) 71 | >>> foo.count_expensive_operations() 72 | 3 73 | 74 | The cache is not shared between instances: 75 | 76 | >>> bar = Foo() 77 | >>> bar.do_something_expensive(a) 78 | >>> bar.count_expensive_operations() 79 | 1 80 | 81 | The following is a hack to stop PyCharm wrongly warning about unresolved references in this doctest. 82 | See https://youtrack.jetbrains.com/issue/PY-31517 83 | 84 | >>> self = Foo() 85 | """ 86 | @wraps(func) 87 | def transformed_function(self, x): 88 | cache_key = "{}_{}".format(id(self), id(func)) 89 | 90 | if cache_key not in _cache or x is not _cache[cache_key][0]: 91 | ret = func(self, x) 92 | 93 | _cache[cache_key] = [x, ret] 94 | 95 | return ret 96 | else: 97 | return _cache[cache_key][1] 98 | 99 | return transformed_function 100 | 101 | 102 | def clear_last_value_caches(obj): 103 | """Clear the :func:`~last_value_cache` of every method on the given object. 104 | 105 | See Also 106 | -------- 107 | :func:`~last_value_cache`""" 108 | obj_id = str(id(obj)) 109 | 110 | keys_to_delete = [] 111 | 112 | for key in _cache: 113 | if key.startswith(obj_id): 114 | keys_to_delete.append(key) 115 | 116 | for key in keys_to_delete: 117 | del _cache[key] 118 | -------------------------------------------------------------------------------- /docs/build/html/_modules/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 |50 | Please activate JavaScript to enable the search 51 | functionality. 52 |
53 |55 | From here you can search these documents. Enter your search 56 | words into the box below and click "search". Note that the search 57 | function will automatically search for all of the words. Pages 58 | containing fewer words won't appear in the result list. 59 |
60 | 65 | 66 |Functions to allow plotting code to be decoupled from the rest of the code.
41 | 45 | 46 | 50 | 51 || 51 | b | ||
| 55 | |
56 | bayesquad | 57 | |
| 60 | |
61 | bayesquad.acquisition_functions | 62 | |
| 65 | |
66 | bayesquad.batch_selection | 67 | |
| 70 | |
71 | bayesquad.gps | 72 | |
| 75 | |
76 | bayesquad.plotting | 77 | |
| 80 | |
81 | bayesquad.priors | 82 | |
| 85 | |
86 | bayesquad.quadrature | 87 | |
Methods for selecting a batch of points to evaluate for Bayesian quadrature.
41 |bayesquad.batch_selection.select_batch(integrand_model: bayesquad.quadrature.IntegrandModel, batch_size: int, batch_method: str = 'Local Penalisation') → List[numpy.ndarray][source]¶Select a batch of points at which to evaluate the integrand.
45 || Parameters: |
|
64 |
|---|---|
| Returns: | A list of arrays. Each array is a point of the new batch. 66 | |
67 |
| Return type: | list[ndarray] 69 | |
70 |
40 | """Functions to allow plotting code to be decoupled from the rest of the code."""
41 |
42 | from functools import wraps
43 | from types import MappingProxyType
44 | from typing import Callable
45 |
46 |
47 | class _Registry:
48 | def __init__(self):
49 | self._callback_registry = {}
50 |
51 | def trigger_callbacks(self, identifier: str, func: Callable):
52 | if identifier not in self._callback_registry:
53 | return
54 |
55 | for callback in self._callback_registry[identifier]:
56 | callback(func)
57 |
58 | def add_callback(self, identifier: str, callback: Callable):
59 | if identifier not in self._callback_registry:
60 | self._callback_registry[identifier] = []
61 |
62 | self._callback_registry[identifier].append(callback)
63 |
64 |
65 | _function_registry = _Registry()
66 |
67 | # Using a mutable object (e.g. an empty dict) as a default parameter can lead to undesirable behaviour, so we use this
68 | # read-only proxy.
69 | #
70 | # See:
71 | # The problem: https://stackoverflow.com/q/1132941
72 | # A solution: https://stackoverflow.com/a/30638022
73 | _EMPTY = MappingProxyType({})
74 |
75 |
76 | [docs]def plottable(identifier: str, *, default_plotting_parameters=_EMPTY):
77 | def decorator(func: Callable):
78 | @wraps(func)
79 | def func_for_plotting(*args, **kwargs):
80 | # Merge default_plotting_parameters into kwargs
81 | kwargs = {**default_plotting_parameters, **kwargs}
82 | return func(*args, **kwargs)
83 |
84 | _function_registry.trigger_callbacks(identifier, func_for_plotting)
85 |
86 | return func
87 | return decorator
88 |
89 |
90 | [docs]def add_callback(identifier: str, callback: Callable):
91 | _function_registry.add_callback(identifier, callback)
92 | ' + _('Hide Search Matches') + '
') 233 | .appendTo($('#searchbox')); 234 | } 235 | }, 236 | 237 | /** 238 | * init the domain index toggle buttons 239 | */ 240 | initIndexTable : function() { 241 | var togglers = $('img.toggler').click(function() { 242 | var src = $(this).attr('src'); 243 | var idnum = $(this).attr('id').substr(7); 244 | $('tr.cg-' + idnum).toggle(); 245 | if (src.substr(-9) === 'minus.png') 246 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 247 | else 248 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 249 | }).css('display', ''); 250 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { 251 | togglers.click(); 252 | } 253 | }, 254 | 255 | /** 256 | * helper function to hide the search marks again 257 | */ 258 | hideSearchWords : function() { 259 | $('#searchbox .highlight-link').fadeOut(300); 260 | $('span.highlighted').removeClass('highlighted'); 261 | }, 262 | 263 | /** 264 | * make the url absolute 265 | */ 266 | makeURL : function(relativeURL) { 267 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 268 | }, 269 | 270 | /** 271 | * get the current relative url 272 | */ 273 | getCurrentURL : function() { 274 | var path = document.location.pathname; 275 | var parts = path.split(/\//); 276 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 277 | if (this === '..') 278 | parts.pop(); 279 | }); 280 | var url = parts.join('/'); 281 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 282 | }, 283 | 284 | initOnKeyListeners: function() { 285 | $(document).keyup(function(event) { 286 | var activeElementType = document.activeElement.tagName; 287 | // don't navigate when in search box or textarea 288 | if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { 289 | switch (event.keyCode) { 290 | case 37: // left 291 | var prevHref = $('link[rel="prev"]').prop('href'); 292 | if (prevHref) { 293 | window.location.href = prevHref; 294 | return false; 295 | } 296 | case 39: // right 297 | var nextHref = $('link[rel="next"]').prop('href'); 298 | if (nextHref) { 299 | window.location.href = nextHref; 300 | return false; 301 | } 302 | } 303 | } 304 | }); 305 | } 306 | }; 307 | 308 | // quick alias for translations 309 | _ = Documentation.gettext; 310 | 311 | $(document).ready(function() { 312 | Documentation.init(); 313 | }); -------------------------------------------------------------------------------- /docs/build/html/_static/underscore.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.3.1 2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the MIT license. 4 | // Portions of Underscore are inspired or borrowed from Prototype, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore 8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== 9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, 10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= 11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e
40 | """Acquisition functions and related functions."""
41 | import numpy as np
42 |
43 | from .plotting import plottable
44 | from .quadrature import IntegrandModel
45 |
46 |
47 | [docs]def model_variance(integrand_model: IntegrandModel):
48 |
49 | @plottable("Model variance", default_plotting_parameters={'calculate_jacobian': False})
50 | def f(x, *, calculate_jacobian=True):
51 | """Evaluate the variance, and the Jacobian of the variance, for the given `IntegrandModel` at a point, or a set
52 | of points.
53 |
54 | Given an array of shape (num_points, num_dimensions), returns an array of shape (num_points) containing the
55 | function values and an array of shape (num_points, num_dimensions) containing the function Jacobians.
56 |
57 | Given an array of shape (num_dimensions), returns a 0D array containing the function value and an array of shape
58 | (num_dimensions) containing the function Jacobian.
59 |
60 | If the Jacobian is not required (e.g. for plotting), the relevant calculations can be disabled by setting
61 | `calculate_jacobian=False`.
62 | """
63 | _, variance = integrand_model.posterior_mean_and_variance(x)
64 |
65 | if calculate_jacobian:
66 | variance_jacobian = integrand_model.posterior_variance_jacobian(x)
67 | else:
68 | variance_jacobian = None
69 |
70 | return variance, variance_jacobian
71 |
72 | return f
73 |
74 |
75 | [docs]def model_variance_norm_of_gradient_squared(integrand_model: IntegrandModel):
76 |
77 | @plottable("Gradient squared", default_plotting_parameters={'calculate_jacobian': False})
78 | def f(x, *, calculate_jacobian=True):
79 | """Evaluate the squared norm of the gradient of the variance, and the Jacobian of this quantity, for the given
80 | `IntegrandModel` at a point, or a set of points.
81 |
82 | Given an array of shape (num_points, num_dimensions), returns an array of shape (num_points) containing the
83 | function values and an array of shape (num_points, num_dimensions) containing the function Jacobians.
84 |
85 | Given an array of shape (num_dimensions), returns a 0D array containing the function value and an array of shape
86 | (num_dimensions) containing the function Jacobian.
87 |
88 | If the Jacobian is not required (e.g. for plotting), the relevant calculations can be disabled by setting
89 | `calculate_jacobian=False`.
90 | """
91 | variance_jacobian = integrand_model.posterior_variance_jacobian(x)
92 |
93 | # Inner product of the Jacobian with itself, for each point.
94 | gradient_squared = np.einsum('...i,...i->...', variance_jacobian, variance_jacobian, optimize=True)
95 |
96 | if calculate_jacobian:
97 | variance_hessian = integrand_model.posterior_variance_hessian(x)
98 |
99 | # Matrix product of Hessian and Jacobian, for each point.
100 | gradient_squared_jacobian = 2 * np.einsum('...ij,...j->...i',
101 | variance_hessian,
102 | variance_jacobian,
103 | optimize=True)
104 | else:
105 | gradient_squared_jacobian = None
106 |
107 | return gradient_squared, gradient_squared_jacobian
108 |
109 | return f
110 | Classes representing probability distributions, intended to be integrated against a likelihood.
41 |bayesquad.priors.Gaussian(mean: numpy.ndarray, covariance: numpy.ndarray)[source]¶Bases: bayesquad.priors.Prior
A multivariate Gaussian prior.
46 || Parameters: |
|
55 |
|---|
mean¶ndarray – A 1D array of shape (num_dimensions).
62 |covariance¶ndarray – A 2D array of shape (num_dimensions, num_dimensions).
68 |precision¶ndarray – The inverse of the covariance matrix.
74 |gradient(x: numpy.ndarray) → Tuple[numpy.ndarray, numpy.ndarray][source]¶See gradient()
bayesquad.priors.Prior[source]¶Bases: abc.ABC
A prior, providing methods for sampling, and for pointwise evaluation of the pdf and its derivatives.
101 |gradient(x: numpy.ndarray) → Tuple[numpy.ndarray, numpy.ndarray][source]¶Compute the Jacobian and Hessian of the prior’s pdf at the given set of points.
105 || Parameters: | x – A 2D array of the points at which to evaluate the derivatives, with shape (num_points, num_dimensions). | 110 |
|---|---|
| Returns: |
|
117 |
logpdf(x: numpy.ndarray) → numpy.ndarray[source]¶Evaluate the prior’s log pdf at the given set of points.
126 || Parameters: | x – An array of shape (num_points, num_dimensions). | 131 |
|---|---|
| Returns: | A 1D array of shape (num_points). | 133 |
| Return type: | ndarray | 135 |
sample(num_points: int = 1) → numpy.ndarray[source]¶Sample num_points points independently from the prior.
144 || Returns: | num_points samples from the prior, as a 2D array of shape (num_points, num_dimensions). | 149 |
|---|---|
| Return type: | ndarray | 151 |