diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e6eb9902..5191298e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,11 +20,10 @@ jobs: python-version: 3.9 cache: 'pip' # optional, adds caching for faster builds - - name: Install dependencies + - name: Install UncertainSCI run: | python -m pip install --upgrade pip - pip install flake8 - pip install -r requirements.txt + pip install --editable .["dev"] - name: Lint with flake8 run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 84ab488a..f343d13c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,15 +27,10 @@ jobs: - name: Display Python version run: python -c "import sys; print(sys.version)" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pytest pytest-cov - pip install -r requirements.txt - - name: Install UncertainSCI run: | - pip install --editable ./ + python -m pip install --upgrade pip + pip install --editable .["dev"] - name: Run tests and compute coverage run: | diff --git a/.gitignore b/.gitignore index 131f7a38..1de96dd3 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/**/generated/ # PyBuilder target/ diff --git a/.readthedocs.yaml b/.readthedocs.yaml index d2c2ad20..f7d9006d 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,6 +10,8 @@ build: os: ubuntu-22.04 tools: python: "3.10" + apt_packages: + - pandoc # Build documentation in the docs/ directory with Sphinx sphinx: @@ -23,6 +25,7 @@ formats: all # Optionally declare the Python requirements required to build your docs python: install: - - requirements: requirements.txt - - requirements: docs/requirements.txt - - path: . + - method: pip + path: . + extra_requirements: + - docs diff --git a/INSTALL.md b/INSTALL.md deleted file mode 100644 index 58eae2d0..00000000 --- a/INSTALL.md +++ /dev/null @@ -1,115 +0,0 @@ -# UncertainSCI Python Environment -People that install UncertainSCI can be sensibly categorized as follows: -- **Users**: people who want to use UncertainSCI but do not need to meddle with its internals -- **Developers**: people who want to meddle with UncertainSCI's internals - -These instructions explain how to install UncertainSCI for both of these use cases. - -**Python Versions:** UncertainSCI officially supports Python versions 3.9 to 3.11. Newer Python may incidentally work, but at this time its support has not been tested. - -## Dependency Overview -This is an overview of the dependencies for UncertainSCI for various use cases. - -### Base Dependencies -At a minimum, UncertainSCI requires all packages in the project's requirements.txt. - -### Doc Dependencies -To build the docs, UncertainSCI requires -- pandoc -- sphinx -- sphinxcontrib-bibtex -- sphinx-markdown-tables -- nbsphinx -- recommonmark - -### Testing & Linting Dependencies -To test and lint the codebase, UncertainSCI requires -- flake8 -- pytest -- pytest-cov - -### Nice-to-haves -- ipython -- jupyter - -## Environment for Production -It is assumed your production environment does not need docs (e.g., pandoc), testing nor linting (e.g., flake8 nor pytest), nor interactive interfaces (e.g., jupyter). The packages and tools for these features are therefore omitted from these installation instructions. - -### With conda -1. Change to the repository root. -2. Set the `ENVNAME` and `PYVER` variables. On *NIX, - ```shell - export ENVNAME= - export PYVER= - ``` - On Windows, - ```shell - $ENVNAME="" - $PYVER="" - ``` -3. Create and activate the conda environment, then install UncertainSCI, - ```shell - conda create -n $ENVNAME python=$PYVER pandoc - conda activate $ENVNAME - python -m pip install . - ``` - -### Without conda -1. You have already installed the version of Python with which you wish to run UncertainSCI. -2. Change to the repository root. -3. Create and activate a virtual environment inside of which to run UncertainSCI, - ```shell - python -m venv .venv - ``` - Activate the virtual environment according to your system. -4. Install UncertainSCI, - ```shell - python -m pip install . - ``` - -## Environment for Development -It is assumed to develop UncertainSCI that you want to be able to build the docs, test and flake the codebase, and have reasonably modern interactive tools. - -### With conda -1. Change to the repository root. -2. Set the `ENVNAME` and `PYVER` variables. On *NIX, - ```shell - export ENVNAME= - export PYVER= - ``` - On Windows, - ```shell - $ENVNAME="" - $PYVER="" - ``` -3. Create and activate the conda environment, then install UncertainSCI, - ```shell - conda create -n $ENVNAME python=$PYVER pandoc - conda activate $ENVNAME - python -m pip install . - ``` -4. Install development helpers, - ```shell - python -m pip install pandoc sphinx sphinxcontrib-bibtex sphinx-markdown-tables nbsphinx recommonmark # docs - python -m pip install flake8 pytest pytest-cov # linting and testing - python -m pip install ipython jupyter # nice-to-haves - ``` - -### Without conda -1. You have already installed the version of Python with which you wish to run UncertainSCI. -2. Change to the repository root. -3. Create and activate a virtual environment inside of which to run UncertainSCI, - ```shell - python -m venv .venv - ``` - Activate the virtual environment according to your system. -4. Install UncertainSCI, - ```shell - python -m pip install . - ``` -5. Install development helpers, - ```shell - python -m pip install pandoc sphinx sphinxcontrib-bibtex sphinx-markdown-tables nbsphinx recommonmark # docs - python -m pip install flake8 pytest pytest-cov # linting and testing - python -m pip install ipython jupyter # nice-to-haves - ``` diff --git a/UncertainSCI/__init__.py b/UncertainSCI/__init__.py index 8b137891..c5aa9ffc 100644 --- a/UncertainSCI/__init__.py +++ b/UncertainSCI/__init__.py @@ -1 +1,3 @@ - +""" +A modern Python-based mathematical uncertainty toolkit. +""" diff --git a/UncertainSCI/distributions.py b/UncertainSCI/distributions.py index 66633374..0cc024f1 100644 --- a/UncertainSCI/distributions.py +++ b/UncertainSCI/distributions.py @@ -1,3 +1,19 @@ +""" +Classes and tools to define probability distributions. + +For PCE (:ref:`pce`), these distributions are evolved through a forward model defining +the stochastic variation of model parameters. + +Tensorizations within a distribution are possible across these families by +instantiating the distribution appropriately. Tensorizations across distributions +is also possible but requires individual instantiation of each distribution, followed +by a constructor call to the :class:`TensorialDistribution` class. + +For example, a three-dimensional random variable :math:`Y = (Y_1, Y_2, Y_3)` can have +independent components, with the distribution of :math:`Y_1` normal, :math:`Y_2` beta, +and :math:`Y_3` exponential. +""" + import numpy as np import scipy as sp from scipy import sparse as sprs @@ -630,23 +646,19 @@ class BetaDistribution(ProbabilityDistribution): \\mu, \\sigma`. Parameters: - alpha (float or iterable of floats, optional): Shape parameter - associated to right-hand boundary. Defaults to 1. - beta (float or iterable of floats, optional): Shape parameter - associated to left-hand boundary. Defaults to 1. - mean (float or iterable of floats, optional): Mean of the distribution. - Defaults to None. - stdev (float or iterable of floats, optional): Standard deviation of - the distribution. Defaults to None. - dim (int, optional): Dimension of the distribution. Defaults to None. - domain (numpy.ndarray or similar, of size 2 x `dim`, optional): Compact - hypercube that is the support of the distribution. Defaults to None + alpha: Shape parameter associated to right-hand boundary. Defaults to 1. + beta: Shape parameter associated to left-hand boundary. Defaults to 1. + mean: Mean of the distribution. Defaults to None. + stdev: Standard deviation of the distribution. Defaults to None. + dim: Dimension of the distribution. Defaults to None. + domain: Compact hypercube of size 2 x ``dim`` that is the support of + the distribution. Defaults to None. Attributes: - dim (int): Dimension of the distribution. - alpha (float or np.ndarray): Shape parameter(s) alpha. - beta (float or np.ndarray): Shape parameter(s) beta. - polys (:class:`JacobiPolynomials` or list thereof): + dim: Dimension of the distribution. + alpha: Shape parameter(s) alpha. + beta: Shape parameter(s) beta. + polys: Jacobi polynomial family or list thereof. """ def __init__(self, alpha=None, beta=None, mean=None, stdev=None, dim=None, domain=None, bounds=None): @@ -992,17 +1004,15 @@ class UniformDistribution(BetaDistribution): \\mu, \\sigma`. Parameters: - mean (float or iterable of floats, optional): Mean of the distribution. - Defaults to None. - stdev (float or iterable of floats, optional): Standard deviation of - the distribution. Defaults to None. - dim (int, optional): Dimension of the distribution. Defaults to None. - domain (numpy.ndarray or similar, of size 2 x `dim`, optional): Compact - hypercube that is the support of the distribution. Defaults to None + mean: Mean of the distribution. Defaults to None. + stdev: Standard deviation of the distribution. Defaults to None. + dim: Dimension of the distribution. Defaults to None. + domain: Compact hypercube of size 2 x ``dim`` that is the support of + the distribution. Defaults to None. Attributes: - dim (int): Dimension of the distribution. - polys (:class:`JacobiPolynomials` or list thereof): + dim: Dimension of the distribution. + polys: Jacobi polynomial family or list thereof. """ def __init__(self, mean=None, stdev=None, dim=None, domain=None, bounds=None): diff --git a/UncertainSCI/families.py b/UncertainSCI/families.py index 12c04b18..ea5eb23c 100644 --- a/UncertainSCI/families.py +++ b/UncertainSCI/families.py @@ -1,8 +1,6 @@ """ -Contains routines that specialize opoly1d things for classical orthogonal polynomial families -- jacobi polys -- hermite poly -- laguerre polys +Routines that specialize :mod:`UncertainSCI.opoly1d` for classical families of +orthogonal polynomials. """ import numpy as np diff --git a/UncertainSCI/indexing.py b/UncertainSCI/indexing.py index 9435db87..cfef4524 100644 --- a/UncertainSCI/indexing.py +++ b/UncertainSCI/indexing.py @@ -1,3 +1,7 @@ +""" +Module containing indexing tools and families. +""" + from itertools import combinations import numpy as np @@ -463,8 +467,3 @@ def get_indices(self): return super().get_indices() else: return hyperbolic_cross_indices(self.dim, self.order) - - -if __name__ == "__main__": - - pass diff --git a/UncertainSCI/opoly1d.py b/UncertainSCI/opoly1d.py index 66651769..98ef4d3d 100644 --- a/UncertainSCI/opoly1d.py +++ b/UncertainSCI/opoly1d.py @@ -1,9 +1,15 @@ """ -Contains classes/methods for general univariate orthogonal polynomial families. -- evaluation -- gauss quadrature -- ratio evaluations -- linear/quadratic measure modifications +Classes and methods for general univariate orthogonal polynomials. + +In particular, this module enables: +- Evaluation +- Gaussian quadrature +- Rational evaluation +- Linear/quadratic measure modifications + +See Also: + :mod:`UncertainSCI.families` for tooling for specific families of orthogonal + polynomials. """ import numpy as np @@ -366,7 +372,7 @@ def derivative_expansion_driver(ab, s, N, K): N: Computes coefficients for :math:`n \\leq N` K: Computes coefficients for :math:`k \\leq K`. Returns: - C: (N+1) x (K+1) numpy array containing coefficients. + Coefficient array with shape (N+1, K+1). """ assert ab.shape[1] == 2 @@ -412,7 +418,6 @@ class OrthogonalPolynomialBasis1D: def __init__(self, recurrence=[], probability_measure=True): self.probability_measure = probability_measure self.ab = np.zeros([0, 2]) - pass def recurrence(self, N): """ @@ -435,15 +440,11 @@ def recurrence(self, N): recurrence_driver is performed to compute the desired coefficients, and the output is stored in the instance variable. - Parameters - ---------- - N: positive integer - Maximum polynomial degree for desired recurrence coefficients + Args: + N: Maximum polynomial degree for desired recurrence coefficients. - Returns - ------- - ab: ndarray - (N+1) x 2 array of recurrence coefficients. + Returns: + The recurrence coefficient array with shape (N+1, 2). """ if N+1 > self.ab.shape[0]: @@ -507,15 +508,12 @@ def apply_jacobi_matrix(self, v): appropriate size for the polynomial family. Applies the Jacobi matrix across the first dimension of v. - Parameters - ---------- - v: ndarray - Input vector or array + Args: + v: Input vector or array. - Returns - ------- - Jv: ndarray - J*v, where J is the Jacobi matrix of size v.shape[0]. + Returns: + The result of applying ``J*v``, where J is the Jacobi matrix of + size ``v.shape[0]``. """ N = v.shape[0] @@ -653,18 +651,12 @@ def tuple_product_generator(self, IC, ab=None): C[n,j] = < p_n p_j, p_alpha >, j, n \\in range(N) - Parameters - ---------- - IC: vector (1d array) - Values of input inner products - - ab: ndarray, optional - Recurrence coefficients + Args: + IC: Values of input inner products. + ab: Recurrence coefficients. - Returns - ------- - C: ndarray - Output coefficient expansion vector for beta + Returns: + The output coefficient expansion vector for beta. """ N = IC.size @@ -693,18 +685,12 @@ def tuple_product(self, N, alpha): The notation <., .> denotes the inner product under which the polynomial family is orthogonal. - Parameters - ---------- - N: integer - Size of matrix to return - - alpha: ndarray (1d) - Multi-index defining a polynomial product + Args: + N: Size of matrix to return. + alpha: Multi-index defining a polynomial product. - Returns - ------- - C: ndarray - Output N x N matrix containing integral values + Returns: + The matrix with shape (N, N) containing integral values. """ M = alpha.size @@ -737,18 +723,12 @@ def derivative_expansion(self, N, d): for j,n = 0, ..., N-1. - Parameters - ---------- - N: integer - Size of matrix to return - - d: integer - Derivative order + Args: + N: Size of matrix to return. + d: Derivative order. - Returns - ------- - C: ndarray - Output N x N matrix containing expansion coefficients + Returns: + The matrix with shape (N, N) containing expansion coefficients. """ assert N >= 0 @@ -904,7 +884,7 @@ def derivative_expansion(self, s, N, K=None): K: Computes coefficients for :math:`k \\leq K` (optional). If not given, is set to N. Returns: - C: (N+1) x (K+1) numpy array containing coefficients. + Coefficient array with shape (N+1, K+1). """ diff --git a/UncertainSCI/pce.py b/UncertainSCI/pce.py index 1fbb6bd2..ba6459d4 100644 --- a/UncertainSCI/pce.py +++ b/UncertainSCI/pce.py @@ -29,12 +29,11 @@ class PolynomialChaosExpansion(): Provides interface to construct and manipulate polynomial chaos expansions. Attributes: - ----------- - coefficients: A numpy array of polynomial chaos expansion coefficients. + coefficients: NumPy array of polynomial chaos expansion coefficients. indices: A MultiIndexSet instance specifying the polynomial - approximation space. + approximation space. distribution: A ProbabilityDistribution instance indicating the - distribution of the random variable. + distribution of the random variable. samples: The experimental or sample design in stochastic space. """ @@ -171,10 +170,10 @@ def map_to_standard_space(self, q): """Maps parameter values from model space to standard space. Parameters: - q (array-like): Samples in model space. + q: Samples in model space. Returns: - p (numpy.ndarray): Samples in standard space + Samples in standard space. """ q = np.asarray(q) @@ -186,10 +185,10 @@ def map_to_model_space(self, p): """Maps parameter values from standard space to model space. Parameters: - p (array-like): Samples in standard space. + p: Samples in standard space. Returns: - q (numpy.ndarray): Samples in model space + Samples in model space. """ p = np.asarray(p) @@ -200,8 +199,7 @@ def generate_samples(self, **kwargs): """Generates sample/experimental design for use in PCE construction. Parameters: - new_samples (array-like, optional): Specifies samples that must be - part of the ensemble. + new_samples: Optional samples that must be part of the ensemble. """ self.check_distribution() @@ -363,12 +361,14 @@ def augment_samples_idist(self, K, weights=None, fast_sampler=True): """ Augments random samples from induced distribution. Typically done via an adaptive refinement procedure. As such some inputs can be given to - customize how the samples are drawn in the context of adaptivity: + customize how the samples are drawn in the context of adaptivity. - K: how many samples to add (required) - weights: a discrete probability distribution on - self.index_set.get_indices() that describes how the induced - distrubtion is sampled. Default is uniform. + Args: + K: Number of samples to add. + weights: Discrete probability distribution on + ``self.index_set.get_indices()`` that describes how the induced + distribution is sampled. Default is uniform. + fast_sampler: Whether to use the fast induced-distribution sampler. """ return self.distribution.polys.idist_mixture_sampling(K, @@ -535,7 +535,7 @@ def build(self, model=None, model_output=None, **options): function should be a vector of size self.dim, and the output should be a 1D numpy array. If model_output is None, this is required. If model_output is given, this is ignored. - model_output: A numpy.ndarray corresponding to the output of the + model_output: NumPy array corresponding to the output of the model at the sample locations specified by self.samples. This is required if the input model is None. Returns: @@ -587,8 +587,8 @@ def mean(self): """Returns PCE mean. Returns: - numpy.ndarray: A vector containing the PCE mean, of size equal to the size - of the vector of the model output. + NumPy array containing the PCE mean, of size equal to the size of + the vector of the model output. """ self.assert_pce_built() @@ -599,8 +599,8 @@ def stdev(self): Returns PCE standard deviation Returns: - numpy.ndarray: A vector containing the PCE standard deviation, of size - equal to the size of the vector of the model output. + NumPy array containing the PCE standard deviation, of size equal to + the size of the vector of the model output. """ self.assert_pce_built() @@ -617,10 +617,10 @@ def pce_eval(self, p, components=None): ignored. If given as None (default), then all components are computed. Returns: - numpy.ndarray: An array containing evaluations (predictions) from the PCE - emulator. If the input components is None, this array is of size ( - self.p.shape[0] x self.coefficients.shape[1] ). Otherwise, the - second dimension is of size components.size. + Array containing evaluations (predictions) from the PCE emulator. + If the input components is None, this array is of size + ``self.p.shape[0] x self.coefficients.shape[1]``. Otherwise, the + second dimension is of size ``components.size``. """ self.assert_pce_built() @@ -793,8 +793,8 @@ def global_derivative_sensitivity(self, dim_list): dimensional indices in 0-based indexing. All entries must be between 0 and self.distribution.dim. Returns: - S: DxK array, where each row corresponds to the sensitivity index - :math:`S_i` across all K features of the PCE model. + DxK array, where each row corresponds to the sensitivity index + :math:`S_i` across all K features of the PCE model. """ indices = self.index_set.get_indices() diff --git a/UncertainSCI/transformations.py b/UncertainSCI/transformations.py index 20219daf..f478ba43 100644 --- a/UncertainSCI/transformations.py +++ b/UncertainSCI/transformations.py @@ -101,14 +101,16 @@ def jacobian_determinant(self): return np.abs(np.linalg.det(self.A)) def compose(self, other): - """ Returns composition of two AffineTransform's + """ + Returns composition of two AffineTransform's Args: other: An AffineTransform instance where the domain and range are - the same dimension as for self. + the same dimension as for self. + Returns: composition: AffineTransform instance, corresponding to the map - self :math:`\\circ` other + self :math:`\\circ` other """ A1 = np.asarray(self.A.todense()) diff --git a/conftest.py b/conftest.py deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/_templates/autosummary/class.rst b/docs/_templates/autosummary/class.rst new file mode 100644 index 00000000..73e7ee24 --- /dev/null +++ b/docs/_templates/autosummary/class.rst @@ -0,0 +1,4 @@ +{{ name | escape | underline }} + +.. autoclass:: {{ fullname }} + :members: diff --git a/docs/_templates/autosummary/function.rst b/docs/_templates/autosummary/function.rst new file mode 100644 index 00000000..ef91acbf --- /dev/null +++ b/docs/_templates/autosummary/function.rst @@ -0,0 +1,3 @@ +{{ name | escape | underline }} + +.. autofunction:: {{ fullname }} diff --git a/docs/_templates/autosummary/module.rst b/docs/_templates/autosummary/module.rst new file mode 100644 index 00000000..c61c1db7 --- /dev/null +++ b/docs/_templates/autosummary/module.rst @@ -0,0 +1,68 @@ +{{ name | escape | underline }} + +.. automodule:: {{ fullname }} + + {% block attributes %} + {%- if attributes %} + .. rubric:: {{ _('Module Attributes') }} + + .. autosummary:: + :toctree: + {% for item in attributes %} + {{ item }} + {%- endfor %} + {% endif %} + {%- endblock %} + + {%- block functions %} + {%- if functions %} + .. rubric:: {{ _('Functions') }} + + .. autosummary:: + :toctree: + :signatures: none + {% for item in functions %} + {{ item }} + {%- endfor %} + {% endif %} + {%- endblock %} + + {%- block classes %} + {%- if classes %} + .. rubric:: {{ _('Classes') }} + + .. autosummary:: + :toctree: + :signatures: none + {% for item in classes %} + {{ item }} + {%- endfor %} + {% endif %} + {%- endblock %} + + {%- block exceptions %} + {%- if exceptions %} + .. rubric:: {{ _('Exceptions') }} + + .. autosummary:: + :toctree: + :signatures: none + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {%- endblock %} + +{%- block modules %} +{%- if modules %} +.. rubric:: Modules + +.. autosummary:: + :toctree: + :recursive: + :signatures: none +{% for item in modules %} + {{ item }} +{%- endfor %} +{% endif %} +{%- endblock %} diff --git a/docs/about.md b/docs/about.md deleted file mode 100644 index 14445c6f..00000000 --- a/docs/about.md +++ /dev/null @@ -1,5 +0,0 @@ - - -# UncertainSCI - -[UncertainSCI](https://github.com/SCIInstitute/UncertainSCI) diff --git a/docs/api_docs/distributions.rst b/docs/api_docs/distributions.rst deleted file mode 100644 index c9aa7b88..00000000 --- a/docs/api_docs/distributions.rst +++ /dev/null @@ -1,39 +0,0 @@ -.. _distributions: - -Distributions -============= - -Introduction ------------- - -This module is used to define probability distributions. For computing polynomial Chaos expansions (see :ref:`pce`), these will be input distributions into a forward model defining the stochastic variation of model parameters. - -UncertainSCI currently supports the following types of random variables: - -- Beta distributions (See :class:`.BetaDistribution`) -- Exponential distributions (See :class:`.ExponentialDistribution`) -- Normal distributions (See :class:`.NormalDistribution`) -- Discrete uniform distributions (See :class:`.DiscreteUniformDistribution`) - -Tensorizations within a distribution are possible across these families by instantiating the distribution appropriately. Tensorizations across distributions is also possible, but requires individual instantiation of each distribution, followed by a constructor call to the TensorialDistribution class. (See :class:`.TensorialDistribution`) - -E.g., a three-dimensional random variable :math:`Y = (Y_1, Y_2, Y_3)` can have independent components, with the distribution of :math:`Y_1` normal, that of :math:`Y_2` beta, and that of :math:`Y_3` exponential. - -The distributions are located in the `distributions.py` file. - -.. automodule:: UncertainSCI.distributions -.. autoclass:: BetaDistribution - :members: - :undoc-members: -.. autoclass:: ExponentialDistribution - :members: - :undoc-members: -.. autoclass:: NormalDistribution - :members: - :undoc-members: -.. autoclass:: DiscreteUniformDistribution - :members: - :undoc-members: -.. autoclass:: TensorialDistribution - :members: - :undoc-members: diff --git a/docs/api_docs/index.rst b/docs/api_docs/index.rst deleted file mode 100644 index f2d16ef5..00000000 --- a/docs/api_docs/index.rst +++ /dev/null @@ -1,12 +0,0 @@ -API Documentation -======================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - spaces - distributions - polynomials - pce - diff --git a/docs/api_docs/polynomials.rst b/docs/api_docs/polynomials.rst deleted file mode 100644 index 5f12d49e..00000000 --- a/docs/api_docs/polynomials.rst +++ /dev/null @@ -1,25 +0,0 @@ -Polynomial Families -=================== - -The computational building blocks of polynomial Chaos expansions (PCE, see -:ref:`pce`) are methods for univariate orthogonal polynomial families. - -.. automodule:: UncertainSCI.opoly1d -.. autoclass:: OrthogonalPolynomialBasis1D - :members: - :undoc-members: - -.. automodule:: UncertainSCI.families -.. autoclass:: JacobiPolynomials - :members: - :undoc-members: -.. autoclass:: HermitePolynomials - :members: - :undoc-members: -.. autoclass:: LaguerrePolynomials - :members: - :undoc-members: -.. autoclass:: DiscreteChebyshevPolynomials - :members: - :undoc-members: - diff --git a/docs/api_docs/spaces.rst b/docs/api_docs/spaces.rst deleted file mode 100644 index 61dc737f..00000000 --- a/docs/api_docs/spaces.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _spaces: - -Polynomial Spaces -================= - -The expressivity of a polynomial Chaos expansion (PCE, see :ref:`pce`) can be -set by specifying a particular polynomial space. - -.. automodule:: UncertainSCI.indexing -.. autoclass:: TotalDegreeSet - :members: - :undoc-members: -.. autoclass:: HyperbolicCrossSet - :members: - :undoc-members: -.. autoclass:: LpSet - :members: - :undoc-members: diff --git a/docs/bin/addModuleStubPage.sh b/docs/bin/addModuleStubPage.sh deleted file mode 100644 index fa7acde7..00000000 --- a/docs/bin/addModuleStubPage.sh +++ /dev/null @@ -1,3 +0,0 @@ -moduleName=$1 -sed s/CreateLatVol/$moduleName/ _includes/modules/CreateLatVol.md > _includes/modules/$moduleName.md -ln -s ../_includes/modules/$moduleName.md modules/$moduleName.md diff --git a/docs/bin/jekyll-page b/docs/bin/jekyll-page deleted file mode 100644 index a8e2f2fb..00000000 --- a/docs/bin/jekyll-page +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env ruby - -require 'date' -require 'optparse' - -options = { - # Expects to be in the bin/ sub-directory by default - :path => File.dirname(File.dirname(__FILE__)) -} - -parser = OptionParser.new do |opt| - opt.banner = 'usage: jekyll-page TITLE CATEGORY [FILENAME] [OPTIONS]' - opt.separator '' - opt.separator 'Options' - opt.on('-e', '--edit', 'Edit the page') do |edit| - options[:edit] = true - end - opt.on('-l', '--link', 'Relink pages') do |link| - options[:link] = true - end - opt.on('-p PATH', '--path PATH', String, 'Path to project root') do |path| - options[:path] = path - end - opt.separator '' -end - -parser.parse! - -title = ARGV[0] -category = ARGV[1] -filename = ARGV[2] - -# Resolve any relative links -BASE_DIR = File.expand_path(options[:path]) -POSTS_DIR = "#{BASE_DIR}/_posts" -PAGES_DIR = "#{BASE_DIR}/_pages" - -# Ensure the _posts directory exists (we are in the correct directory) -if not Dir.exists?(POSTS_DIR) - puts "#{POSTS_DIR} directory does not exists" - exit -end - -# Create _pages directory if it doesn't exist -if not Dir.exists?(PAGES_DIR) - Dir.mkdir(PAGES_DIR) -end - -if options[:link] - Dir.foreach(POSTS_DIR) do |name| - next if name[0] == '.' - nodate = name[/\d{4}-\d{2}-\d{2}-(?.*)/, 'rest'] - if File.symlink?("#{PAGES_DIR}/#{nodate}") - File.delete("#{PAGES_DIR}/#{nodate}") - end - abspath = File.absolute_path("#{POSTS_DIR}/#{name}") - File.symlink(abspath, "#{PAGES_DIR}/#{nodate}") - end -end - -if not title or not category - # This flag can be used by itself, exit silently if no arguments - # are defined - if not options[:link] - puts parser - end - exit -end - -if not filename - filename = title.downcase.gsub(/[^a-z0-9\s]/, '').gsub(/\s+/, '-') -end - -today=Date.today().strftime('%F') -now=DateTime.now().strftime('%F %T') - -filepath = "#{POSTS_DIR}/#{today}-#{filename}.md" -symlink = "#{PAGES_DIR}/#{filename}.md" - -if File.exists?(filepath) - puts "File #{filepath} already exists" - exit -end - -content = < - This project was supported by grants from the National Institute of Biomedical Imaging and Bioengineering (U24EB029012) from the National Institutes of Health. @@ -20,10 +17,10 @@ Jess Tate ### Software requirements #### UncertainSCI -To make a Tutorial for UncertainSCI, start with an up-to-date version of the code and documentation. Download the source code or clone the repository from [github](https://github.com/SCIInstitute/UncertainSCI.git). We suggest [creating a fork](#creating-your-uncertainsci-fork) of the repository so that you can track your changes and create pull requests to the UncertainSCI repository. UncertainSCI requirements are found [here](../user_docs/getting_started.html#system-requirements) +To make a Tutorial for UncertainSCI, start with an up-to-date version of the code and documentation. Download the source code or clone the repository from [github](https://github.com/SCIInstitute/UncertainSCI.git). We suggest [creating a fork](#creating-your-uncertainsci-fork) of the repository so that you can track your changes and create pull requests to the UncertainSCI repository. UncertainSCI requirements are found [here](../user_docs/getting_started.md#system-requirements) #### Dependencies and Development Tools -UncertainSCI uses Read the Docs and Sphinx to build and host tutorial documentation. This platform converts markdown files to html for web viewing using Sphinx, a Python Library. Testing the new documentation may require building the web pages locally for viewing. This will require installing Python, pip, Sphinx, Recommonmark, and other packages in the [`docs/requirements.txt` file](https://github.com/SCIInstitute/UncertainSCI/blob/master/docs/requirements.txt). More information can be found in [the walkthorugh]( ) and on the [Sphinx documentation](https://www.sphinx-doc.org). +UncertainSCI uses Read the Docs and Sphinx to build and host tutorial documentation. This platform converts markdown files to html for web viewing using Sphinx, a Python Library. Testing the new documentation may require building the web pages locally for viewing. This will require installing Python, pip, Sphinx, MyST-NB, and the other packages in the `docs` optional dependency group. More information can be found in [testing locally](#testing-locally) and on the [Sphinx documentation](https://www.sphinx-doc.org). #### Creating Your UncertainSCI Fork With your own github account, go to the [UncertainSCI Github page](https://github.com/SCIInstitute/UncertainSCI). Click the fork button on the upper right side of the page. It will ask you where to move the fork to, chose your own account. Once the repository is forked, clone it to your local machine with the following command. @@ -74,12 +71,8 @@ To make a new tutorial, a markdown file is required for the content of the tutor ### Markdown File The main file needed for a new tutorial is a markdown file. The file should have an file ending of *.md* and should be located in the `UncertainSCI/docs/tutorials/` directory. There is a [template file](https://github.com/SCIInstitute/UncertainSCI/blob/master/docs/tutorials/template.md) that can be used, or an existing tutorial like this one can be used. -If using math equations in a latex, a call to the mathjax server is required at the begining of the document: -``` - -``` +Math equations can be written directly in Markdown. MyST-NB and Sphinx handle +math rendering during the documentation build. Sphinx will build the menu and table of contents from the header names, and the document will be formated correctly if the proper markdown headings levels are used. For instance, the Document title should be the first content: ``` @@ -111,23 +104,28 @@ Additional files added to the `tutorials` folder should be minimized as much as ### Linking to New Tutorial -For the new tutorial to be visible on the [tutorials page](../tutorials/index.html#tutorials), add the filename to the list in the [`UncertainSCI/docs/tutorials/index.rst` file](https://github.com/SCIInstitute/UncertainSCI/blob/master/docs/tutorials/index.rst). +For the new tutorial to be visible on the [tutorials page](../tutorials/index.rst), add the filename to the list in the [`UncertainSCI/docs/tutorials/index.rst` file](https://github.com/SCIInstitute/UncertainSCI/blob/master/docs/tutorials/index.rst). ## Testing Documentation **This chapter describes how to test the look and content of the new tutorial. Test the generated github-pages with either a local Sphinx build or using the online build on Read the Docs.** ### Testing Locally -Testing the documentation locally involves building documentation website on your local machine using Sphinx and Recommonmark. These instructions are adapted from [Read the Docs' help page](https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html). +Testing the documentation locally involves building documentation website on your local machine using Sphinx and MyST-NB. These instructions are adapted from [Read the Docs' help page](https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html). #### Installing Shpinx -To install the Sphinx, make sure that a relatively recent version of Python 3. Installing sphinx and other dependencies is easiest with [pip](https://pip.pypa.io/en/stable/installing/), just run +To install Sphinx, make sure that a relatively recent version of Python 3 is available. The notebook documentation also requires the standalone Pandoc executable. With conda, install Pandoc first: +``` +conda install -c conda-forge pandoc ``` -pip install -r requirements.txt + +Then install the Python documentation dependencies with [pip](https://pip.pypa.io/en/stable/installing/): +``` +python -m pip install ".[docs]" ``` -in the `UncertainSCI/docs` folder and the relavent python dependencies, including Sphinx, will be installed. +in the repository root and the relavent python dependencies, including Sphinx, will be installed. -Alternatively, the dependencies listed in [`UncertainSCI/docs/requirements.txt` file](https://github.com/SCIInstitute/UncertainSCI/blob/master/docs/requirements.txt) could be installed seperately. +Alternatively, install Pandoc with your operating system package manager and install the dependencies listed in the `docs` optional dependency group in `pyproject.toml` seperately. Please [ask](https://github.com/SCIInstitute/UncertainSCI/discussions) if you have any questions. @@ -176,18 +174,18 @@ And to reference (not working with Sphinx): ### Math -Math equations can be used in Markdown using [MathJax](http://docs.mathjax.org/en/latest/basic/mathematics.html). Mathjax will convert LaTex format: -``` -$$ \frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} $$ +Math equations can be used directly in Markdown. MyST-NB and Sphinx will render LaTeX-style math: ``` -$$ \frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} $$ -It can also use MathJax specific tags: +$$ +\frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} +$$ ``` -\\[ x = {-b \pm \sqrt{b^2-4ac} \over 2a} \\] -``` -\\[ x = {-b \pm \sqrt{b^2-4ac} \over 2a} \\] -inline equations use the `\\(\mathbf{p}\\)` sytanx: \\(\mathbf{p}\\) +$$ +\frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} +$$ + +Inline equations use dollar delimiters, as in ``$\mathbf{p}$``: $\mathbf{p}$ ### Citations @@ -198,21 +196,21 @@ Citations to include in the UncertainSCI docs can be included in the `UncertainS After the reference has been added to `UncertainSCI/docs/references.bib`, the final step is to include the command in the appropriate place. -The sphinxcontrib-bibtex is built to run with rst in Sphinx. However, it can be used in markdown using the [AutoStructify](https://recommonmark.readthedocs.io/en/latest/auto_structify.html) package. This will require using using an `eval_rst` block as follows: +The sphinxcontrib-bibtex is built to run with rst in Sphinx. However, it can be used in Markdown through MyST's `eval-rst` directive as follows: ```` -```eval_rst +```{eval-rst} The whole paragraph will need to be in the eval_rst block :cite:p:`JDT:Bur2020`. For multiple references: :cite:p:`JDT:Bur2020,gupta1983` ``` ```` -```eval_rst +```{eval-rst} The whole paragraph will need to be in the eval_rst block :cite:p:`JDT:Bur2020`. For multiple references: :cite:p:`JDT:Bur2020,gupta1983` ``` add a bibliography section ```` -```eval_rst +```{eval-rst} .. bibliography:: ../references.bib ``` ```` @@ -220,7 +218,7 @@ add a bibliography section TODO: move bibliography section back here when docutils and rtd theme play nicely together #### Bibliography -```eval_rst +```{eval-rst} .. bibliography:: ../references.bib ``` @@ -245,9 +243,9 @@ Including links in Markdown is simple, just use `<>` or `[]()`. For example, an ``` [Adding Content](#adding-content) ``` -When using internal links to sections, include the name of the section, all lower case and with `-` replacing spaces, and all special characters ommited. Linking to other pages in within the UncertainSCI documentation requires a relative path. [Demos](../tutorials/demos.html#demos) is: +When using internal links to sections, include the name of the section, all lower case and with `-` replacing spaces, and all special characters ommited. Linking to other pages in within the UncertainSCI documentation requires a relative path. [Demos](../tutorials/demos/index.rst) is: ``` -[Demos](../tutorials/demos.html#demos) +[Demos](../tutorials/demos/index.rst) ``` Links to other websites can include the full URL. Using `<>` will show the URL, `[]()` will hide it with other text. ``` @@ -259,7 +257,7 @@ Links to other websites can include the full URL. Using `<>` will show the URL, ### Tables -Tables can be used with normal markdown syntax with the [sphinx-markdown-tables](https://github.com/ryanfox/sphinx-markdown-tables) package +Tables can be used with normal Markdown syntax through MyST. ``` | Syntax | Description | @@ -274,7 +272,7 @@ Tables can be used with normal markdown syntax with the [sphinx-markdown-tables] | Paragraph | Text | -```eval_rst +```{eval-rst} +------------+------------+-----------+ | Header 1 | Header 2 | Header 3 | +============+============+===========+ @@ -288,13 +286,13 @@ Tables can be used with normal markdown syntax with the [sphinx-markdown-tables] ### Referencing Sphinx -To link the UncertainSCI API generated using Sphinx, Use this syntax: [`[text](../api_docs/pce.html#polynomial-chaos-expansions)`](../api_docs/pce.html#polynomial-chaos-expansions). +To link the UncertainSCI API generated using Sphinx, Use this syntax: [`[text](../api_docs/pce.rst)`](../api_docs/pce.rst). ## Content Guide -Try to be comprehensive, yet consise, and keep in mind the target audience for the tutorial. It is ok to write an advanced tutorial that builds on more basic knowledge, but please make this expectation clear and link to tutorials and materials that will help the reader develop the required understanding. Include code snippets, example scripts, screenshots, and videos as appropriate. Please use [existing tutorials](../tutorials/index.html#Contents) as try to match the style, flow, and level of detail they provide. +Try to be comprehensive, yet consise, and keep in mind the target audience for the tutorial. It is ok to write an advanced tutorial that builds on more basic knowledge, but please make this expectation clear and link to tutorials and materials that will help the reader develop the required understanding. Include code snippets, example scripts, screenshots, and videos as appropriate. Please use [existing tutorials](../tutorials/index.rst) as try to match the style, flow, and level of detail they provide. ## Supplemental Materials @@ -302,7 +300,7 @@ Some things to consider including with the tutorial. ### Example Scripts -Example scripts should be located in the `UncertainSCI/demos/` directory. Consider using one of the existing demos as a template and try to follow the coding standards outlined in the [contribution guide](contribute.html). +Example scripts should be located in the `UncertainSCI/demos/` directory. Consider using one of the existing demos as a template and try to follow the coding standards outlined in the [contribution guide](contribute.md). ### Movies @@ -332,6 +330,5 @@ Datasets should be located serperately, unless the size is small. Please [ask]( ### Bibliography -```eval_rst -.. bibliography:: ../references.bib -``` + +The documentation bibliography is centralized in the references page. diff --git a/docs/dev_docs/api/index.rst b/docs/dev_docs/api/index.rst new file mode 100644 index 00000000..2269188d --- /dev/null +++ b/docs/dev_docs/api/index.rst @@ -0,0 +1,28 @@ +API Reference +============= + +.. automodule:: UncertainSCI + + +.. seealso:: + See :doc:`../../formalism/index` for detail on the analytic properties of these tools. + + +.. rubric:: PCE Modules + +.. autosummary:: + :toctree: generated + :recursive: + :signatures: none + + distributions + families + indexing + model_examples + opoly1d + opolynd + pce + sampling + transformations + ttr + vis diff --git a/docs/dev_docs/contribute.md b/docs/dev_docs/contribute.md index 1b6e17aa..0ac4a34d 100644 --- a/docs/dev_docs/contribute.md +++ b/docs/dev_docs/contribute.md @@ -4,25 +4,25 @@ Thank you for you contributions to UncertainSCI! We welcome and appreciate and ## Community Support -A great way to start contributing to UncertainSCI is to submit and answer questions on our [discussion board]. +A great way to start contributing to UncertainSCI is to submit and answer questions on our [discussion board](https://github.com/SCIInstitute/UncertainSCI/discussions). -Other ways of contacting the communtity are located on our [support page](../user_docs/support.html#support) +Other ways of contacting the communtity are located on our [support page](../user_docs/support.md). ## Bugs and Features -We encourage users to report any bugs they find and request any features they'd like as a [GitHub issue]. If you would like to tackle any issues, please volunteer by commenting in the issue or [assigning yourself]. +We encourage users to report any bugs they find and request any features they'd like as a [GitHub issue](https://github.com/SCIInstitute/UncertainSCI/issues). If you would like to tackle any issues, please volunteer by commenting in the issue or [assigning yourself](https://docs.github.com/en/issues/tracking-your-work-with-issues/assigning-issues-and-pull-requests-to-other-github-users). ## Make a Tutorial -If you have a tutorial you'd like to share, we'd love to have it. We have a [Tutorial Tutorial](HowToTutorial.html) to explain how to make and contribute tutorials. +If you have a tutorial you'd like to share, we'd love to have it. We have a [Tutorial Tutorial](HowToTutorial.md) to explain how to make and contribute tutorials. ## Contribute Code We appreciate to code maintenance and development that our community can provide. If you'd like to submit a bug fix, dependency update, or an added feature, please keep in mind the [style guide](#style-guide), create a [fork](#fork-repo) of the UncertainSCI repo, and use a [Pull Request](#pull-requests) to add it to UncertainSCI. -It is best practice to make sure that there is [GitHub issue] to describe the required changes to the code, and having these issues documented become more important with the scope of the additions and changes. Possible additions can also be discussed on our [discussion board]. +It is best practice to make sure that there is a [GitHub issue](https://github.com/SCIInstitute/UncertainSCI/issues) to describe the required changes to the code, and having these issues documented become more important with the scope of the additions and changes. Possible additions can also be discussed on our [discussion board](https://github.com/SCIInstitute/UncertainSCI/discussions). ### Fork Repo @@ -64,12 +64,12 @@ Please see the [Github help page](https://help.github.com) for more information. ### Pull Requests -With the contributions added to a branch on a fork of UncertainSCI, it is ready to create a [pull request]. While this can be done in many ways, the easiest is probably through the web page of the forked repo. When navigating to the main page, it will usually display the a `contribute` button near the top of the page for recently updated branches. This is a shortcut to creating a pull request to the main repo and branch. Alternatively, a pull request can be created from the pull request tab of either the main repo or the fork. Before making a pull request, please make sure that you've tried your best to follow the [style guide](#style-guide), and that the branch is up-to-date with the lastest master branch. Also, please update or add [testing](#testing) as appropriate. +With the contributions added to a branch on a fork of UncertainSCI, it is ready to create a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests). While this can be done in many ways, the easiest is probably through the web page of the forked repo. When navigating to the main page, it will usually display the a `contribute` button near the top of the page for recently updated branches. This is a shortcut to creating a pull request to the main repo and branch. Alternatively, a pull request can be created from the pull request tab of either the main repo or the fork. Before making a pull request, please make sure that you've tried your best to follow the [style guide](#style-guide), and that the branch is up-to-date with the lastest master branch. Also, please update or add [testing](#testing) as appropriate. -Once the pull request is created, the maintainers of UncertainSCI will assign reviewers who will test and review the code to ensure that it meets the requirements of the style guide and is stable. It is best to limit the size of each pull request to facilitate review, so if there are major new additions, please add a [GitHub issue] to track the progress. +Once the pull request is created, the maintainers of UncertainSCI will assign reviewers who will test and review the code to ensure that it meets the requirements of the style guide and is stable. It is best to limit the size of each pull request to facilitate review, so if there are major new additions, please add a [GitHub issue](https://github.com/SCIInstitute/UncertainSCI/issues) to track the progress. -## Syle Guide +## Style Guide If you are editing code, take a few minutes to look at the code around you and determine its style. Please try to keep the style of new code as similar as possible to unchanged code to avoid jarring inconsistencies in the style. @@ -92,16 +92,14 @@ If you are editing code, take a few minutes to look at the code around you and d ### Demos and Usecases -New demos and usecases are always welcome. Please add self-contained scripts demonstrating core functionality to the [demos folder]. Demos that require external packages can be located in seperate repos, such as this [UQ BEM heart position usecase] +New demos and usecases are always welcome. Please add self-contained scripts demonstrating core functionality to the [demos folder](https://github.com/SCIInstitute/UncertainSCI/tree/master/demos). Demos that require external packages can be located in seperate repos, such as this [UQ BEM heart position usecase](https://github.com/SCIInstitute/UQExampleBEMHeartPosition) ### Testing -In addition to demos, please add unit testing to new function contributed to UncertainSCI using pytest. Unit test should be placed in the [test folder], which contains several tests to use as examples. To run the test, use the command: +In addition to demos, please add unit testing to new function contributed to UncertainSCI using pytest. Unit test should be placed in the [test folder](https://github.com/SCIInstitute/UncertainSCI/tree/master/tests), which contains several tests to use as examples. To run the test, use the command: ``` pytest tests ``` - - diff --git a/docs/dev_docs/index.rst b/docs/dev_docs/index.rst index 2a556778..d9cae50c 100644 --- a/docs/dev_docs/index.rst +++ b/docs/dev_docs/index.rst @@ -7,4 +7,4 @@ Developer Documentation contribute HowToTutorial - + api/index diff --git a/docs/formalism/index.rst b/docs/formalism/index.rst new file mode 100644 index 00000000..70a45d76 --- /dev/null +++ b/docs/formalism/index.rst @@ -0,0 +1,7 @@ +Mathematical Formalism +====================== + +.. toctree:: + :maxdepth: 2 + + pce diff --git a/docs/api_docs/pce.rst b/docs/formalism/pce.rst similarity index 89% rename from docs/api_docs/pce.rst rename to docs/formalism/pce.rst index 826f42d0..21c743dd 100644 --- a/docs/api_docs/pce.rst +++ b/docs/formalism/pce.rst @@ -36,13 +36,5 @@ For PCE approaches, most of the computation involves computing the coefficients In order to utilize the PCE approaches in UncertainSCI, two items must be provided: -1. The distribution of the random variable :math:`\xi`. See :ref:`distributions` for how to generate this distribution. +1. The distribution of the random variable :math:`\xi`. See :mod:`UncertainSCI.distributions` for how to generate this distribution. 2. The type of polynomial functions in :eq:`expansion`. This amounts to defining a particular polynomial subspace. See :ref:`spaces` for how to generate this subspace. - -PolynomialChaosExpansion ------------------------- - -.. automodule:: UncertainSCI.pce -.. autoclass:: PolynomialChaosExpansion - :members: - :undoc-members: diff --git a/docs/index.rst b/docs/index.rst index d84d5b59..b3781bec 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,12 +23,13 @@ Currently implemented in UncertainSCI is Polynomial Chaos Expansion (PCE) with a :maxdepth: 2 :caption: Contents: + user_docs/install user_docs/getting_started user_docs/support tutorials/index + formalism/index dev_docs/index - api_docs/index - + references Contributors =============== @@ -39,20 +40,9 @@ Acknowledgements This project was supported by grants from the National Institute of Biomedical Imaging and Bioengineering (U24EB029012) from the National Institutes of Health. -.. - TODO: move bibliography back here when the docutils and sphinx_rtd_theme play nicely together - - Indices and Tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` - - -Bibliography -================ -.. bibliography:: ./references.bib - :cited: - diff --git a/docs/references.rst b/docs/references.rst new file mode 100644 index 00000000..b065c398 --- /dev/null +++ b/docs/references.rst @@ -0,0 +1,4 @@ +References +========== + +.. bibliography:: references.bib diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 26f5ae64..00000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,12 +0,0 @@ -docutils -pygments -recommonmark -sphinx -sphinx-issues -sphinx-markdown-tables -sphinx-notfound-page -sphinx_rtd_theme>=1.3.0 -sphinxcontrib-bibtex -sphinx-markdown-tables -nbsphinx -ipykernel \ No newline at end of file diff --git a/docs/tutorials/demos/pce_statistics.rst b/docs/tutorials/demos/pce_statistics.rst index e5922896..546be6c4 100644 --- a/docs/tutorials/demos/pce_statistics.rst +++ b/docs/tutorials/demos/pce_statistics.rst @@ -1,5 +1,5 @@ PCE Statistics -===== +============== Building PCE emulators ---------------------- diff --git a/docs/tutorials/demos/simple_boxplots.md b/docs/tutorials/demos/simple_boxplots.md index f93f53af..58c6ec4d 100644 --- a/docs/tutorials/demos/simple_boxplots.md +++ b/docs/tutorials/demos/simple_boxplots.md @@ -1,8 +1,5 @@ # Simple example with boxplots - This project was supported by grants from the National Institute of Biomedical Imaging and Bioengineering (U24EB029012) from the National Institutes of Health. @@ -32,11 +29,11 @@ b = 0.05 f = ishigami_function(a,b) ``` -This generates a function `f` of three parameters. See the [`[Ishigami Function]`](../models.html#ishigami-function) description for more information about this model. +This generates a function `f` of three parameters. See the [Ishigami Function](../models.md#ishigami-function) description for more information about this model. ### Parameter distributions -A more complete discussion of creating parameter distributions is given in the [`[Defining Random Parameters]`](../parameters.html) tutorial. Here we only present a simple setup. We will assume that our three parameters, +A more complete discussion of creating parameter distributions is given in the [Defining Random Parameters](../parameters.md) tutorial. Here we only present a simple setup. We will assume that our three parameters, \begin{align} \mathbf{P} = (P_1, P_2, P_3) \in \mathbb{R}^3 @@ -56,7 +53,7 @@ p3 = BetaDistribution(alpha=1, beta=1, domain=bounds) p = TensorialDistribution(distributions=[p1, p2, p3]) ``` -We have used the fact that a `BetaDistribution` with parameters `alpha=beta=1` corresponds to the uniform distribution. See [`[Beta Distribution]`](../parameters.html#beta-distribution) for more information about the Beta distribution. Note also that we have individually defined the parameters, and then combined them into a single three-dimensional random parameter using the `TensorialDistribution` command. +We have used the fact that a `BetaDistribution` with parameters `alpha=beta=1` corresponds to the uniform distribution. See [Beta Distribution](../parameters.md#beta-distribution) for more information about the Beta distribution. Note also that we have individually defined the parameters, and then combined them into a single three-dimensional random parameter using the `TensorialDistribution` command. ### Defining polynomial order @@ -107,4 +104,3 @@ We generate boxplots using standard Monte Carlo sampling and also sampling from Boxplots are generated using the `matplotlib` boxplot feature. ![Boxplot comparisons](../../_static/simple_boxplots.png "Boxplots") - diff --git a/docs/tutorials/models.md b/docs/tutorials/models.md index e97ffeae..894250ba 100644 --- a/docs/tutorials/models.md +++ b/docs/tutorials/models.md @@ -1,8 +1,5 @@ # Built-in forward models - This project was supported by grants from the National Institute of Biomedical Imaging and Bioengineering (U24EB029012) from the National Institutes of Health. diff --git a/docs/tutorials/notebooks/adapt_pce.ipynb b/docs/tutorials/notebooks/adapt_pce.ipynb index 7c0f8702..ec3c3527 100644 --- a/docs/tutorials/notebooks/adapt_pce.ipynb +++ b/docs/tutorials/notebooks/adapt_pce.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "927510c7", "metadata": {}, "outputs": [], @@ -62,7 +62,7 @@ "source": [ "### Define Forward model\n", "\n", - "The model in this example is a 1D laplacian ODE. See the `laplace_ode_1d` [method](../models.html) or `UncertainSCI/model_examples.py` for details.\n", + "The model in this example is a 1D laplacian ODE. See the `laplace_ode_1d` [method](../models.md) or `UncertainSCI/model_examples.py` for details.\n", "\n", "$$\n", "-\\frac{d}{dx} a(x,p) \\cdot \\frac{d}{dx} u(x,p) = f(x)\n", @@ -87,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "303bbbe3", "metadata": {}, "outputs": [], @@ -123,7 +123,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "26f5e93b", "metadata": {}, "outputs": [], @@ -143,12 +143,12 @@ "source": [ "### Initial Expressivity of the PCE\n", "\n", - "This example uses a different setup than you might see in [other examples](./build_pce.html). Other setups will be equivalent for many non-adaptive cases, but it is useful to operate with the index set in this example. Another important distinction that is necessary for the adaptive case is supplying the model as a lambda function to the PCE object. " + "This example uses a different setup than you might see in [other examples](./build_pce.ipynb). Other setups will be equivalent for many non-adaptive cases, but it is useful to operate with the index set in this example. Another important distinction that is necessary for the adaptive case is supplying the model as a lambda function to the PCE object. " ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "aa4edbf2", "metadata": {}, "outputs": [], @@ -161,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "55932726", "metadata": {}, "outputs": [], @@ -185,92 +185,10 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "id": "7c289e10", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "new indices: 1, new samples: 4\n", - "old residual: 1.418e-09, old loocv: 4.334e-06\n", - "new residual: 1.424e-09, new loocv: 4.259e-06\n", - "new indices: 1, new samples: 4\n", - "old residual: 1.424e-09, old loocv: 4.259e-06\n", - "new residual: 1.446e-09, new loocv: 4.243e-06\n", - "new indices: 1, new samples: 4\n", - "old residual: 1.446e-09, old loocv: 4.243e-06\n", - "new residual: 9.789e-10, new loocv: 2.748e-06\n", - "new indices: 1, new samples: 4\n", - "old residual: 9.789e-10, old loocv: 2.748e-06\n", - "new residual: 9.637e-10, new loocv: 2.499e-06\n", - "new indices: 1, new samples: 4\n", - "old residual: 9.637e-10, old loocv: 2.499e-06\n", - "new residual: 6.000e-10, new loocv: 2.085e-06\n", - "new indices: 1, new samples: 4\n", - "old residual: 6.000e-10, old loocv: 2.085e-06\n", - "new residual: 2.177e-10, new loocv: 1.412e-06\n", - "new indices: 1, new samples: 4\n", - "old residual: 2.177e-10, old loocv: 1.412e-06\n", - "new residual: 9.205e-11, new loocv: 9.741e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 9.205e-11, old loocv: 9.741e-07\n", - "new residual: 6.980e-11, new loocv: 8.633e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 6.980e-11, old loocv: 8.633e-07\n", - "new residual: 6.651e-11, new loocv: 8.321e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 6.651e-11, old loocv: 8.321e-07\n", - "new residual: 7.158e-11, new loocv: 8.528e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 7.158e-11, old loocv: 8.528e-07\n", - "new residual: 4.889e-11, new loocv: 6.559e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 4.889e-11, old loocv: 6.559e-07\n", - "new residual: 4.642e-11, new loocv: 6.220e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 4.642e-11, old loocv: 6.220e-07\n", - "new residual: 4.520e-11, new loocv: 6.129e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 4.520e-11, old loocv: 6.129e-07\n", - "new residual: 4.639e-11, new loocv: 6.159e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 4.639e-11, old loocv: 6.159e-07\n", - "new residual: 3.642e-11, new loocv: 4.480e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 3.642e-11, old loocv: 4.480e-07\n", - "new residual: 3.216e-11, new loocv: 3.926e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 3.216e-11, old loocv: 3.926e-07\n", - "new residual: 3.096e-11, new loocv: 3.793e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 3.096e-11, old loocv: 3.793e-07\n", - "new residual: 2.029e-11, new loocv: 3.257e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 2.029e-11, old loocv: 3.257e-07\n", - "new residual: 7.890e-12, new loocv: 2.240e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 7.890e-12, old loocv: 2.240e-07\n", - "new residual: 2.909e-12, new loocv: 1.355e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 2.909e-12, old loocv: 1.355e-07\n", - "new residual: 1.907e-12, new loocv: 1.112e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 1.907e-12, old loocv: 1.112e-07\n", - "new residual: 1.733e-12, new loocv: 1.058e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 1.733e-12, old loocv: 1.058e-07\n", - "new residual: 1.723e-12, new loocv: 1.050e-07\n", - "new indices: 1, new samples: 4\n", - "old residual: 1.723e-12, old loocv: 1.050e-07\n", - "new residual: 1.540e-12, new loocv: 9.896e-08\n", - "new indices: 1, new samples: 4\n", - "old residual: 1.540e-12, old loocv: 9.896e-08\n", - "new residual: 1.594e-12, new loocv: 9.867e-08\n" - ] - } - ], + "outputs": [], "source": [ "# pce.adapt_robustness(max_new_samples=50)\n", "residuals, loocvs, added_indices, added_samples = pce.adapt_expressivity(max_new_samples=100, add_rule=3)\n" @@ -288,7 +206,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": null, "id": "c20b30d4", "metadata": {}, "outputs": [], @@ -300,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": null, "id": "49d326c7", "metadata": {}, "outputs": [], @@ -311,7 +229,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": null, "id": "e4a19d74", "metadata": {}, "outputs": [], @@ -323,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": null, "id": "e23f6ece", "metadata": {}, "outputs": [], @@ -335,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": null, "id": "4945132c", "metadata": {}, "outputs": [], @@ -361,7 +279,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": null, "id": "eb408ce7", "metadata": {}, "outputs": [], @@ -391,7 +309,7 @@ "source": [ "## Visualize Statistics\n", "\n", - "Similar to [other examples](./build_pce.html), we will plot the uncertainty over the domain of the domain of the model. This example shows how users might do so more manually instead of using the [built in plotting functions](./build_pce.html#output-visualizations)\n", + "Similar to [other examples](./build_pce.ipynb), we will plot the uncertainty over the domain of the domain of the model. This example shows how users might do so more manually instead of using the [built in plotting functions](./build_pce.ipynb#output-visualizations)\n", "\n", "### Plotting Setup\n", "\n", @@ -400,7 +318,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": null, "id": "cc0f4b63", "metadata": {}, "outputs": [], @@ -422,21 +340,10 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": null, "id": "d1712790", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# # Visualization\n", "V = 50 # Number of MC samples to visualize\n", @@ -469,998 +376,10 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": null, "id": "5f53e3b2", "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# quantile plot\n", "plt.figure()\n", @@ -1519,998 +438,10 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": null, "id": "eee0c068", "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Sensitivity due to variable interactions')" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Sensitivity pie chart, averaged over all model degrees of freedom\n", "average_global_SI = np.sum(global_sensitivity, axis=1)/N\n", @@ -2537,988 +468,10 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": null, "id": "8b7f9de8", "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_device_pixel_ratio', {\n", - " device_pixel_ratio: fig.ratio,\n", - " });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'dblclick',\n", - " on_mouse_event_closure('dblclick')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " fig.rubberband_canvas.style.cursor = msg['cursor'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " var img = evt.data;\n", - " if (img.type !== 'image/png') {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " img.type = 'image/png';\n", - " }\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " img\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * https://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.key === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.key;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.key !== 'Control') {\n", - " value += 'ctrl+';\n", - " }\n", - " else if (event.altKey && event.key !== 'Alt') {\n", - " value += 'alt+';\n", - " }\n", - " else if (event.shiftKey && event.key !== 'Shift') {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k' + event.key;\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.binaryType = comm.kernel.ws.binaryType;\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " function updateReadyState(_event) {\n", - " if (comm.kernel.ws) {\n", - " ws.readyState = comm.kernel.ws.readyState;\n", - " } else {\n", - " ws.readyState = 3; // Closed state.\n", - " }\n", - " }\n", - " comm.kernel.ws.addEventListener('open', updateReadyState);\n", - " comm.kernel.ws.addEventListener('close', updateReadyState);\n", - " comm.kernel.ws.addEventListener('error', updateReadyState);\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " var data = msg['content']['data'];\n", - " if (data['blob'] !== undefined) {\n", - " data = {\n", - " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", - " };\n", - " }\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(data);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Index set plot\n", "fig = plt.figure()\n", diff --git a/docs/tutorials/notebooks/build_pce.ipynb b/docs/tutorials/notebooks/build_pce.ipynb index b720d946..b37f2a09 100644 --- a/docs/tutorials/notebooks/build_pce.ipynb +++ b/docs/tutorials/notebooks/build_pce.ipynb @@ -7,12 +7,12 @@ "source": [ "# Simple Example Showing UQ With PCE\n", "\n", - "This example shows some basic functionality of UncertainSCI using the polynomial Chaos emulators (PCE) to quantify uncertainty in a 1D function. It is essentially identical to `demos/build_pce.py` and uses a [1D Laplacian ODE](../models.html) as a model with three parameters" + "This example shows some basic functionality of UncertainSCI using the polynomial Chaos emulators (PCE) to quantify uncertainty in a 1D function. It is essentially identical to `demos/build_pce.py` and uses a [1D Laplacian ODE](../models.md) as a model with three parameters" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "id": "e06c0581", "metadata": {}, "outputs": [], @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "3e7c6ba0", "metadata": {}, "outputs": [], @@ -69,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "9f0ab690", "metadata": {}, "outputs": [], @@ -89,12 +89,12 @@ "-\\frac{d}{dx} a(x,p) \\cdot \\frac{d}{dx} u(x,p) = f(x)\n", "$$\n", "\n", - "with $x$ in $[-1,1]$ discretized with $N$ points, where $a(x,p)$ is a Fourier-Series-parameterized diffusion model with the variables $p_j=[a, b, z]$. See the `laplace_ode_1d` [method](../models.html) or `UncertainSCI/model_examples.py` for details." + "with $x$ in $[-1,1]$ discretized with $N$ points, where $a(x,p)$ is a Fourier-Series-parameterized diffusion model with the variables $p_j=[a, b, z]$. See the `laplace_ode_1d` [method](../models.md) or `UncertainSCI/model_examples.py` for details." ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "694c11f5", "metadata": {}, "outputs": [], @@ -124,19 +124,10 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "3b4d49ee", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Precomputing data for Jacobi parameters (alpha,beta) = (-0.500000, 0.000000)...Done\n", - "This queries the model 66 times\n" - ] - } - ], + "outputs": [], "source": [ "\n", "pce = PolynomialChaosExpansion(distribution=[p1, p2, p3], order=order, plabels=plabels)\n", @@ -157,7 +148,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "id": "5d59274f", "metadata": {}, "outputs": [], @@ -179,45 +170,10 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "id": "577c137c", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([1.75571628e-37, 5.64860235e-17, 2.10743598e-16, 4.30180091e-16,\n", - " 6.73615485e-16, 8.98426649e-16, 1.06808811e-15, 1.15833221e-15,\n", - " 1.16057868e-15, 1.08209494e-15, 9.43231789e-16, 7.72726181e-16,\n", - " 6.02299430e-16, 4.61625174e-16, 3.74362183e-16, 3.55551159e-16,\n", - " 4.10403164e-16, 5.34387196e-16, 7.14489737e-16, 9.31478341e-16,\n", - " 1.16290358e-15, 1.38643597e-15, 1.58302359e-15, 1.73934375e-15,\n", - " 1.84914225e-15, 1.91328322e-15, 1.93860602e-15, 1.93592175e-15,\n", - " 1.91761943e-15, 1.89536658e-15, 1.87829599e-15, 1.87191182e-15,\n", - " 1.87777401e-15, 1.89387162e-15, 1.91549769e-15, 1.93639635e-15,\n", - " 1.94995954e-15, 1.95029022e-15, 1.93300605e-15, 1.89571844e-15,\n", - " 1.83817752e-15, 1.76211869e-15, 1.67087823e-15, 1.56886365e-15,\n", - " 1.46096875e-15, 1.35201633e-15, 1.24629417e-15, 1.14722754e-15,\n", - " 1.05720583e-15, 9.77557484e-16, 9.08648189e-16, 8.50065649e-16,\n", - " 8.00849025e-16, 7.59724059e-16, 7.25312441e-16, 6.96294722e-16,\n", - " 6.71517851e-16, 6.50048858e-16, 6.31183955e-16, 6.14427000e-16,\n", - " 5.99452329e-16, 5.86065283e-16, 5.74169862e-16, 5.63747820e-16,\n", - " 5.54848130e-16, 5.47581156e-16, 5.42108762e-16, 5.38620514e-16,\n", - " 5.37288102e-16, 5.38194279e-16, 5.41239598e-16, 5.46038218e-16,\n", - " 5.51822165e-16, 5.57379403e-16, 5.61052914e-16, 5.60824129e-16,\n", - " 5.54493189e-16, 5.39951481e-16, 5.15520386e-16, 4.80308188e-16,\n", - " 4.34519740e-16, 3.79646212e-16, 3.18469931e-16, 2.54843985e-16,\n", - " 1.93246402e-16, 1.38157999e-16, 9.33612879e-17, 6.12921066e-17,\n", - " 4.25845893e-17, 3.59260824e-17, 3.82825975e-17, 4.54770963e-17,\n", - " 5.30202417e-17, 5.70278062e-17, 5.50298773e-17, 4.64948566e-17,\n", - " 3.29537537e-17, 1.77021507e-17, 5.15427668e-18, 0.00000000e+00])" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "pce.build(model_output=model_output)" ] @@ -234,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "b9009892", "metadata": {}, "outputs": [], @@ -258,93 +214,30 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "id": "09296b66", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAHGCAYAAACmS4sdAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd5hcVf348ff0srO9974pW1M32WRTSQid0AIISImCiIooX0V+YkNRQQUREJGOQmjSCaT3skl2s7333dmZrdP73N8f2YyEhBJaBM7reeZ5kju3nHvm7s5nT/kcmSRJEoIgCIIgCKeI/FQXQBAEQRCErzcRjAiCIAiCcEqJYEQQBEEQhFNKBCOCIAiCIJxSIhgRBEEQBOGUEsGIIAiCIAinlAhGBEEQBEE4pUQwIgiCIAjCKSWCEUEQBEEQTikRjAiCIAiCcEqJYET4SnjiiSeQyWTIZDK2bt163PuSJJGXl4dMJmPJkiVfePn+V+3evZtf/vKXTExMnLIy/PKXv0Qmk31prvdFlPfo89zd3X3Sx37QZ/ppzikInzcRjAhfKeHh4Tz66KPHbd+2bRsdHR2Eh4efglL979q9eze/+tWvTmkwIhzvrLPOYs+ePSQnJ5/0sR/0mX6acwrC500EI8JXypo1a3jppZewWq3HbH/00UeZP38+GRkZp6hkn9ySJUu4+uqrT3UxvjScTuepLsKnFh8fz7x589BoNP/T5xSEz4oIRoSvlMsuuwyAZ599NrTNYrHw0ksvce21157wmLa2Ni6//HISEhLQaDRMmzaNBx544Jh92tvbueaaa8jPz0ev15Oamso555xDXV3dMfsdbcJvaGjgsssuIzIyksTERK699losFstnfLcfbnh4mG9/+9ukp6ej0WiIj49nwYIFbNy4MVTWW2+9FYDs7Ozjurk+j3t+8803KSsrQ6PRkJ2dzT333HPCsp/stQ8dOsRFF11EdHQ0ubm5J329D3Iyx3/Uc/TKK68gk8nYtGnTccc+9NBDyGQyamtrgeO7VE6mPj7oM/2gbpqdO3eyfPlywsPD0ev1VFRU8Oabbx533v+V51r4alKe6gIIwmcpIiKCiy66iMcee4zrr78eOBKYyOVy1qxZw7333nvM/o2NjVRUVJCRkcGf/vQnkpKSeOedd/j+97/PyMgIv/jFLwAYHBwkNjaW3//+98THxzM2NsaTTz5JeXk51dXVTJky5ZjzXnjhhaxZs4brrruOuro6brvtNgAee+yxDy2/JEkEAoHjtkmShN/vP2a7UvnhP75XXnklhw4d4re//S0FBQVMTExw6NAhRkdHAVi7di1jY2Pcf//9vPzyy6Hm++nTp38u97xp0ybOO+885s+fz3PPPUcgEOCPf/wjJpPpuLKf7LUvuOACLr30Um644QYcDsdJX+9ETub4j/McnX322SQkJPD444+zfPnyY45/4oknmDlzJiUlJScsy8etjw/7TE80VmTbtm2sWLGCkpISHn30UTQaDQ8++CDnnHMOzz77LGvWrDlm/0/6XAvCR5IE4Svg8ccflwCpqqpK2rJliwRI9fX1kiRJ0pw5c6Srr75akiRJKiwslBYvXhw67vTTT5fS0tIki8VyzPluuukmSavVSmNjYye8nt/vl7xer5Sfny/98Ic/DG3/xS9+IQHSH//4x2P2v/HGGyWtVisFg8EPvY+jZf84r66urg89l8FgkG6++eYP3efuu+/+WOeSpE9/z+Xl5VJKSorkcrlC+1itVikmJkb6qF9FH3XtO+6447hjPs31Tvb4j/sc3XLLLZJOp5MmJiZC+zQ2NkqAdP/994e2HX2eP+hz+aD6kKQP/kxPdM558+ZJCQkJks1mO+bcRUVFUlpaWuiz+7TPtSB8FNFNI3zlLF68mNzcXB577DHq6uqoqqo6YReN2+1m06ZNrF69Gr1ej9/vD73OPPNM3G43e/fuBcDv9/O73/2O6dOno1arUSqVqNVq2traaGpqOu7c55577jH/Lykpwe12YzabP7Tss2bNoqqq6pjXzJkzOfvss4/bnpKS8qHnmjt3Lk888QR33nkne/fuxefzfVTVHeOzvGeHw0FVVRUXXHABWq02tE94eDjnnHPOp772hRdeeMz/T/Z673cyx5/Mc3TttdficrlYt25d6PjHH38cjUbD5Zdf/oHlOdn6+DgcDgf79u3joosuwmAwhLYrFAquvPJK+vv7aWlpOeaYT/pcC8JHEd00wleOTCbjmmuu4a9//Stut5uCggIqKyuP2290dBS/38/999/P/ffff8JzjYyMAHDLLbfwwAMP8JOf/ITFixcTHR2NXC5n7dq1uFyu446LjY095v9HBw2eaN/3Cg8PZ/bs2cdti42NPW77R1m3bh133nkn//znP/n5z3+O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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "mean_stdev_plot(pce, ensemble=50)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "id": "13eae6c0", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAHFCAYAAAAg3/mzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACnlklEQVR4nOzdd3iTZffA8e+TpEm6S1taVsseZe8p4gIFxPX6ihMX/sQNvC6cOHGLvgoOBJyIr3vgwIEgqCAbWjaljELp3pnP74+bNE0Xbenu+VxXLtonT5I7pU1Ozn3uc2u6rusIIYQQQtQTQ30PQAghhBDNmwQjQgghhKhXEowIIYQQol5JMCKEEEKIeiXBiBBCCCHqlQQjQgghhKhXEowIIYQQol5JMCKEEEKIeiXBiBBCCCHqlQQjollYvHgxmqahaRorVqwodb2u63Tp0gVN0zjjjDNq9LE7dOjAddddV/T9ihUryh2HqHkfffQRc+fOLfM6TdOYPXt20fc1/X+TmJiIpmm88MILNXJ/NeWMM86o8d9zIU6FBCOiWQkODuadd94pdfz3339n7969BAcH1/oYBg4cyJ9//snAgQNr/bFExcHIn3/+ydSpU+t2QEKIUiQYEc3K5MmT+eyzz8jOzvY5/s477zBixAhiY2NrfQwhISEMHz6ckJCQWn+syujQoYNPdqA5GT58OO3atavvYQjR7EkwIpqVK664AoAlS5YUHcvKyuKzzz7jhhtuKPM2drudJ598kh49emCxWGjZsiXXX389x48f9znP4XBw77330qpVKwICAjjttNNYu3Ztqfsrayrgn3/+4fLLL6dDhw74+/vToUMHrrjiCg4cOOBzW89002+//cYtt9xCZGQkERERXHLJJRw5cqS6P5Zq++677+jfvz8Wi4WOHTvywgsvMHv2bDRNKzrHM1WxePHiUrcvOU2yZ88err/+erp27UpAQABt27Zl0qRJbN261ed2np/hkiVLePDBB2nTpg0hISGcc8457Ny5s+i8M844g++++44DBw4UTdMVH1vJxy/PP//8wwUXXEB4eDhWq5UBAwbwySefVPrn5Ha7eeqpp4iNjcVqtTJ48GB++eUXn3Nq+rmDmn587rnnaN++PVarlYEDB/L999+XOb4nn3yS7t274+/vT1hYGH379uWVV16p9HMU4lRIMCKalZCQEC699FIWLlxYdGzJkiUYDAYmT55c6ny3282FF17IM888w5VXXsl3333HM888w/LlyznjjDMoKCgoOvemm27ihRdeYMqUKXz11Vf861//4pJLLiEjI+Ok40pMTKR79+7MnTuXH3/8kWeffZbk5GSGDBlCampqqfOnTp2Kn58fH330Ec899xwrVqzg6quvruZPpXp++eUXLrzwQoKDg/n44495/vnn+eSTT1i0aFG17/PIkSNERETwzDPP8MMPP/D6669jMpkYNmxYqTdagAceeIADBw6wYMEC3nrrLXbv3s2kSZNwuVwAzJs3j1GjRtGqVSv+/PPPoktV/Pbbb4waNYrMzEzeeOMNvvrqK/r378/kyZPLDLDK8tprr/HDDz8wd+5cPvjgAwwGA+PHj/cZS00/d4DHHnuM++67j7Fjx/Lll19yyy23cNNNN5W6v+eee47Zs2dzxRVX8N1337F06VJuvPFGMjMzq/SzEqLadCGagUWLFumAvm7dOv23337TAX3btm26ruv6kCFD9Ouuu07XdV3v1auXPmbMmKLbLVmyRAf0zz77zOf+1q1bpwP6vHnzdF3X9YSEBB3QZ8yY4XPehx9+qAP6tddeW3TM8/i//fZbueN1Op16bm6uHhgYqL/yyiulnsett97qc/5zzz2nA3pycnKFPwe32607HA6fS/v27fWHH3641PGTGTZsmN6mTRu9oKCg6Fh2drYeHh6uF39p2b9/vw7oixYtKnUfgP7oo4+W+xhOp1O32+16165dfX62np/hhAkTfM7/5JNPdED/888/i45NnDhRb9++fZn3X/Lxy/q/6dGjhz5gwIBSP5Pzzz9fb926te5yucodv+e5l/dzOuecc2rtuWdkZOhWq1W/+OKLfc5bvXq1Dvj8np9//vl6//79yx2LELVNMiOi2RkzZgydO3dm4cKFbN26lXXr1pU7RfPtt98SFhbGpEmTcDqdRZf+/fvTqlWroqmW3377DYCrrrrK5/aXXXYZJpPppGPKzc3lvvvuo0uXLphMJkwmE0FBQeTl5ZGQkFDq/AsuuMDn+759+wKUmtYp6d1338XPz8/ncuDAAZ544olSxyuSl5fHunXruOSSS7BarUXHg4ODmTRp0kmfb3mcTidPP/00PXv2xGw2YzKZMJvN7N69u0Z/DpW1Z88eduzYUfT/Wvx3YMKECSQnJ5eZtSipvJ/TypUrizIZNf3c//zzTwoLC0v9To4cOZL27dv7HBs6dCibN2/m1ltv5ccffyxVUyVEbTv5q6QQTYymaVx//fW8+uqrFBYW0q1bN0aPHl3muceOHSMzMxOz2Vzm9Z4plLS0NABatWrlc73JZCIiIuKkY7ryyiv55ZdfePjhhxkyZAghISFomsaECRN8poI8St6nxWIBKPPc4iZNmsS6det8jl1wwQWcf/75/N///d9Jx+mRkZGB2+0u9Xyh9M+gKmbOnMnrr7/Offfdx5gxY2jRogUGg4GpU6fW6M+hso4dOwbA3Xffzd13313mOWVNo5VU3s/JbreTm5tLaGhojT/38n4nyzo2a9YsAgMD+eCDD3jjjTcwGo2cfvrpPPvsswwePPikz0+IUyXBiGiWrrvuOh555BHeeOMNnnrqqXLP8xSI/vDDD2Ve71kK7HljOHr0KG3bti263ul0Fr0plCcrK4tvv/2WRx99lPvvv7/ouM1mIz09vdLPqTIiIiJKvYmZzWbatGlTpTedFi1aoGkaR48eLXVdyWOejIDNZvM5XtbP5YMPPmDKlCk8/fTTPsdTU1MJCwur9PhqSmRkJKDerC+55JIyz+nevftJ76e8n5PZbCYoKAio+ede/HeyrMfu0KFD0fcmk4mZM2cyc+ZMMjMz+fnnn3nggQc499xzOXjwIAEBAVV+fCGqQqZpRLPUtm1b7rnnHiZNmsS1115b7nnnn38+aWlpuFwuBg8eXOrieSPyNJD68MMPfW7/ySef4HQ6KxyLpmnoul70ydZjwYIFPsWIDUlgYCBDhw7l888/p7CwsOh4Tk4O33zzjc+50dHRWK1WtmzZ4nP8q6++KnW/mqaV+jl89913HD58uNpjtVgs1c6UdO/ena5du7J58+Yy//8HDx5cqd405f2cRo8ejdFoBGr+uQ8fPhyr1Vrqd3LNmjUVTmOFhYVx6aWXctttt5Genk5iYmK1Hl+IqpDMiGi2nnnmmZOec/nll/Phhx8yYcIE7rrrLoYOHYqfnx+HDh3it99+48ILL+Tiiy8mLi6Oq6++mrlz5+Ln58c555zDtm3beOGFF07aTyQkJITTTz+d559/nsjISDp06MDvv//OO++8Uy/ZgMp64oknOO+88xg7diz/+c9/cLlcPPvsswQGBvpkdDRN4+qrr2bhwoV07tyZfv36sXbtWj766KNS93n++eezePFievToQd++fVm/fj3PP//8KfUC6dOnD59//jnz589n0KBBGAyGKmWB3nzzTcaPH8+5557LddddR9u2bUlPTychIYENGzbwv//976T3YTQaGTt2LDNnzsTtdvPss8+SnZ3NY489VnROTT/3Fi1acPfdd/Pkk08ydepU/v3vf3Pw4EFmz55dappm0qRJ9O7dm8GDB9OyZUsOHDjA3Llzad++PV27dq3W4wtRFRKMCFEBo9HI119/zSuvvML777/PnDlzMJlMtGvXjjFjxtCnT5+ic9955x2io6NZvHgxr776Kv379+ezzz7j8ssvP+njfPTRR9x1113ce++9OJ1ORo0axfLly5k4cWJtPr1T4lku+tBDDzF58mRatWrFrbfeSkFBgc+bLMCLL74IqCWkubm5nHXWWXz77bc+UwUAr7zyCn5+fsyZM4fc3FwGDhzI559/zkMPPVTtcd51111s376dBx54gKysLHRdR9f1St/+zDPPZO3atTz11FNMnz6djIwMIiIi6NmzJ5dddlml7uP222+nsLCQO++8k5SUFHr16sV3333HqFGjis6pjef++OOPExgYyLx583j//ffp0aMHb7zxRqn29GeeeSafffYZCxYsIDs7m1atWjF27FgefvjhkxYzC1ETNL0qf5VCCHESs2fP5rHHHqvSG74QonmTmhEhhBBC1CsJRoQQQghRr2SaRgghhBD1SjIjQgghhKhXEowIIYQQol5VKxiZN28eHTt2xGq1MmjQIFatWlXuudddd53P1t2eS69evao9aCGEEEI0HVWuGVm6dCnXXHNN0dbcb775JgsWLCA+Pp7Y2NhS52dlZfl0P3Q6nfTr14877riD2bNnV+ox3W43R44cITg4GE3TqjJcIYQQQtQTXdfJycmhTZs2GAwV5D+qus3v0KFD9WnTpvkc69Gjh37//fdX6vZffPGFrmmanpiYWOnHPHjwoA7IRS5ykYtc5CKXRng5ePBghe/zVerAarfbWb9+vc9mXgDjxo1jzZo1lbqPd955h3POOafUFtbF2Ww2n0219BPJm4MHD560tbYQQgghGobs7GxiYmJOuodTlYKR1NRUXC4X0dHRPsejo6PL3BmypOTkZL7//vsy96Qobs6cOaXaSYPaw0OCESGEEKJxOVmJRbUKWEveqa7rlarlWLx4MWFhYVx00UUV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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "quantile_plot(pce, bands=3, xvals=x, xlabel='$x$')" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "id": "f9367274", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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AcgAZLVaLQ8aNEh+6aWX5JKSEsd2qampskqlkmfNmlXt/iUlJXKLFi3kiRMnOm6bPn26DED+/vvvq217/fXXyx07dnT8/I9//EMODg6ut75NmzbJAORNmzY5bnvooYfkut4+bdq0kadPn+74+aeffpIByOvWrXPcZrVa5ZiYGHn8+PFNOo7NZpPj4+Plm2++udrtY8eOldu1ayfb7fY6H09SUpIMQH7kkUeq3f7NN9/IAKrVPnfu3FqPv2jRIhmAfPr0aVmWG/fa1GbZsmU1Hrssy3JBQYGs1+vl66+/vtrtqampslarlSdPnlzvft955x0ZgHzs2DHHbfn5+bJWq5XnzJlT5/2sVqtsNpvl9u3bV3ueql6joUOH1rhPba9fbfstLS2VDQaD/Pbbbztur3o+b7311mrbb926VQYgP//8847bpk+fLrdp08bx87Zt22QA8htvvFHtvmfPnpX1er38+OOP11nPxceuei1lWZaHDRsmA5C3b99ebdsuXbrIY8aMcfy8c+dOGYC8aNGiGvvt1KmT3KtXL9lisVS7fdy4cXJ0dLRss9mqHX/atGn11inLdb8uzz33nAxAXr9+fZ33zcnJkQHIc+fOrfG7S5+DxrzvmvNcQ+KwZcANhIWFYcuWLdi5cydefvll3HzzzTh+/DiefPJJdO/e3fENau3atbBarZg2bRqsVqvjn06nw7Bhw2oMDJIkCTfeeGO12xITE6s10fbr1w+FhYWYNGkSVqxYUeu3tSs1duxYtGjRoto31LVr1yI9PR133313k/apUCjwj3/8A6tWrUJqaioAIDk5GWvWrMGDDz5Yb1/rpk2bAKBGi8TEiRNr7appiMa+Ng21bds2GI3GGjMcYmNjcc0119RoGbnUlClToNVqq30T/e6772AymTBjxgzHbVarFS+++CK6dOkCjUYDlUoFjUaDEydO1NodMX78+AbVX1pain//+99ISEiASqWCSqWCv78/ysrKat3vpa/JoEGD0KZNG8drVptVq1ZBkiTceeed1Z77Fi1aoEePHk1+7lu0aIF+/fpVu+3Sv5+6nDx5EkePHnU8novruv7665GRkVGjxaW257Shr8vq1avRoUMHjBo1qikPtYbGvu/c5VxDTccw4Eauuuoq/Pvf/8ayZcuQnp6ORx55BCkpKY5BhFXNnX379oVara72b+nSpTX+uPz8/KDT6ardptVqUVFR4fh56tSp+Pzzz3HmzBmMHz8ekZGR6N+/P9avX99sj0ulUmHq1KlYvny5o7l38eLFiI6OxpgxY5q837vvvht6vR4ffvghgMomdr1ef9mAkZeXB6DyZH9pnWFhYU2qpbGvTUNV1VpbF0xMTIzj93UJDQ3FTTfdhC+//BI2mw1A5XPfr18/dO3a1bHdo48+imeffRa33HILVq5cie3bt2Pnzp3o0aMHjEZjjf02dNT55MmT8e677+Lee+/F2rVrsWPHDuzcuRMRERG17vfS16TqtvoeZ1ZWFmRZRlRUVI3n/q+//mryc1/be0Gr1dZad201AcC//vWvGjU9+OCDAFCjrtqe04a+Ljk5OWjVqlWjHl99Gvu+c5dzDTUdZxO4KbVajblz52LhwoU4dOgQACA8PBwA8MMPP6BNmzbNdqwZM2ZgxowZKCsrw++//465c+di3LhxOH78eLMdZ8aMGXjttdewZMkS3HHHHfjpp58we/ZsKJXKJu8zKCgI06dPx6effop//etfWLRoESZPnozg4OB671d1ks/MzETLli0dt1ut1honuaoTnMlkglarddx+6YncWa9NVa0ZGRk1fpeenu44bn1mzJiBZcuWYf369WjdujV27tyJDz74oNo2X3/9NaZNm+YYu1AlNze31uezIaPci4qKsGrVKsydOxdPPPGE43aTyYT8/Pxa75OZmVnrbQkJCXUeJzw8HJIkYcuWLdVeoyq13eZsVa/Lk08+idtuu63WbTp27Fjt59qe04a+LhEREUhLS7vCqi9ojvddbVxxrqGmYRhwA1UDfC5V1QwYExMDABgzZgxUKhWSk5Mb3EzbGAaDAWPHjoXZbMYtt9yCw4cP1/kHWnWCNRqN0Ov1l913586d0b9/fyxatAg2m61GM3VdLnecf/7zn3j//fcxYcIEFBYW4h//+Mdl9zl8+HAAwDfffIM+ffo4bv/+++9htVqrbVu1uM2BAwccI8cBYOXKldW2u9LX5uLHebGBAwdCr9fj66+/dsw4AIC0tDRs3LjRMcCyPqNHj0bLli2xaNEitG7dGjqdDpMmTaq2jSRJNT40f/75Z5w7d67eD+L6SJIEWZZr7PfTTz91tFJc6ptvvqn2/P355584c+aMY1BebcaNG4eXX34Z586dw8SJE5tUa1PV9bp17NgR7du3x/79+2t8kDdGQ1+XsWPH4j//+Q82btyIa665plG11qY53nf1acy5hlyDYcANjBkzBq1atcKNN96ITp06wW63Y9++fXjjjTfg7++Phx9+GEDlB9Nzzz2Hp59+GqdOncJ1112HkJAQZGVlYceOHTAYDI1eoOe+++6DXq/H4MGDER0djczMTLz00ksICgqq9uF3qe7duwMAXnnlFYwdOxZKpRKJiYnQaDR13ufuu+/GzJkzkZ6ejkGDBtX4ZtSU43To0AHXXXcdVq9ejauvvho9evS47D47d+6MO++8E2+99RbUajVGjRqFQ4cO4fXXX0dgYGC1ba+//nqEhobinnvuwXPPPQeVSoXFixfj7Nmz1ba70temW7duAICPP/4YAQEB0Ol0aNu2LcLCwvDss8/iqaeewrRp0zBp0iTk5eVh/vz50Ol0mDt37mUfr1KpxLRp0/Dmm28iMDAQt912G4KCgqptM27cOCxevBidOnVCYmIidu/ejddee+2Kmp4DAwMxdOhQvPbaawgPD0dcXBx+++03fPbZZ3W23uzatQv33nsvbr/9dpw9exZPP/00WrZs6Whar83gwYPx97//HTNmzMCuXbswdOhQGAwGZGRk4I8//kD37t3xwAMPNPlx1Kddu3bQ6/X45ptv0LlzZ/j7+yMmJgYxMTH46KOPMHbsWIwZMwZ33XUXWrZsifz8fCQlJWHPnj1YtmzZZfff0Ndl9uzZWLp0KW6++WY88cQT6NevH4xGI3777TeMGzcOI0aMQEBAANq0aYMVK1Zg5MiRCA0NdbwulwoODr7i992lmnquIRcRPYKRZHnp0qXy5MmT5fbt28v+/v6yWq2WW7duLU+dOlU+cuRIje1//PFHecSIEXJgYKCs1WrlNm3ayBMmTJA3bNjg2Gb69OmywWCocd9LR8d/8cUX8ogRI+SoqChZo9HIMTEx8sSJE+UDBw44tqltlLjJZJLvvfdeOSIiQpYkqdpI5EtnE1QpKiqS9Xq9DED+5JNPavy+scepsnjxYhmAvGTJkhr7rIvJZJLnzJkjR0ZGyjqdTh4wYIC8bdu2WmvfsWOHPGjQINlgMMgtW7aU586dK3/66ae11tKQ16Yub731lty2bVtZqVTWGKH+6aefyomJibJGo5GDgoLkm2++WT58+HCDH+/x48cds1VqG3FeUFAg33PPPXJkZKTs5+cnX3311fKWLVvkYcOGycOGDXNsV/UaLVu2rMY+anv90tLS5PHjx8shISFyQECAfN1118mHDh2q8TxXjWZft26dPHXqVDk4ONgxmv3EiRPVjnPpbIIqn3/+udy/f3/ZYDDIer1ebteunTxt2jR5165d9T43dc0m6Nq1a41tazv2d999J3fq1ElWq9U1Ruvv379fnjhxohwZGSmr1Wq5RYsW8jXXXCN/+OGHNY6/c+fOGsdr6OtSte3DDz8st27dWlar1XJkZKR8ww03yEePHnVss2HDBrlXr16yVqutNnOmtudAlhv2vmvOcw2JI8nyJau2EHmY8ePH46+//kJKSgrUarXocoiIPA5nE5BHMplM2LZtG95++20sX74cjz32GIPAFRo+fDhmz57d5Ps05f5E5B44ZoA8UkZGBgYNGoTAwEDMnDkTs2bNEl0SEZHHYhggjxQXF1fjugRERNQ0HDNARAAqV4xLS0tDYWFhtaAVGBiIIUOG4O2330a7du2q3Uer1cJsNtfYl0KhQHBwMB544AEsWLCg2hz6uLi4Wlfx46mISByOGSAiAIDNZkNpaSmGDRuGe++917Egk1arhSRJuPXWW2tcbKpPnz7w8/PDlClT0KVLF8ftQ4cOxTvvvIOFCxfi008/rXafnTt3IiMjAxkZGUhLS8OAAQMwZMgQ5z9AIqoTWwaICEDlAMDs7GwcPnwYkiQhJyfHcTXC3377DcOGDcPBgwcdayJcep9WrVohPT3dcbniI0eO4IknnsBPP/1U51UbH374YaxYscKxRDERicGWASICULkyXWlpKQICAqBQKKpdlvjaa68FAMdFoS42YMAAfPLJJ8jIyEBAQABeeuklnDhxAjabzXG529pWHPz444/x2WefYcWKFQwCRIIxDBARAODQoUPIyMhAp06d0KJFC/Ts2dPxu6rr0tc2PiAjI8NxpcjRo0c3aHnqzZs3Y9asWfjyyy8btGokETkXwwARIS8vD+Xl5bBarZg3bx4yMjKqXQ+gvLy81vsZjUasXbsWsiyjW7duOHLkCP766y+0b98eSqWy2n9XOXnyJMaPH4+nnnqqzov4EJFrccwAEcFut0Or1cJqtSI+Pt5xtbqqi9okJCTg5MmTWL58OW655RbH70JDQ1FRUYFevXrBbDbj+PHjkGUZc+bMQY8ePXDffffhjTfewMyZMx336d27N2JiYvD1119Xm2VQ2+WLicg1GAaICADQo0cPnDp1CqWlpTV+t2DBAjz77LPVwkBKSgratm1b674UCgWCgoIwc+ZMvPjii44P/fruw1MRkTgMA0RERD6OYwaIyCekpKRAkqQa/4YPHy66NCLhuBwxEfmE2NhYx1gIAMjMzMSoUaMwdOhQgVURuQd2ExCRz6moqMDw4cMRERGBFStWQKFgIyn5NrYMEJHPueeee1BSUoL169czCBCBYYCIfMzzzz+PNWvWYMeOHQgICBBdDpFbYDcBEfmM//73v5g0aRJWr16NkSNHii6HyG0wDBCRTzh06BD69++PRx99FA899JDjdo1Gg9DQUIGVEYnHMEBEPmHx4sWYMWNGjduHDRuGzZs3u74gIjfCMEBEROTjOIyWiIjIxzEMEBER+ThOLSTyAhUWGwrLLcgvM6Ow3IyCcgsKys0oKKv878JyMwqNFpisNtjsMux2wCbLsNllSHY7/q4uhMoagYQtCyGp1Ng1ti02RxdAq9RCp9JBr9JDp9TBoDYgTB+GCH0EIvwiEK4PR7g+HCoFTyVEnox/wUQeIL/MjNO5pUjOKcOpnDKczi1FWoHR8WFvtNiavG8VgJKAQijMgajYfwAAkNXbjt9sBxt0fwkSQnQhCNeHI0JfGRCqgkKMIQYJwQloFdCq2uWKici9MAwQuQmT1YaU3HKcyinFqdzKD/1TuaU4nVuGwnKLcw8uA5AujCU2KeyNuKuM/Ip85Ffk43jB8Vq30av0aBvUFgnBCUgITkC74HZoH9we0f7RV1o5ETUDhgEiAWRZxsnsUuw6U4DdZwqwJ7UAKbllsAub2yNBcdEXd5Oy4WGgIYxWI47kHcGRvCPVbvdX+yM+ON4RErqHd0fX8K5QK9TNenwiqh/DAJELGM027DtbiN1n8s9/+BeiyOjkb/uNIF/0vwBgkpo3DNSl1FKKAzkHcCDngOM2vUqPxPBE9Inqg6taXIXEiERolVqX1EPkqxgGiJwgu7gCO1LysSul8lv/kfRiWMV97b8s6fy/KiZF08cgXCmj1YjtmduxPXM7sB9QK9ToHt4dfaL6oE9UH/SK7AU/tZ+w+oi8EcMAUTOw22XsPVuITUez8evRbCRlFIsuqdGki8YMVAgMA5ey2C3Yk70He7L34JODn0AlqdAptBP6RvfF8FbD0TOyJxQSZ0kTXQmGAaImKjNZ8dvxHGxIysJvx3KQV2YWXdIVkKq1DFQorMIquRyrbMWhvEM4lHcIiw4tQqguFENbDcWI2BEYGDMQepVedIlEHodhgKgRiowWbDiShTWHM/H78RyYrK7pW3cFqdqYAfdpGbic/Ip8/HjyR/x48kfolDoMihmE0XGjMTx2OAxqg+jyiDwCwwDRZZSZrPj5QAZWHczAtuRcWGzu2/ffVDKqhwGjG3UTNEaFrQIbz27ExrMboVVqMThmMEbHjcaI2BEcZ0BUD4YBojrsTS3Akh1nsepAOsrMnvnh2FCVAwgvGjMA95np0FQmm6laMLi2zbWY0GEC+kT1EV0akdthGCC6SFG5Bf/bm4alO8/iaGaJ6HJcR3b8DwDA6MZjBprCZDNh1alVWHVqFdoFtcOEDhNwY7sbEaQNEl0akVtgGCACsC05D0t2pmLNoUyvGgfQYJJ08QKEKJc8v2WgLslFyXhl5yt4a89bGN1mNG7veDt6RfYSXRaRUAwD5LNySkz4YXcavt91Fqdzy0SXI5QsAxIuhKByyZNnRjSMyWbCylMrsfLUSiQEJzhaCwI1gaJLI3I5SZZl7xsNRVSP41kleG/TSfxyMMMrBwM2lgrAC4YiBMqhiPv2EUCSMPEJpeiyhNApdRgdNxrTu05Hh5AOosshchm2DJDPOJBWiHc3nsT6pCwwAtdU1TIgqdUAfLCrBJWzEX5K/gkrk1dieOxwzEycia7hXUWXReR0DAPk9Xaczse7m07i9+M5oktxb1UBSaMGYBJZiXAyZGw6uwmbzm7C4JaDcX/i/egZ2VN0WUROwzBAXuv34zl4d+NJ7EjJF12K25MgQaq6OJGaYeBiW89txdZzW9G3RV/MTJyJ/tH9RZdE1OwYBsiryLKM9Uey8N6mk9ifViS6HI8hA5Cq+k7UPC3UZmfmTuzM3ImeET1xX+J9GNpqqOiSiJoN/+rJa/xyMAPv/HrCt9YHaEaORYfUarGFuLl9Ofvw0K8PoXNoZ9zf435c0/oa0SURXTGGAfJ4h84VYf7Kw9iZUiC6FA8mAfL5bgKVb84kaKyk/CQ8vOlh9G3RF//u+290DO0ouiSiJmMYII+VW2rCa2uOYdnus7BzdsAVkWXZ0TIga3haaIydmTtxx6o7cFv72zCr1yyE6EJEl0TUaPyrJ49jsdmxeGsK3tl4AiUV3rVsrigSpAthQMXTQmPZZBuWHV+GNSlrcH/i/ZjUeRLUCna3kOdQiC6AqDF+TcrCmIW/44VfkhgEmpl0vpvArmY3QVOVmEvw2q7XMP6n8fjj3B+iyyFqMH4FII9wMrsUC1YdwW9cK8A5pAuzCewqfke4UqeLTuOBDQ9gSMsheKzvY2gb1FZ0SUT1Yhggt1ZcYcFb60/gy20psHJggNPIsoSqVQftHEDYbLac24JtGdswudNkPNTzIfip/USXRFQrfgUgt7XhSBZGvfEbPt96mkHABRwtA+wmaFZWuxVfHvkSt664FX+m/ym6HKJaMQyQ2yksN2P2kr2498tdyC7hSniu4hgzoJQEV+Kd0svSMXP9TMz9cy5KzFwLg9wLwwC5lXWHM3Htwt/x47500aX4GNmxzoBNzdOCM/3vxP9wy4pb8Hva76JLIXLgXz25hSKjBY8s3Ye/f7UbOWwNcLmLpxZalTwtOFt2eTaO7/wAWPEQYGIrAYnHAYQk3LbkPPxr2X6cKzSKLsVnVV6b4HzLAIcMOF1iYDxmHFgLyDbg9O/ALR8CcYNFl0U+jF8BSBiz1Y6XfknClE//YhBwA1VhwKrimAFn0iq1WJCRBqVsq7yhMBX4Yhyw7hnAZhFbHPkshgES4nhWCW5+bys++v0UlxJ2CxJgZxhwhVl+CYjPPln9RtkO/Pl/wOfXAYVnxRRGPo1hgFxu+d403PTuH0jKKBZdCp0ny4B0fp0BK7sJnKZ3UAKmHlxb9wbndgEfDQVOrHddUURgGCAXstrsmL/yMB5Zuh8VFrvocugiEuCYTWDhWcEp9EodFqSdhkK+zHvfmA98czvw63OA3eaa4sjn8c+eXCKv1IQ7P9uORVtTRJdCdZDOdxNYOKzYKWbr26J17ukGbi0DW94AvrwZKMlyal1EAMMAucDBtCLc9O5W/HUqX3QpVBcJqFqO2KLgII7m1j+oAyYdXNf4O6ZsAT4aAqTwokfkXAwD5FT/25OGCR/+ydkC7k6WLrQMKBkGmpNB5Yfnzhx3rOPQaKVZwBc3AX++27yFEV2EYYCcwmqzY95Ph/Ho9/thsnJ8gLurXGegsn/azDDQrP6liUVMQeqV7US2AeueBlY9Ath46W5qfuwdpGaXV2rCg9/swfbT7BbwKOfneJrZTdBsBgd3woS9TegeqMuuz4GCFOD2LwBdYPPtl3weWwaoWR1MK8KN//cHg4AHqmoZMCk4gr05BKj9Mf/UoebfcfJG4LPRlYsVETUThgFqNltO5OCOj7chvahCdCnUFOenvLGboHk8oYxGVJGTLriVkwR8MhJI2+Wc/ZPPYRigZvHLwQzcs3gXys38VumRZAmSnS0DzWV4cBfclPSrcw9Slg0sHgccXu7c45BPYBigK7ZkRypmfbcXZhsHCnq08y0DJgVfxysRrAnC3BN7XHMwqxFYNgPY+o5rjkdei2GArshHvyXjif8dhI0XGPBs0oVFhyokjla/Ek8jDOGl2S48ogysfxbY9KILj0nehmGAmuyVNUfx0uqjosugZiDLqJy+BrYMXInRIV1x3bHNYg7+2yvA2qfFHJs8HqcWUqPZ7TKeWXEI327naGbvcWHMgFHBloGmCNWG4JljO8QWse1dwFwGjFsISLz6JDUcwwA1isVmx+yl+/DzgQzRpVCzkh1hoEKyCK7FM/3HFoiQsjzRZQC7FwEWI3DL+4CCl6CkhmE3ATWY0WzDvV/sYhDwQpVXLawc92HkbIJGGxfSDSNPbBFdxgUHlgDLpgNWs+hKyEMwDFCDGM02TPt8O347niO6FHIKCdL5ZW6NYDdBY0TqwvBk0lbRZdSUtBJYMhmwcN0PujyGAboss9WOmV/vxs6UAtGlkJNUDiCsHDhoVLCboDHmmXUINBaJLqN2J9cD308DbHxNqX4MA1Qvu13GI9/vw+9sEfB+jpYBfnA01G0h3TEkeZvoMup3Yi2w/H7AzlkiVDeGAarXMysOcYyAj5CqWgY4gLBBovUReOyIG40TqM+hH4Bf5oiugtwYwwDV6bW1Rzl90GdIgN0GqNWQOSPtsiRIeM6ohH9FsehSGm7X58D6uaKrIDfFMEC1+nTLKby3KVl0GeRKdhsktVp0FR5hYkg3DDgteE2Bptj6FvDHQtFVkBtiGKAalu06ixd+SRJdBrmYZLcDGoaBy4n1a4FHD20WXUbTbZhX2UpAdBGGAapm7eFMPPG/g1VTzskHVL3Uks0KsGWgXgpJgQUlNviZy0SXcmV+ngMc/EF0FeRGGAbI4c/kXMz6bi8vOuRjJMiVicBuA9RclLQ+U4K6oU/qbtFlXDnZDvz4IHDWA7s6yCkYBggAcOhcEf7+5W6YrZx+5JukyqmFDAN1ijO0xMMHN4guo/nYTJWLEhWeFV0JuQGGAUJOiQn3fbkLpSauPOerZACQbZAZBmqllJR4obAcWquXreZXlgN8ewdgKhVdCQnGMODjzFY77v96NzKKvOwkR40m2WyQVbywTW3uCuqCxLT9ostwjuzDwH/v5aJEPo5hwMc9++Mh7D7DZYYJgN0KWc0wcKkE/1g8dGC96DKc6/hqYMN/RFdBArFN0Ict3noaS3exv9Bb5Kx4BeXH/sDFU0FUITEIG/tP6GK71di+cOt3KPrjWwAy7kTllQu7h4WgpE0gAroHIGdVDrL+lwVUfWGUgKABQWh5T0tYi6w4/vhxqAJUkFQS2j7ZFpowjSsepkupJBVeyCuE2uYDV//78/+A8I5A76miKyEB2DLgo7Yl5+H5n7mWgLfI3/ARyo9ucQQBhSEEAGAtyEDW93NhLc6utr0x9SCK/vgGUKqhbdkZOo2+ckIBgNS3UlF2qgxZ/82qTAgqABIgqSWUHS5DweYCpLyeAlWwCuowNcJGhXllEACA+wI7o0v6YdFluM6qR4AUN7wCIzkdw4APyiyqwKzv9sDKKYReo/TAekClgcIvCP49xyL2H18BChWgVENSaVCy95dq2xduXgQoVGjzr/+h1Z2vIi46HoEqFZKLSqCJ0qBoa1HlqEIbACuga6ODQqOAKliFwh2FsORYACVgt9oRNjpMyGN2ts4BbXDfgXWiy3AtuwVYdhdQmn3ZTcm7MAz4GIvNjoe+3YPcUh9o9vQRdnM5ZEsFYDXDXl4MfdteAAB1eCwg26FQqWE6d7TafSx5aZW/v0grrQ5GqxXWcivUUerK1gCtBOgB0zkTZFmGpcwC40kjFP4KSJDQ6q5WkBTedzEDtUKNF7Kyobb74EWbyrI5oNAHMQz4mBd+TuKAQS9jyU+/6CcZCr/KLgKlXzAg2yHbrLCVVX/NZaup8vcX7gZ/ReXgQXuFHSEDQhB9Z3Rlv4ERkC0y7BY7JJsEpb8SCp0CllwLkucn49CMQ0ialYS8DXlOfZyu9KB/R7TPOia6DHFO/wZseV10FeRCHEDoQ37an47Ff6aILoOcTKr6ol5tTenLf3vPM1e2FrW4owVUgSqEjQxD2MgLXQAlB0twZuEZKIOUsGRaoDAoIKkk2IpssJXbkPF1BjKWZEAfp0f05Gj4xfvVeayyo2XI+C4DpnMmqEJUiBgbgdBrQh2/Lz1UivSv0mEttiKwdyBiZsRAoar87mIrtyF5fjLiHo9zyliFxMB4zDiwttn363E2vwy0GQTEXS26EnIBtgz4iFM5pXjivwdEl0FOoA6NuegnydEKYDMWAZICklIFpSG42n0klRa28kLHz8XlRThlMgIAQgaG1DiG3W7H2ffPQhWsgqSpDBb2MjtsRTZIagmQAXWkGhHXR8C/qz9SXkuBpaD2JnZzjhkpb6bA0MGAds+1Q8S4CGR8k4GinUUAANku4+xHZxE6IhTxz8TDeMqIgs0XWjYyv89E6IhQpwQBrVKLBRlpUMq2Zt+3x5Ftld0FZbmiKyEXYBjwATa7jEe/349yM09w3kih8YOk1p0fQBgIY8o+AIAl7ywgKSBbLdC27FTtPuqwVpW/B1By5Ddk5J6DXqGAXq2CQlfztHDus3OABKgCVNCF66r9TrbIUOgUUKgVUBqUiLo1CppwDfI35tdab/6mfGjCNIieEg1djA6hw0IRPCQYuWsqP3RspTbYSmwIvSYUupY6BPQKgCndBAAoO1EGY4rRaYMWZ/klID77pFP27ZFKMoD//R3OvnLZ8OHDMXv2bKceg+rHMOADPvwtGfvOFooug5zIP/Ha8wMIi1C69xecfXdq5bUGbBbYrWYYT+9B6lsTkf7Zg8hd9QaCh88AbFakvTsN2Stfh1qlQbndjqviY1B6tBS28gvBseJcBYq2FQEqwFpkRct7W0JSSZA00oVWggo7zDlm+LWv7BqQNBLKjtd+Zb/yk+Xw7+Zf7baA7gEwphghW2UoA5RQBatQergUdrMdZcfLoIvVwW61I/2LdLSc3tIpgxZ7ByVg6kF2D9SQ/Cvwx5uiqyAnYxjwckkZxXh7wwnRZZCThY6aCb9OQ1A1NsB+vqtAFRKNqInzIZuMkC0m2MqLYS3Ogb51d4SMvA+2sspv72Zr5TfvLcdSkfJyCjK+yXDs+8ybZ6AKUkETokHEuAioQ9SInh4N2SZDNp//xigDodeEQh+nR+GfhTCeMsJaVPu1LqxFVigDq690qApUATbAWmqFJEmIfTAWOT/l4MRTJ6BvrUfIkBDk/pwL/y7+kDQSTj1/CsefON5sgxb1Sh0WpJ2GQuYI+lptfAE4u1N0FeREkizzyvXeymKz46Z3tyIpo1h0KeTGVJAxT2VDnx+ewImJ/fB0uz2Nur8p24Rzn51D+bFyQAHo2+ihaaFBxZkKtH+xfY3tj//7OEKGhCBiXITjtrITZTj9wml0fKsj1MHqmsfINOHMwjNoN78dTr90GmGjwxDQPQAnnj6Bto+3hS5WV+M+jfGkf2dMZqtA/cI7ADO3AOore65rM3z4cHTrVrlK5tdffw2lUokHHngACxYsgCR539RVd8SWAS/29oYTDALUQJUnXEsTLk2gjdQi/sl4dPmoCzq+2RHt5raDbJOhDq/5oQ4AqiBVjVYDW7ENUAIq/5oTnGRZxrlF59Diby0AGag4U4Ggq4KgClTB0NGAsqO1d0c0VP+gDph00McWF2qK3OPA5hedtvsvvvgCKpUK27dvxzvvvIOFCxfi008/ddrxqDqGAS+172whPvgtWXQZ5CGqvnxZlE1vKFRoFVAHq2Ers6H0YCkCewfWup1fgh9KD1e/ZG7poVLo4/SQVDW/BRb8XgCVvwqBvQId10mQbbLj/+UrWEnToPLDc2eOQwIbSBvkz3eBtN1O2XVsbCwWLlyIjh07YsqUKZg1axYWLlzolGNRTQwDXqjCYsOc7/fBxuWGqYGuJAyUHCxByYESmHPMKD1UitMvn4Y2WouQqyunKGYuy0Tax2mO7UNHhMKca0bGdxmoSK9Awe8FKPi9AOHXhdfYt7XYipyfcioXQAKgNCihjdEib10eyk+WoyypzDFosSn+pYlFTEFqk+/vc2QbsOJB4PwYk+Y0YMCAal0CAwcOxIkTJ2CzcRaUK3DRIS/02tpjSM65sqZT8jHnz8FmRePDgN1oR+ayTFgLrFAalAi8KhBR46Mc3/KthVaY8y4sf62J0CDu0ThkfJeB/F/zoQpWIXpKNIL6BtXYd8Y3GQgfGw51yIUuh5b3tsS5T84hb30ewseG17u4UX0GB3fChL3sHmi0nKOVCxKNmiu6EmpGDANeZvupPCzaelp0GeRhpPNpoClhIKhfEIL61fwgr9LqvlY1bjN0MiBhfsJl9x37QGyN2/zi/dD+pZoDExsjQO2P+acOXdE+fNqf7wBdbgJiejXbLv/6668aP7dv3x5KZRMGslCjsZvAi5SbrXjshwNg7wA1WlXLgNI3ptY9oYxGVFH65Tek2tmtwI8PAdbmu+DZ2bNn8eijj+LYsWP47rvv8H//9394+OGHm23/VD+2DHiRdzeeRGp+uegyyANVDaAz+UAYGB7cBTftXSO6DM+XfRjY+hYw7PFm2d20adNgNBrRr18/KJVKzJo1C3//+9+bZd90eQwDXuJsfjk+/YPdA9Q0VQO3TJJ3D9YK1gRh7onGraNA9djyJpB4BxDS5op2s3nzZsd/f/DBB1dYFDUFuwm8xAs/J8Fs9f5vdeQcVWO4vb1l4GmEIbw0W3QZ3sNqBNY+JboKagYMA15gW3Ie1hzOFF0GebLzacAkeW8YGB3SFdcd2yy6DO9zdBVwYoPoKugKMQx4OJtdxnOrjogugzycJFWOGahQ1H49AU8Xqg3BM8d2iC7De61+HLDVfslq8gwMAx5uyc5ULjlMV6xqamGF5J1h4D+2QISUNc9FjagW+cnA9o9EV0FXgGHAgxVXWPDmuuOiyyAvUDVmoELhfQMIx4V0w8gTW0SX4f1+exVg4PJYDAMe7O0NJ5BX1nzzfImMXtYyEKkLw5NJW0WX4RtMRcCm50VXQU3EMOChknNK8eW2FNFlkJeoWhLe27oJ5pl1CDQWiS7Dd+z+Asg+KroKagKGAQ/1ws9JsNi41CA1j6pFh7ypZeC2kO4YkrxNdBm+RbYBm18SXQU1AcOAB/r9eA42HuVcaWpG55sGyhXe0e0UrY/AY0c4TkCIIyuAzIOiq6BGYhjwQG+u56BBal4XWgY8f3qYBAnPGZXwr+AsGzFkYBNbBzwNw4CH+fNkLvadLRRdBnkZCQBUKtjg+V1PE0O6YcBprikg1LGfgXNc9tmTMAx4mHc3nRRdAnkpSa0WXcIVi/VrgUcPbRZdBgHAphdFV0CNwDDgQfakFuDPZM7jpeYnQQY0nh0GFJICC0ps8DOXiS6FAODkeuAsW2g8BcOAB3lvI1sFyDkkSIDasy9iOiWoG/qk7hZdBl1sI9cd8BQMAx4iKaMYG49xBgE5hwQZ8OBugjhDSzx8kBfLcTunfwNSuOiTJ2AY8BDvbToJ2fPHdpG7kmSPbRlQSkq8UFgOrbVCdClUm61vi66AGoBhwAOcyinFLwczRJdBXk5WeWYYuCuoCxLT9osug+pyYh2Qe0J0FXQZDAMe4IPNybCzVYCcSIIMWa0UXUajJfjH4qED60WXQfWSgb8+EF0EXQbDgJs7V2jEj/vOiS6DvJwEQPawbgKVpMILeYVQ27xj1USvtv87oDxfdBVUD4YBN/fxb8m8BgE5nyzDrvKs08F9gZ3RJf2w6DKoISzlwO5FoqugenjWX7+PKTJa8P2uNNFlkA+QANg9qJugc0Ab3HdgnegyqDF2fALYPH+5a2/FMODGlu9Jg9FiE10G+QJJhl3lGWFArVDjhaxsqO38YPEoJRnAof+JroLqwDDgxr7dkSq6BPIRkizD5iHdBA/6d0T7rGOiy6Cm+Os90RVQHTzjr98H7Tidj+NZpaLLIB8hAbArJdFlXFZiYDxmHFgrugxqqoz9QOpfoqugWjAMuKlvtp8RXQL5FBk2tXufDrRKLRZkpEEps+vMo+39WnQFVAv3/uv3UfllZqw+lCm6DPIhkizD6uYtA7P82iE+m9fn8HiHfwTM5aKroEswDLih5XvPwWy1iy6DfIzNjcNA76AETD3I2QNewVwCJP0kugq6BMOAG/phN6cTkmtJsMOqcs8woFfqsCDtNBQyA7LXYFeB22EYcDOH04uQlFEsugzyNTJgddMFCGfr26J17mnRZVBzSvkDKOC4KHfCMOBmlnGRIRJAggyLG54N+gd1wCR2D3ghuXKJYnIbbvjn77ssNjt+2p8uugzyNRIgyXZY3WzNIYPKD8+dOQ4JXI7bK+37Brwuu/tgGHAjG49mI7+MF10hAWTA4mbdBP/SxCKmwLULb/1+xoobvytHzBslkOYX48ejda9yOHOlEdL8Yrz1l6nefX6y24whi8oQ8koxQl4pxqgvy7DjXPXpkd8csCB2YQlCXynGY+sqqv0updCODv9XimKTl31wFqYCKVtEV0HnMQy4kdUHM0SXQD5KATvMCvf5sBkc3AkTDrv+0sRlZhk9ohR493pdvdv9eNSC7edsiAm4/KDLzWesmNRNjU3TDdh2jwGtgxQY/VUZzhVXDojMLbfj3pVGvH6tDmvvNOCL/Rb8fPxCCHngZyNeHqVFoNY9B3hekYM/iK6AznOz7wK+y2qzY9OxHNFlkA8zK9xjtH6A2h/zTx0Scuyx7dUY2159/idjrducK7bjH79UYO2dfrjh28vPl//mNr9qP39yow4/HLHg19NWTOuhwakCGUFaCXd0qzzuiLZKHMmx44YOwLcHLdAoJdzWWV3brj3fsdWA3Q4o+L1UNL4CbmJHSj6KjLzwCokhyXaYle7RMvCEMhpRRe45dsYuy5i63IjHBmnQNbJpgyzKLYDFDoTqK7/ptw9VoNwiY2+GDflGGTvP2ZAYpUS+UcZ/NlXg3bH1t1J4tLJsIG2H6CoIbBlwG+uPZIkugXyZLLtFGBge3AU37V0juow6vfKHGSoF8M/+mibv44kNFWgZIGFUfOXpN0Qv4Ytb9Jj2oxFGi4xpPdQYk6DC3SuMmNVPg9OFdty0pBwWGzBvuBYTunhZK0HSSqD1ANFV+DyGATfxa1K26BLIh0myHWaF2DX/gzVBmHtij9Aa6rM73Ya3t5uxZ6YBktS0/vtXt5rw3SELNt9lgO6iRZ5u7azGrRd1BWxOseJgtg3vXq9Dwjul+G68Hi38JfT7tAxD2ygRafCiRt2jPwNjXhBdhc9jGHADxzJLkJrPtbpJIFmGSfCYgacRhvDSg0JrqM+WVCuyy2S0XnjhaqI2GZizzoS3/jIjZXZAvfd//U8TXtxiwoZpBiRG1d3FYLLKePDnCnx9mx4n8+2w2oFhcZWn6g5hCmxPs+HGjl4UBgpOA1mHgaiuoivxaQwDbmD9EV6UiEQTGwZGh3TFdXtWCzt+Q0xNVDua9quM+bocUxPVmNGz/qb717aa8PwWE9be6YerYuofa7DgdxPGJqjQO1qJvRk2WO0Xum8stsoA4nWSVjEMCMYw4AbWs4uABJMgo0JhFXLsUG0InjnmHoPISs0yTuZfCEWnC+zYl2lDqF5C6yAFwqpPDIBaAbTwl9Ax/MIH/LTlRrQMkPDSqMqBf69uNeHZTSZ8e5seccEKZJZW7t9fI8FfU7274XC2DUsPW7FvpgEA0ClcAYUk4bM9ZrTwl3A0146+lwkTHunoSmD4v0VX4dMYBgTLLq7AgbRC0WWQr7PLMEliWgb+YwtESFmekGNfale6DSO+uNBl9+g6EwATpvdQY/Et+gbtI7XIDoV0oRn//Z1mmG3AhGXVpyrOHabBvOEXZgrIsoy/r6rAwjFaGM6HBL1awuJbdHjolwqYrMC71+vQMtCLugiqZB6svFZBSBvRlfgsSZa5HqRI325PxVPL3beflLyfSpKxSDqLr9usxJ+6sy499riQbnhpzy8uPSa5qRveBPreI7oKn+WFEdOzcLwAuQNJlmF0cTdBpC4MTyZtdekxyY1xaWKhGAYEMppt+DPZPZpHycfJMiok1y56Nc+sQ6CxyKXHJDeW8ofoCnwaw4BAe1ILYLK6xxKw5Nsk2GCUXNcycFtIdwxJ3uay45EHKMsBspNEV+GzGAYE2n2mQHQJRAAAyQ6UK1zTMhCtj8BjR9gkTLU4zfeFKAwDAjEMkNuQbaiA81sGJEh4zqiEf0Wx049FHijld9EV+CyGAUFkWcbeVIYBchOyjHIXjBmYGNINA067x5oC5IZStgKc4CYEw4AgJ7NLUVwhZpEXohpkGVYnrzMQ69cCjx7a7NRjkIcz5gNZYi5f7esYBgRhFwG5FScvaqeQFFhQYoOfucy5ByLPx3EDQjAMCMIwQG6laRfha7ApQd3QJ3W3cw9C3uHsX6Ir8EkMA4Ls5ngBciOywnlpIM7QEg8f3OC0/ZOXydgvugKfxDAgQEGZGadz2VxK7kNWOGfQllJS4oXCcmitFU7ZP3mhghTAWCi6Cp/DMCDAntQCDpgltyJLznlD3hXUBYlp/KZHjcTWAZdjGBCA4wXI3ciK5j8VJPjH4qED65t9v+QDGAZcjmFAgD0cL0Buxt7M3QQqSYUX8gqhtpmbdb/kIxgGXI5hQIAj6Vx9jdxMM3cT3BfYGV3SDzfrPsmHMAy4HMOAi+WWmrjYELkdezOeCToHtMF9B9Y13w7J9+QnA6ZS0VX4FIYBF+MsAnJH9mZqGVAr1HghKxtqu2svh0xeRrYDmQdFV+FTGAZc7HQOwwC5H1sznQke9O+I9lnHmmdn5Nu4LLFLMQy42Cm2DJA7aobrEiQGxmPGgbXNUAwRgPzToivwKQwDLnY6l/1g5H5sVzibQKvUYkFGGpSyrZkqIp9XwDDgSgwDLsYxA+SObIoraxmY5dcO8dknm6kaIgD5p0RX4FMYBlzIbpdxJq9cdBlENVxJy0DvoARMPcjZA9TMClLApVpdh2HAhc4VGmGyOvea8URNYWvimAG9UocFaaehkPm+pmZmrQCK00VX4TMYBlyIgwfJXdmaOLVwtr4tWueyb5echOMGXIZhwIVO53DwILknm6LxA//6B3XAJHYPkDNx3IDLMAy4EAcPkruyonHN/AaVH547cxwS2KdLTsTphS7DMOBCqfkcPEjuySo1rmXgX5pYxBSkOqkaovMKUkRX4DMYBlwop9QkugSiWlkbMZtgcHAnTDjMSxOTC5Rkiq7AZzAMuFBeKS/nSu6poS0DAWp/zD/FZWLJRcqyRVfgMxgGXCivjGGA3JMFDbuS5hPKaEQVcboXuUhpjugKfAbDgIsUV1hg5hoD5KYsDZhNMDy4C25K+tUF1RCdZyoCrOxedQWV6AJ8BbsIyJ2ZpfpbBoI1QZh7Yo+LqiFfIav9YNOFwKwNhVEdglJlMIoVgciTA5FrC0Cm1YA7Si2ICNaKLtXrMQy4SH4Z0y25r8uNGXgaYQgv5fXlqX6yNhBWXRhMmhCUq0NQqgxCoRSIPHsgcmwGZNj8cc5kQEqFHqfL9SioUAEl9e/zmnI7IoJdUr5PYxhwkSKjRXQJRHWqr2VgdEhXXLdntQurIXcgSwrIulBYdKEwaUJQpgpGsSIIhQhCnmxAli0AGRYDzpr8kGL0Q4pRC2OFEihq3joKjWxVdQWGARcpqWjYAC0iEUxS7WE1VBuCZ47tcHE15AyyUgO7PgxmbSgq1MEoVQWjWApEAQKRKwcg0+KPdIs/Uiv0SDHqcbZCA5tR/LCyYn6RcgmGARfhG5rcmQW1dxP8xxaIkLI8F1dDDSFrDLDpwmDShsKoDkaJIhjFUgDyEIgcWwAyrf5IM/shtcIPKUYdsso0gAcuglpYznOnKzAMuEgxWwbIjZlq6SYYF9INI/f8IqAa3yNDgqwLhvV8k3y5KhglyiAUSkHIswcg2+aPdKsBaSYDUiv0OFWuQ0mFCigWXbnzsYvVNRgGXKS4gm9ocl8mqXq/bKQuDE8mbRVUjeeTFSrY9aGwaENhUgc7+tsLEIRcOQBZVn+kW/yQdr6//YxRC1OF+CZ5d8Rzp2swDLgIxwyQO7t0AOE8sw6BxmYeCebBZJUeNn0oLJoQGDWVU+CKpEDkIxC59gBkWP2Rbq78cD9Vrsc5owZyuSS6bK9gtfNiWK7AMOAiXHCI3JUsSzDiQsvAbSHdMWTPzwIrcr7KKXCVTfJGdQhKFJVN8vmobJLPOt8kf6bCD6eNOuSVqgFegVwImVnAJRgGXITfEcidVZzvJojWR+CxI1sEV9M4lVPgQmDVhaLifH97VZN8vuxfbQrcmQo9Usr1KKtQNPsUOHIOmWnAJRgGiAhGmCFBwnNGJfwrxI5Kk5Ua2M/Pbzeqz89vr5oCZw9Als0f58xV89v1OGN0jylw5BzsJXANhgEXkdg0QG5KAlABMyaGdMMAJ3QPyGoDbPpQmDXnp8Bd1N+eY/dHltUfaebKUfKny/XI9NApcOQcdrYMuATDAJGPkyUJ4X4hePTQ5stvCwmyLuh8f3uoYwpcEQKRJwcg217ZJJ9m9sMZY2V/e1EDlpwlqguzgGswDLiIxFED5LbseESOgiUESFcFo0QR5FiVLsvmj3SzAWnn+9tPl+s4BY5cimMGXINhgMjH2WQJd+27Q3QZRLXimAHXYMR3EY4ZICJqPBlMA67AMOAiDANERI3HlgHXYBggIiK3xTEDrsEw4DJsGiAiaixmAddgGCAiIrelVvJjyhX4LLsI389ERI0XpFeLLsEn8CPKRfiGJiJqvGA/njtdgWHARUL8NKJLICLyOPwi5RoMAy4SamAYICJqLIYB12AYcBG2DBARNV4wz50uwTDgIiFsGSAiajS2DLgGw4CLhDLdEhE1GgcQugbDgIuEGPiGJiJqLLYMuAbDgIsE6NRQK7kKIRFRQ2lVCujUStFl+ASGARfiQBgiooZjF4HrMAy4EMcNEBE1HLsIXIdhwIU4boCIqOHYmuo6DAMuxLUGiIgarnWon+gSfAbDgAvFBOtFl0BE5DHahhtEl+AzGAZcKD6Cb2wiooaKC+M501UYBlwoPtxfdAlERB4jLpzdBK7CMOBC7dgyQETUYGwZcB2GAReKDNQhQKsSXQYRkduLDNDCwPOlyzAMuBjHDRARXV4cBw+6FMOAi8VHcNwAEdHltGUXgUsxDLhYPNMuEdFlsWXAtRgGXIwtA0REl9eWMwlcimHAxThmgIjo8tgy4FoMAy7WNtwABa9kTERUJ0nitEJXYxhwMZ1ayWWJiYjq0SbUDzq1UnQZPoVhQID2kRw3QERUl8RWwaJL8DkMAwLwjU5EVLcescGiS/A5DAMC9GodLLoEIiK31aNVkOgSfA7DgAC9YkMgcRAhEVENKoWErjEMA67GMCBAkJ+a1+kmIqpF+6gA6DUcPOhqDAOC9IoNEV0CEZHb6cnxAkIwDAjSu02w6BKIiNxO3zh+URKBYUCQvnGhoksgInI7PDeKwTAgSPtIf4QaNKLLICJyGy0CdYgN5TUJRGAYEESSJDaHERFd5CqeE4VhGBCof9sw0SUQEbkNdhGIwzAgUL+2fOMTEVUZEM8vSKIwDAjUJToQgTqV6DKIiIRrFaJHxxYBosvwWQwDAikUEoZ3jBRdBhGRcKM6R4kuwacxDAh2bRf+ARARjezML0YiMQwINqJTJDRKvgxE5LsCtCqOFxCMn0KC+WtVGNiOfwRE5LuGdoiAml+KhOKz7wZGd2VXARH5rlFd2EUgGsOAG7i2cxQvaUxEPkmpkDCCA6mFYxhwA5GBOvRoFSy6DCIil+vTOgTBflyaXTSGATfBrgIi8kXsInAPDANuYnSXFqJLICJyuZFcX8AtMAy4iYRIf8RHGESXQUTkMvHhBrSL8BddBoFhwK1wASIi8iWju7JF1F0wDLiR6/iHQUQ+5ParWokugc5jGHAjvVqHICGSTWZE5P36xoWwi8CNMAy4mb/1jRVdAhGR091+Fc917oRhwM3c1rsVr1VARF7NX6vCuMRo0WXQRfip42ZCDRquOUBEXm1cYjT8NCrRZdBFGAbc0OR+rUWXQETkNOwicD8MA25oYLswtAnzE10GEVGzS4j0R582IaLLoEswDLghSZJwBwcSEpEXuoOtAm6JYcBNTejTCioFL2VIRN5DrZRwa++WosugWjAMuKnIAB1GduYFPIjIe1zTKRLh/lrRZVAtGAbc2CQOJCQiL8LuT/fFMODGhraPQMtgvegyiIiuWFyYH4Z1YGunu2IYcGMKhYTJ/dk6QESeb+awdlByHJTbYhhwc9MGtkGgjotzEJHnahGow/jevCiRO+OnjJsL0Klx16A4vLPxpOhShEn74G7YirNr3O7f6waEjX4AAGDJPYuC3xahIvUQABnqsNaIuOXfUAXW3ixZfuxPFP31PSwFGYDdClVIDAL73gr/btc4tik9vAmFv30B2VIB/8TRCBlxt+N31qIsZC19FtHT34JCyzUhiOpz75C20Kj43dOdMQx4gLuvbovP/jiNMrNNdClCRE9fCNjtjp/NuWeQvfQZGDoNBgBYCjKQ+c3j8E+8FsFXT4GkNcCSdxaSUlPnPhV6fwQNnAh1aCygVMGYvAN5v7wFpV8Q9PF9YCsvQv6a/0PY9bOhCm6B7B/mQ9u6O/za9QUA5K19HyHD7mIQILqMED81uzs9AMOABwj20+DOAW3w0e+nRJcihNIvqNrPxr+WQRUcDW1sdwBA4e9fQt/uqmrf3NXBLerdp651YrWf1VfdjLJDG2FKOwJ9fB9YCzMhaf1g6DzUsb0lNxVo1xdlRzZDUqrg13FQczw8Iq82fVAcr0PgAdhu4yHuHRIPnZovl2yzoOzIZvgnXgtJkiDLdhhP7YIqJAZZS5/F2f+bgowvH0X58W0N36csw5iyD5b8NGhjuwEAVKEtIVtMMGclw2YsgTnjODQRcbAZS1C45RuEXnu/sx4ikdcwaJSYMait6DKoARjXPEREgBZ/69sai/9MEV2KUOXH/4K9ohSGbiMBAPayIshmI4q3/4DgIVMRMnwGjKd3I2f5i4ia9CJ0rbvXuS+7qQxp702HbLMAkgJhox+Avm0vAIBS54/wGx5B7qo3IVvNMHS7Bvr4Psj95S0E9BkHa1EWsv+7ALBbETR4MgydrnbJ4yfyJJP7t0aQn1p0GdQADAMeZOaweHy7PRVmm/3yG3up0gProI/vA1VAGABAliufC33CAAT2vQUAoImKh+lcEkr2ra43DEgaPaJnvAPZXIGKM/uQv/EzqIJbOLoQ/DoMgl+HC10BFakHYMk5g9Br70f6x39H+I2PQWkIQcaXj0IX2w1KQ7BzHjSRB9KoFLhvSLzoMqiB2O7sQaKD9Bjfx3fX9bYWZaPizH749xjjuE3pFwgolFCHV1/ZTB0WC1txTr37kyQF1CEx0ETFI7DfbTB0HIyibctq3Va2WpC/7gOEjnkI1oIMyHYbdK27Qx3WCurQljBlHLvyB0jkRcb3boXIQJ3oMqiBGAY8zIPDE3z2AkalB9dXjvY/P6IfACSlGtoW7WHNP1dtW0v+OSjrmFZYF1mWK7sMalH45xLo4vtA2yIBkO2A/cLMDtlurTbbgcjXKRUSHhjWTnQZ1AgMAx4mNtQPN/WIEV2Gy8myHaUHN8DQbSQkhbLa7wL734aypC0o2bcGloJ0FO9eCePJHQjofb1jm9xVb6Dgt8WOn4u2fQ/j6b2wFGbCkncWxTuWo+zwRhi6jqhxbHPOGZQf/R3BV98JAFCFtgIkBUr2r0N58k5Y8tKgiW7vnAdO5IFu7hGD1mGcdutJOGbAAz10TQJW7E+HzS6LLsVlKlL2wVacA//Ea2v8zq/DIISNeRBFfy1Dwa8fQxXaEhG3PgVdq66ObazFOYB0IfvaLSbkr38ftpI8SCoN1KGtED5ujmMqYRVZlpG/9l2EXHMfFJrKJk+FWouw62cjf/0HkG0WhF57P1QB4U565ESeRatSYM6YjqLLoEaSZFn2nU8UL/L08oP4Znuq6DKIiKq5f1g7PDG2k+gyqJHYTeChHr22AwK0bNghIvcRatDgoREcK+CJGAY8VJi/Fg9dkyC6DCIih39ek4AAHdcV8EQMAx5sxuA4xIbqRZdBRIT4cAOmDGgjugxqIoYBD6ZVKfHEdZ1Fl0FEhKdv6Ay1kh8pnoqvnIe7ITEa/duGii6DiHzYiI4RGNk5SnQZdAUYBrzAczd389mFiIhILI1SgWfHdRFdBl0hhgEv0LFFAKYNjBNdBhH5oBmD4xAf4S+6DLpCDANe4pFr2yMiQCu6DCLyIZEBWswaydU3vQHDgJcI0KnxJBf6ICIXemZcF/hzvROvwDDgRW7r3YqDCYnIJcZ2a+GT10nxVgwDXub123vAoFFefkMioiYKM2jw/C3dRJdBzYhhwMvEhvrhGY7sJSInWnBLN4T5c4ySN2EY8EKT+rXGiI4RossgIi90Y48YXN89WnQZ1MwYBrzUKxMSEeLHNcKJqPlEBGix4Oaul9+QPA7DgJeKDNBhAfv0iKgZvXhrdwT7aUSXQU7AMODFxiXG4EaO9iWiZnBbr5a4tguXHPZWDANe7vmbuyEqkAN9iKjpogK1mHsTuwe8GcOAlwvyU+OV8YmiyyAiD/by+EQE6TkGyZsxDPiA4R0jMbl/a9FlEJEHuuOqWIzoGCm6DHIyhgEf8cwNndEmzE90GUTkQbpEB2I+Zw/4BIYBH+GnUeGDKX2gV3N1QiK6vCC9Gh9N7QMdzxk+gWHAh3SJCcQrEzh+gIjqp5CAt//WE7GhbE30FQwDPuamHjGYOTRedBlE5MYeGdUBwzlOwKcwDPigx6/rhCHtw0WXQURu6NouUfjHNQmiyyAXYxjwQUqFhHcn9UZrNgES0UXiww14c2IPSJIkuhRyMYYBHxXkp8bH0/rAj5c7JiIABo0SH03tgwAd1xPwRQwDPqxTi0C8NqGH6DKIyA28dnsPtI8KEF0GCcIw4ONuSIzGA8PbiS6DiASaOTSelyX2cQwDhMdGd8TwjhGiyyAiAYa0D8fj13USXQYJxjBAUCgkvP23XogPN4guhYhcqEerIHx4Zx8oFRww6OsYBghA5WpjX93bH9FBOtGlEJELtIswYNGMfjBoVaJLITfAMEAOLYP1+Oqe/ggzaESXQkROFB2kw1f39Eco/9bpPIYBqiYh0h9f3N0PAfy2QOSVQvzU+OqefogJ1osuhdwIwwDV0K1lED6dfhV0ar49iLyJn0aJz+/qi4RITiGk6ni2p1r1jw/D+1N6Q63kwCIib6BRKvDhnX3Qq3WI6FLIDTEMUJ2u6RSF12/vAQ40JvJsCgl4Y2IPDO3AKcRUO4YBqtfNPVviuZu7iS6DiK7A/Ju64sYeMaLLIDfGMECXdeeANnhsTEfRZRBRE8we1R5TB8aJLoPcHMMANchDIxIwc1i86DKIqBFmj2qP2aM6iC6DPIAky7IsugjyHK+uOYr3NyeLLoOILuPJsZ0wcxivO0INwzBAjfbB5mS8suao6DKIqBaSVDlGYBq7BqgRGAaoSb7aloL//HQYfPcQuQ+FBLx8WyIm9o0VXQp5GIYBarL/7k7D4/89AJudbyEi0TRKBd6Y2IOzBqhJGAboiqw7nIl/LtmLCotddClEPsugUeLDqX0wpD3XEaCmYRigK7YrJR/3fLELRUaL6FKIfE6oQYPP7+qLnrHBokshD8YwQM3iRFYJpn++A+lFFaJLIfIZMUE6fHlPfyRE+osuhTwcwwA1m8yiCkz/fAeOZZWILoXI63WJDsRnd12F6CBefZCuHMMANasiowX/+HYPtpzIFV0Kkde6sUcMXh2fCL1GKboU8hIMA9Ts7HYZr607hg+4OBFRs1JIwOPXdcL9XEyImhnDADnN6oMZ+Ney/Sgz20SXQuTxgvRqvDOpF4bxyoPkBAwD5FQnskow86vdOJVbJroUIo/VIcofH0+9CnHhBtGlkJdiGCCnK6mw4JGl+7EhKUt0KUQeZ0zXKLw5sScMWpXoUsiL8aqFPmrNmjW4+uqrERwcjLCwMIwbNw7Jyc7p4w/QqfHJtD549NoOUEhOOQSR15Ek4JFRHfDhnX0YBMjp2DLgo/773/9CkiR0794dZWVl+M9//oOUlBTs27cPCoXzMuKmo9l4eMleFFdYnXYMIk8XoFVh4R09MapLlOhSyEcwDBAAICcnB5GRkTh48CC6devm1GOdySvDzK9242gm1yMgulS3loF4645eXEiIXIrdBD4qOTkZkydPRnx8PAIDA9G2bVsAQGpqqtOP3SbMgOUPDsbUAW0gsduACACgUkj45zUJWP7gYAYBcjl2RPmoG2+8EbGxsfjkk08QExMDu92Obt26wWw2u+T4eo0SC27phuu6tcDjPxzAuUKjS45L5I7iww14846evL4ACcOWAR+Ul5eHpKQkPPPMMxg5ciQ6d+6MgoICIbUMTgjHmtlDMPGqVkKOTySSJAHTB7bBz/8cwiBAQrFlwAeFhIQgLCwMH3/8MaKjo5GamoonnnhCWD0BOjVendAD13VrgSf+exDZJSZhtRC5SnSQDq9OSORlh8ktsGXABykUCixZsgS7d+9Gt27d8Mgjj+C1114TXRau6RSF9Y8Mwy09Y0SXQuRUN/eMwZrZQxkEyG1wNgG5pTWHMvD08kPIK3PNGAYiVwjxU+P5W7rjhsRo0aUQVcMwQG4rr9SEZ348hNWHMkWXQnTFbugejbk3dUFkgE50KUQ1MAyQ21tzKAMv/JKEs/mccUCep1OLAMy9sSsGtgsTXQpRnRgGyCOYrDZ89sdpvL8pGaUmrl5I7i/YT41Hr+2AKf3bQMl1uMnNMQyQR8kuqcDra4/hh91psPOdS25IqZAwqV8s5lzbESEGjehyiBqEYYA80qFzRXhu5RHsSMkXXQqRQ/+2oZh3U1d0jg4UXQpRozAMkEf7+UAGXlqdhLQCjicgcWKCdHjqhs4Yl8hpseSZGAbI41VYqsYTnESZ2Sa6HPIherUS9w1piweGJ0CvUYouh6jJGAbIa2QXV+DtX09g2a40mG120eWQF9OrlbhzQGvMHNYO4f5a0eUQXTGGAfI6GUVGfLA5GUt2noXZylBAzUenVuDO/m0wc1g7RAQwBJD3YBggr5VVXIEPNifjux2pMDEU0BXQq5WY1K817h8ez0WDyCsxDJDXyy6pwKKtKfj6rzMoqeAaBdRwQXo1pg+Kw4xBcZwmSF6NYYB8RqnJim+3n8Hnf6Qgs7hCdDnkxqICtbj36nhM7t8aBi0v7krej2GAfI7FZsePe8/h0y2ncSyrRHQ55Eb6tAnBpH6tcVOPGGhUvKgr+Q6GAfJpu88UYOnOVKw6kIFyTkv0SUF6NW7t1RKT+7dGh6gA0eUQCcEwQASgzGTFyv3pWLrrLPamFoouh1ygb1xlK8D13aOhU3ONAPJtDANElziRVYIlO89i+d5zyC8ziy6HmlGwnxq39WqFyf1jkRDJVgCiKgwDRHUwW+3YkJSFJTvP4o8TObwwkoeSJKBfXCgm9WuNsd1bQKtiKwDRpRgGiBrgXKERP+1Lx/ojmdh3tpDBwM2plRIGxIdhdNcWGN0lClGBXBuAqD4MA0SNlFtqwsakbKxPysIfJ3JhtHDgoTswaJQY3jESo7tGYUSnSATq1KJLIvIYDANEV6DCYsPWk7nYkJSFX5OykV1iEl2STwn312BU5yiM7hqFwQnh7AIgaiKGAaJmIssyDqQVYUNSFtYfycLRTK5h0NwUEtCpRSAGJ1R2AfRpHQKFQhJdFpHHYxggcpLskgrsOVOAPamF2H2mAAfPFfHCSY2kVyvRMzYYfeNCcFVcKHq1DkYAm/+Jmh3DAJGLmK12HE4vwu4zBdibWog9qQXIKOKyyBeLCNDiqjYh6NMmBH3jQtE1JhAqJVcCJHI2hgEigdILjdiTWoDdZwqw72whTmaVosTkGxdTCjNo0D7KHx2iApDYqvLbf5swg+iyiHwSwwCRm8kqrkBydilO5pTiZHYpknNKkZJbjsziCtg8bE6jUiEhJliHuDAD2oYbkBDpj/aRAegQ5Y8wf63o8ojoPIYBIg9hsdmRVmBEan555b+8MuSUmFBQbkGh0YKicjMKjRYUGy1OXwdBqZAQrFcj1KBBiEGDUL/K/w8zaBDmr0GbMD+0CTMgNsSPF/wh8gAMA0ReRpZlFButKDSaUVhuQUG5GUVGCwrLLSipsAAAJEk6//+AQpIgnf9vCRLO/wrS+dsNWiVC/DSOD/4wgwZBerVjH0Tk+RgGiIiIfBzb74iIiHwcwwAREZGPYxggIiLycQwDREREPo5hgIiIyMcxDBAREfk4hgEiIiIfxzBARETk4xgGiIiIfBzDABERkY9jGCAiIvJxDANEREQ+jmGAiIjIxzEMEBER+TiGASIiIh/HMEBEROTjGAaIiIh8HMMAERGRj2MYICIi8nEMA0RERD6OYYCIiMjHMQwQERH5OIYBIiIiH8cwQERE5OMYBoiIiHwcwwAREZGP+3/OzHnp56IxvgAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "piechart_sensitivity(pce)" ] diff --git a/docs/tutorials/parameters.md b/docs/tutorials/parameters.md index 23aa773d..f21f999c 100644 --- a/docs/tutorials/parameters.md +++ b/docs/tutorials/parameters.md @@ -1,8 +1,5 @@ # Defining random parameters - This project was supported by grants from the National Institute of Biomedical Imaging and Bioengineering (U24EB029012) from the National Institutes of Health. diff --git a/docs/tutorials/template.md b/docs/tutorials/template.md index 8f854f31..154ccfda 100644 --- a/docs/tutorials/template.md +++ b/docs/tutorials/template.md @@ -1,8 +1,5 @@ # Template for Tutorial - This project was supported by grants from the National Institute of Biomedical Imaging and Bioengineering (U24EB029012) from the National Institutes of Health. @@ -41,30 +38,27 @@ Example Subsection. These can go to 6 `#`'s. Subsections are optional for tab ![Example for including an image in tutorial.](../_static/UncertainSCI.png "UncertainSCI example image") ### Math -Math equations use [MathJax](http://docs.mathjax.org/en/latest/basic/mathematics.html). This requires the inclusion of this near the beginning of the document: -``` - -``` +Math equations can be written directly in Markdown. MyST-NB and Sphinx handle math rendering during the documentation build. Example equation: -\\[ x = {-b \pm \sqrt{b^2-4ac} \over 2a} \\] -$$ \frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} $$ -inline equations use the `\\(\mathbf{p}\\)` sytanx: \\(\mathbf{p}\\) +$$ +\frac{\partial \rho}{\partial t} + \nabla \cdot \vec{j} = 0 \,. \label{eq:continuity} +$$ + +Inline equations use dollar delimiters, as in ``$ a^2 + b^2 = c^2 $``, which displays as $a^2 + b^2 = c^2$. ### Citations -Sphinx has a built in citation manager for bibtex: [sphinxcontrib-bibtex](https://sphinxcontrib-bibtex.readthedocs.io/en/latest/). Works well for RST, but we are still working on it for markdown. The sphinxcontrib-bibtex is built to run with rst in Sphinx. However, it can be used in markdown using the [AutoStructify](https://recommonmark.readthedocs.io/en/latest/auto_structify.html) package. +Sphinx has a built in citation manager for bibtex: [sphinxcontrib-bibtex](https://sphinxcontrib-bibtex.readthedocs.io/en/latest/). Use MyST's `eval-rst` directive when a Markdown page needs an rst-only citation directive. -```eval_rst +```{eval-rst} The whole paragraph will need to be in the eval_rst block :cite:p:`JDT:Bur2020`. For multiple references: :cite:p:`JDT:Bur2020,gupta1983` ``` add a bibliography section ```` -```eval_rst +```{eval-rst} .. bibliography:: ``` ```` @@ -88,7 +82,7 @@ External link: , or [Markdown](https://www.markdo ### Tables -Tables can be used with normal markdown syntax with the [sphinx-markdown-tables](https://github.com/ryanfox/sphinx-markdown-tables) package +Tables can be used with normal Markdown syntax through MyST. ``` | Syntax | Description | @@ -106,7 +100,7 @@ Tables can be used with normal markdown syntax with the [sphinx-markdown-tables] ### Referencing Sphynx -To link the UncertainSCI API generated using Sphynx, Use this syntax: [`[text](../api_docs/pce.html#polynomial-chaos-expansions)`](../api_docs/pce.html#polynomial-chaos-expansions) +To link the UncertainSCI API generated using Sphinx, use this syntax: [`[text](../formalism/pce)`](../formalism/pce) diff --git a/docs/user_docs/faq.md b/docs/user_docs/faq.md deleted file mode 100644 index 6adcb0f0..00000000 --- a/docs/user_docs/faq.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "FAQs" -category: null -layout: default ---- - - -### FAQs content... diff --git a/docs/user_docs/getting_started.md b/docs/user_docs/getting_started.md index 92b100d9..5119df6f 100644 --- a/docs/user_docs/getting_started.md +++ b/docs/user_docs/getting_started.md @@ -3,7 +3,7 @@ ## System Requirements -Requires Python 3 and modules listed in `requirements.txt` +Requires Python 3.9, 3.10, or 3.11. Runtime dependencies are installed automatically when installing UncertainSCI. ## Getting UncertainSCI @@ -15,11 +15,11 @@ The source code for UncertainSCI can be downloaded from the [Github page](https: ### Installing UncertainSCI From Source -UncertainSCI can be built from source code using the `setup.py` script. To call this script, navagate to the source root directory in a terminal window and run the command `pip install .` or `python -m pip install .` +UncertainSCI can be built from source code using the project metadata in `pyproject.toml`. To install it, navagate to the source root directory in a terminal window and run the command `pip install .` or `python -m pip install .` ## UncertainSCI Overview -Users can evaluate the effect of input uncertainty on forward models with UncertainSCI's implementation of [polynomial Chaos expansion (PCE)](../api_docs/pce.html). The pipeline for the process is shown in the following image: +Users can evaluate the effect of input uncertainty on forward models with UncertainSCI's implementation of [polynomial Chaos expansion (PCE)](../formalism/pce). The pipeline for the process is shown in the following image: ![User pipeline for UncertainSCI. After the user inputs parameter distributions, UncertainSCI will compute an efficient sampling scheme. The parameter samples are run through the targeted modeling pipeline, which can be implemented in external software tools. The computed solutions are collected and compiled into relevant statistics with UncertainSCI.](../../paper/UncertainSCI_pipeline.png) @@ -45,7 +45,7 @@ Distribution type of the parameters may effect the number of samples, but to a m #### Running UncertainSCI for Sample Generation -With the model setup, the user will need to setup the input parameter distribution using UncertainSCI's [distribution datatype](../api_docs/distributions.html). While there are a few distribution types to choose from, the [Beta distribution](../api_docs/distributions.html#UncertainSCI.distributions.BetaDistribution) is a common choice. If we had three input parameters, we can define a different beta distribution for each, thus: +With the model setup, the user will need to setup the input parameter distribution using UncertainSCI's [distribution datatype](../dev_docs/api/generated/UncertainSCI.distributions.rst). While there are a few distribution types to choose from, the {class}`UncertainSCI.distributions.BetaDistribution` is a common choice. If we had three input parameters, we can define a different beta distribution for each, thus: ```Python from UncertainSCI.distributions import BetaDistribution @@ -62,7 +62,7 @@ After the input parameters are set, we can generate a parameter sampling that wi # # Polynomial order order = 5 ``` -Now we can create the [PCE object](../api_docs/pce.html#module-UncertainSCI.pce) and generate parameter samples: +Now we can create the {class}`UncertainSCI.pce.PolynomialChaosExpansion` object and generate parameter samples: ```Python from UncertainSCI.pce import PolynomialChaosExpansion @@ -118,13 +118,15 @@ piechart_sensitivity(pce) plt.show() ``` -The [API documentation](../api_docs/index.html) explains the implementation of UncertainSCI in more detail. +The [discussion of PCE in the Formalism section](../formalism/pce.rst) explains PCE in +more detail. Implementation details of UncertainSCI can be found in +[the API reference](../dev_docs/api/index.rst) and in the source code. ## Running UncertainSCI Demos -There are a number of demos included with UncertainSCI to test it's installation and to demonstrate its use. The [previous description](#running-uncertainsci) can be found as a notebook with some more details [here](../tutorials/notebooks/build_pce.html) and as a script in `demos/build_pce.py`. +There are a number of demos included with UncertainSCI to test it's installation and to demonstrate its use. The [previous description](#running-uncertainsci) can be found as a notebook with some more details [here](../tutorials/notebooks/build_pce.ipynb) and as a script in `demos/build_pce.py`. The demo scripts can be a way to quickly test the installation. Make sure that UncertainSCI is [installed](#getting-uncertainsci), then simply call the script with python using the command `python demos/build_pce.py`. Other demos can be run similarily. -We have included a number of demos and [tutorials](../tutorials/index.html) to teach users how to use UncertainSCI with various examples. +We have included a number of demos and [tutorials](../tutorials/index.rst) to teach users how to use UncertainSCI with various examples. diff --git a/docs/user_docs/install.rst b/docs/user_docs/install.rst index 98759a5f..a8599f11 100644 --- a/docs/user_docs/install.rst +++ b/docs/user_docs/install.rst @@ -1,4 +1,50 @@ Installation ============ -Use ``pip install -r requirements.txt`` to install dependencies. +UncertainSCI supports Python 3.9, 3.10, and 3.11. + +From PyPI +--------- + +Install the latest published package with: + +.. code-block:: shell + + python -m pip install UncertainSCI + +From Source +----------- + +From a `source checkout `_, install +the package with: + +.. code-block:: shell + + python -m pip install . + +Optional dependency targets are available for common tasks: + +.. code-block:: shell + + python -m pip install ".[docs]" + python -m pip install ".[interactive]" + python -m pip install ".[dev]" + +Building the notebook documentation also requires the standalone Pandoc +executable. With conda, install it with: + +.. code-block:: shell + + conda install -c conda-forge pandoc + +Alternatively, install Pandoc with your operating system package manager. + +Targets can be combined with a comma, such as: + +.. code-block:: shell + + python -m pip install ".[docs,interactive]" + +Note that the ``dev`` target includes all optional dependencies plus development +tools such as ``flake8``, ``pytest``, and ``pytest-cov``. If you're looking for +a quick start in development, use ``dev``. diff --git a/docs/user_docs/specs.md b/docs/user_docs/specs.md deleted file mode 100644 index 1ab6e6d6..00000000 --- a/docs/user_docs/specs.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "Specifications" -category: null -layout: default ---- - - -### Specifications content... diff --git a/formatting-rules.md b/formatting-rules.md new file mode 100644 index 00000000..df0a7ccd --- /dev/null +++ b/formatting-rules.md @@ -0,0 +1,250 @@ +# Formatting Rules + +The following rules apply to Python. Defer to industry-standard best practices +for code other than Python. + +1. Lines longer than 120 characters should be broken across multiple lines. + + For function calls, put each argument on its own line. The function call + + ```python + thisIsAnExampleOfALongLine(someVeryLongArgument1, someVeryLongArgument2, someVeryLongArgument3, someVeryLongArgument4, someVeryLongArgument5) + ``` + + should be broken like: + + ```python + thisIsAnExampleOfALongLine( + someVeryLongArgument1, + someVeryLongArgument2, + someVeryLongArgument3, + someVeryLongArgument4, + someVeryLongArgument5 + ) + ``` + + For long non-function call expressions, use parentheses and keep each + continued expression element on its own line. Binary operators should stay + at the end of continued lines. The expression + + ```python + someVeryLongResultName = someVeryLongArgument1 + someVeryLongArgument2 + someVeryLongArgument3 + someVeryLongArgument4 + someVeryLongArgument5 + ``` + + should be broken like: + + ```python + someVeryLongResultName = ( + someVeryLongArgument1 + + someVeryLongArgument2 + + someVeryLongArgument3 + + someVeryLongArgument4 + + someVeryLongArgument5 + ) + ``` + +2. Lines of code ending with a colon (`:`) should be followed immediately by + executable code, or by a docstring where docstrings are valid. The + class-definition exception is that one blank line may separate a class + docstring from the first method or class attribute. Blank lines inside a + multi-line docstring are allowed. + + The following are *bad* examples: + + ```python + def myFunction(*args): + + """myFunction does something!""" + + _myFunctionInternals(*args) + ``` + + ```python + def myFunction(*args): + """myFunction does something!""" + + _myFunctionInternals(*args) + ``` + + ```python + def myFunction(*args): + """myFunction does something! + + Arguments: + args: Some arguments. + """ + + _myFunctionInternals(*args) + ``` + + ```python + if myCondition: + + + # This is a trivial comment about doSomething. + + doSomething() + ``` + + ```python + class MyClass: + + """MyClass containerizes something useful.""" + + def __init__(self): + _doInit(self) + ``` + + ```python + class MyClass: + + def __init__(self): + _doInit(self) + ``` + + The following are *good* examples: + + ```python + def myFunction(*args): + _myFunctionInternals(*args) + ``` + + ```python + def myFunction(*args): + """myFunction does something!""" + _myFunctionInternals(*args) + ``` + + ```python + def myFunction(*args): + """myFunction does something! + + Arguments: + args: Some arguments. + """ + _myFunctionInternals(*args) + ``` + + ```python + if myCondition: + doSomething() # This is a non-trivial comment about doSomething. + ``` + + ```python + class MyClass: + """MyClass containerizes something useful.""" + + def __init__(self): + _doInit(self) + ``` + + ```python + class MyClass: + def __init__(self): + _doInit(self) + ``` + +3. Within a function body, never use more than one contiguous blank line. A + single blank line may be used to separate substantial logical sections, but + short straight-line functions should not contain blank lines. + + For example + + ```python + def myFunction(*args): + intermediate = _myFunctionStep1(*args) + + + result = _myFunctionStep2(intermediate) + + + return result + ``` + + should be replaced by: + + ```python + def myFunction(*args): + intermediate = _myFunctionStep1(*args) + result = _myFunctionStep2(intermediate) + return result + ``` + + For very simple data transformations, prefer returning the result directly. For + example: + + ```python + def myFunction(*args): + intermediate = _myFunctionStep1(*args) + return _myFunctionStep2(intermediate) + ``` + +4. Comments should be full sentences, with exactly one space following the `#`. + + Bad comments: + + ```python + #bad comment + ``` + + ```python + # another bad comment + ``` + + A good comment: + + ```python + # This is a good comment. + ``` + + `TODO` comments and other inline memos should use the same spacing and + sentence style: + + ```python + # TODO: This is a complete sentence directing some future reader. + ``` + +5. Standalone `#` comments immediately after a line ending with a colon (`:`) or + immediately after a docstring are discouraged but not forbidden. Prefer + moving that information into the docstring or closer to the code it + describes. + +6. Code that must be disabled should *not* be commented out with triple quotes + or `#`. Remove it, or place it behind an explicit condition when it must + remain available. + + Bad: + + ```python + def myFunction(): + # return 'Hello world!' + return None + ``` + + ```python + def myFunction(): + """ + return 'Hello world!' + """ + return None + ``` + + Acceptable when the disabled path is intentionally retained: + + ```python + def myFunction(useGreeting): + if useGreeting: + return 'Hello world!' + return None + ``` + + Better when the disabled code is no longer needed: + + ```python + def myFunction(): + return None + ``` + +7. Defer to general best practices for rules not otherwise specified here. + These rules should be compatible with, or reinforce, common Python style + conventions. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..4b64a175 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,84 @@ +[build-system] +requires = ["setuptools>=61"] +build-backend = "setuptools.build_meta" + +[project] +name = "UncertainSCI" +version = "1.0.1.1" +description = "A Non-invasive Uncertainty Quantification tool" +readme = { file = "README.md", content-type = "text/markdown" } +requires-python = ">=3.9,<3.12" +license = { text = "MIT" } +authors = [ + { name = "UncertainSCI Developers", email = "uncertainsci@sci.utah.edu" }, +] +keywords = ["Uncertainty Quantification", "Simulation"] +classifiers = [ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: Healthcare Industry", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Medical Science Apps.", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Software Development :: Libraries", + "Operating System :: Android", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Operating System :: Unix", + "Operating System :: MacOS", +] +dependencies = [ + "matplotlib>=3.1.3", + "numpy>=1.25,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*", + "packaging", + "scipy>=1.4.1", +] + +[project.optional-dependencies] +docs = [ + "ipykernel", + "myst-nb", + "pygments", + "sphinx", + "sphinx-copybutton", + "sphinx_rtd_theme>=1.3.0", + "sphinxcontrib-bibtex", +] +interactive = [ + "ipython", + "jupyter", +] +dev = [ + "flake8", + "ipykernel", + "ipython", + "jupyter", + "myst-nb", + "pygments", + "pytest", + "pytest-cov", + "sphinx", + "sphinx-copybutton", + "sphinx_rtd_theme>=1.3.0", + "sphinxcontrib-bibtex", +] + +[project.urls] +Homepage = "https://sci.utah.edu/sci-software/simulation/uncertainsci.html" +Documentation = "https://uncertainsci.readthedocs.io" +Source = "https://github.com/SCIInstitute/UncertainSCI" +Download = "https://github.com/SCIInstitute/UncertainSCI" + +[tool.setuptools] +package-dir = { "" = "." } + +[tool.setuptools.packages.find] +where = ["."] +include = ["UncertainSCI*"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 38f83434..00000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -matplotlib>=3.1.3 -numpy>=1.25 -scipy>=1.4.1 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 08aedd7e..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -description_file = README.md diff --git a/setup.py b/setup.py deleted file mode 100644 index 7af1ab1f..00000000 --- a/setup.py +++ /dev/null @@ -1,46 +0,0 @@ -from setuptools import setup, find_packages - -with open("README.md", "r") as fh: - long_description = fh.read() - -setup( - name='UncertainSCI', - version='1.0.1.1', - author='UncertainSCI Developers', - author_email='uncertainsci@sci.utah.edu', - packages=find_packages(), - package_dir={'': '.'}, - download_url=r'https://github.com/SCIInstitute/UncertainSCI', - description=r'A Non-invasive Uncertainty Quantification tool', - long_description= long_description, - long_description_content_type="text/markdown", - classifiers=[ - "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Intended Audience :: Education", - "Intended Audience :: Healthcare Industry", - "Intended Audience :: Science/Research", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Medical Science Apps.", - "Topic :: Scientific/Engineering :: Information Analysis", - "Topic :: Software Development :: Libraries", - "Operating System :: Android", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Operating System :: Unix", - "Operating System :: MacOS" - ], - license='MIT', - keywords='Uncertainty Quantification, Simulation', - url=r'https://sci.utah.edu/sci-software/simulation/uncertainsci.html', - install_requires=[ - "matplotlib>=3.1.3", - "numpy>=1.25", - "scipy>=1.4.1" - ] - )