diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..366b813d --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 508ad71576e30cdeb1f2af9ce7bf5fc4 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/CHANGELOG.html b/CHANGELOG.html new file mode 100644 index 00000000..cded8891 --- /dev/null +++ b/CHANGELOG.html @@ -0,0 +1,610 @@ + + + + + + + + + Changelog - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Changelog

+

All notable changes to the axtreme project will be documented in this file.
+The changelog format is based on Keep a Changelog.

+
+

Unreleased

+
+
+

0.1.1 - 2024-12-27

+
+

Added:

+

Major addition of new qoi method MarginalCDFExtrapolation. The following helpers are alse added.

+
    +
  • utils/numerical_precision: quantify the precision possible with different datatypes

  • +
  • distributions/mixture: The contains mixture distributions required for marginalisation

  • +
  • distributions/icdf: optimisation methods for finding icdfs where not availab.

  • +
  • Associated test for these pieces of functionality.

  • +
+
+
+

Changed

+
    +
  • tests/qoi/test_gp_brute_force_system.py : Improved type-checking

  • +
  • pyproject.toml:

    +
      +
    • cleaned up and reorganized dependencies

    • +
    • removed orphaned dependency pytest-django

    • +
    +
  • +
  • .pre-commit-config.yaml : updated with latest changes in python_project_template

  • +
  • README.md : updated with latest changes from python_project_template

  • +
  • GitHub workflows _test.yml and _test_future.yml : rewrote how pytest gets called in a cleaner way

  • +
  • eval/object_logging: unpack_object: minor update to support type attributes.

  • +
  • eval/qoi_helpers.py: minor updates to prevent divide by 0 warnings

  • +
  • tutorials/end_to_end_v2.py -> tutorials/basic_example.py. Updated to use MarginalCDFExtrapolation.

  • +
  • data/importance_dataset.py: Updated typing and used torch’s StackedDataset.

  • +
+
+
+

Fixed

+
    +
  • Minor updates to docs.

  • +
+
+
+

Dependencies

+
    +
  • Updated to pyarrow>=18.1 (from pyarrow>=17.0)

  • +
  • Updated to statsmodels>=0.14.4 (from statsmodels>=0.14.2)

  • +
+
+
+
+

0.1.0 - 2024-12-10

+
    +
  • Initial release.

  • +
+
+
+

0.0.1 - 2023-02-21

+
+

Added

+
    +
  • added this

  • +
+
+
+

Changed

+
    +
  • changed that

  • +
+
+
+

Dependencies

+
    +
  • updated to some_package_on_pypi>=0.1.0

  • +
+
+
+

Fixed

+
    +
  • fixed issue #12345

  • +
+
+
+

Deprecated

+
    +
  • following features will soon be removed and have been marked as deprecated:

    +
      +
    • function x in module z

    • +
    +
  • +
+
+
+

Removed

+
    +
  • following features have been removed:

    +
      +
    • function y in module z

    • +
    +
  • +
+ +
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/LICENSE.html b/LICENSE.html new file mode 100644 index 00000000..176d771b --- /dev/null +++ b/LICENSE.html @@ -0,0 +1,479 @@ + + + + + + + + + LICENSE - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

LICENSE

+

MIT License

+

Copyright (c) 2024 DNV open source

+

Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.

+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/README.html b/README.html new file mode 100644 index 00000000..0d8d05cc --- /dev/null +++ b/README.html @@ -0,0 +1,789 @@ + + + + + + + + + axtreme - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+

pypi +versions +license +ci +docs

+
+

axtreme

+

Development repo for the RaPiD project with extensions for Ax and BoTorch.

+
+

Repo Structure

+
    +
  • src/: Main package directory

  • +
  • tests/: Test directory

  • +
  • examples/: Examples and demos

  • +
  • tutorials/: Tutorial notebooks

  • +
+
+
+

Development Setup

+
+

1. Install uv

+

This project uses uv as package manager. +If you haven’t already, install uv, preferably using it’s “Standalone installer” method:
+..on Windows:

+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
+
+
+

..on MacOS and Linux:

+
curl -LsSf https://astral.sh/uv/install.sh | sh
+
+
+

(see docs.astral.sh/uv for all / alternative installation methods.)

+

Once installed, you can update uv to its latest version, anytime, by running:

+
uv self update
+
+
+
+
+

2. Install Python

+

This project requires Python 3.11 or later.
+If you don’t already have a compatible version installed on your machine, the probably most comfortable way to install Python is through uv:

+
uv python install
+
+
+

This will install the latest stable version of Python into the uv Python directory, i.e. as a uv-managed version of Python.

+

Alternatively, and if you want a standalone version of Python on your machine, you can install Python either via winget:

+
winget install --id Python.Python
+
+
+

or you can download and install Python from the python.org website.

+
+
+

3. Clone the repository

+

Clone the axtreme repository into your local development directory:

+
git clone https://github.com/dnv-opensource/axtreme path/to/your/dev/axtreme
+
+
+

Change into the project directory after cloning:

+
cd axtreme
+
+
+
+
+

4. Install dependencies

+

Run uv sync to create a virtual environment and install all project dependencies into it:

+
uv sync
+
+
+
+

Note: Using --no-dev will omit installing development dependencies.

+
+
+

Note: uv will create a new virtual environment called .venv in the project root directory when running +uv sync for the first time. Optionally, you can create your own using e.g. uv venv, before running +uv sync.

+
+
+
+

5. (Optional) Install CUDA support

+

Run uv sync with option --extra cuda to in addition install torch with CUDA support:

+
uv sync --extra cuda
+
+
+
+

Note: The exact version of torch that is installed by default depends on the system you are using. E.g., Linux +will install the CUDA version by default, while Windows and macOS will install the CPU version.

+
+

Alternatively, you can manually install torch with CUDA support. +Note 1: Do this preferably after running uv sync. That way you ensure a virtual environment exists, which is a prerequisite before you install torch with CUDA support using below uv pip install command.

+

To manually install torch with CUDA support, generate a uv pip install command matching your local machine’s operating system using the wizard on the official PyTorch website. +Note: As we use uv as package manager, remember to replace pip in the command generated by the wizard with uv pip.

+

If you are on Windows, the resulting uv pip install command will most likely look something like this:

+
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
+
+
+

Hint: If you are unsure which cuda version to indicate in above uv pip install .. /cuXXX command, you can use the shell command nvidia-smi on your local system to find out the cuda version supported by the current graphics driver installed on your system. When then generating the uv pip install command with the wizard from the PyTorch website, select the cuda version that matches the major version of what your graphics driver supports (major version must match, minor version may deviate).

+
+
+

6. (Optional) Activate the virtual environment

+

When using uv, there is in almost all cases no longer a need to manually activate the virtual environment.
+uv will find the .venv virtual environment in the working directory or any parent directory, and activate it on the fly whenever you run a command via uv inside your project folder structure:

+
uv run <command>
+
+
+

However, you still can manually activate the virtual environment if needed. +When developing in an IDE, for instance, this can in some cases be necessary depending on your IDE settings. +To manually activate the virtual environment, run one of the “known” legacy commands:
+..on Windows:

+
.venv\Scripts\activate.bat
+
+
+

..on Linux:

+
source .venv/bin/activate
+
+
+
+
+

7. Install pre-commit hooks

+

The .pre-commit-config.yaml file in the project root directory contains a configuration for pre-commit hooks. +To install the pre-commit hooks defined therein in your local git repository, run:

+
uv run pre-commit install
+
+
+

All pre-commit hooks configured in .pre-commit-config.yaml will now run each time you commit changes.

+

pre-commit can also manually be invoked, at anytime, using:

+
uv run pre-commit run --all-files
+
+
+

To skip the pre-commit validation on commits (e.g. when intentionally committing broken code), run:

+
uv run git commit -m <MSG> --no-verify
+
+
+

To update the hooks configured in .pre-commit-config.yaml to their newest versions, run:

+
uv run pre-commit autoupdate
+
+
+
+
+

8. Test that the installation works

+

To test that the installation works, run pytest in the project root folder:

+
uv run pytest
+
+
+

You should now be ready to start developing!

+
+
+
+

Development Tools

+

You should familiarize yourself with the following tools used in this project. The tools can be configured in the pyproject.toml file;

+
    +
  • ruff (linting + formatting)

  • +
  • mypy (static type checking)

  • +
  • pytest (unit testing)

  • +
  • pre-commit (code quality checks and fixes on commit)

  • +
+

A brief overview of the tools is provided below:

+
+

ruff Formatter

+

Format the code according to the formatting rules in the pyproject.toml file:

+
uv run ruff format
+
+
+
+
+

ruff Linter

+

Check the code for issues according to the linting rules in the pyproject.toml file:

+
uv run ruff check
+
+
+

Fix any issues that can be fixed automatically:

+
uv run ruff check --fix
+
+
+
+
+

mypy

+

Perform static type checking on source code:

+
uv run mypy
+
+
+
+
+

pytest

+

Run all tests (with coverage) using:

+
uv run pytest
+
+
+

Generate a coverage report in addition to running the tests:

+
uv run pytest --cov=rapid --cov-branch --cov-report=json --cov-report=term-missing
+
+
+
+
+
+

Documentation

+

See axtreme’s documentation on GitHub pages.

+
+
+

Notes on Design Decisions

+
+

Imports

+

We are breaking this rule, and often import classes etc. This follows the approach taken in packages such as pytorch botorch etc.

+
+

Definition

+

Google code standard suggests:

+
+

“Use import statements for packages and modules only, not for individual types, classes, or functions”

+
+
+
+

pros

+
    +
  • often package with similar names (e.g utils), but the actual method required is clear diferentiated.

  • +
  • Less verbose

  • +
+
+
+

cons

+
    +
  • Breaking some recommended practice, not sure what they impact will be.

  • +
+
+
+
+

Numpy vs. Tensors

+
    +
  • Numpy: Working with ax/in general

  • +
  • Torch: working inside or touching “Botorch Layer”, or anywhere need gpu or grad

  • +
+
+

pros

+
    +
  • If work mostly with tensor need to constantly convert them to numpy when winteracting with ax, plot etc.

  • +
+
+
+

cons

+
    +
  • numpy and tensors have slightly different interfaces

  • +
  • Means we don’t have one default way of working

  • +
+
+
+
+
+

Meta

+

Copyright (c) 2024 DNV AS. All rights reserved.

+

Sebastian Winter - sebastian.winter@dnv.com

+

Kristoffer Skare - kristoffer.skare@dnv.com

+

Magnus Kristiansen - magnus.kristiansen@dnv.com

+

Distributed under the MIT license. See LICENSE for more information.

+

https://github.com/dnv-opensource/axtreme

+
+
+

Contributing

+
    +
  1. Fork it (https://github.com/dnv-opensource/axtreme/fork) (Note: this is currently disabled for this repo. For DNV internal development, continue with the next step.)

  2. +
  3. Create an issue in your GitHub repo

  4. +
  5. Create your branch based on the issue number and type (git checkout -b issue-name)

  6. +
  7. Evaluate and stage the changes you want to commit (git add -i)

  8. +
  9. Commit your changes (git commit -am 'place a descriptive commit message here')

  10. +
  11. Push to the branch (git push origin issue-name)

  12. +
  13. Create a new Pull Request in GitHub

  14. +
+

For your contribution, please make sure you follow the STYLEGUIDE before creating the Pull Request.

+ +
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/STYLEGUIDE.html b/STYLEGUIDE.html new file mode 100644 index 00000000..16da0b77 --- /dev/null +++ b/STYLEGUIDE.html @@ -0,0 +1,942 @@ + + + + + + + + + Style Guide - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Style Guide

+

All code shall be Ruff formatted.

+

References, details as well as examples of bad/good styles and their respective reasoning can be found below.

+
+

References

+ +
+
+

Code Layout

+
    +
  • Use 4 spaces instead of tabs

  • +
  • Maximum line length is 120 characters (not 79 as proposed in PEP-8)

  • +
  • 2 blank lines between classes and functions

  • +
  • 1 blank line within class, between class methods

  • +
  • Use blank lines for logic separation of functionality within functions/methods wherever it is justified

  • +
  • No whitespace adjacent to parentheses, brackets, or braces

  • +
+
    # Bad
+    spam( items[ 1 ], { key1 : arg1, key2 : arg2 }, )
+
+    # Good
+    spam(items[1], {key1: arg1, key2: arg2}, [])
+
+
+
    +
  • Surround operators with single whitespace on either side.

  • +
+
    # Bad
+    x<1
+
+    # Good
+    x == 1
+
+
+
    +
  • Never end your lines with a semicolon, and do not use a semicolon to put two statements on the same line

  • +
  • When branching, always start a new block on a new line

  • +
+
    # Bad
+    if flag: return None
+
+    # Good
+    if flag:
+        return None
+
+
+
    +
  • Similarly to branching, do not write methods on one line in any case:

  • +
+
    # Bad
+    def do_something(self): print("Something")
+
+    # Good
+    def do_something(self):
+        print("Something")
+
+
+
    +
  • Place a class’s __init__ function (the constructor) always at the beginning of the class

  • +
+
+
+

Line Breaks

+
    +
  • If function arguments do not fit into the specified line length, move them to a new line with indentation

  • +
+
    # Bad
+    def long_function_name(var_one, var_two, var_three,
+        var_four):
+        print(var_one)
+
+    # Bad
+    def long_function_name(var_one, var_two, var_three,
+            var_four):
+        print(var_one)
+
+    # Better (but not preferred)
+    def long_function_name(var_one,
+                           var_two,
+                           var_three,
+                           var_four):
+        print(var_one)
+
+    # Good (and preferred)
+    def long_function_name(
+        var_one,
+        var_two,
+        var_three,
+        var_four,
+    ):
+        print(var_one)
+
+
+
    +
  • Move concatenated logical conditions to new lines if the line does not fit the maximum line size. This will help you understand the condition by looking from top to bottom. Poor formatting makes it difficult to read and understand complex predicates.

  • +
+
    # Good
+    if (
+        this_is_one_thing
+        and that_is_another_thing
+        or that_is_third_thing
+        or that_is_yet_another_thing
+        and one_more_thing
+    ):
+        do_something()
+
+
+
    +
  • Where binary operations stretch multiple lines, break lines before the binary operators, not thereafter

  • +
+
    # Bad
+    GDP = (
+        private_consumption +
+        gross_investment +
+        government_investment +
+        government_spending +
+        (exports - imports)
+    )
+
+    # Good
+    GDP = (
+        private_consumption
+        + gross_investment
+        + government_investment
+        + government_spending
+        + (exports - imports)
+    )
+
+
+
    +
  • Chaining methods should be broken up on multiple lines for better readability

  • +
+
    (
+        df.write.format("jdbc")
+        .option("url", "jdbc:postgresql:dbserver")
+        .option("dbtable", "schema.tablename")
+        .option("user", "username")
+        .option("password", "password")
+        .save()
+    )
+
+
+
    +
  • Add a trailing comma to sequences of items when the closing container token ], ), or } does not appear on the same line as the final element

  • +
+
    # Bad
+    y = [
+        0,
+        1,
+        4,
+        6
+    ]
+    z = {
+        'a': 1,
+        'b': 2
+    }
+
+    # Good
+    x = [1, 2, 3]
+
+    # Good
+    y = [
+        0,
+        1,
+        4,
+        6,         <- note the trailing comma
+    ]
+    z = {
+        'a': 1,
+        'b': 2,    <- note the trailing comma
+    }
+
+
+
+
+

String Formatting

+
    +
  • When quoting string literals, use double-quoted strings. When the string itself contains single or double quote characters, however, use the respective other one to avoid backslashes in the string. It improves readability.

  • +
  • Use f-strings to format strings:

  • +
+
    # Bad
+    print("Hello, %s. You are %s years old. You are a %s." % (name, age, profession))
+
+    # Good
+    print(f"Hello, {name}. You are {age} years old. You are a {profession}.")
+
+
+
    +
  • Use multiline strings, not \ , since it gets much more readable.

  • +
+
    raise AttributeError(
+        "Here is a multiline error message with a very long first line "
+        "and a shorter second line."
+    )
+
+
+
+
+

Naming Conventions

+
    +
  • For module names: lowercase . +Long module names can have words separated by underscores (really_long_module_name.py), but this is not required. Try to use the convention of nearby files.

  • +
  • For class names: CamelCase

  • +
  • For methods, functions, variables and attributes: lowercase_with_underscores

  • +
  • For constants: UPPERCASE or UPPERCASE_WITH_UNDERSCORES +(Python does not differentiate between variables and constants. Using UPPERCASE for constants is just a convention, but helps a lot to quickly identify variables meant to serve as constants.)

  • +
  • Implementation-specific private methods and variables will use _single_underscore_prefix

  • +
  • Don’t include the type of a variable in its name. +E.g. use senders instead of sender_list

  • +
  • Names shall be clear about what a variable, class, or function contains or does. If you struggle to come up with a clear name, rethink your architecture: Often, the difficulty in finding a crisp name for something is a hint that separation of responsibilities can be improved. The solution then is less to agree on a name, but to start a round of refactoring: The name you’re seeking often comes naturally then with refactoring to an improved architecture with clear responsibilities. +(see SRP, Single-Responsibilty Principle by Robert C. Martin)

  • +
+
+
+

Named Arguments

+
    +
  • Use named arguments to improve readability and avoid mistakes introduced with future code maintenance

  • +
+
    # Bad
+    urlget("[http://google.com](http://google.com/)", 20)
+
+    # Good
+    urlget("[http://google.com](http://google.com/)", timeout=20)
+
+
+
    +
  • Never use mutable objects as default arguments in Python. If an attribute in a class or a named parameter in a function is of a mutable data type (e.g. a list or dict), never set its default value in the declaration of an object but always set it to None first, and then only later assign the default value in the class’s constructor, or the functions body, respectively. Sounds complicated? If you prefer the shortcut, the examples below are your friend. +If you are interested in the long story including the why‘s, read these discussions on Reddit and Twitter.

  • +
+
    # Bad
+    class Foo:
+        items = []
+
+    # Good
+    class Foo:
+        items = None
+        def __init__(self):
+            self.items = []
+
+
+    # Bad
+    class Foo:
+        def __init__(self, items=[]):
+            self.items = items
+
+    # Good
+    class Foo:
+        def __init__(self, items=None):
+            self.items = items or []
+
+
+    # Bad
+    def some_function(x, y, items=[]):
+        ...
+
+    # Good
+    def some_function(x, y, items=None):
+        items = items or []
+        ...
+
+
+
+
+

Commenting

+
    +
  • First of all, if the code needs comments to clarify its work, you should think about refactoring it. The best comment to code is the code itself.

  • +
  • Describe complex, possibly incomprehensible points and side effects in the comments

  • +
  • Separate # and the comment with one whitespace

  • +
+
    #bad comment
+    # good comment
+
+
+
    +
  • Use inline comments sparsely

  • +
  • Where used, inline comments shall have 2 whitespaces before the # and one whitespace thereafter

  • +
+
    x = y + z  # inline comment
+    str1 = str2 + str3  # another inline comment
+
+
+
    +
  • If a piece of code is poorly understood, mark the piece with a @TODO: tag and your name to support future refactoring:

  • +
+
    def get_ancestors_ids(self):
+        # @TODO: Do a cache reset while saving the category tree. CLAROS, YYYY-MM-DD
+        cache_name = f"{self._meta.model_name}_ancestors_{self.pk}"
+        cached_ids = cache.get(cache_name)
+        if cached_ids:
+            return cached_ids
+
+        ids = [c.pk for c in self.get_ancestors(include_self=True)]
+        cache.set(cache_name, ids, timeout=3600)
+
+        return ids
+
+
+
+
+

Type hints

+
    +
  • Use type hints in function signatures and module-scope variables. This is good documentation and can be used with linters for type checking and error checking. Use them whenever possible.

  • +
  • Use pyi files to type annotate third-party or extension modules.

  • +
+
+
+

Docstrings

+
    +
  • All Docstrings should be written in Numpy format. For a good tutorial on Docstrings, see Documenting Python Code: A Complete Guide

  • +
  • In a Docstring, summarize function/method behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions

  • +
  • Wrap Docstrings with triple double quotes (“””)

  • +
  • The description of the arguments must be indented

  • +
+
    def some_method(name, print=False):
+        """This function does something
+
+        Parameters
+        ----------
+        name : str
+            The name to use
+        print: bool, optional
+            A flag used to print the name to the console, by default False
+
+        Raises
+        ------
+        KeyError
+            If name is not found
+
+        Returns
+        -------
+        int
+            The return code
+        """
+        ...
+        return 0
+
+
+
+
+

Exceptions

+
    +
  • Raise specific exceptions and catch specific exceptions, such as KeyError, ValueError, etc.

  • +
  • Do not raise or catch just Exception, except in rare cases where this is unavoidable, such as a try/except block on the top-level loop of some long-running process. For a good tutorial on why this matters, see The Most Diabolical Python Antipattern.

  • +
  • Minimize the amount of code in a try/except block. The larger the body of the try, +the more likely that an exception will be raised by a line of code that you didn’t expect to raise an exception.

  • +
+
+
+

Imports

+
    +
  • Avoid creating circular imports by importing modules more specialized than the one you are editing

  • +
  • Relative imports are forbidden (PEP-8 only “highly discourages” them). Where absolutely needed, the from future import absolute_import syntax should be used (see PEP-328)

  • +
  • Never use wildcard imports (from <module> import *). Always be explicit about what you’re importing. Namespaces make code easier to read, so use them.

  • +
  • Break long imports using parentheses and indent by 4 spaces. Include the trailing comma after the last import and place the closing bracket on a separate line

  • +
+
    from my_pkg.utils import (
+        some_utility_method_1,
+        some_utility_method_2,
+        some_utility_method_3,
+        some_utility_method_4,
+        some_utility_method_5,
+    )
+
+
+
    +
  • Imports should be written in the following order, separated by a blank line:

    +
      +
    1. build-in modules

    2. +
    3. third-party modules

    4. +
    5. local application/library specific imports

    6. +
    +
  • +
+
    import logging
+    import os
+    import typing as T
+
+    import pandas as pd
+    import numpy as np
+
+    import axtreme
+    import axtreme.my_module
+    from axtreme.my_module import my_function, MyClass
+
+
+
    +
  • Even if a Python file is intended to be used as executable / script file only, it shall still be importable as a module, and its import should not have any side effects. Its main functionality shall hence be in a main() function, so that the code can be imported as a module for testing or being reused in the future:

  • +
+
    def main():
+        ...
+
+    if __name__ == "__main__":
+        main()
+
+
+
+
+

Unit-tests

+
    +
  • Use pytest as the preferred testing framework.

  • +
  • The name of a test shall clearly express what is being tested.

  • +
  • Each test should preferably check only one specific aspect.

  • +
+
    # Bad
+    def test_smth():
+        result = f()
+        assert isinstance(result, list)
+        assert result[0] == 1
+        assert result[1] == 2
+        assert result[2] == 3
+        assert result[3] == 4
+
+    # Good
+    def test_smth_type():
+        result = f()
+        assert isinstance(result, list), "Result should be list"
+
+    def test_smth_values():
+        result = f()
+        assert set(result) == set(expected), f"Result should be {set(expected)}"
+
+
+
+
+

And finally: It is a bad idea to use

+
    +
  • global variables.

  • +
  • iterators where they can be replaced by vectorized operations.

  • +
  • lambda where it is not required.

  • +
  • map and lambda where it can be replaced by a simple list comprehension.

  • +
  • multiple nested maps and lambdas.

  • +
  • nested functions. They are hard to test and debug.

  • +
+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.acquisition.html b/_autosummary/axtreme.acquisition.html new file mode 100644 index 00000000..5c1a742c --- /dev/null +++ b/_autosummary/axtreme.acquisition.html @@ -0,0 +1,480 @@ + + + + + + + + + axtreme.acquisition - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.acquisition

+

Modules

+
+ + + + + + +

qoi_look_ahead

QoILookAhead acquisition function that looks ahead at possible models and optimize according to a quantity of interest.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.acquisition.qoi_look_ahead.QoILookAhead.html b/_autosummary/axtreme.acquisition.qoi_look_ahead.QoILookAhead.html new file mode 100644 index 00000000..aa8ea8ab --- /dev/null +++ b/_autosummary/axtreme.acquisition.qoi_look_ahead.QoILookAhead.html @@ -0,0 +1,782 @@ + + + + + + + + + QoILookAhead - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

QoILookAhead

+
+
+class axtreme.acquisition.qoi_look_ahead.QoILookAhead(model: SingleTaskGP, qoi_estimator: QoIEstimator, sampler: PosteriorSampler | None = None)
+

Bases: AcquisitionFunction

+

QoILookAhead is a generic acquisition function that estimates the usefulness of a design point.

+

It estimates the usefulness of a design point by:

+
    +
  • Creating a new model(s) (e.g the looking ahead) by including the design point in the training data.

    +
    +

    Note

    +

    The new model condition on the design point, it does not update hyperparameters.

    +
    +
  • +
  • Calculate the QoI with the new model, and find the variance of this distribution.

  • +
+

The design point that results in the lowest variance QoI is considered the most desireable.

+
+
Note on Optimisation:

Optimising the AcquisitionFunction is an important part of the DoE process. The stochasticity and smoothness of +the acquisition function determine what optimisers can be used. This acquisition function has the following +properties with the default setup:

+
+
Smoothness:

QoILookAhead is smooth (twice differentiable) if:

+
    +
  • The model used for instantiation produces smooth outputs.

  • +
  • A sampler produces smooth y values.

  • +
  • The method used to produce y_var estimates is smooth.

  • +
  • The QoIEstimator is smooth with respect to the model (e.g small changes in the model produce smooth +change in the QoIEstimator result.)

  • +
+

The default optimiser assume the QoI may not be smooth, and uses a gradient free optimiser. If your QoI is +smooth these setting should be overridden.

+
+
Stochasticity:

QoILookAhead is deterministic if all the above components are deterministic. +With default settings it is deterministic.

+
+
+
+
+__init__(model: SingleTaskGP, qoi_estimator: QoIEstimator, sampler: PosteriorSampler | None = None) None
+

QoILookAhead acquisition function.

+
+
Parameters:
+
    +
  • model

    A fitted model. Only SingleTaskGP models are currently supported.

    +
      +
    • General GpytorchModel may eventually be supported.

    • +
    +

  • +
  • qoi_estimator – A callable conforming to QoIEstimator protocol.

  • +
  • sampler

    A sampler that is used to sample fantasy observations for each candidate point. +If None, a MeanSampler is used. This then uses the mean of the posterior as the fantasy observation.

    +
    +

    Note

    +

    Sampler choice can effect the stochasticty and smoothness of the acquisition function. See class +docs for details.

    +
    +

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(model, qoi_estimator[, sampler])

QoILookAhead acquisition function.

add_module(name, module)

Add a child module to the current module.

apply(fn)

Apply fn recursively to every submodule (as returned by .children()) as well as self.

bfloat16()

Casts all floating point parameters and buffers to bfloat16 datatype.

buffers([recurse])

Return an iterator over module buffers.

children()

Return an iterator over immediate children modules.

compile(*args, **kwargs)

Compile this Module's forward using torch.compile().

cpu()

Move all model parameters and buffers to the CPU.

cuda([device])

Move all model parameters and buffers to the GPU.

double()

Casts all floating point parameters and buffers to double datatype.

eval()

Set the module in evaluation mode.

extra_repr()

Set the extra representation of the module.

float()

Casts all floating point parameters and buffers to float datatype.

forward(X)

Forward method for the QoI acquisition function.

get_buffer(target)

Return the buffer given by target if it exists, otherwise throw an error.

get_extra_state()

Return any extra state to include in the module's state_dict.

get_parameter(target)

Return the parameter given by target if it exists, otherwise throw an error.

get_submodule(target)

Return the submodule given by target if it exists, otherwise throw an error.

half()

Casts all floating point parameters and buffers to half datatype.

ipu([device])

Move all model parameters and buffers to the IPU.

load_state_dict(state_dict[, strict, assign])

Copy parameters and buffers from state_dict into this module and its descendants.

lookahead(x_point, y_point, yvar_point)

Performs a single lookahead calculation.

modules()

Return an iterator over all modules in the network.

named_buffers([prefix, recurse, ...])

Return an iterator over module buffers, yielding both the name of the buffer as well as the buffer itself.

named_children()

Return an iterator over immediate children modules, yielding both the name of the module as well as the module itself.

named_modules([memo, prefix, remove_duplicate])

Return an iterator over all modules in the network, yielding both the name of the module as well as the module itself.

named_parameters([prefix, recurse, ...])

Return an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself.

parameters([recurse])

Return an iterator over module parameters.

register_backward_hook(hook)

Register a backward hook on the module.

register_buffer(name, tensor[, persistent])

Add a buffer to the module.

register_forward_hook(hook, *[, prepend, ...])

Register a forward hook on the module.

register_forward_pre_hook(hook, *[, ...])

Register a forward pre-hook on the module.

register_full_backward_hook(hook[, prepend])

Register a backward hook on the module.

register_full_backward_pre_hook(hook[, prepend])

Register a backward pre-hook on the module.

register_load_state_dict_post_hook(hook)

Register a post hook to be run after module's load_state_dict is called.

register_module(name, module)

Alias for add_module().

register_parameter(name, param)

Add a parameter to the module.

register_state_dict_pre_hook(hook)

Register a pre-hook for the state_dict() method.

requires_grad_([requires_grad])

Change if autograd should record operations on parameters in this module.

set_X_pending([X_pending])

Informs the acquisition function about pending design points.

set_extra_state(state)

Set extra state contained in the loaded state_dict.

share_memory()

See torch.Tensor.share_memory_().

state_dict(*args[, destination, prefix, ...])

Return a dictionary containing references to the whole state of the module.

to(*args, **kwargs)

Move and/or cast the parameters and buffers.

to_empty(*, device[, recurse])

Move the parameters and buffers to the specified device without copying storage.

train([mode])

Set the module in training mode.

type(dst_type)

Casts all parameters and buffers to dst_type.

xpu([device])

Move all model parameters and buffers to the XPU.

zero_grad([set_to_none])

Reset gradients of all model parameters.

+
+

Attributes

+
+ + + + + + + + + + + + + + + +

T_destination

call_super_init

dump_patches

training

+
+
+
+forward(X: Tensor) Tensor
+

Forward method for the QoI acquisition function.

+

For each candidate point in x this acquisition function does the following:

+
    +
  • Fantasizes (via the chosen sampler) possible new observations (y) at this candidate point.

  • +
  • Trains a new GP with the additional (x,y_i) pair for each fantasy observation y_i.

  • +
  • Evaluates the qoi_estimator on these new GPs, and reports the variance in the resulting estimates.

  • +
+

This optimization will pick the point that resulted in the lowest mean variance in the QoI estimates.

+
+
Parameters:
+

X – (t_batch, 1, d) input points to evaluate the acquisiton function at.

+
+
Returns:
+

The output of the QoI acquisition function that will be optimized with shape (num_points,).

+
+
+
+

Todo

+
    +
  • This should be updated to use the FantasizeMixin. This is the botorch interface indicating +model.fantasize(X) is supported, which does a large chunk of the functionality below. The challenge is +model.fantasize(X) adds an additonal dimension at the start of all posteriors calculated e.g. +(num_fantasies, batch_shape, n, m). Unclear if our QoI methods can handle/respect the num_fantasies +dimension, of if the different fantasy models can easily be extracted. Revisit at a future date.

  • +
  • Consider making the jobs batchable or multiprocessed.

  • +
+
+
+ +
+
+lookahead(x_point: Tensor, y_point: Tensor, yvar_point: Tensor | None) Tensor
+

Performs a single lookahead calculation.

+

Adds a single additional datapoint to the GP, and determines the QoI with the new GP.

+
+
Parameters:
+
    +
  • x_point – (d,) The x location of the new point

  • +
  • y_point – (m,) The y (target) of the new point

  • +
  • yvar_point – (m,) The y_var of the new point

  • +
+
+
Returns:
+

(,) Variance of the QoI with the lookahead GP

+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.acquisition.qoi_look_ahead.html b/_autosummary/axtreme.acquisition.qoi_look_ahead.html new file mode 100644 index 00000000..509757d1 --- /dev/null +++ b/_autosummary/axtreme.acquisition.qoi_look_ahead.html @@ -0,0 +1,709 @@ + + + + + + + + + axtreme.acquisition.qoi_look_ahead - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.acquisition.qoi_look_ahead

+

QoILookAhead acquisition function that looks ahead at possible models and optimize according to a quantity of interest.

+

Functions

+
+ + + + + + + + + + + + + + + + + + +

average_observational_noise(new_points, ...)

Return the average observational noise.

closest_observational_noise(new_points, ...)

Find the closest point in a training dataset, and collect its observational noise.

conditional_update(model, X, Y, ...)

A wrapper around BatchedMultiOutputGPyTorchModel.condition_on_observations with a number of safety checks.

construct_inputs_qoi_look_ahead(model, ...)

This is how default arguments for acquisition functions are handled in Ax/Botorch.

reject_if_batched_model(model)

Helper function to reject batched model in code where they are not yet supported.

+
+

Classes

+
+ + + + + + +

QoILookAhead(model, qoi_estimator[, sampler])

QoILookAhead is a generic acquisition function that estimates the usefulness of a design point.

+
+
+
+axtreme.acquisition.qoi_look_ahead.average_observational_noise(new_points: Tensor, train_x: Tensor | None, train_yvar: Tensor) Tensor
+

Return the average observational noise.

+
+
Parameters:
+
    +
  • new_points – (n, d) The points to produce observational_noise.

  • +
  • train_x – (n’,d). This is not used, but is kept to keep a consistent function signature

  • +
  • train_yvar – (n’,m) The observational variance associated with each point.

  • +
+
+
Returns:
+

(n,m) Tensor with the variance for each of the new_points.

+
+
+

Details: +This function is useful for Non-Batched SingleTaskGPs because they will always have arguments of these dimension.

+
+

Warning

+

Certain pattern of homoskedasticity cause this method to perform poorly, causing the acquisition function to +recommend suboptimal points (as compared to closest_observational_noise). The trade off is derivative based +optimisation techniques can be used. See Issue #213 for details.

+
+
+ +
+
+axtreme.acquisition.qoi_look_ahead.closest_observational_noise(new_points: Tensor, train_x: Tensor, train_yvar: Tensor) Tensor
+

Find the closest point in a training dataset, and collect its observational noise.

+
+
Parameters:
+
    +
  • new_points – (n, d) The points to produce observational_noise. Features should be normalise to [0,1] square.

  • +
  • train_x – (n’,d) The points to compare similarity to. Features should be normalise to [0,1] square.

  • +
  • train_yvar – (n’,m) The observational variance associated with each point.

  • +
+
+
Returns:
+

(n,m) Tensor with the variance for each of the new_points.

+
+
+

Details: +This function is useful for Non-Batched SingleTaskGPs because they will always have arguments of these dimension.

+
+

Warning

+

This function is not smooth, meaning optimizers that use gradient (1st or 2nd order derivatives) such as +L-BFGS-B will not work. The trade off is it is more robust to the effect of patterns in yvar than +average_observational_noise . See Issue #213 for details.

+
+
+ +
+
+axtreme.acquisition.qoi_look_ahead.conditional_update(model: Model, X: Tensor, Y: Tensor, observation_noise: Tensor | None) Model
+

A wrapper around BatchedMultiOutputGPyTorchModel.condition_on_observations with a number of safety checks.

+

This function adds an additional datapoint to the model, preserving the dimension of the original model. Does not +changing any of the models hyperparameters. This is like training a new SingleTaskGP with all the datapoints +(Hyperparameters are not fit in SingleTaskGP).

+
+
Parameters:
+
    +
  • model (Model) – The model to update.

  • +
  • X

    As per condition_on_observations. Shape (*b, n’, d).

    +
    +

    Note

    +

    condition_on_observations expects this to be in the “model” space. It will not be +transformed by the input_transform on the model.

    +
    +

  • +
  • Y

    As per condition_on_observations. Shape (*b, n’, m).

    +
    +

    Note

    +

    condition_on_observations expects this to be in the “output/problem” space (not model space). +It will be transformed by the output_transform on the model.

    +
    +

  • +
  • observation_noise (torch.Tensor | None) –

    Used as the noise argument in condition_on_observations. Shape +should match Y (*b, n’, m).

    +
    +

    Note

    +

    condition_on_observations expects this to be in the “model” space. It will not be +transformed by the output_transform on the model.

    +
    +

  • +
+
+
Returns:
+

    +
  • GP with the same underlying structure, including the new points, and the same original number of dimensions.

  • +
+

+
+
+
+
Developer Note:

There are different ways to create a fantasy model. The following were considered:

+
    +
  • BatchedMultiOutputGPyTorchModel.condition_on_observations: well documented interface producing a GP of +the same format.

  • +
  • model.get_fantasy_model: This is a Gpytorch implementation. Interface uses different notation, and +input shape need to be manually adjusted depending on the model.

  • +
  • model.fantasize: This method would be very convient for our wider purpose, but its posteriors is of shape +(num_fantasies, batch_shape, n, m). Unclear if our QoI methods can handle/respect the num_fantasies dim.

  • +
+

Revisit this at a later date.

+
+
+
+ +
+
+axtreme.acquisition.qoi_look_ahead.construct_inputs_qoi_look_ahead(model: SingleTaskGP, qoi_estimator: QoIEstimator, sampler: PosteriorSampler, **_: dict[str, Any]) dict[str, Any]
+

This is how default arguments for acquisition functions are handled in Ax/Botorch.

+
+
Context

When Ax.BOTORCH gets instantiated, construction arguments for the acquisition function can be provided. +These are passed through Ax as a set of Kwargs

+
+
+
+
Parameters:
+

defaults. (This function takes a subset of the acquisition functions __init__() args and can add)

+
+
Returns:
+

Args for the Botorch acquisition function __init__() (output).

+
+
+
+

Note

+

This functionality allows Ax to pass generic arguments without needing to know which acquisition function they +will be passed to. Interestingly, this functionality is provided by the BoTorch package, even though it seems +like it should be the responsibility of Ax. This issue is discussed in detail here: GitHub discussion.

+
+
+ +
+
+axtreme.acquisition.qoi_look_ahead.reject_if_batched_model(model: SingleTaskGP) None
+

Helper function to reject batched model in code where they are not yet supported.

+
+
Parameters:
+

model – The model to check

+
+
Returns:
+

Raise not yet implements in model is batched. Otherwise None.

+
+
+
+
Details:

botorch models can have batched training data, and or batched.

+
    +
  • gp batch prediction (non-batched model):

    +
      +
    • train_x = (n,d) # This is a single GP

    • +
    • train_y = (n,m)

    • +
    • predicting_x = (b,n’,d)

    • +
    • result will be: (b, n’,m).

      +
        +
      • There are b seperate joint distribution (each with n points, a t targets)

      • +
      +
    • +
    +
  • +
  • batched gps model:

    +
      +
    • train_x = (b_gp,n,d)

    • +
    • train_y = (b_gp,n,m)

      +
        +
      • b_gp seperate GPs, where each GP gets all its own hyperparams etc trained on (n,d) point.

      • +
      +
    • +
    • prediciton_x = (n’,d)

    • +
    • result will be: (b_gp, n’,m).

      +
        +
      • Each of the seperate b_gp gps makes its own estimate of the joint distribution.

      • +
      +
    • +
    +
  • +
+

More details: BoTorch batching

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d.html b/_autosummary/axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d.html new file mode 100644 index 00000000..d158fdaa --- /dev/null +++ b/_autosummary/axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d.html @@ -0,0 +1,582 @@ + + + + + + + + + BatchInvariantSampler2d - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

BatchInvariantSampler2d

+
+
+class axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d(sampler: Sampler[int] | Iterable[int], batch_shape: Size)
+

Bases: Sampler[list[list[int]]]

+

Returns 2d batchs where the final dataset in invariant to changes in the last batch dimension.

+
+
The standard BatchSampler
    +
  • has 1 row that it batches in sizes b.

  • +
  • returns items of shape (1) * b

  • +
+
+
This BatchSampler has:
    +
  • n rows that are batched in size b.

  • +
  • returns batches of n * b

  • +
+
+
+

Importantly, the concatenated batches (along the last dimension) will alway the same 2d matrix, +regardless of the bach size.

+

Examples

+
>>> Conceptually the full dataset might have the following indexs
+[[ 1, 3, 5]
+ [ 2, 4, 6]]
+
+
+
>>> If batched along index = -1, with batch size 2 will return results as follows
+b1= [[1,3],   b2= [[5],
+     [2,4]]]       [6]]
+
+
+
>>> concat([b1, b2], axis=-1)
+[[ 1, 3, 5]
+ [ 2, 4, 6]]
+
+
+

This is important when the final dataset produced should be invariate to changes in b.

+
+

Note

+
    +
  • The final batch can return a partial batch (n rows, less than b columns)

  • +
  • Related to issue #76

  • +
+
+
+

Todo

+
+
This is a very specific case because its cater to general case.
    +
  • Can we make a more general 2d case? The batched dim needs to be filled last. +Any aggregation is then expected on the batch dim

  • +
  • Can we make a general higher dim case?

  • +
  • +
    Should we just take multiple samplers and batch them in parallel?
      +
    • Pro: Might be cleaner conceptually

    • +
    • Con: When we treat as a dataset we want to get through all data before we start repeating data

    • +
    +
    +
    +
  • +
+
+
+
+
+
+__init__(sampler: Sampler[int] | Iterable[int], batch_shape: Size) None
+

Will produce batch (along the rows) of a 2d batch.

+
+
Parameters:
+
    +
  • sampler (Sampler[int] | Iterable[int]) – Sampler (e.g RandomSampler or SerquentialSampler) to be batched. +- Must be Sized (e.g have __len__) +- See torch DataLoader implmentation for an examples

  • +
  • batch_shape (torch.Size) – The batch shape created of the underlieing sample.

  • +
+
+
+
+ +

Methods

+
+ + + + + + +

__init__(sampler, batch_shape)

Will produce batch (along the rows) of a 2d batch.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.batch_invariant_sampler.html b/_autosummary/axtreme.data.batch_invariant_sampler.html new file mode 100644 index 00000000..0c0bb492 --- /dev/null +++ b/_autosummary/axtreme.data.batch_invariant_sampler.html @@ -0,0 +1,516 @@ + + + + + + + + + axtreme.data.batch_invariant_sampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.batch_invariant_sampler

+

Contains samplers where the total dataset procuded is not effect by the size of the batch dimension used.

+

Batch invariance in 1d. +This can be achieved using the standard BatchSampler, for example:

+
>>> from torch.utils.data import BatchSampler
+>>> data = [1, 2, 3, 4, 5]
+>>> list(BatchSampler(data, batch_size=3, drop_last=False))
+[1, 2, 3], [4, 5, 6]]
+>>> list(BatchSampler(data, batch_size=2, drop_last=False))
+[[1, 2], [3, 4], [5]]
+
+
+

Regardless of batch size, these results can be concatenated along the batch dimension to prodcude the same result.

+

Batch invariance in 2d:

+
>>> data = [1, 2, 3, 4, 5, 6]
+We want to turn things into a 2d dataset, where the dimension being batched along (e.g rows) does not effect the
+final data produced. This will not be the case with MultiBatchSampler:
+
+
+
>>> list(MultiBatchSampler(data, batch_shape=torch.Size([2, 3])))
+[[
+    [1, 2, 3],
+    [4, 5, 6]
+]]
+>>> b1, b2, b3 = list(MultiBatchSampler(data, batch_shape=torch.Size([2, 1])))
+>>> print(f"{b1=},{b2=},{b3=})
+b1= [[1], b2= [[3], b3= [[5],
+     [2]]      [4]]      [6]]
+>>>  concat([b1,b2,b3], axis = -1)
+[[ 1, 3, 5]
+ [ 2, 4, 6]]
+
+
+

The datasets produced will put data in different location based on the batch shape. +This is aproblem if you will be aggrgating (e.g over rows), and were expecting the batches to be invariant over that +dimension.

+

Provide invariante batching in a specific dimension.

+

Classes

+
+ + + + + + +

BatchInvariantSampler2d(sampler, batch_shape)

Returns 2d batchs where the final dataset in invariant to changes in the last batch dimension.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.dataset.MinimalDataset.html b/_autosummary/axtreme.data.dataset.MinimalDataset.html new file mode 100644 index 00000000..dc66bf8a --- /dev/null +++ b/_autosummary/axtreme.data.dataset.MinimalDataset.html @@ -0,0 +1,552 @@ + + + + + + + + + MinimalDataset - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MinimalDataset

+
+
+class axtreme.data.dataset.MinimalDataset(data: Sequence[T] | T)
+

Bases: Dataset[T]

+

Creates a Dataset over a list-like data source.

+
+

Note

+

list, np.array or tensor forfill the __getitem__ and __len__ requirement directly - but this makes +them conform with the __add__ behaviour defined for datasets.

+
+
+
+__init__(data: Sequence[T] | T) None
+

Creates a Dataset over a list-like data source.

+
+
Parameters:
+
    +
  • data – Supports being indexed (supports __getitem__) and len, where index values are considered datapoints.

  • +
  • e.g (-)

  • +
  • DataLoader. (- Datapoints should be compatible with) –

      +
    • General work with numerics and matrixes

    • +
    • Specifics of what DataLoader consume from datasets see torch._utils.collate.default_collate

    • +
    +

  • +
+
+
+

Examples

+
>>> data = [1, 2, 3]
+>>> ds = MinimalDataset(data)
+>>> ds[0]
+1
+
+
+
>>> data = np.array([[1, 2, 3], [4, 5, 6]])
+>>> ds = MinimalDataset(data)
+>>> ds[0]
+1p.array([1,2,3])
+
+
+
>>> data = torch.tensor([[1], [2]])
+>>> ds = MinimalDataset(data)
+>>> ds[0]
+torch.tensor([1])
+
+
+
+ +

Methods

+
+ + + + + + +

__init__(data)

Creates a Dataset over a list-like data source.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.dataset.html b/_autosummary/axtreme.data.dataset.html new file mode 100644 index 00000000..6a44f212 --- /dev/null +++ b/_autosummary/axtreme.data.dataset.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.data.dataset - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.dataset

+

Contains objects and helpers for creating data unit testing.

+

Classes

+
+ + + + + + +

MinimalDataset(data)

Creates a Dataset over a list-like data source.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.fixed_random_sample.FixedRandomSampler.html b/_autosummary/axtreme.data.fixed_random_sample.FixedRandomSampler.html new file mode 100644 index 00000000..e0261ef2 --- /dev/null +++ b/_autosummary/axtreme.data.fixed_random_sample.FixedRandomSampler.html @@ -0,0 +1,562 @@ + + + + + + + + + FixedRandomSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

FixedRandomSampler

+
+
+class axtreme.data.fixed_random_sample.FixedRandomSampler(data_source: Sized, num_samples: int | None = None, seed: int | None = None, *, replacement: bool = False)
+

Bases: Sampler[int]

+

Samples elements randomly.

+

This sampler differs from torch’s RandomSampler as it will return the same random sample each time it is +iterated in full. If without replacement, then sample from a shuffled dataset. If with replacement, then user can +specify num_samples to draw.

+
+
+__init__(data_source: Sized, num_samples: int | None = None, seed: int | None = None, *, replacement: bool = False) None
+

Initalise the sampler.

+
+
Parameters:
+
    +
  • data_source – dataset to sample from

  • +
  • replacement – samples are drawn on-demand with replacement if True, default=``False``

  • +
  • num_samples – number of samples to draw, default=`len(dataset)`.

  • +
  • seed – seed for the random number generator, if None one will be allocated randomly.

  • +
+
+
+
+ +

Methods

+
+ + + + + + +

__init__(data_source[, num_samples, seed, ...])

Initalise the sampler.

+
+

Attributes

+
+ + + + + + + + + + + + +

num_samples

data_source

replacement

+
+
+
+data_source: Sized
+
+ +
+
+property num_samples: int
+
+ +
+
+replacement: bool
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.fixed_random_sample.html b/_autosummary/axtreme.data.fixed_random_sample.html new file mode 100644 index 00000000..dafb2eb3 --- /dev/null +++ b/_autosummary/axtreme.data.fixed_random_sample.html @@ -0,0 +1,483 @@ + + + + + + + + + axtreme.data.fixed_random_sample - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.fixed_random_sample

+

A copy of pytorch’s RandomSampler that uses the same random sample for each iteration.

+

This is basically an identical copy, except the Generator has been swapped for a seed, which creates the same generator +each time the samples are iterated through (e.g the DataLoader is run to completion).

+

Classes

+
+ + + + + + +

FixedRandomSampler(data_source[, ...])

Samples elements randomly.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.html b/_autosummary/axtreme.data.html new file mode 100644 index 00000000..6cc17984 --- /dev/null +++ b/_autosummary/axtreme.data.html @@ -0,0 +1,498 @@ + + + + + + + + + axtreme.data - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data

+

Modules

+
+ + + + + + + + + + + + + + + + + + + + + + + + +

batch_invariant_sampler

Contains samplers where the total dataset procuded is not effect by the size of the batch dimension used.

dataset

Contains objects and helpers for creating data unit testing.

fixed_random_sample

A copy of pytorch's RandomSampler that uses the same random sample for each iteration.

importance_dataset

Dataset that return importance sample information in the form (data, importance_weight).

multi_dim_batch_sampler

Allows retuning batches of data of an arbitrary dimension.

numpy_file_dataset

Datasets to help work with numpy files (.npy).

sizable_sequential_sample

Sequential sampling.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.importance_dataset.ImportanceAddedWrapper.html b/_autosummary/axtreme.data.importance_dataset.ImportanceAddedWrapper.html new file mode 100644 index 00000000..8daf6af8 --- /dev/null +++ b/_autosummary/axtreme.data.importance_dataset.ImportanceAddedWrapper.html @@ -0,0 +1,525 @@ + + + + + + + + + ImportanceAddedWrapper - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

ImportanceAddedWrapper

+
+
+class axtreme.data.importance_dataset.ImportanceAddedWrapper(data_dataset: Dataset[T_co], importance_dataset: Dataset[T_co])
+

Bases: StackDataset[Tuple[T_co, …]]

+

Thin wrapper makes the method for creating the dataset more explicit, and ensure order and type of output.

+
+
+__init__(data_dataset: Dataset[T_co], importance_dataset: Dataset[T_co]) None
+

Ensures the StackDataset is created as a tuple regardless of the way args are passed.

+
+ +

Methods

+
+ + + + + + +

__init__(data_dataset, importance_dataset)

Ensures the StackDataset is created as a tuple regardless of the way args are passed.

+
+

Attributes

+
+ + + + + + +

datasets

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.importance_dataset.ImportanceIndexWrapper.html b/_autosummary/axtreme.data.importance_dataset.ImportanceIndexWrapper.html new file mode 100644 index 00000000..4a2cd55c --- /dev/null +++ b/_autosummary/axtreme.data.importance_dataset.ImportanceIndexWrapper.html @@ -0,0 +1,530 @@ + + + + + + + + + ImportanceIndexWrapper - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

ImportanceIndexWrapper

+
+
+class axtreme.data.importance_dataset.ImportanceIndexWrapper(dataset: Dataset[T_np_interface], importance_idx: int)
+

Bases: Dataset[tuple[T_np_interface, float]]

+

Wraps an existing dataset, returning a column/index of the item as the importance weight.

+
+
+__init__(dataset: Dataset[T_np_interface], importance_idx: int) None
+

Wrap an existing dataset, returning part of the item as the importance weight.

+
+
Parameters:
+
    +
  • dataset – A dataset, where one of the columns should be used as an importance weight. +- Note: Currently only datasets that return numpy or torch tensors are supported

  • +
  • importance_idx – the column index containing the importance weights.

  • +
+
+
+
+

Todo

+
    +
  • Generalise this to deal with other types of dataset output (list, numpy etc).

  • +
+
+
+ +

Methods

+
+ + + + + + +

__init__(dataset, importance_idx)

Wrap an existing dataset, returning part of the item as the importance weight.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.importance_dataset.html b/_autosummary/axtreme.data.importance_dataset.html new file mode 100644 index 00000000..ee54baf8 --- /dev/null +++ b/_autosummary/axtreme.data.importance_dataset.html @@ -0,0 +1,502 @@ + + + + + + + + + axtreme.data.importance_dataset - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.importance_dataset

+

Dataset that return importance sample information in the form (data, importance_weight).

+
+
Dev details:

Datasets can return a variety of things when __get_item__ is called, for example: +- Tuples +- Dicts

+

The dataloader will respect objects like dict and tuple, and will convert float/int/list/numpy content into +tensors as it is assumed to be data. +- By default done by collate_fn arg of Dataloader. +- For defaults see torch.utils.data._utils.collate.default_collate

+

While this is straight forward to implement, typing can be a challenge (torch.utils.data.Dataset provides some +guidances, but appears they found it challenging too).

+
+
+
+

Todo

+
    +
  • Revisit the typing and the implications of covariate/contravariant etc.

  • +
+
+

Classes

+
+ + + + + + + + + +

ImportanceAddedWrapper(data_dataset, ...)

Thin wrapper makes the method for creating the dataset more explicit, and ensure order and type of output.

ImportanceIndexWrapper(dataset, importance_idx)

Wraps an existing dataset, returning a column/index of the item as the importance weight.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.multi_dim_batch_sampler.MultiBatchSampler.html b/_autosummary/axtreme.data.multi_dim_batch_sampler.MultiBatchSampler.html new file mode 100644 index 00000000..d546957d --- /dev/null +++ b/_autosummary/axtreme.data.multi_dim_batch_sampler.MultiBatchSampler.html @@ -0,0 +1,564 @@ + + + + + + + + + MultiBatchSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MultiBatchSampler

+
+
+class axtreme.data.multi_dim_batch_sampler.MultiBatchSampler(sampler: Sampler[int] | Iterable[int], batch_shape: Size, partial_batch_dim: None | int = -1)
+

Bases: Sampler[list[int]]

+

Reads the entire sampler into batches of shape batch_shape.

+

The final batch may not have enough samples to completely fill the batch shape. Behaviour is then as follows:

+
    +
  • +
    If partial_batch_dim is not None, attempt to batch samples allowing this dim to be variable in size. E.g:
    >>> batch_shape = torch.Size([3, 5])
    +>>> partial_batch_index = -1
    +try: remaining_samples.view([3,-1])
    +
    +
    +
    +
    +
  • +
+

This check is performed up front and the sampler will throw and error.

+
+

Warning

+
    +
  • If the batch shape changes, even in the partial_batch_index dimension, data will be returned in a different +order.

  • +
  • See BatchSampler2d for details.

  • +
+
+
+

Todo

+
    +
  • Determing the right approach for handling partial batch that requires more than one parital index. +e.g fit 5 items into batch_shape = torch.Size([3,2])

  • +
  • Perhaps return a new batch that is no bigger than the original in any dimension. This batcher is likely +for gp throughput, so then the batches only have performance not logical meaning.

  • +
+
+
+
+__init__(sampler: Sampler[int] | Iterable[int], batch_shape: Size, partial_batch_dim: None | int = -1) None
+

Allows you to produces batchs of arbitrary shape.

+
+
Parameters:
+
    +
  • sampler (Sampler[int] | Iterable[int]) –

    Sampler (e.g RandomSampler or SerquentialSampler).

    +
      +
    • See torch DataLoader implementation for an examples

    • +
    +

  • +
  • batch_shape (torch.Size) – The batch shape created of the underling sample.

  • +
  • partial_batch_dim

    Dimension of the batch that can be partially filled if there is not enough samples in +sampler.

    +
      +
    • Currently only one dimension can be partially filled

    • +
    • if None, no dimension is allowed to be partially filled

    • +
    +

  • +
+
+
+
+ +

Methods

+
+ + + + + + +

__init__(sampler, batch_shape[, ...])

Allows you to produces batchs of arbitrary shape.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.multi_dim_batch_sampler.html b/_autosummary/axtreme.data.multi_dim_batch_sampler.html new file mode 100644 index 00000000..577216f2 --- /dev/null +++ b/_autosummary/axtreme.data.multi_dim_batch_sampler.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.data.multi_dim_batch_sampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.multi_dim_batch_sampler

+

Allows retuning batches of data of an arbitrary dimension.

+

Classes

+
+ + + + + + +

MultiBatchSampler(sampler, batch_shape[, ...])

Reads the entire sampler into batches of shape batch_shape.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.numpy_file_dataset.NumpyFileDataset.html b/_autosummary/axtreme.data.numpy_file_dataset.NumpyFileDataset.html new file mode 100644 index 00000000..2a8f6601 --- /dev/null +++ b/_autosummary/axtreme.data.numpy_file_dataset.NumpyFileDataset.html @@ -0,0 +1,587 @@ + + + + + + + + + NumpyFileDataset - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

NumpyFileDataset

+
+
+class axtreme.data.numpy_file_dataset.NumpyFileDataset(root_dir: str | Path)
+

Bases: Dataset[Tensor]

+

Helper to work with directories of .npy data.

+
+

Note

+
    +
  • Highly recommened to use an in memory dataset if possible. This is typically a bottleneck.

  • +
  • +
    Using with a sequential sampler will be significantly faster because this performs rudimental cacheing.
      +
    • Random sampling will require from disk read for EVERY datapoint. Suggest randomise the save files.

    • +
    +
    +
    +
  • +
+
+
+
Assumes:
    +
  • Each row is a data point

  • +
  • Each file has the same number of datapoints within it.

  • +
+
+
Dev:
+
+
+
+

Todo

+
    +
  • +
    This is slow compared to reading from memory. 100k dataset (3ms for memory, 20s with this dataloader)
      +
    • This is because EVERY SINGLE datapoint requireds a new read from disk.

    • +
    • +
      TODO: Consider different file types that might be more appropriate (row specfic access)
        +
      • HDF5?

      • +
      +
      +
      +
    • +
    • +
      TODO: consider intergration with an imporance weight
        +
      • Look at the example with images, can return many things

      • +
      • npz allows you to combine multiple arrays, could have soem logic if other array none, no imporance.

      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
+
+
+
Answered:
    +
  • +
    Is Sampler a more approapriate way of framing this?
      +
    • No. The samples class just take an existing dataset and shuffles it. Like shuffle in dataloader.

    • +
    +
    +
    +
  • +
+
+
+
+
+__init__(root_dir: str | Path) None
+

Initialise the Dataset.

+
+

Note

+

Data should be loaded lazily (in __getitem__, not here)

+
+
+
Parameters:
+

root_dir (string) – Directory with .npy files

+
+
+
+ +

Methods

+
+ + + + + + +

__init__(root_dir)

Initialise the Dataset.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.numpy_file_dataset.html b/_autosummary/axtreme.data.numpy_file_dataset.html new file mode 100644 index 00000000..7cf6abf2 --- /dev/null +++ b/_autosummary/axtreme.data.numpy_file_dataset.html @@ -0,0 +1,515 @@ + + + + + + + + + axtreme.data.numpy_file_dataset - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.numpy_file_dataset

+

Datasets to help work with numpy files (.npy).

+

Functions

+
+ + + + + + +

collect_np_file(file_path)

+
+

Classes

+
+ + + + + + +

NumpyFileDataset(root_dir)

Helper to work with directories of .npy data.

+
+
+
+axtreme.data.numpy_file_dataset.collect_np_file(file_path: str | Path) ndarray[Any, dtype[float64]]
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.sizable_sequential_sample.SizableSequentialSampler.html b/_autosummary/axtreme.data.sizable_sequential_sample.SizableSequentialSampler.html new file mode 100644 index 00000000..157c6f4e --- /dev/null +++ b/_autosummary/axtreme.data.sizable_sequential_sample.SizableSequentialSampler.html @@ -0,0 +1,550 @@ + + + + + + + + + SizableSequentialSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

SizableSequentialSampler

+
+
+class axtreme.data.sizable_sequential_sample.SizableSequentialSampler(data_source: Sized, num_samples: None | int = None)
+

Bases: Sampler[int]

+

Samples elements sequentially, always in the same order.

+

Follows the pattern in RandomSampler to allow for sampling a specific number of samplers. +This can be smaller or larger than the amount in the dataset.

+
+
+__init__(data_source: Sized, num_samples: None | int = None) None
+

Create the sampler.

+
+
Parameters:
+
    +
  • data_source (Dataset) – dataset to sample from

  • +
  • num_samples (int) – number of samples to draw, default=`len(dataset)`.

  • +
+
+
+
+ +

Methods

+
+ + + + + + +

__init__(data_source[, num_samples])

Create the sampler.

+
+

Attributes

+
+ + + + + + + + + +

num_samples

data_source

+
+
+
+data_source: Sized
+
+ +
+
+property num_samples: int
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.data.sizable_sequential_sample.html b/_autosummary/axtreme.data.sizable_sequential_sample.html new file mode 100644 index 00000000..342feafc --- /dev/null +++ b/_autosummary/axtreme.data.sizable_sequential_sample.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.data.sizable_sequential_sample - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.data.sizable_sequential_sample

+

Sequential sampling.

+

Classes

+
+ + + + + + +

SizableSequentialSampler(data_source[, ...])

Samples elements sequentially, always in the same order.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.distributions.helpers.html b/_autosummary/axtreme.distributions.helpers.html new file mode 100644 index 00000000..a03ebcc9 --- /dev/null +++ b/_autosummary/axtreme.distributions.helpers.html @@ -0,0 +1,580 @@ + + + + + + + + + axtreme.distributions.helpers - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.distributions.helpers

+

Helpers built ontop of the distributions module.

+
+

Todo

+

These are seperate from utils becuase of circular import caused by ApproximateMixture. Potentially there is a +more elegant solution.

+
+

Functions

+
+ + + + + + + + + + + + +

approx_mixture_cdf_resolution(dist)

To what resolution (number of decimal places) is cdf output accurate to.

dist_cdf_resolution(dist)

To what resolution (number of decimal places) is cdf output accurate to.

mixture_cdf_resolution(dist)

To what resolution (number of decimal places) is cdf output accurate to.

+
+
+
+axtreme.distributions.helpers.approx_mixture_cdf_resolution(dist: ApproximateMixture) float
+

To what resolution (number of decimal places) is cdf output accurate to.

+

This is identical to mixture_cdf_resolution except for the conservatism introduced by the approximation. +See ApproximateMixture “Impact of Approximation:” for details

+
+ +
+
+axtreme.distributions.helpers.dist_cdf_resolution(dist: Distribution) float
+

To what resolution (number of decimal places) is cdf output accurate to.

+

This is effected by:

+
+
    +
  • The numeric precision of the datatype q is stored with (e.g float32)

  • +
  • The internal calculation and numerical error incurrred by them.

  • +
+
+
+
Returns:
+

10**precision, where precision is the decimal position. E.g if accurate to 3 decimal places, return 0.001

+
+
+
+

Note

+
    +
  • We are interested in the cdf(x) -> q accuracy, as this is used heavily.

  • +
  • icdf(q) -> x does not have the same resolution as detailed here. The difference in results increases with x.

  • +
  • +
    This number/method is determined emprically. Tests show it is a good bound for float16 and float32.

    Assumed to hold for float64

    +
    +
    +
  • +
+
+
+ +
+
+axtreme.distributions.helpers.mixture_cdf_resolution(dist: MixtureSameFamily) float
+

To what resolution (number of decimal places) is cdf output accurate to.

+

This compared to dist_cdf_resolution this is also impacted by weights*components.

+

This is effected by:

+
+
    +
  • The numeric precision of the datatype q is stored with (e.g float32)

  • +
  • The internal calculation and numerical error incurred by them.

  • +
  • Combination of weight*components

  • +
+
+
+
Returns:
+

10**precision, where precision is the decimal position. E.g if accurate to 3 decimal places, return 0.001

+
+
+
+

Note

+
    +
  • We are interested in the cdf(x) -> q accuracy, as this is used heavily.

  • +
  • icdf(q) -> x does not have the same resolution as this. The difference in results increases with x.

  • +
  • This number/method is determined emprically. Tests show it is a good bound for float16 and float32. +Assumed to hold for float64

  • +
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.distributions.html b/_autosummary/axtreme.distributions.html new file mode 100644 index 00000000..ca7983fa --- /dev/null +++ b/_autosummary/axtreme.distributions.html @@ -0,0 +1,491 @@ + + + + + + + + + axtreme.distributions - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.distributions

+

Modules

+
+ + + + + + + + + + + + + + + +

helpers

Helpers built ontop of the distributions module.

icdf

Helper for finding inverse cdf for function that do not have an icdf method.

mixture

Mixture model variants.

utils

helpers for working with distribution.

+
+
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.distributions.icdf.html b/_autosummary/axtreme.distributions.icdf.html new file mode 100644 index 00000000..abb91491 --- /dev/null +++ b/_autosummary/axtreme.distributions.icdf.html @@ -0,0 +1,570 @@ + + + + + + + + + axtreme.distributions.icdf - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.distributions.icdf

+

Helper for finding inverse cdf for function that do not have an icdf method.

+

Functions

+
+ + + + + + + + + +

icdf(dist, q, max_acceptable_error, opt_bounds)

Calculated the inverse CDF for each distribution in a batch.

icdf_1d(dist, quantile, ...)

Calculates inverse CDF values for distributions which do not have a icdf function.

+
+
+
+axtreme.distributions.icdf.icdf(dist: Distribution, q: Tensor, max_acceptable_error: float, opt_bounds: Tensor) Tensor
+

Calculated the inverse CDF for each distribution in a batch.

+

This method is useful when the distrbution does not have an icdf method. In this case the CDF can be run repeatidly +until we find the x where cdf(`x) == quantile`. We use optimisation to make this search effecient.

+
+
Parameters:
+
    +
  • dist – (*batch_shape,) mixture distribution producing events of event_shape samples

  • +
  • q – quantile to find the inverse cdf of. Must be boardcastable up to (*batch_shape,). Must not have more +dimensions than *batch_shape (only 1 q can be passed to each of the distributions in the batch.)

  • +
  • opt_bounds – (2,`*batch`). The lower and lower x bounds withing which the q can be found. If unknown, set to +a very large range. opt_bounds.shape[1:] must be broadcastable to dist.batch_shape.

  • +
  • max_acceptable_error – return values must be within icdf(q +/- max_acceptable_error)

  • +
+
+
Returns:
+

Tensor of shape (dist.batch_shape) of the icdf(x) results.

+
+
+
+ +
+
+axtreme.distributions.icdf.icdf_1d(dist: Distribution, quantile: float, max_acceptable_error: float, bounds: tuple[float, float]) Tensor
+

Calculates inverse CDF values for distributions which do not have a icdf function.

+

Some distributions do not have an inverse CDF function. In this case the CDF can be run repeatidly until we find the +x where cdf(`x) == quantile`. We use optimisation to make this search effecient. This function only supports +distribution with 1d input and output.

+
+
Parameters:
+
    +
  • dist

    This expects a Distribution like object. The specific methods and attributes required are:

    +
      +
    • methods: cdf(), and potentially log_prob() depending on the optimiser used.

    • +
    • Attributes: None.

    • +
    +

  • +
  • quantile – The quantile for which to find the corresponding x value.

  • +
  • max_acceptable_error – return values must be within icdf(q +/- max_acceptable_error)

  • +
  • bounds – The bounds to serach for the root in

  • +
+
+
Returns:
+

A tensor of shape (1,) of the x value corresponding to the quantile.

+
+
+
+
Details:
+
There are a number of way numerical issues can effect this results:
    +
  • Case 1: Function output (dist.cdf) is not precise enough to support max_acceptable_error.

  • +
  • Case 2: Function internals are not precise enough to support max_acceptable_error (e.g they introduce +numeric error).

  • +
  • Case 3: Optimiation input (x), is not accurate enough to support step sizes need to achieve +max_acceptable_error.

  • +
  • Case 4: The optimisation process does not find a suitable result.

  • +
  • Case 5: The output datatype truncation is not precise enough, failing max_acceptable_error after +truncation.

  • +
+
+
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.distributions.mixture.ApproximateMixture.html b/_autosummary/axtreme.distributions.mixture.ApproximateMixture.html new file mode 100644 index 00000000..665d38d8 --- /dev/null +++ b/_autosummary/axtreme.distributions.mixture.ApproximateMixture.html @@ -0,0 +1,750 @@ + + + + + + + + + ApproximateMixture - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

ApproximateMixture

+
+
+class axtreme.distributions.mixture.ApproximateMixture(mixture_distribution: Categorical, component_distribution: Distribution, *, validate_args: bool | None = None, check_dtype: bool = True)
+

Bases: MixtureSameFamily

+

Mixture distributions where extreme caclulations are approximated.

+

Some distribution only support a limited range of quantiles (e.g \([.01, 99]\)) due to numerical issues (see +“Details”). When calculation such as \(q=cdf(x)\) or \(x=icdf(q)\) fail outside this range the function then +error. ApproximateMixture allows all x values ,and approximates the results for x values outside the supported +range (see “Details” for approximation method).

+

Details:

+
+

Distribution Quantiles Bounds:

+
+

Some distributions (e.g TransformedDistribution) have bounds on the quantiles they can support. +Calculations such as \(q=cdf(x)\) or \(x=icdf(q)\) will fail when q is outside of these bounds. +Bounds exist because for sum distributions \(icdf(1)=inf\) or \(icdf(0)=-inf\). Eventually there +comes a point for q value close to 0 or 1 where they lack the numerical precision to capture very small +changes in q, and the very large values of x.

+
+

Approximation principles:

+
+

It is assumed we want to conservatively estimate (\(1-cdf(x)\)), the chance the a value will exceed some +level \(x\). For example, x could represent the strength a structure is designed to withstand, and +(\(1-cdf(x)\)) represents the chance of experiencing a force that will break the structure (e.g the +risk). It is better to overestimate the risk (conservative), rather than underestimate it. In other words, +if the \(cdf_est(x)\) over estimates the \(cdf_true(x)\), then the true risk of exceeding x is. e.g:

+

TLDR:

+
+
    +
  • \(cdf_est(x) < cdf_true(x)\): produces conservative design (okay)

  • +
  • \(cdf_est(x) > cdf_true(x)\): BAD

  • +
+
+

Worked example:

+
+
    +
  • \(cdf_est(x) = .5\) and \(cdf_true(x) = .4\)

  • +
  • If structure is designed to be \(x\) strong, then estimated number of failure is .5, true number +of failures is .6.

  • +
  • Have underestimated the risk and designed a structure more likely to fail than we expect.

  • +
+
+
+

Approximate results.

+
+

ApproximateMixture provides exact results within the quantile bounds [finfo.eps, 1 - finfo.eps] (where +finfo = torch.finfo(component_distribution.dtype)) For details regarding why this range is selected see +_lower_bound_x and _upper_bound_x. Values smaller than finfo.eps are approximated +according to _lower_bound_x. Values larger than 1 - finfo.eps are approximated according to +_upper_bound_x. Note the range [finfo.eps, 1 - finfo.eps] is still used even if the component +distribution supports a greater range.

+
+

Impact of Approximation:

+
+

As a result of the approximation, the cdf method can underestimate the analytical cdf value by up to +finfo.eps. This values come from the following calculation, Similar behaviour occurs at the lower bound.

+
+
    +
  • Consider one of the underlying distributions in the marginal: once x hits the upper bound

    +
    +
      +
    • it will give q = 1.0-finfo.eps

    • +
    • in reality it could be as high as 1.0

    • +
    • so the q give is finfo.eps too small (at worst)

    • +
    +
    +
  • +
  • The marginal cdf is calcualted from the underlying distributions:

    +
    +
      +
    • e.g \(q_marginal = w_1 * q_1 + ... + w_n * q_n\)

    • +
    • \(sum(w_i) = 1\)

    • +
    +
    +
  • +
  • In the worst case:

    +
    +
      +
    • Underling distribution: q give is finfo.eps too small (at worst)

    • +
    • weight = 1

    • +
    +
    +
  • +
+
+
+
+
+

Note

+

It is worth ensuring that the ApproximateMixture distribution has suitable numeric precision for its intended +use. See axtreme.distributions.utils.mixture_dtype for more details.

+
+
+
+__init__(mixture_distribution: Categorical, component_distribution: Distribution, *, validate_args: bool | None = None, check_dtype: bool = True) None
+

Initialise the ApproximateMixture.

+
+
Parameters:
+
    +
  • mixture_distributiontorch.distributions.Categorical-like instance. Manages the probability of +selecting component. The number of categories must match the rightmost batch dimension of the +component_distribution. Must have either scalar batch_shape or batch_shape matching +component_distribution.batch_shape[:-1]

  • +
  • component_distributiontorch.distributions.Distribution-likeinstance. Right-most batch dimension +indexes component.

  • +
  • validate_args – Runs the default validation defined by torch

  • +
  • check_dtype – Check datatype of distributions match and inpput are at least as precise as the distribution.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(mixture_distribution, ...[, ...])

Initialise the ApproximateMixture.

cdf(x)

Return the CDF.

entropy()

Returns entropy of distribution, batched over batch_shape.

enumerate_support([expand])

Returns tensor containing all values supported by a discrete distribution.

expand(batch_shape[, _instance])

Returns a new distribution instance (or populates an existing instance provided by a derived class) with batch dimensions expanded to batch_shape.

icdf(value)

Returns the inverse cumulative density/mass function evaluated at value.

log_prob(x)

Calculate the log prob (e.g log(pdf)).

perplexity()

Returns perplexity of distribution, batched over batch_shape.

rsample([sample_shape])

Generates a sample_shape shaped reparameterized sample or sample_shape shaped batch of reparameterized samples if the distribution parameters are batched.

sample([sample_shape])

Generates a sample_shape shaped sample or sample_shape shaped batch of samples if the distribution parameters are batched.

sample_n(n)

Generates n samples or n batches of samples if the distribution parameters are batched.

set_default_validate_args(value)

Sets whether validation is enabled or disabled.

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

arg_constraints

batch_shape

Returns the shape over which parameters are batched.

component_distribution

event_shape

Returns the shape of a single sample (without batching).

has_enumerate_support

has_rsample

mean

Returns the mean of the distribution.

mixture_distribution

mode

Returns the mode of the distribution.

stddev

Returns the standard deviation of the distribution.

support

Returns a Constraint object representing this distribution's support.

variance

Returns the variance of the distribution.

+
+
+
+cdf(x: Tensor) Tensor
+

Return the CDF.

+

Identical to MixtureSameFamily implementation except for clamping.

+
+
Parameters:
+

x

Values to calcuate the CDF for. Must be broadcastable with the ApproximateMixture.batch_shape. E.g

+
    +
  • self.component_distribution.batch_shape = (2,5) (last dimension is the components that are +combined to make a single Mixture distribution)

  • +
  • self.batch_shape = (2,)

  • +
  • x.shape = (10) This will fail as it is not broadcastable

  • +
  • x.shape = (10,1) This will pass as it is broadcastable

  • +
+

+
+
Returns:
+

-1], self.batch_shape)

+
+
Return type:
+

Tensor of shape (x.shape[

+
+
+
+ +
+
+log_prob(x: Tensor) Tensor
+

Calculate the log prob (e.g log(pdf)).

+
+
Parameters:
+

x

Values to calcuate the log prob for. Must be broadcastable with the ApproximateMixture.batch_shape. +E.g

+
+
    +
  • self.component_distribution.batch_shape = (2,5) (last dimension is the components that are +combined to make a single Mixture distribution)

  • +
  • self.batch_shape = (2,)

  • +
  • x.shape = (10) This will fail as it is not broadcastable

  • +
  • x.shape = (10,1) This will pass as it is broadcastable

  • +
+
+

+
+
Returns:
+

-1], self.batch_shape)

+
+
Return type:
+

Tensor of shape (x.shape[

+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.distributions.mixture.html b/_autosummary/axtreme.distributions.mixture.html new file mode 100644 index 00000000..94ceb021 --- /dev/null +++ b/_autosummary/axtreme.distributions.mixture.html @@ -0,0 +1,548 @@ + + + + + + + + + axtreme.distributions.mixture - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.distributions.mixture

+

Mixture model variants.

+

Functions

+
+ + + + + + +

icdf_value_bounds(dist, q)

Returns bounds in which the value for quantile q is gaurenteed to be found.

+
+

Classes

+
+ + + + + + +

ApproximateMixture(mixture_distribution, ...)

Mixture distributions where extreme caclulations are approximated.

+
+
+
+axtreme.distributions.mixture.icdf_value_bounds(dist: MixtureSameFamily, q: Tensor) Tensor
+

Returns bounds in which the value for quantile q is gaurenteed to be found.

+
+
Parameters:
+
    +
  • dist(*batch_shape,) mixture distribution producing events of event_shape samples.

  • +
  • q – quantile to find the inverse cdf of. Must be boardcastable up to (*batch_shape,). Must not have more +dimensions than *batch_shape (only 1 q can be passed to each of the distributions in the batch.)

  • +
+
+
Returns:
+

tensor of shape (2,*batch_shape), there the first index represents the lower +bounds, and the second the upper bounds.

+
+
+

Details: +Mixture distribution calculate the CDF as follows:

+
+

\(q = w_i * CDF_1(y) + w_2 * CDF_2(y) + ... + w_n * CDF_n(y)\) +Which can be written as: \(q = w_i * q_1 + w_2 * q_2 + ... + w_n * q_n\)

+

where \(0 <= w_i <= 1\) and \(\\sum{w_i} = 1\)

+
+

An effective way to bound the x values the can produce y is:

+
+
    +
  • take the icdf(q) for each distribution. Now have X_n values.

  • +
  • lower_bound = min(X_n): at this point the first component distribution has become big enough to produce q. +As the weights are between [0,1] no point prior would be able to procude q as no q_i was large enough.s

  • +
  • upper_bound = max(X_n): at this point the last component distribution has become big enough to produce q. +As the weights sum to one, q must be produced by this point.

  • +
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.distributions.utils.html b/_autosummary/axtreme.distributions.utils.html new file mode 100644 index 00000000..cac2cbca --- /dev/null +++ b/_autosummary/axtreme.distributions.utils.html @@ -0,0 +1,573 @@ + + + + + + + + + axtreme.distributions.utils - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.distributions.utils

+

helpers for working with distribution.

+

Functions

+
+ + + + + + + + + + + + +

dist_dtype(dist)

Return the dtype the distribution calculates values in.

index_batch_dist(dist, index)

Applies indexing to a MixtureSameFamily object along the batch dimension.

index_batch_mixture_dist(dist, index)

Applies indexing to a MixtureSameFamily object along the batch dimension.

+
+
+
+axtreme.distributions.utils.dist_dtype(dist: Distribution) dtype
+

Return the dtype the distribution calculates values in.

+

Parameters may be of different tpyes. It appears the distribution defaults to the largest dtype.

+
+
Parameters:
+

dist – the distribution to find the dtype of.

+
+
Returns:
+

dtype the ditribution returns result in.

+
+
+
+ +
+
+axtreme.distributions.utils.index_batch_dist(dist: Distribution, index: tuple[slice | int, ...]) Distribution
+

Applies indexing to a MixtureSameFamily object along the batch dimension.

+
+
Parameters:
+
    +
  • dist – The distribution to be indexed (only along the batch dimensions)

  • +
  • index – The index/slice to be applied. e.g (slice(1,4), Ellipsis) is equivalent to [1:4,…]. +Slices larger than the batch dimension will cause index error.

  • +
+
+
Returns:
+

A “veiw” of the underling distribution. This is a new object, but we call it a veiw as it is built on a view of +the underling data.

+
+
+
+

Note

+

The returned distribution is built on a view of the underling data. The follows the behaviour of slicing tensors +in pytorch as detailed here. +As such gradients etc are connected.

+
+
+ +
+
+axtreme.distributions.utils.index_batch_mixture_dist(dist: MixtureSameFamily, index: tuple[slice | int, ...]) MixtureSameFamily
+

Applies indexing to a MixtureSameFamily object along the batch dimension.

+
+
Parameters:
+
    +
  • dist – The distribution to be indexed (only along the batch dimensions)

  • +
  • index – The index/slice to be applied. e.g (slice(1,4), Ellipsis) is equivalent to [1:4,…]. +Slices larger than the batch dimension will cause index error.

  • +
+
+
Returns:
+

A “veiw” of the underling distribution. This is a new object, but we call it a veiw as it is built on a view of +the underling data.

+
+
+
+

Note

+

The returned distribution is built on a view of the underling data. The follows the behaviour of slicing tensors +in pytorch as detailed here. +As such gradients etc are connected.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.html b/_autosummary/axtreme.eval.html new file mode 100644 index 00000000..01ec3ae7 --- /dev/null +++ b/_autosummary/axtreme.eval.html @@ -0,0 +1,489 @@ + + + + + + + + + axtreme.eval - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.eval

+

Modules

+
+ + + + + + + + + + + + + + + +

object_logging

Helpers for unpacking nestes objects for logging purposes.

qoi_helpers

Plotting helper tailored for analysingQoIJobResults.

qoi_job

Classes to organize the evaluation of a QoIs.

utils

Additional helpers.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.object_logging.html b/_autosummary/axtreme.eval.object_logging.html new file mode 100644 index 00000000..4fb7408f --- /dev/null +++ b/_autosummary/axtreme.eval.object_logging.html @@ -0,0 +1,646 @@ + + + + + + + + + axtreme.eval.object_logging - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.eval.object_logging

+

Helpers for unpacking nestes objects for logging purposes.

+

When running experiments it is useful to record the objects that produced those results for reproducibility. This module +provides helper for unpacking nested objects for logging. It default implementations, and supports cusomistion so the +right level of granuality can be achieved.

+

Functions

+
+ + + + + + + + + + + + + + + + + + + + + +

default_config()

Default/handy processing configurations.

get_closest_class_value(obj, dic)

Searches a dictionary for the closest class, and return the value stored.

nested_content_to_str(d)

Helper function to turn all values in nested dictionaries to str.

public_vars(obj)

Like vars() but just returns public items.

unpack_object(obj[, ...])

Recursively extracts attributes from objects.

unpack_object_str_content(obj[, ...])

Helper that converts all unpack_object to string.

+
+
+
+axtreme.eval.object_logging.default_config() dict[type, Callable[[Any], dict[str, Any | dict[str, Any | NestedDict]]]]
+

Default/handy processing configurations.

+
+ +
+
+axtreme.eval.object_logging.get_closest_class_value(obj: object, dic: dict[type, T]) T | None
+

Searches a dictionary for the closest class, and return the value stored.

+

Searches the class heirachy from bottom to top for a matching key in the dictionary. Returns the values stored with +by that key.

+
+
Parameters:
+
    +
  • obj – Object to find the class for

  • +
  • dic – takes object of that type,

  • +
+
+
Returns:
+

The value in stored in the dictionary for the closest class, or None if no match is found.

+
+
+
+ +
+
+axtreme.eval.object_logging.nested_content_to_str(d: dict[str, Any | dict[str, Any | NestedDict]]) dict[str, str | dict[str, str | NestedStrDict]]
+

Helper function to turn all values in nested dictionaries to str.

+
+ +
+
+axtreme.eval.object_logging.public_vars(obj: object) dict[str, Any]
+

Like vars() but just returns public items.

+
+ +
+
+axtreme.eval.object_logging.unpack_object(obj: object, custom_unpacking_config: dict[type, Callable[[Any], dict[str, Any | dict[str, Any | NestedDict]]]] | None = None, depth: int = 1) dict[str, Any | dict[str, Any | NestedDict]]
+

Recursively extracts attributes from objects.

+

This can be useful for logging the state of an object. It will unpack the public attributes of an object up to +‘depth’. Specific unpacking function can also be provided for attribute object in custom_unpacking_config. If +these objects are encounter the unpacking function will be used instead.

+
+
Parameters:
+
    +
  • obj – the object to unpack.

  • +
  • custom_unpacking_config

    Overrides default unpacking behaviour for object that subclass the keys.

    +
      +
    • Keys: Types

    • +
    • Values: Functions that take instance of that type, and produces a custom unpacking.

    • +
    • This unpacking should be of the following format:

    • +
    +

  • +
  • depth

      +
    • How many levels of objects to unpack.

    • +
    +

  • +
+
+
Returns:
+

A nested dictionary.

+
    +
  • +
    Without custom unpacking:
      +
    • keys: are the public attribute names

    • +
    • values: are the attribute value, or nested dictionary of the object being unpacked.

      +
      +

      {“__class__”: RootObjectClass, “attribute_1”: {“__class__”: Foo, “a”: “blah”, “b”: None}, “attribute_2”: “x”}

      +
      +
    • +
    +
    +
    +
  • +
  • +
    With custom unpacking:
      +
    • keys: Determined by the custom unpacking function if used otherwise as above.

    • +
    • Values: Determined by the custom unpacking function if used otherwise as above.

      +
      +

      {“__class__”: RootObjectClass, “attribute_1”: {“custom_unpacking_key1”: “name of class if FOO”, “custom_unpacking_key2”: [1, 2, 3]}, “attribute_2”: “x”}

      +
      +
    • +
    +
    +
    +
  • +
+

+
+
+
+

Todo

+

depth: How many levels of objects to unpack.

+
+
+ +
+
+axtreme.eval.object_logging.unpack_object_str_content(obj: object, custom_unpacking_config: None | dict[type, Callable[[Any], dict[str, Any | dict[str, Any | NestedDict]]]] = None, depth: int = 1) dict[str, str | dict[str, str | NestedStrDict]]
+

Helper that converts all unpack_object to string.

+
+
Parameters:
+
    +
  • obj – the object to unpack.

  • +
  • custom_unpacking_config

    Overrides default unpacking behaviour for object that subclass the keys. If None +default_config() is used.

    +
      +
    • Keys: Types

    • +
    • Values: Functions that take instance of that type, and produces a custom unpacking. This unpacking should +be of the following format:

    • +
    +

  • +
  • depth

      +
    • How many levels of objects to unpack.

    • +
    +

  • +
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.qoi_helpers.html b/_autosummary/axtreme.eval.qoi_helpers.html new file mode 100644 index 00000000..caa79f64 --- /dev/null +++ b/_autosummary/axtreme.eval.qoi_helpers.html @@ -0,0 +1,579 @@ + + + + + + + + + axtreme.eval.qoi_helpers - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.eval.qoi_helpers

+

Plotting helper tailored for analysingQoIJobResults.

+

Functions

+
+ + + + + + + + + + + + + + + +

plot_col_histogram(df, ax[, col_name, ...])

Helper which creates a histogram (on the given ax) based on a column of the df.

plot_distribution(df, ax[, n_hists, ...])

Helperfor plotting histograms (on the given ax) of dataframe cells containing lists.

plot_groups(df_grouped, plotting_funcs)

Takes a grouped dataframe, and generates a row of plots for each group, using plotting_funcs.

qoi_ignoring_gp_uncertainty(qoi, model)

Helper to run a QoI with a model, ignoring uncertainty in the model (e.g using the posterior mean).

+
+
+
+axtreme.eval.qoi_helpers.plot_col_histogram(df: DataFrame, ax: Axes, col_name: str = 'mean', brute_force: float | None = None) None
+

Helper which creates a histogram (on the given ax) based on a column of the df.

+

Designed for use with the ‘mean’ or ‘var’ column of a QoiJobResults dataframe.

+
+
Parameters:
+
    +
  • df – A dataframe.

  • +
  • ax – The axis to plot on.

  • +
  • col_name – The column of the df containing lists.

  • +
  • brute_force – Represents the true value (e.g mean). Plots a vertical line if provided.

  • +
+
+
+
+ +
+
+axtreme.eval.qoi_helpers.plot_distribution(df: DataFrame, ax: Axes, n_hists: int = 3, col_name: str = 'samples', brute_force: float | None = None) None
+

Helperfor plotting histograms (on the given ax) of dataframe cells containing lists.

+

Designed for use with the ‘samples’ column of a QoiJobResults dataframe.

+
+
Parameters:
+
    +
  • df – A dataframe.

  • +
  • ax – The axis to plot on.

  • +
  • n_hists – The number of cells of column col_name to plot.

  • +
  • col_name – The column of the df containing lists.

  • +
  • brute_force – Represents the true value (e.g mean). Plots a vertical line if provided.

  • +
+
+
+
+ +
+
+axtreme.eval.qoi_helpers.plot_groups(df_grouped: DataFrameGroupBy, plotting_funcs: list[Callable[[DataFrame, Axes], None]]) Figure
+

Takes a grouped dataframe, and generates a row of plots for each group, using plotting_funcs.

+
+
Parameters:
+
    +
  • df_grouped – The groupby object to plot

  • +
  • plotting_funcs – list of plots to be generated for each group. See plot_col_histogram for an example of a +plotting function.

  • +
+
+
+
+ +
+
+axtreme.eval.qoi_helpers.qoi_ignoring_gp_uncertainty(qoi: GPBruteForce, model: SingleTaskGP) Tensor
+

Helper to run a QoI with a model, ignoring uncertainty in the model (e.g using the posterior mean).

+
+
Parameters:
+
    +
  • qoi – The QoI estimator to use

  • +
  • model – The model to use

  • +
+
+
Returns:
+

the estimates made by the QoI using only the posterior mean of the model.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.qoi_job.QoIJob.html b/_autosummary/axtreme.eval.qoi_job.QoIJob.html new file mode 100644 index 00000000..661c66aa --- /dev/null +++ b/_autosummary/axtreme.eval.qoi_job.QoIJob.html @@ -0,0 +1,566 @@ + + + + + + + + + QoIJob - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

QoIJob

+
+
+class axtreme.eval.qoi_job.QoIJob(model: ~botorch.models.model.Model, qoi: ~axtreme.qoi.qoi_estimator.QoIEstimator, name: str | None = None, tags: dict[str, str | float] = <factory>, metadata: dict[str, str | float] = <factory>)
+

Bases: object

+

Helper to make the interface below clear.

+
+
+__init__(model: ~botorch.models.model.Model, qoi: ~axtreme.qoi.qoi_estimator.QoIEstimator, name: str | None = None, tags: dict[str, str | float] = <factory>, metadata: dict[str, str | float] = <factory>) None
+
+ +

Methods

+
+ + + + + + +

__init__(model, qoi[, name, tags, metadata])

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + +

name

model

qoi

tags

metadata

+
+
+
+metadata: dict[str, str | float]
+
+ +
+
+model: Model
+
+ +
+
+name: str | None = None
+
+ +
+
+qoi: QoIEstimator
+
+ +
+
+tags: dict[str, str | float]
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.qoi_job.QoIJobResult.html b/_autosummary/axtreme.eval.qoi_job.QoIJobResult.html new file mode 100644 index 00000000..458dedff --- /dev/null +++ b/_autosummary/axtreme.eval.qoi_job.QoIJobResult.html @@ -0,0 +1,625 @@ + + + + + + + + + QoIJobResult - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

QoIJobResult

+
+
+class axtreme.eval.qoi_job.QoIJobResult(mean: ~torch.Tensor, var: ~torch.Tensor, samples: ~torch.Tensor, tags: dict[str, str | float] = <factory>, metadata: dict[str, ~typing.Any] = <factory>)
+

Bases: object

+

Dataclass to store the results of running a QoIEstimator (as produced by QoIJob).

+
+
Parameters:
+
    +
  • mean – the mean of the QoIEstimator results. +Note, if UT methods are used in the QoIEstimator, this can’t be calculated directory form samples

  • +
  • var – variance in the QoIEstimator results. +Note, if UT methods are used in the QoIEstimator, this can’t be calculated directory form samples

  • +
  • samples – Samples produced by the QoIEstimator

  • +
  • tags – Label assigned to the result by the user. This information can typically be found somewhere in metadata, +putting them here is for convience (more accessible and less noise).

  • +
  • metadata – Optional indepth information about the conditions that produced these results.

  • +
+
+
+
+
+__init__(mean: ~torch.Tensor, var: ~torch.Tensor, samples: ~torch.Tensor, tags: dict[str, str | float] = <factory>, metadata: dict[str, ~typing.Any] = <factory>) None
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + +

__init__(mean, var, samples[, tags, metadata])

from_dict(kvs, *[, infer_missing])

from_json(s, *[, parse_float, parse_int, ...])

schema(*[, infer_missing, only, exclude, ...])

to_dict([encode_json])

to_json(*[, skipkeys, ensure_ascii, ...])

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + +

mean

var

samples

tags

metadata

+
+
+
+classmethod from_dict(kvs: dict | list | str | int | float | bool | None, *, infer_missing=False) A
+
+ +
+
+classmethod from_json(s: str | bytes | bytearray, *, parse_float=None, parse_int=None, parse_constant=None, infer_missing=False, **kw) A
+
+ +
+
+classmethod schema(*, infer_missing: bool = False, only=None, exclude=(), many: bool = False, context=None, load_only=(), dump_only=(), partial: bool = False, unknown=None) SchemaF[A]
+
+ +
+
+to_dict(encode_json=False) Dict[str, dict | list | str | int | float | bool | None]
+
+ +
+
+to_json(*, skipkeys: bool = False, ensure_ascii: bool = True, check_circular: bool = True, allow_nan: bool = True, indent: int | str | None = None, separators: Tuple[str, str] | None = None, default: Callable | None = None, sort_keys: bool = False, **kw) str
+
+ +
+
+mean: Tensor
+
+ +
+
+metadata: dict[str, Any]
+
+ +
+
+samples: Tensor
+
+ +
+
+tags: dict[str, str | float]
+
+ +
+
+var: Tensor
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.qoi_job.html b/_autosummary/axtreme.eval.qoi_job.html new file mode 100644 index 00000000..2d39ed20 --- /dev/null +++ b/_autosummary/axtreme.eval.qoi_job.html @@ -0,0 +1,484 @@ + + + + + + + + + axtreme.eval.qoi_job - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.eval.qoi_job

+

Classes to organize the evaluation of a QoIs.

+

Classes

+
+ + + + + + + + + +

QoIJob(model, qoi, name, tags, ...)

Helper to make the interface below clear.

QoIJobResult(mean, var, samples, tags, ...)

Dataclass to store the results of running a QoIEstimator (as produced by QoIJob).

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.eval.utils.html b/_autosummary/axtreme.eval.utils.html new file mode 100644 index 00000000..64a098e2 --- /dev/null +++ b/_autosummary/axtreme.eval.utils.html @@ -0,0 +1,508 @@ + + + + + + + + + axtreme.eval.utils - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.eval.utils

+

Additional helpers.

+

Functions

+
+ + + + + + +

append_to_json(obj, output_file)

Appends a json object to a file containing a list of objects.

+
+
+
+axtreme.eval.utils.append_to_json(obj: Any, output_file: Path) None
+

Appends a json object to a file containing a list of objects.

+

object: Json serialisable object to append. +output_file: The file to append results to. If does not exist, it will be created.

+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.evaluation.EvaluationFunction.html b/_autosummary/axtreme.evaluation.EvaluationFunction.html new file mode 100644 index 00000000..ca901c64 --- /dev/null +++ b/_autosummary/axtreme.evaluation.EvaluationFunction.html @@ -0,0 +1,581 @@ + + + + + + + + + EvaluationFunction - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

EvaluationFunction

+
+
+class axtreme.evaluation.EvaluationFunction(simulator: Simulator, output_dist: rv_continuous, parameter_order: list[str], n_simulations_per_point: int = 20)
+

Bases: object

+

Class for evaluating a simulation at a point, and fits a distribution to the results.

+

Take ax.Parameter, runs the simulator at that point, and packages the result into the format later required +for unpacking in the metrics.

+
+
+__init__(simulator: Simulator, output_dist: rv_continuous, parameter_order: list[str], n_simulations_per_point: int = 20) None
+

Initializes the EvaluationFunction.

+
+
Parameters:
+
    +
  • simulator – Conforming to the simulator in

  • +
  • output_dist – Distribution that should be used to fit the response. This is the distribution of the noise +in the simulation, at a given x,

  • +
  • n_simulations_per_point – The number of simulations to run at each point.

  • +
  • parameter_order

    Order of features that the simulator expects.

    +
    +

    Note

    +

    This is a temporary measure to check that the order isn’t ever shuffled.

    +
    +
    +

    Todo

    +

    Got through ax and check is order is always respected, so we can remove this

    +
    +

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + +

__init__(simulator, output_dist, parameter_order)

Initializes the EvaluationFunction.

post_process_simulation_output(y)

Post process the simulation output be fitting a the distribution to the results.

run_simulator(x)

Runs the simulator at a point and returns the results.

+
+
+
+post_process_simulation_output(y: ndarray[tuple[int, int, int], dtype[float64]]) SimulationPointResults
+

Post process the simulation output be fitting a the distribution to the results.

+
+
Parameters:
+

y

The output of the simulation with shape (n_simulations_per_points,)

+
+

Note

+

This is the output of the simulator, at a single point and a single output dimension.

+
+

+
+
Returns:
+

A SimulationPointResults object with the mean and covariance of the fitted distribution.

+
+
+
+ +
+
+run_simulator(x: ndarray[tuple[int, int], dtype[float64]]) ndarray[tuple[int, int, int], dtype[float64]]
+

Runs the simulator at a point and returns the results.

+
+
Parameters:
+

x – The points at which to run the simulator with shape (n_points, n_input_dims)

+
+
Returns:
+

The results of the simulator with shape (n_points, n_simulations_per_point, n_output_dims)

+
+
Raises:
+

AssertionError – If the shape of the output of self.simulator is not as expected.

+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.evaluation.SimulationPointResults.html b/_autosummary/axtreme.evaluation.SimulationPointResults.html new file mode 100644 index 00000000..5cb5bb67 --- /dev/null +++ b/_autosummary/axtreme.evaluation.SimulationPointResults.html @@ -0,0 +1,616 @@ + + + + + + + + + SimulationPointResults - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

SimulationPointResults

+
+
+class axtreme.evaluation.SimulationPointResults(metric_names: list[str], means: ndarray[tuple[int], dtype[float64]], cov: ndarray[tuple[int, int], dtype[float64]] | None)
+

Bases: object

+

For a point that has been simulation, stores the mean(s) and covariance(s).

+
+
Parameters:
+
    +
  • means (NDArray[np.float64]) – array of the mean paramter/metric estimates at a X point.

  • +
  • cov (NDArray[np.float64]|None) – covarianc matrix with uncertainty distibution of the metric estimates. +- This can be None if the error is unknown

  • +
  • parameter_names – list of names. Gives the index where relevant data is stored

  • +
+
+
+
+
Design rational:
    +
  • The primary purpose of this is to define the interface between the Runner which generate simulation results, +and Metric which reports the required parts of the results for AX to then use.

  • +
  • +
    The intent is to :
      +
    • Explicitally define the interface information between the two (rather than use a dict)

    • +
    • Prevent Runner needing to know about specific structure of metric.

    • +
    • Prevent Metric needing to know the stucture of Runner

    • +
    • Esentially it mean the translatioin logic between these two components is contained in one discrete +unit/object

    • +
    +
    +
    +
  • +
+
+
+

This is generated (in the Runner) when the simulation is evaluated for a specific Trial. +It is attached to the Trail.metadata, and later read by Metric.fetch_trial_data.

+
+
Parameters:
+
    +
  • metric_name (-) – The name of the metric that these results are relevant to

  • +
  • mean (-) – The mean estimate of the metric for this particular trial

  • +
  • sem (-) – Standard Error Measure, as defined here

  • +
+
+
+
+
Background: For documenation on what can do into this object
+
+
+
+

Todo

+

Revist if there is a better abstraction for this. Detail in Github issue #31.

+
+
+
+__init__(metric_names: list[str], means: ndarray[tuple[int], dtype[float64]], cov: ndarray[tuple[int, int], dtype[float64]] | None) None
+
+ +

Methods

+
+ + + + + + + + + +

__init__(metric_names, means, cov)

metric_data(metric_name)

Construct the 'Metric data-related columns' as defined in ax.Data.

+
+

Attributes

+
+ + + + + + + + + + + + +

metric_names

means

cov

+
+
+
+metric_data(metric_name: str) dict[str, float | None]
+

Construct the ‘Metric data-related columns’ as defined in ax.Data.

+
+
This consists of:
    +
  • “mean”: mean estimate of this parameter

  • +
  • “sem”: as defined here

  • +
+
+
+
+ +
+
+cov: ndarray[tuple[int, int], dtype[float64]] | None
+
+ +
+
+means: ndarray[tuple[int], dtype[float64]]
+
+ +
+
+metric_names: list[str]
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.evaluation.html b/_autosummary/axtreme.evaluation.html new file mode 100644 index 00000000..cbe0bb5d --- /dev/null +++ b/_autosummary/axtreme.evaluation.html @@ -0,0 +1,484 @@ + + + + + + + + + axtreme.evaluation - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.evaluation

+

Responsible for running simulators with a given set of Ax Parameters, and returning estimate with uncertainty.

+

Classes

+
+ + + + + + + + + +

EvaluationFunction(simulator, output_dist, ...)

Class for evaluating a simulation at a point, and fits a distribution to the results.

SimulationPointResults(metric_names, means, cov)

For a point that has been simulation, stores the mean(s) and covariance(s).

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.experiment.html b/_autosummary/axtreme.experiment.html new file mode 100644 index 00000000..881ee49b --- /dev/null +++ b/_autosummary/axtreme.experiment.html @@ -0,0 +1,691 @@ + + + + + + + + + axtreme.experiment - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.experiment

+

Helper functions for ax Experiments.

+

Functions

+
+ + + + + + + + + + + + + + + + + + + + + +

add_json_data_to_experiment(experiment, ...)

Adds the data from a dictionary to an ax Experiment.

add_metric_data_to_experiment(experiment, ...)

Add metric data to an experiment.

add_simulation_data_to_experiment(...)

Add raw simulator data to an experiment.

add_sobol_points_to_experiment(experiment[, ...])

Adds some points (chosen by sobol) to an experiment.

extract_data_from_experiment_as_json(experiment)

Extracts the data from an ax Experiment.

make_experiment(simulator, search_space, dist)

Returns an experiment according to the given simulator, search_space, and dist_class.

+
+
+
+axtreme.experiment.add_json_data_to_experiment(experiment: Experiment, json_data: dict[int, dict[str, dict[str, dict[str, float | dict[str, float]]]]]) None
+

Adds the data from a dictionary to an ax Experiment.

+
+
Parameters:
+
    +
  • experiment – The ax Experiment to add the data to.

  • +
  • json_data – The data to add to the ax Experiment. The structure should be the same as the output of +extract_data_from_experiment.

  • +
+
+
+

Example

+
{
+    "trial_index": {
+        "arm_name": {
+            "parameters": {
+                "parameter_name": "parameter_value"
+            },
+            "metrics": {
+                "metric_name": {
+                    "mean": 0.0,
+                    "sem": 0.0
+                }
+            }
+        }
+    }
+}
+
+
+
+ +
+
+axtreme.experiment.add_metric_data_to_experiment(experiment: Experiment, parameterizations: Iterable[Dict[str, None | str | bool | float | int]], metric_data: Iterable[Mapping[str, float | tuple[float, float | None] | dict[str, float | None]]]) tuple[Data, int]
+

Add metric data to an experiment.

+

This function is used to add data from previously run simulations to an experiment. +To use this function one needs to have an estimate of the mean and standard error for each metric. +This is useful if the simulator is slow or expensive to run and the data is already available.

+
+
Parameters:
+
    +
  • experiment – The ax Experiment to add the data to.

  • +
  • parameterizations

    The parameterizations used in the simulation.

    +
      +
    • Iterable where each element is a dict parameter names and values ({[param_name]: value}).

    • +
    +

  • +
  • metric_data

    The metric data from the simulation.

    +
      +
    • Iterable where each element is a dict of metric names and values.

    • +
    • The values can be a float, a tuple of (mean, sem), or a dict of {“mean”: mean, “sem”: sem}.

    • +
    • If a float is provided, the sem is assumed to be 0.

    • +
    +

  • +
+
+
Returns:
+

    +
  • The data that was attached to the experiment.

  • +
  • The trial index of the trial that was created.

  • +
+

+
+
+
+ +
+
+axtreme.experiment.add_simulation_data_to_experiment(experiment: Experiment, parameters: list[str], simulation_inputs: Iterable[ndarray[Any, dtype[float64]]], simulation_outputs: Iterable[ndarray[Any, dtype[float64]]]) tuple[Data, int]
+

Add raw simulator data to an experiment.

+

This function is used to add data from previously run simulations to an experiment. +This is very useful if the simulator is slow or expensive to run and the data is already available. +Using this function allows you to add the data to the experiment and then use it to train the model +which can be used to collect new data by running new simulations.

+
+
Parameters:
+
    +
  • experiment – The ax Experiment to add the data to.

  • +
  • parameters

    The names of the parameters used as input to the simulator.

    +
      +
    • This has to match the names of the parameters in the search space of the experiment.

    • +
    • This should match the order of the input dimensions in the simulation_inputs.

    • +
    +

  • +
  • simulation_inputs

    The inputs to the simulator.

    +
      +
    • Iterable where each element is the parameters used in the simulation.

    • +
    • Each element should be a numpy array with shape (n_input_dims,)

    • +
    +

  • +
  • simulation_outputs

    The outputs from the simulator.

    +
      +
    • Iterable where each element is multiple output from the simulation ran with the same input.

    • +
    • Each element should be a numpy array with shape (n_simulations_per_point,)

    • +
    • Only supports a single output dimension for now.

    • +
    +

  • +
+
+
Returns:
+

    +
  • The data that was attached to the experiment.

  • +
  • The trial index of the trial that was created.

  • +
+

+
+
+
+ +
+
+axtreme.experiment.add_sobol_points_to_experiment(experiment: Experiment, n_iter: int = 5, seed: int | None = None) None
+

Adds some points (chosen by sobol) to an experiment.

+

Typically used to initialise the experiment so a GP has data for training.

+
+ +
+
+axtreme.experiment.extract_data_from_experiment_as_json(experiment: Experiment) dict[int, dict[str, dict[str, dict[str, float | dict[str, float]]]]]
+

Extracts the data from an ax Experiment.

+
+
Parameters:
+

experiment – The Ax experiment to extract the data from.

+
+
Returns:
+

{
+    "trial_index": {
+        "arm_name": {
+            "parameters": {
+                "parameter_name": "parameter_value"
+            },
+            "metrics": {
+                "metric_name": {
+                    "mean": 0.0,
+                    "sem": 0.0
+                }
+            }
+        }
+    }
+}
+
+
+

+
+
Return type:
+

A dictionary with the following structure

+
+
+
+ +
+
+axtreme.experiment.make_experiment(simulator: Simulator, search_space: SearchSpace, dist: rv_continuous, n_simulations_per_point: int = 100) Experiment
+

Returns an experiment according to the given simulator, search_space, and dist_class.

+
+
Parameters:
+
    +
  • simulator – The simulator to use for the experiment.

  • +
  • search_space – The ax search space to use for the experiment.

  • +
  • dist – The distribution that the result of a simulation is assumed to follow.

  • +
  • n_simulations_per_point – The number of simulations to run for each point in the experiment.

  • +
+
+
Returns:
+

An ax Experiment.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.metrics.LocalMetadataMetric.html b/_autosummary/axtreme.metrics.LocalMetadataMetric.html new file mode 100644 index 00000000..0f0c1084 --- /dev/null +++ b/_autosummary/axtreme.metrics.LocalMetadataMetric.html @@ -0,0 +1,604 @@ + + + + + + + + + LocalMetadataMetric - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

LocalMetadataMetric

+
+
+class axtreme.metrics.LocalMetadataMetric(name: str, lower_is_better: bool | None = None, properties: Dict[str, Any] | None = None)
+

Bases: Metric

+

This metric retrieves its results form the trial metadata.

+

The simple example run the simultion within this function call +(e.g. see) +In general, this method should only ‘fetch’ the results from somewhere else where they have been run. +For example, Runner deploys simulation of remote, this connects to remote and collects result. +This is local implementation of this patter, where results are stored on trail metadata.

+

This is useful when: +- Running a single simulation produces multiple output metrics +(meaning the simulation doesn’t need to be run as many times) +- Want to execute the simulation when trail.run() is called

+
+

Note

+

This object is coupled with LocalMetadataRunner, through SimulationPointResults

+
+

Background:

+

Flow: +- trial.run() called, internally call the runner, and puts the resulting data into metadata +- Later Metric.fetch_trial_data(trial) is called Therefore, Metric has access to all the “bookkeeping” +trial information directly, the only thing that should be in metadata is run result.

+
+
+__init__(name: str, lower_is_better: bool | None = None, properties: Dict[str, Any] | None = None) None
+

Inits Metric.

+
+
Parameters:
+
    +
  • name – Name of metric.

  • +
  • lower_is_better – Flag for metrics which should be minimized.

  • +
  • properties – Dictionary of this metric’s properties

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(name[, lower_is_better, properties])

Inits Metric.

bulk_fetch_experiment_data(experiment, metrics)

Fetch multiple metrics data for multiple trials on an experiment, using instance attributes of the metrics.

bulk_fetch_trial_data(trial, metrics, **kwargs)

Fetch multiple metrics data for one trial, using instance attributes of the metrics.

clone()

Create a copy of this Metric.

deserialize_init_args(args[, ...])

Given a dictionary, deserialize the properties needed to initialize the object.

fetch_data_prefer_lookup(experiment, metrics)

Fetch or lookup (with fallback to fetching) data for given metrics, depending on whether they are available while running.

fetch_experiment_data_multi(experiment, metrics)

Fetch multiple metrics data for an experiment.

fetch_trial_data(trial, **kwargs)

Fetch data for one trial.

fetch_trial_data_multi(trial, metrics, **kwargs)

Fetch multiple metrics data for one trial.

is_available_while_running()

Whether metrics of this class are available while the trial is running.

maybe_raise_deprecation_warning_on_class_methods()

period_of_new_data_after_trial_completion()

Period of time metrics of this class are still expecting new data to arrive after trial completion.

serialize_init_args(obj)

Serialize the properties needed to initialize the object.

+
+

Attributes

+
+ + + + + + + + + + + + + + + +

db_id

fetch_multi_group_by_metric

Metric class, with which to group this metric in Experiment._metrics_by_class, which is used to combine metrics on experiment into groups and then fetch their data via Metric.fetch_trial_data_multi for each group.

name

Get name of metric.

summary_dict

Returns a dictionary containing the metric's name and properties.

+
+
+
+fetch_trial_data(trial: BaseTrial, **kwargs: Any) Result[Data, MetricFetchE]
+

Fetch data for one trial.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.metrics.html b/_autosummary/axtreme.metrics.html new file mode 100644 index 00000000..9b6bb3fa --- /dev/null +++ b/_autosummary/axtreme.metrics.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.metrics - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.metrics

+

Additional Metric implemenations.

+

Classes

+
+ + + + + + +

LocalMetadataMetric(name[, lower_is_better, ...])

This metric retrieves its results form the trial metadata.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.plotting.doe.html b/_autosummary/axtreme.plotting.doe.html new file mode 100644 index 00000000..c96c757b --- /dev/null +++ b/_autosummary/axtreme.plotting.doe.html @@ -0,0 +1,530 @@ + + + + + + + + + axtreme.plotting.doe - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.plotting.doe

+

Helper function for plotting DoE behaviour.

+

Functions

+
+ + + + + + +

plot_qoi_estimates(results[, ax, q, ...])

Plots how the QoI estimates changes over DoE process.

+
+
+
+axtreme.plotting.doe.plot_qoi_estimates(results: ndarray[tuple[int, int], dtype[float64]], ax: None | Axes = None, q: tuple[float, ...] = (0.1, 0.5, 0.9), points_between_ests: int = 1, name: str | None = None, **kwargs: Any) Axes
+

Plots how the QoI estimates changes over DoE process.

+
+
Parameters:
+
    +
  • results

    shape (n_doe_rounds, n_qoi_estimates).

    +
      +
    • n_doe_rounds: The number of DoE rounds in which a QoI estimate was produced.

    • +
    • n_qoi_estimates: the number of estimates produced by a single run of the QoI estimator.

    • +
    +

  • +
  • ax – ax to add the plots to. If not provided, one will be created.

  • +
  • q – the quantiles that should be used/reported.

  • +
  • points_between_ests – This should be used if multplie DoE iterations are used between qoi estimates +(e.g if the estimate is expensive). It adjusts the scale of the x axis.

  • +
  • name – optional name that should be added to the legend information for this plot

  • +
  • kwargs – kwargs that should be passed to matplotlib. Must be applicable to ax.plot and ax.fill_between

  • +
+
+
Returns:
+

the ax with the plot.

+
+
Return type:
+

Axes

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.plotting.gp_fit.html b/_autosummary/axtreme.plotting.gp_fit.html new file mode 100644 index 00000000..e19c9a2c --- /dev/null +++ b/_autosummary/axtreme.plotting.gp_fit.html @@ -0,0 +1,586 @@ + + + + + + + + + axtreme.plotting.gp_fit - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.plotting.gp_fit

+

Plotting module for visualizing how well the GP fits the data.

+

Functions

+
+ + + + + + + + + + + + + + + +

plot_1d_model(model[, X, ax])

Plots a model with 1d in put, and any number of outputs..

plot_gp_fits_2d_surface(model_bridge, ...[, ...])

Plot the GP fit for the given metrics over the 2D search space.

plot_surface_over_2d_search_space(...[, ...])

Creates a figure with the functions in funcs ploted over the search_space.

scatter_plot_training(model_bridge, metric_name)

Make a scattter plot of a metric for the training data of the model.

+
+
+
+axtreme.plotting.gp_fit.plot_1d_model(model: SingleTaskGP, X: Tensor | None = None, ax: None | Axes = None) Axes
+

Plots a model with 1d in put, and any number of outputs..

+
+
Parameters:
+
    +
  • model – Only SingleTaskGp is supported an training data is extracted from the model.

  • +
  • X – (n,1): Linspace of [0,1] is used by default. Only 1d is currently supported.

  • +
  • ax – will plot to this axis if provied

  • +
+
+
+
+ +
+
+axtreme.plotting.gp_fit.plot_gp_fits_2d_surface(model_bridge: TorchModelBridge, search_space: SearchSpace, metrics: dict[str, Callable[[ndarray[tuple[int, int], dtype[float64]]], ndarray[tuple[int], dtype[float64]]]] | None = None, num_points: int = 101) Figure
+

Plot the GP fit for the given metrics over the 2D search space.

+
+
Parameters:
+
    +
  • model_bridge – The model bridge used to make predictions.

  • +
  • search_space – The search space over which the functions are to be evaluated and plotted.

  • +
  • metrics – A dictionary of metrics to plot. The keys are the names of the metrics in the model bridge model +and the values are callables that return the metric value for a given input.

  • +
  • num_points – The number of points in each dimension to evaluate the functions at.

  • +
+
+
+
+ +
+
+axtreme.plotting.gp_fit.plot_surface_over_2d_search_space(search_space: SearchSpace, funcs: list[Callable[[ndarray[tuple[int, int], dtype[float64]]], ndarray[tuple[int], dtype[float64]]]], colors: list[str] | None = None, num_points: int = 101) Figure
+

Creates a figure with the functions in funcs ploted over the search_space.

+
+

Note

+

Currently only support search spaces with 2 parameters.

+
+
+
Parameters:
+
    +
  • search_space – The search space over which the functions are to be evaluated and plotted.

  • +
  • funcs – A list of callables that take in a numpy array with shape (num_values, num_parameters=2 ) +and return a numpy array with (num_values) elements.

  • +
  • colors – A list of colors to use for each function. If None, will use default Plotly colors.

  • +
  • num_points – The number of points in each dimension to evaluate the functions at.

  • +
+
+
+
+ +
+
+axtreme.plotting.gp_fit.scatter_plot_training(model_bridge: TorchModelBridge, metric_name: str, axis: tuple[int, int] = (0, 1), figure: Figure | None = None, *, error_bars: bool = True, error_bar_confidence_interval: float = 0.95) Figure
+

Make a scattter plot of a metric for the training data of the model.

+
+
Parameters:
+
    +
  • model_bridge – The model the training data scatter plot is to be made for.

  • +
  • metric_name – The name of the metric to plot. Must match the name of a metric in the model.

  • +
  • axis – The axis of the input space to plot the scatter plot in

  • +
  • figure – The figure to add the scatter plot to. If None, a new figure is created.

  • +
  • error_bars – Whether to add error bars to the plot.

  • +
  • error_bar_confidence_interval – The confidence interval the error bars in the scatter plot represents.

  • +
+
+
Returns:
+

A Scatter3d plot of the training data for the given metric.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.plotting.histogram3d.html b/_autosummary/axtreme.plotting.histogram3d.html new file mode 100644 index 00000000..a0cf7abf --- /dev/null +++ b/_autosummary/axtreme.plotting.histogram3d.html @@ -0,0 +1,559 @@ + + + + + + + + + axtreme.plotting.histogram3d - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.plotting.histogram3d

+

3D histogram plotting function.

+

Plotly does not have a plotly.graph_objects.Histogram3d object, this is an attempt to remedy that. +The closest is plotly.graph_objects.Histogram2d, but that creates a 2D heatmap.

+

See Also: +- https://github.com/serge-tochilov/barchart3d-plotly +- https://github.com/AymericFerreira/Plotly_barchart3D +- https://community.plotly.com/t/how-to-do-a-3d-bar-chart-if-possible/32287/5

+

Functions

+
+ + + + + + + + + +

histogram3d(samples, *[, n_bins, bounds, ...])

Generate a 3D figure of a 2D histogram of the input samples.

histogram_surface3d(samples, *[, n_bins, ...])

Generate a 3D figure of a 2D histogram of the input samples.

+
+
+
+axtreme.plotting.histogram3d.histogram3d(samples: ndarray[tuple[int, int], dtype[float64]], *, n_bins: int = 20, bounds: Sequence[tuple[float, float]] | None = None, density: bool = True, flatshading: bool = True, show: bool = False, mesh3d_kwargs: dict[str, Any] | None = None, layout_kwargs: dict[str, Any] | None = None) Figure
+

Generate a 3D figure of a 2D histogram of the input samples.

+

Computes a 2D histogram that is then plotted in 3D as a 3D bar chart (confusing naming…).

+
+
Parameters:
+
    +
  • samples – An array of shape (n_samples, 2) of samples to compute the histogram of.

  • +
  • n_bins – The number of bins to use in each dimension.

  • +
  • bounds – An array of shape (2, 2) of the bounds of the histogram: ((x_min, x_max), (y_min, y_max)). If None, the +bounds are handled by numpy.histogramdd.

  • +
  • density – If True, the histogram is normalized to form a probability density function.

  • +
  • flatshading – If True, the 3D bars are shaded smoothly.

  • +
  • show – If True, the figure is displayed.

  • +
  • mesh3d_kwargs – A dictionary of keyword arguments to pass to the plotly Mesh3d object.

  • +
  • layout_kwargs – A dictionary of keyword arguments to pass to the update_layout method of the figure.

  • +
+
+
Returns:
+

A plotly figure of the 3D histogram. If show is True, the figure is also displayed.

+
+
+
+ +
+
+axtreme.plotting.histogram3d.histogram_surface3d(samples: ndarray[tuple[int, int], dtype[float64]], *, n_bins: int = 20, bounds: Sequence[tuple[float, float]] | None = None, density: bool = True, show: bool = False, surface3d_kwargs: dict[str, Any] | None = None, layout_kwargs: dict[str, Any] | None = None) Figure
+

Generate a 3D figure of a 2D histogram of the input samples.

+

Computes a 2D histogram that is then plotted in 3D as a surface plot.

+
+
Parameters:
+
    +
  • samples – An array of shape (n_samples, 2) of samples to compute the histogram of.

  • +
  • n_bins – The number of bins to use in each dimension.

  • +
  • bounds – An array of shape (2, 2) of the bounds of the histogram: ((x_min, x_max), (y_min, y_max)). If None, the +bounds are handled by numpy.histogramdd.

  • +
  • density – If True, the histogram is normalized to form a probability density function.

  • +
  • show – If True, the figure is displayed.

  • +
  • surface3d_kwargs – A dictionary of keyword arguments to pass to the plotly Surface3d object.

  • +
  • layout_kwargs – A dictionary of keyword arguments to pass to the update_layout method of the figure.

  • +
+
+
Returns:
+

A plotly figure of the 3D histogram. If show is True, the figure is also displayed.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.plotting.html b/_autosummary/axtreme.plotting.html new file mode 100644 index 00000000..5875a102 --- /dev/null +++ b/_autosummary/axtreme.plotting.html @@ -0,0 +1,486 @@ + + + + + + + + + axtreme.plotting - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.plotting

+

Modules

+
+ + + + + + + + + + + + +

doe

Helper function for plotting DoE behaviour.

gp_fit

Plotting module for visualizing how well the GP fits the data.

histogram3d

3D histogram plotting function.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.gp_bruteforce.GPBruteForce.html b/_autosummary/axtreme.qoi.gp_bruteforce.GPBruteForce.html new file mode 100644 index 00000000..ef5bdbd8 --- /dev/null +++ b/_autosummary/axtreme.qoi.gp_bruteforce.GPBruteForce.html @@ -0,0 +1,669 @@ + + + + + + + + + GPBruteForce - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

GPBruteForce

+
+
+class axtreme.qoi.gp_bruteforce.GPBruteForce(env_iterable: Iterable[Tensor], input_transform: InputTransform | None = None, outcome_transform: OutcomeTransform | None = None, posterior_sampler: PosteriorSampler | None = None, *, erd_samples_per_period: int = 1, shared_surrogate_base_samples: bool = False, device: device | None = None, no_grad: bool = True, seed: int | None = None)
+

Bases: MeanVarPosteriorSampledEstimates, QoIEstimator

+

Estimate the QoI for an extreme response distribution, using a surrogate model.

+

Uses a full periods of environment samples, and passes each sample through the surrogate.

+

Overview of the algorithem:

+
    +
  • Take n periods of environment data points.

  • +
  • Use the surrogate model to estimate the likely response distribution at each point (the posterior).

  • +
  • Take n_posterior_samples of the posterior, each representing a guess at what the true simulator is.

  • +
  • For each posterior sample:

    +
      +
    • Simulate the response seen at each data point.

    • +
    • Find the largest response in each period. Each of these is a sample of that posterior’s ERD.

    • +
    • Calculate the QoI based on these ERD samples.

    • +
    +
  • +
  • Return the QoIs calculated by each posterior sample.

  • +
+

Uncertainty in the results comes from three sources:

+
    +
  • The envirionment samples used.

  • +
  • Uncertainty in the GP and the posterior samples used.

  • +
  • Randomness from sampling the surrogates output distribution.

  • +
+
+
Optimisation Notes:

GPBruteForce is not smooth w.r.t to smooth changes in the model (e.g like provided By QoILookAhead).

+
+
+
+

Todo

+

Provide reference to the gpbruteforce.md file in docs so it renders (sw 2024-11-29).

+
+
+
+__init__(env_iterable: Iterable[Tensor], input_transform: InputTransform | None = None, outcome_transform: OutcomeTransform | None = None, posterior_sampler: PosteriorSampler | None = None, *, erd_samples_per_period: int = 1, shared_surrogate_base_samples: bool = False, device: device | None = None, no_grad: bool = True, seed: int | None = None) None
+

Initialise the QOI estimator.

+
+
Parameters:
+
    +
  • env_iterable

    An iterable that produces the env data to be used. Typically this is a DataLoader.

    +
      +
    • The iterable contains batches of shape (n_periods, batch_size, d).

    • +
    • Combining all of the batch should produce the shape (n_periods, period_len, d).

    • +
    • This is an iterable because predictions often need to be made in batches for memory reasons.

    • +
    • If your data is small, you can process it all at once by passing [data], where data is a tensor.

    • +
    +

  • +
  • input_transform – Transforms that should be applied to the env_samples before being passed to the model.

  • +
  • outcome_transform – Transforms that should be applied to the output of the model before they are used.

  • +
  • posterior_sampler

    The sampler to use to draw samples from the posterior of the GP.

    +
      +
    • n_posterior_samples is set in the PosteriorSampler.

    • +
    +
    +

    Note

    +

    If env_iterable contains batches, a batch-compatible sampler, such as +NormalIndependentSampler, should be chosen.

    +
    +

  • +
  • erd_samples_per_period – Number of ERD samples created from a single period of data. This can reduce the +noise of sampling the response drawn from the surrogate’s response distribution (at a point ‘x’).

  • +
  • shared_surrogate_base_samples

    If True, all n_posterior_samples will use the same base samples when +sampling the surrogate’s response output. As a result, the posterior samples are responsible for any +difference in ERD distribution (e.g., surrogate sampling noise no longer contributes).

    +
      +
    • Set to False: Better shows overall uncertainty in QoI.

    • +
    • Set to True: Shows only uncertainty caused by GP uncertainty.

    • +
    +

  • +
  • device – The device that the model should be run on.

  • +
  • no_grad – Whether to disable gradient tracking for this QOI calculation.

  • +
  • seed – The seed to use for the random number generator. If None, no seed is set.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + +

__init__(env_iterable[, input_transform, ...])

Initialise the QOI estimator.

mean(x)

Function that computes the mean of the estimates produced by using self.posterior_sampler.

posterior_samples_erd_samples(model)

Returns the erd samples created by each posterior sample.

sample_surrogate(params[, n_samples, ...])

Create the surrogate model for a given set of input parameters, and sample response of the surrogate.

var(x)

Function that computes the variance of the estimates produced by using self.posterior_sampler.

+
+

Attributes

+
+ + + + + + +

posterior_sampler

+
+
+
+posterior_samples_erd_samples(model: Model) Tensor
+

Returns the erd samples created by each posterior sample.

+

__call__ uses these erd sample to create a QoI estimate per posterior.

+
+
Parameters:
+

model – The GP model to use for the QOI estimation. It should have output dimension 2 which represents the +location and scale of a Gumbel distribution.

+
+
Returns:
+

The erd samples obtained for each function (posterior sample) obtianed from the GP. +Shape: (n_posterior_samples, n_periods * erd_samples_per_period)

+
+
Return type:
+

Tensor

+
+
+
+ +
+
+static sample_surrogate(params: Tensor, n_samples: int = 1, base_sample_broadcast_dims: list[int] | None = None) Tensor
+

Create the surrogate model for a given set of input parameters, and sample response of the surrogate.

+

Typically a GP is used to parameterise the surrogate model at a specific x. The now parameterise model can be +run multiple times to get different realisations of the stochastic response.

+
+
Parameters:
+
    +
  • params – (*b, p) tensor of parameters. The last dimesion is expected to contain the parameters required to

  • +
  • dimension. (instantiate a single surrogate model. All other dimensions are optional batch)

  • +
  • n_samples – The number of samples to draw from the surrogate model at a single x point.

  • +
  • base_sample_broadcast_dims

    List of indexes in (*b). Base samples will be shared (broadcast) across these +dimension of *b. For example:

    +
      +
    • params.shape is (n_posterior_samples, n_periods, batch_size, n_params).

      +
        +
      • *b = (n_posterior_samples, n_periods, batch_size)

      • +
      • p = (n_params)

      • +
      +
    • +
    • You would like to use the same base samples for each n_posterior_samples, so that any difference in +output can be attributed to the difference in the n_params, rather than due to the randomness in the +sample generated by the surrogate mode.

    • +
    • By setting base_sample_broadcast_dims=[0] the base samples used would be of shape +(1, n_periods, batch_size), which would achieve the desired effect.

    • +
    +

  • +
+
+
Returns:
+

tensor of (n_samples, *b) representing the response of the surrogate model.

+
+
+
+

Todo

+

The base_sample_broadcast_dims behaviour is challenging to describe now that is in this function rather +than in context. Alternately base samples could be directly applied like in +posterior.rsample_from_base_samples. We have avoid this so complexity is contained here for now.

+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.gp_bruteforce.html b/_autosummary/axtreme.qoi.gp_bruteforce.html new file mode 100644 index 00000000..fee4fe29 --- /dev/null +++ b/_autosummary/axtreme.qoi.gp_bruteforce.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.qoi.gp_bruteforce - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.qoi.gp_bruteforce

+

GPBruteForce calculates QoIs by applying the surrogate to each env sample in the period.

+

Classes

+
+ + + + + + +

GPBruteForce(env_iterable[, ...])

Estimate the QoI for an extreme response distribution, using a surrogate model.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.html b/_autosummary/axtreme.qoi.html new file mode 100644 index 00000000..256a929f --- /dev/null +++ b/_autosummary/axtreme.qoi.html @@ -0,0 +1,488 @@ + + + + + + + + + axtreme.qoi - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.qoi

+

Modules

+
+ + + + + + + + + + + + +

gp_bruteforce

GPBruteForce calculates QoIs by applying the surrogate to each env sample in the period.

marginal_cdf_extrapolation

MarginalCDFExtrapolation calculates QoIs by estimating the behaviour of a single timestep, and extrapolating.

qoi_estimator

Module for quantity of interest Quantity of Interest estimator protocol.

+
+
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation.html b/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation.html new file mode 100644 index 00000000..4ea0f653 --- /dev/null +++ b/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation.html @@ -0,0 +1,624 @@ + + + + + + + + + MarginalCDFExtrapolation - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MarginalCDFExtrapolation

+
+
+class axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation(env_iterable: Iterable[Tensor] | Iterable[list[Tensor]], period_len: int, quantile: Tensor | None = None, input_transform: InputTransform | None = None, outcome_transform: OutcomeTransform | None = None, posterior_sampler: PosteriorSampler | None = None, response_distribution: type[Distribution] = Gumbel, quantile_accuracy: Tensor | None = None, dtype: dtype = torch.float64, *, device: device | None = None, no_grad: bool = True)
+

Bases: MeanVarPosteriorSampledEstimates, QoIEstimator

+

Estimate an ERD QoI using the marginal CDF for a single timestep.

+
+
Basic Idea:
    +
  • +
    Get the marginal CDF of the response for a single timestep (e.g. 1 hour).

    Marginal CDF: The CDF after marginalising out all sources of randomness within a timestep. E.g if you +considered all the variablity in a single timestep (e.g all the different weather conditions), collected +the different CDFs they produce, and then averaged them, you would have the marginal CDF.

    +
    +
    +
  • +
  • +
    Using the average CDF you can then calculate:
      +
    • +
      “The probablity that a response of size y won’t be exceeded in 1 hour” as follows:
        +
      • \(CDF(y = .8) = .5\)

      • +
      +
      +
      +
    • +
    • +
      “The probablity that a response of size y won’t be exceeded in 2 hours” as follows:
        +
      • [Prb not exceeded in hour one] AND [Prb not exceeded in hour two]

      • +
      • \(CDF(y = .8) * CDF(y = .8) = .5 * .5 = .25\)

      • +
      +
      +
      +
    • +
    • +
      “The probablity that a response of size y won’t be exceeded in N hours” as follows:
        +
      • \(CDF(y = .8)^N = (.5)^N\)

      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
+

This is possible because we are using the ‘average’ timestep, which is the same for all timesteps.

+
+
Strengths:
    +
  • Once the ‘average’ CDF has been obtained, very large values of N can be calculated quickly.

  • +
+
+
Challenge:
    +
  • Need to obtain the ‘average’ CDF, and it must be very accurate.

  • +
+
+
+

See [#TODO(sw 2024_11_4) put in link to pre-print] for details.

+
+
+__init__(env_iterable: Iterable[Tensor] | Iterable[list[Tensor]], period_len: int, quantile: Tensor | None = None, input_transform: InputTransform | None = None, outcome_transform: OutcomeTransform | None = None, posterior_sampler: PosteriorSampler | None = None, response_distribution: type[Distribution] = Gumbel, quantile_accuracy: Tensor | None = None, dtype: dtype = torch.float64, *, device: device | None = None, no_grad: bool = True) None
+

Initialise the QOI estimator.

+
+
Parameters:
+
    +
  • env_iterable

    An interable that produces the env data to be used. Typically this is a DataLoader. +Supports standard env data, and weighted env data (e.g Importance sampled).

    +
      +
    • Standards env data: Expects tensor of shape (batch_size, d)

    • +
    • Weighted data: Expectes list of tensors.

      +
      +
        +
      • The first: the env data of shape (batch_size,d).

      • +
      • The second item: the weight, of shape (batch_size,).

      • +
      +
      +
    • +
    +

  • +
  • period_len – The number of env samples in the period of interest.

  • +
  • quantile – Shape (,). The quantile of the ERD to be estimate (the QoI). Should be within range (0,1). +default .5.

  • +
  • input_transform – transforms that should be applied to the env_samples before being passed to the model

  • +
  • outcome_transform – transforms that should be applied to the output of the model before they are used

  • +
  • posterior_sampler

    The sampler to use to draw samples from the posterior of the GP.

    +
      +
    • n_posterior_samples: is set in the PosteriorSampler

    • +
    • NOTE: if env_iterable contains batches, a batch compatible sampler such as +NormalIndependentSampler or “ut_sampler” should be selected.

    • +
    +

  • +
  • response_distribution – The distribution which models the stochastic response of the simulation at a single +input point.

  • +
  • quantile_accuracy – shape (,). Default value .01. Internally, optimisation is used to find the quantile. +The optimiser is allowed to terminate once in the region quantile +/- quantile_accuracy. The greater +the accuracy required, the longer the optimisation will take. Typically other sources of uncertainty +produce far greater uncertainty.

  • +
  • dtype – The dtype used for the distribution. This has implications for the numerical accuracy possible.

  • +
  • device – The device QoI should be performed on.

  • +
  • no_grad – If gradient requires tracking through this QOI calculation.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + +

__init__(env_iterable, period_len[, ...])

Initialise the QOI estimator.

mean(x)

Function that computes the mean of the estimates produced by using self.posterior_sampler.

var(x)

Function that computes the variance of the estimates produced by using self.posterior_sampler.

+
+

Attributes

+
+ + + + + + +

posterior_sampler

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.html b/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.html new file mode 100644 index 00000000..f53ea018 --- /dev/null +++ b/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.html @@ -0,0 +1,561 @@ + + + + + + + + + axtreme.qoi.marginal_cdf_extrapolation - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.qoi.marginal_cdf_extrapolation

+

MarginalCDFExtrapolation calculates QoIs by estimating the behaviour of a single timestep, and extrapolating.

+

Functions

+
+ + + + + + + + + +

acceptable_timestep_error(q, period_len[, atol])

Maximum possible single timestep error while still producing required accuracy in period estimate.

q_to_qtimestep(q, period_len)

Convert a long term quantile to an equivalent single timestep quantile.

+
+

Classes

+
+ + + + + + +

MarginalCDFExtrapolation(env_iterable, ...)

Estimate an ERD QoI using the marginal CDF for a single timestep.

+
+
+
+axtreme.qoi.marginal_cdf_extrapolation.acceptable_timestep_error(q: float, period_len: int, atol: float = 0.01) float
+

Maximum possible single timestep error while still producing required accuracy in period estimate.

+

We often make estimates for a single timestep, and scale them to a period (many timesteps). e.g. +q = q_timestep^period_len. Errors in the single timestep estimates compound. This function returns the largest +error possible to a single timestep to still be within the required accuracy in the period estimate.

+
+
Parameters:
+
    +
  • q – long term quantile being estimated.

  • +
  • period_len – the number of timesteps that make up the period of interest.

  • +
  • atol – the maximum absolute error acceptable in q

  • +
+
+
Returns:
+

The maximum absolute error acceptable in the q_timestep estimate.

+
+
+
+ +
+
+axtreme.qoi.marginal_cdf_extrapolation.q_to_qtimestep(q: float, period_len: int) float
+

Convert a long term quantile to an equivalent single timestep quantile.

+
+
Parameters:
+
    +
  • q – long term quantile being estimated.

  • +
  • period_len – the number of timesteps that make up the period of interest.

  • +
+
+
Returns:
+

The equivalent quantile for a single timestep with error +-

+
+
+
+

Note

+

This funciton exists because there were numerical concerns for this process. Having a function allows us to +document them in tests. It is appropriately accuract for very large periods. Periods of 1e13 creates an error of +less that 1e-3 in q (the full quantile estimate). See +test/qoi/test_margianl_cdf_extpolation/test_q_to_qtimestep_numerical_precision_period_increase for details.

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.qoi_estimator.QoIEstimator.html b/_autosummary/axtreme.qoi.qoi_estimator.QoIEstimator.html new file mode 100644 index 00000000..b640d4e7 --- /dev/null +++ b/_autosummary/axtreme.qoi.qoi_estimator.QoIEstimator.html @@ -0,0 +1,564 @@ + + + + + + + + + QoIEstimator - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

QoIEstimator

+
+
+class axtreme.qoi.qoi_estimator.QoIEstimator(*args, **kwargs)
+

Bases: Protocol

+

A protocol for quantity of interest (QoI) estimators.

+
+
+__init__(*args, **kwargs)
+
+ +

Methods

+
+ + + + + + + + + + + + +

__init__(*args, **kwargs)

mean(x)

Function that computes the mean of the QoI estimates (the output of the call() method).

var(x)

Function that computes the variance of the QoI estimates (the output of the call() method).

+
+
+
+mean(x: Tensor) Tensor
+

Function that computes the mean of the QoI estimates (the output of the call() method).

+

For many applications this should just be using a default implementation that computes the mean. +E.g using torch.mean(x).

+

However, in some special cases, it might be useful to provide a custom implementation +to give a more accurate estimate. E.g. when UTSampler is used.

+
+
Parameters:
+

x – A tensor of QoI estimates with shape (number_of_estimates,).

+
+
Returns:
+

The mean of the QoI estimates. Should be a scalar.

+
+
Return type:
+

torch.Tensor

+
+
+
+ +
+
+var(x: Tensor) Tensor
+

Function that computes the variance of the QoI estimates (the output of the call() method).

+

For many applications this should just be using a default implementation that computes the variance. +E.g. using torch.var(x).

+

However, in some special cases, it might be useful to provide a custom implementation +to give a more accurate estimate. E.g. when UTSampler is used.

+
+
Parameters:
+

x – A tensor of QoI estimates with shape (number_of_estimates,).

+
+
Returns:
+

The variance of the QoI estimates. Should be a scalar.

+
+
Return type:
+

torch.Tensor

+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.qoi.qoi_estimator.html b/_autosummary/axtreme.qoi.qoi_estimator.html new file mode 100644 index 00000000..29d299ea --- /dev/null +++ b/_autosummary/axtreme.qoi.qoi_estimator.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.qoi.qoi_estimator - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.qoi.qoi_estimator

+

Module for quantity of interest Quantity of Interest estimator protocol.

+

Classes

+
+ + + + + + +

QoIEstimator(*args, **kwargs)

A protocol for quantity of interest (QoI) estimators.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.runner.LocalMetadataRunner.html b/_autosummary/axtreme.runner.LocalMetadataRunner.html new file mode 100644 index 00000000..f6ea7a07 --- /dev/null +++ b/_autosummary/axtreme.runner.LocalMetadataRunner.html @@ -0,0 +1,603 @@ + + + + + + + + + LocalMetadataRunner - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

LocalMetadataRunner

+
+
+class axtreme.runner.LocalMetadataRunner(evaluation_function: EvaluationFunction)
+

Bases: Runner

+

Except for the addition of evauation_function this is coppied exactly from ax.runners.SyntheticRunner.

+
+
+__init__(evaluation_function: EvaluationFunction) None
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(evaluation_function)

clone()

Create a copy of this Runner.

deserialize_init_args(args[, ...])

Given a dictionary, deserialize the properties needed to initialize the object.

poll_available_capacity()

Checks how much available capacity there is to schedule trial evaluations.

poll_exception(trial)

Returns the exception from a trial.

poll_trial_status(trials)

Checks the status of any non-terminal trials and returns their indices as a mapping from TrialStatus to a list of indices.

run(trial)

Deploys a trial based on custom runner subclass implementation.

run_multiple(trials)

Runs a single evaluation for each of the given trials.

serialize_init_args(obj)

Serialize the properties needed to initialize the object.

stop(trial[, reason])

Stop a trial based on custom runner subclass implementation.

+
+

Attributes

+
+ + + + + + + + + + + + +

db_id

run_metadata_report_keys

A list of keys of the metadata dict returned by run() that are relevant outside the runner-internal impolementation.

staging_required

Whether the trial goes to staged or running state once deployed.

+
+
+
+poll_trial_status(trials: Iterable[BaseTrial]) dict[TrialStatus, set[int]]
+

Checks the status of any non-terminal trials and returns their +indices as a mapping from TrialStatus to a list of indices. Required +for runners used with Ax Scheduler.

+

NOTE: Does not need to handle waiting between polling calls while trials +are running; this function should just perform a single poll.

+
+
Parameters:
+

trials – Trials to poll.

+
+
Returns:
+

A dictionary mapping TrialStatus to a list of trial indices that have +the respective status at the time of the polling. This does not need to +include trials that at the time of polling already have a terminal +(ABANDONED, FAILED, COMPLETED) status (but it may).

+
+
+
+ +
+
+run(trial: BaseTrial) dict[str, Any]
+

Deploys a trial based on custom runner subclass implementation.

+
+
Parameters:
+

trial – The trial to deploy.

+
+
Returns:
+

Dict of run metadata from the deployment process.

+
+
+
+ +
+
+property run_metadata_report_keys: list[str]
+

A list of keys of the metadata dict returned by run() that are +relevant outside the runner-internal impolementation. These can e.g. +be reported in Scheduler.report_results().

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.runner.html b/_autosummary/axtreme.runner.html new file mode 100644 index 00000000..4a330cc6 --- /dev/null +++ b/_autosummary/axtreme.runner.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.runner - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.runner

+

Additional Runner implementatiions.

+

Classes

+
+ + + + + + +

LocalMetadataRunner(evaluation_function)

Except for the addition of evauation_function this is coppied exactly from ax.runners.SyntheticRunner.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.base.MeanVarPosteriorSampledEstimates.html b/_autosummary/axtreme.sampling.base.MeanVarPosteriorSampledEstimates.html new file mode 100644 index 00000000..9d681fbe --- /dev/null +++ b/_autosummary/axtreme.sampling.base.MeanVarPosteriorSampledEstimates.html @@ -0,0 +1,629 @@ + + + + + + + + + MeanVarPosteriorSampledEstimates - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MeanVarPosteriorSampledEstimates

+
+
+class axtreme.sampling.base.MeanVarPosteriorSampledEstimates(*args, **kwargs)
+

Bases: Protocol

+

This is a protocol for classes that computes estimates using a PosteriorSampler.

+

Some posterior samplers require that mean and variance of the estimates calculated by sampling from it need to be +calculated in a special way. This protocol allows for these special methods to be easier to be used on the +outside of the class that inherits from this protocol. One example of a case where this is useful is when using a +posterior sampler in a QoIEstimator. For more information check issue #132.

+

Example of usage:

+
class MyClass(MeanVarPosteriorSampledEstimates):
+    def __init__(self, posterior_sampler: PosteriorSampler):
+        self.posterior_sampler = posterior_sampler
+
+    def f(self, x: torch.Tensor) -> torch.Tensor:
+        # Some functions that takes the samples and returns a tensor
+        # The dimension representing the posterior_sampling should be preserved.
+        ...
+
+    def foo(self) -> torch.Tensor:
+        #  Get a model and points x to evaluate posterior
+        x: torch.Tensor = ...
+        model: botorch.models.Model = ...
+
+        # Calculating posterior
+        posterior = model.posterior(x)
+
+        # Sampling from the posterior
+        samples = self.posterior_sampler(posterior)
+
+        return self.f(samples)
+
+
+estimator = MyClass(posterior_sampler)
+result = estimator.foo()
+
+# Using the mean and var methods from MeanVarPosteriorSampledEstimates
+# This will use the mean and var methods from the posterior_sampler if they are available.
+mean = estimator.mean(result)
+var = estimator.var(result)
+
+
+
+
+__init__(*args, **kwargs)
+
+ +

Methods

+
+ + + + + + + + + + + + +

__init__(*args, **kwargs)

mean(x)

Function that computes the mean of the estimates produced by using self.posterior_sampler.

var(x)

Function that computes the variance of the estimates produced by using self.posterior_sampler.

+
+

Attributes

+
+ + + + + + +

posterior_sampler

+
+
+
+mean(x: Tensor) Tensor
+

Function that computes the mean of the estimates produced by using self.posterior_sampler.

+

The dimension representing the posterior_sampling should be preserved from the sampling using +self.posterior_sampler to sample a posterior until using this method.

+

For many applications this method will just be using a default implementation that computes the mean. +E.g using torch.mean(x) like in this implementation.

+

However, in some special cases, it might be useful to provide a custom implementation +to give a more accurate estimate. +For instance if one uses UTSampler to sample the posterior +the mean should be estimated as a weighted sum of the estimates.

+

This function uses the mean method of the posterior_sampler if it is available, +otherwise it uses the default implementation.

+
+
Parameters:
+

x – A tensor of the estimates with shape (num_posterior_samples,).

+
+
Returns:
+

The mean of the the estimates. Should be a scalar with shape ().

+
+
Return type:
+

torch.Tensor

+
+
+
+ +
+
+var(x: Tensor) Tensor
+

Function that computes the variance of the estimates produced by using self.posterior_sampler.

+

The dimension representing the posterior_sampling should be preserved from the sampling using +self.posterior_sampler to sample a posterior until using this method.

+

For many applications this method will just be using a default implementation that computes the variance. +E.g using torch.var(x) like in this implementation.

+

However, in some special cases, it might be useful to provide a custom implementation +to give a more accurate estimate. +For instance if one uses UTSampler to sample the posterior +the variance should be estimated in a special way.

+

This function uses the variance method of the posterior_sampler if it is available, +otherwise it uses the default implementation.

+
+
Parameters:
+

x – A tensor of the estimates with shape (num_posterior_samples,).

+
+
Returns:
+

The variance of the the estimates. Should be a scalar with shape ().

+
+
Return type:
+

torch.Tensor

+
+
+
+ +
+
+posterior_sampler: PosteriorSampler
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.base.PosteriorSampler.html b/_autosummary/axtreme.sampling.base.PosteriorSampler.html new file mode 100644 index 00000000..e384875b --- /dev/null +++ b/_autosummary/axtreme.sampling.base.PosteriorSampler.html @@ -0,0 +1,563 @@ + + + + + + + + + PosteriorSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

PosteriorSampler

+
+
+class axtreme.sampling.base.PosteriorSampler(*args, **kwargs)
+

Bases: Protocol

+

Defines the protocol for sampler function.

+

This follows the definition of the MCSampler.forward() method, but allows for simple function based implementations.

+
+

Note

+

Function using posteriors should check if there are special mean and var methods if they support posterior +samplers that require them (e.g UT). See note below for details.

+
+

Notes on samplers the require special aggregation of results:

+
    +
  • We use a surrogate model to estimate a Quantity of Interest (QOI), and provide uncertainty of that estimate. +Typically it is challenging to calculate this on the posterior directly, so often we take samples of the +posterior and calculate the value of interest using those. We can then combine those estimates to give the QOI +mean/variance for the overall posterior.

  • +
  • Some methods (e.g UT) select posterior samples in a special way which means less samples are needed. The +calculations for each of these samples then need to be combined in a special way to estimate the QOI +mean/variance for the overall posterior. If such special methods are needed, they should be implement on the +posterior sampler with the following signature.

    +
    def mean(self, x: torch.Tensor) -> torch.Tensor: ...
    +def var(self, x: torch.Tensor) -> torch.Tensor: ...
    +
    +
    +

    Where

    +
      +
    • x is the scores (e.g QOIs) for each posterior sample.

      +
        +
      • It is expected to be of shape (batch_shape)

      • +
      +
      +

      Todo

      +

      Batching gets confusing here, how should we do UT of multiple batch dims? Is it only +ever flat, should we say that here?

      +
      +
        +
      • Output is a scalar.

      • +
      +
    • +
    +
  • +
+
+

Todo

+

Need to fix/revisit this. Feel wrong that functions that use posterior need to check for some optional methods +that “might” be there (and those functions are not programmatically defined as part of the protocol). Extra +info in #132.

+
+

Note

+

The functions are not on the protocol because we want MCSampler from botorch to fall into protocol +definition.

+
+
+
+
+__init__(*args, **kwargs)
+
+ +

Methods

+
+ + + + + + +

__init__(*args, **kwargs)

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.base.html b/_autosummary/axtreme.sampling.base.html new file mode 100644 index 00000000..f6b72b14 --- /dev/null +++ b/_autosummary/axtreme.sampling.base.html @@ -0,0 +1,484 @@ + + + + + + + + + axtreme.sampling.base - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.sampling.base

+

Defines the interface posterior samplers are expected to adhear to.

+

Classes

+
+ + + + + + + + + +

MeanVarPosteriorSampledEstimates(*args, **kwargs)

This is a protocol for classes that computes estimates using a PosteriorSampler.

PosteriorSampler(*args, **kwargs)

Defines the protocol for sampler function.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.html b/_autosummary/axtreme.sampling.html new file mode 100644 index 00000000..dbf71e24 --- /dev/null +++ b/_autosummary/axtreme.sampling.html @@ -0,0 +1,493 @@ + + + + + + + + + axtreme.sampling - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.sampling

+

Module for sampling from a posterior distribution.

+

Modules

+
+ + + + + + + + + + + + + + + + + + +

base

Defines the interface posterior samplers are expected to adhear to.

independent_sampler

Base class for sampling methods that ignore covariance between different input points.

mean_sampler

Module for the MeanPosteriorSampler class.

normal_independent_sampler

Module for the NormalIndependentSampler class.

ut_sampler

Module for the UTSampler class for sampling a posterior using the Unscented Transform.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.independent_sampler.IndependentMCSampler.html b/_autosummary/axtreme.sampling.independent_sampler.IndependentMCSampler.html new file mode 100644 index 00000000..77fbe174 --- /dev/null +++ b/_autosummary/axtreme.sampling.independent_sampler.IndependentMCSampler.html @@ -0,0 +1,749 @@ + + + + + + + + + IndependentMCSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

IndependentMCSampler

+
+
+class axtreme.sampling.independent_sampler.IndependentMCSampler(sample_shape: Size, seed: int | None = None, **kwargs: Any)
+

Bases: MCSampler, ABC

+

Abstract base class for MCSamplers that independantly apply the same set of base samples at each x point.

+

This should be used when you want to ignore the covariance between different x points, and sample the X output +space independently.

+
+

Note

+

Dimensions of the posterior are described using botorch notation (detailed in glassary.md) where:

+
    +
  • *b: batch shape (can have arbitrary dimensionality).

  • +
  • n: the number of x input points.

  • +
  • m: dimensionality of targets space.

  • +
+

For example:

+
    +
  • MultivariateNormal: (*b, n)

  • +
  • MultitaskMultivariateNormal: (*b, n, m)

  • +
+
+
+
Dev Notes:
    +
  • Is the shape of the base samples up to us to define, or are there some other parts of the system that expect +MCSampler to have certain shape.

    +
    +

    Answer: MCSampler does not define base_sample - we can do what we want.

    +
    +
  • +
  • MultivariateNormal and MultitaskMultivariateNormal both requires shape (*sample_shape, *posterior.shape() +for base_samples in posterior.rsample_from_base_samples

    +
      +
    • For MultitaskMultivariateNormal: posterior.shape() = (*b,n,m)

    • +
    • For MultivariateNormal: posterior.shape() = (*b,n)

    • +
    +
  • +
+
+
+

Design decision: we decide to make m explicit throughout.

+
+
    +
  • e.g base samples will always have shape (*sample_shape,m)

  • +
  • This makes our code cleaner. When then convert back to implicit m dimension when calling +posterior.rsample_from_base_samples

  • +
+
+
+
+__init__(sample_shape: Size, seed: int | None = None, **kwargs: Any) None
+

Abstract base class for samplers.

+
+
Parameters:
+
    +
  • sample_shape – The sample_shape of the samples to generate. The full shape +of the samples is given by posterior._extended_shape(sample_shape).

  • +
  • seed – An optional seed to use for sampling.

  • +
  • **kwargs – Catch-all for deprecated kwargs.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(sample_shape[, seed])

Abstract base class for samplers.

add_module(name, module)

Add a child module to the current module.

apply(fn)

Apply fn recursively to every submodule (as returned by .children()) as well as self.

bfloat16()

Casts all floating point parameters and buffers to bfloat16 datatype.

buffers([recurse])

Return an iterator over module buffers.

children()

Return an iterator over immediate children modules.

compile(*args, **kwargs)

Compile this Module's forward using torch.compile().

cpu()

Move all model parameters and buffers to the CPU.

cuda([device])

Move all model parameters and buffers to the GPU.

double()

Casts all floating point parameters and buffers to double datatype.

eval()

Set the module in evaluation mode.

extra_repr()

Set the extra representation of the module.

float()

Casts all floating point parameters and buffers to float datatype.

forward(posterior)

Draw samples from the posterior, treating each of the n input points as independant.

get_buffer(target)

Return the buffer given by target if it exists, otherwise throw an error.

get_extra_state()

Return any extra state to include in the module's state_dict.

get_parameter(target)

Return the parameter given by target if it exists, otherwise throw an error.

get_submodule(target)

Return the submodule given by target if it exists, otherwise throw an error.

half()

Casts all floating point parameters and buffers to half datatype.

ipu([device])

Move all model parameters and buffers to the IPU.

load_state_dict(state_dict[, strict, assign])

Copy parameters and buffers from state_dict into this module and its descendants.

modules()

Return an iterator over all modules in the network.

named_buffers([prefix, recurse, ...])

Return an iterator over module buffers, yielding both the name of the buffer as well as the buffer itself.

named_children()

Return an iterator over immediate children modules, yielding both the name of the module as well as the module itself.

named_modules([memo, prefix, remove_duplicate])

Return an iterator over all modules in the network, yielding both the name of the module as well as the module itself.

named_parameters([prefix, recurse, ...])

Return an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself.

parameters([recurse])

Return an iterator over module parameters.

register_backward_hook(hook)

Register a backward hook on the module.

register_buffer(name, tensor[, persistent])

Add a buffer to the module.

register_forward_hook(hook, *[, prepend, ...])

Register a forward hook on the module.

register_forward_pre_hook(hook, *[, ...])

Register a forward pre-hook on the module.

register_full_backward_hook(hook[, prepend])

Register a backward hook on the module.

register_full_backward_pre_hook(hook[, prepend])

Register a backward pre-hook on the module.

register_load_state_dict_post_hook(hook)

Register a post hook to be run after module's load_state_dict is called.

register_module(name, module)

Alias for add_module().

register_parameter(name, param)

Add a parameter to the module.

register_state_dict_pre_hook(hook)

Register a pre-hook for the state_dict() method.

requires_grad_([requires_grad])

Change if autograd should record operations on parameters in this module.

set_extra_state(state)

Set extra state contained in the loaded state_dict.

share_memory()

See torch.Tensor.share_memory_().

state_dict(*args[, destination, prefix, ...])

Return a dictionary containing references to the whole state of the module.

to(*args, **kwargs)

Move and/or cast the parameters and buffers.

to_empty(*, device[, recurse])

Move the parameters and buffers to the specified device without copying storage.

train([mode])

Set the module in training mode.

type(dst_type)

Casts all parameters and buffers to dst_type.

xpu([device])

Move all model parameters and buffers to the XPU.

zero_grad([set_to_none])

Reset gradients of all model parameters.

+
+

Attributes

+
+ + + + + + + + + + + + + + + +

T_destination

call_super_init

dump_patches

training

+
+
+
+forward(posterior: Posterior) Tensor
+

Draw samples from the posterior, treating each of the n input points as independant.

+
+
Parameters:
+

posterior – The posterior which should be sampled.

+
+
Returns:
+

(*sample_shape, *b, n, m) where: +- *b: is the posterior batch shape +- n: number of input points in posterior +- m: dimensionality of target

+

NOTE: While MultitaskMultivariateNormal and MultivariateNormal have different shapes ((*b,n,m) and (*b,n)) +the output of this function is always of shape (*sample_shape, *b, n, m). +This is consistent with the behaviour of MCSampler.

+

+
+
Return type:
+

Returns a samples of the posterior with shape

+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.independent_sampler.html b/_autosummary/axtreme.sampling.independent_sampler.html new file mode 100644 index 00000000..df9e6f8d --- /dev/null +++ b/_autosummary/axtreme.sampling.independent_sampler.html @@ -0,0 +1,529 @@ + + + + + + + + + axtreme.sampling.independent_sampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.sampling.independent_sampler

+

Base class for sampling methods that ignore covariance between different input points.

+

Todo: TODO +- For MultiTask models (e.g GPs with multiple targets that are not indpendant), this covariance should be considered. +- Currently ALL covariance is ignored.

+

Functions

+
+ + + + + + +

diagonalize_distribution(posterior)

Diagonalize the distribution of the posterior.

+
+

Classes

+
+ + + + + + +

IndependentMCSampler(sample_shape[, seed])

Abstract base class for MCSamplers that independantly apply the same set of base samples at each x point.

+
+
+
+axtreme.sampling.independent_sampler.diagonalize_distribution(posterior: GPyTorchPosterior) GPyTorchPosterior
+

Diagonalize the distribution of the posterior.

+

The points in the posterior need to be treated as independent from each other. +Therefore we want the covariance matrix to be diagonal.

+
+
Parameters:
+

posterior – The posterior to diagonalize.

+
+
Returns:
+

The diagonalized posterior.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.mean_sampler.MeanSampler.html b/_autosummary/axtreme.sampling.mean_sampler.MeanSampler.html new file mode 100644 index 00000000..2caaf44e --- /dev/null +++ b/_autosummary/axtreme.sampling.mean_sampler.MeanSampler.html @@ -0,0 +1,515 @@ + + + + + + + + + MeanSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

MeanSampler

+
+
+class axtreme.sampling.mean_sampler.MeanSampler(*args, **kwargs)
+

Bases: PosteriorSampler

+

Class for sampling a posterior by returning the mean of the posterior.

+

This is a simple sampler that just returns the mean of the posterior.

+
+
+__init__(*args, **kwargs)
+
+ +

Methods

+
+ + + + + + +

__init__(*args, **kwargs)

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.mean_sampler.html b/_autosummary/axtreme.sampling.mean_sampler.html new file mode 100644 index 00000000..ee02748a --- /dev/null +++ b/_autosummary/axtreme.sampling.mean_sampler.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.sampling.mean_sampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.sampling.mean_sampler

+

Module for the MeanPosteriorSampler class.

+

Classes

+
+ + + + + + +

MeanSampler(*args, **kwargs)

Class for sampling a posterior by returning the mean of the posterior.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.normal_independent_sampler.NormalIndependentSampler.html b/_autosummary/axtreme.sampling.normal_independent_sampler.NormalIndependentSampler.html new file mode 100644 index 00000000..ede8a548 --- /dev/null +++ b/_autosummary/axtreme.sampling.normal_independent_sampler.NormalIndependentSampler.html @@ -0,0 +1,682 @@ + + + + + + + + + NormalIndependentSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

NormalIndependentSampler

+
+
+class axtreme.sampling.normal_independent_sampler.NormalIndependentSampler(sample_shape: Size, seed: int | None = None, **kwargs: Any)
+

Bases: IndependentMCSampler

+

IndependentMCSampler that randomly generates base samples from a Normal distribution.

+
+
+__init__(sample_shape: Size, seed: int | None = None, **kwargs: Any) None
+

Abstract base class for samplers.

+
+
Parameters:
+
    +
  • sample_shape – The sample_shape of the samples to generate. The full shape +of the samples is given by posterior._extended_shape(sample_shape).

  • +
  • seed – An optional seed to use for sampling.

  • +
  • **kwargs – Catch-all for deprecated kwargs.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__(sample_shape[, seed])

Abstract base class for samplers.

add_module(name, module)

Add a child module to the current module.

apply(fn)

Apply fn recursively to every submodule (as returned by .children()) as well as self.

bfloat16()

Casts all floating point parameters and buffers to bfloat16 datatype.

buffers([recurse])

Return an iterator over module buffers.

children()

Return an iterator over immediate children modules.

compile(*args, **kwargs)

Compile this Module's forward using torch.compile().

cpu()

Move all model parameters and buffers to the CPU.

cuda([device])

Move all model parameters and buffers to the GPU.

double()

Casts all floating point parameters and buffers to double datatype.

eval()

Set the module in evaluation mode.

extra_repr()

Set the extra representation of the module.

float()

Casts all floating point parameters and buffers to float datatype.

forward(posterior)

Draw samples from the posterior, treating each of the n input points as independant.

get_buffer(target)

Return the buffer given by target if it exists, otherwise throw an error.

get_extra_state()

Return any extra state to include in the module's state_dict.

get_parameter(target)

Return the parameter given by target if it exists, otherwise throw an error.

get_submodule(target)

Return the submodule given by target if it exists, otherwise throw an error.

half()

Casts all floating point parameters and buffers to half datatype.

ipu([device])

Move all model parameters and buffers to the IPU.

load_state_dict(state_dict[, strict, assign])

Copy parameters and buffers from state_dict into this module and its descendants.

modules()

Return an iterator over all modules in the network.

named_buffers([prefix, recurse, ...])

Return an iterator over module buffers, yielding both the name of the buffer as well as the buffer itself.

named_children()

Return an iterator over immediate children modules, yielding both the name of the module as well as the module itself.

named_modules([memo, prefix, remove_duplicate])

Return an iterator over all modules in the network, yielding both the name of the module as well as the module itself.

named_parameters([prefix, recurse, ...])

Return an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself.

parameters([recurse])

Return an iterator over module parameters.

register_backward_hook(hook)

Register a backward hook on the module.

register_buffer(name, tensor[, persistent])

Add a buffer to the module.

register_forward_hook(hook, *[, prepend, ...])

Register a forward hook on the module.

register_forward_pre_hook(hook, *[, ...])

Register a forward pre-hook on the module.

register_full_backward_hook(hook[, prepend])

Register a backward hook on the module.

register_full_backward_pre_hook(hook[, prepend])

Register a backward pre-hook on the module.

register_load_state_dict_post_hook(hook)

Register a post hook to be run after module's load_state_dict is called.

register_module(name, module)

Alias for add_module().

register_parameter(name, param)

Add a parameter to the module.

register_state_dict_pre_hook(hook)

Register a pre-hook for the state_dict() method.

requires_grad_([requires_grad])

Change if autograd should record operations on parameters in this module.

set_extra_state(state)

Set extra state contained in the loaded state_dict.

share_memory()

See torch.Tensor.share_memory_().

state_dict(*args[, destination, prefix, ...])

Return a dictionary containing references to the whole state of the module.

to(*args, **kwargs)

Move and/or cast the parameters and buffers.

to_empty(*, device[, recurse])

Move the parameters and buffers to the specified device without copying storage.

train([mode])

Set the module in training mode.

type(dst_type)

Casts all parameters and buffers to dst_type.

xpu([device])

Move all model parameters and buffers to the XPU.

zero_grad([set_to_none])

Reset gradients of all model parameters.

+
+

Attributes

+
+ + + + + + + + + + + + + + + +

T_destination

call_super_init

dump_patches

training

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.normal_independent_sampler.html b/_autosummary/axtreme.sampling.normal_independent_sampler.html new file mode 100644 index 00000000..25287d6b --- /dev/null +++ b/_autosummary/axtreme.sampling.normal_independent_sampler.html @@ -0,0 +1,484 @@ + + + + + + + + + axtreme.sampling.normal_independent_sampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.sampling.normal_independent_sampler

+

Module for the NormalIndependentSampler class.

+

This module contains the NormalIndependentSampler class, which is a subclass of IndependentMCSampler. +It is used to randomly generate base samples from a Normal distribution and when you want to ignore +the covariance between different x points, and sample a single X output space independently.

+

Classes

+
+ + + + + + +

NormalIndependentSampler(sample_shape[, seed])

IndependentMCSampler that randomly generates base samples from a Normal distribution.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.ut_sampler.UTSampler.html b/_autosummary/axtreme.sampling.ut_sampler.UTSampler.html new file mode 100644 index 00000000..d600f16f --- /dev/null +++ b/_autosummary/axtreme.sampling.ut_sampler.UTSampler.html @@ -0,0 +1,779 @@ + + + + + + + + + UTSampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

UTSampler

+
+
+class axtreme.sampling.ut_sampler.UTSampler(alpha: float = 1, beta: float = 2, kappa_base: float = 3)
+

Bases: IndependentMCSampler

+

Class for sampling a posterior using the Unscented Transform.

+

The Unscented Transform is a method for transforming a distribution through a non-linear function. +The method is based on the Unscented Kalman Filter. +It uses a set of sigma points to estimate the mean and covariance of the transformed distribution.

+
+
+__init__(alpha: float = 1, beta: float = 2, kappa_base: float = 3) None
+

Initializer for the UTSampler.

+
+
Parameters:
+
    +
  • alpha – Scaling parameter for the sigma points. See filterpy.kalman.MerweScaledSigmaPoints.

  • +
  • beta – Parameter for the distribution. +- For Gaussian distributions, beta=2 is optimal. +- See filterpy.kalman.MerweScaledSigmaPoints.

  • +
  • kappa_base – Base parameter for the sigma points. See filterpy.kalman.MerweScaledSigmaPoints.

  • +
+
+
+
+ +

Methods

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

__init__([alpha, beta, kappa_base])

Initializer for the UTSampler.

add_module(name, module)

Add a child module to the current module.

apply(fn)

Apply fn recursively to every submodule (as returned by .children()) as well as self.

bfloat16()

Casts all floating point parameters and buffers to bfloat16 datatype.

buffers([recurse])

Return an iterator over module buffers.

children()

Return an iterator over immediate children modules.

compile(*args, **kwargs)

Compile this Module's forward using torch.compile().

cpu()

Move all model parameters and buffers to the CPU.

cuda([device])

Move all model parameters and buffers to the GPU.

double()

Casts all floating point parameters and buffers to double datatype.

eval()

Set the module in evaluation mode.

extra_repr()

Set the extra representation of the module.

float()

Casts all floating point parameters and buffers to float datatype.

forward(posterior)

Draw samples from the posterior, treating each of the n input points as independant.

get_buffer(target)

Return the buffer given by target if it exists, otherwise throw an error.

get_extra_state()

Return any extra state to include in the module's state_dict.

get_parameter(target)

Return the parameter given by target if it exists, otherwise throw an error.

get_submodule(target)

Return the submodule given by target if it exists, otherwise throw an error.

half()

Casts all floating point parameters and buffers to half datatype.

ipu([device])

Move all model parameters and buffers to the IPU.

load_state_dict(state_dict[, strict, assign])

Copy parameters and buffers from state_dict into this module and its descendants.

mean(transformed_points[, dim])

Estimate the mean of the transformed UT sampled points.

modules()

Return an iterator over all modules in the network.

named_buffers([prefix, recurse, ...])

Return an iterator over module buffers, yielding both the name of the buffer as well as the buffer itself.

named_children()

Return an iterator over immediate children modules, yielding both the name of the module as well as the module itself.

named_modules([memo, prefix, remove_duplicate])

Return an iterator over all modules in the network, yielding both the name of the module as well as the module itself.

named_parameters([prefix, recurse, ...])

Return an iterator over module parameters, yielding both the name of the parameter as well as the parameter itself.

parameters([recurse])

Return an iterator over module parameters.

register_backward_hook(hook)

Register a backward hook on the module.

register_buffer(name, tensor[, persistent])

Add a buffer to the module.

register_forward_hook(hook, *[, prepend, ...])

Register a forward hook on the module.

register_forward_pre_hook(hook, *[, ...])

Register a forward pre-hook on the module.

register_full_backward_hook(hook[, prepend])

Register a backward hook on the module.

register_full_backward_pre_hook(hook[, prepend])

Register a backward pre-hook on the module.

register_load_state_dict_post_hook(hook)

Register a post hook to be run after module's load_state_dict is called.

register_module(name, module)

Alias for add_module().

register_parameter(name, param)

Add a parameter to the module.

register_state_dict_pre_hook(hook)

Register a pre-hook for the state_dict() method.

requires_grad_([requires_grad])

Change if autograd should record operations on parameters in this module.

set_extra_state(state)

Set extra state contained in the loaded state_dict.

share_memory()

See torch.Tensor.share_memory_().

state_dict(*args[, destination, prefix, ...])

Return a dictionary containing references to the whole state of the module.

to(*args, **kwargs)

Move and/or cast the parameters and buffers.

to_empty(*, device[, recurse])

Move the parameters and buffers to the specified device without copying storage.

train([mode])

Set the module in training mode.

type(dst_type)

Casts all parameters and buffers to dst_type.

var(transformed_points[, dim])

Estimate the variance of the transformed UT sampled points.

xpu([device])

Move all model parameters and buffers to the XPU.

zero_grad([set_to_none])

Reset gradients of all model parameters.

+
+

Attributes

+
+ + + + + + + + + + + + + + + + + + + + + + + + +

T_destination

alpha

The alpha parameter defined by filterpy.kalman.MerweScaledSigmaPoints.

beta

The beta parameter defined by filterpy.kalman.MerweScaledSigmaPoints.

call_super_init

dump_patches

kappa_base

The kappa_base parameter related to kappa defined by filterpy.kalman.MerweScaledSigmaPoints.

training

+
+
+
+mean(transformed_points: Tensor, dim: int = 0) Tensor
+

Estimate the mean of the transformed UT sampled points.

+

The UT sampled points are designed together with the weights to estimate the mean of the distribution +When the points are transformed through some function, +the mean of the transformed points is estimated by calculating the weighted sum of the points.

+
+
This will only work correctly if the last points generated using this sampler
    +
  • Have the same number of targets (m) the transformed points.

  • +
  • Were generated using the same alpha, beta, and kappa_base parameters.

  • +
+
+
+
+
Parameters:
+
    +
  • transformed_points – The transformed points to estimate the mean of.

  • +
  • dim – The dimension along which to calculate the mean.

  • +
+
+
Returns:
+

The estimated mean of the distribution.

+
+
+
+ +
+
+var(transformed_points: Tensor, dim: int = 0) Tensor
+

Estimate the variance of the transformed UT sampled points.

+

The UT sampled points are designed together with the weights to estimate the variance of the distribution +When the points are transformed through some function, +the variance of the transformed points is estimated by calculating the weighted sum of the points.

+
+
This will only work correctly if the last points generated using this sampler
    +
  • Have the same number of targets (m) as the transformed points.

  • +
  • Were generated using the same alpha, beta, and kappa_base parameters.

  • +
+
+
+
+
Parameters:
+
    +
  • transformed_points – The transformed points to estimate the variance of.

  • +
  • dim – The dimension along which to calculate the variance.

  • +
+
+
Returns:
+

The estimated variance of the distribution.

+
+
+
+ +
+
+property alpha: float
+

The alpha parameter defined by filterpy.kalman.MerweScaledSigmaPoints.

+
+ +
+
+property beta: float
+

The beta parameter defined by filterpy.kalman.MerweScaledSigmaPoints.

+
+ +
+
+property kappa_base: float
+

The kappa_base parameter related to kappa defined by filterpy.kalman.MerweScaledSigmaPoints.

+

The kappa value used in filterpy.kalman.MerweScaledSigmaPoints is calculated as kappa_base - num_target.

+
+ +
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.sampling.ut_sampler.html b/_autosummary/axtreme.sampling.ut_sampler.html new file mode 100644 index 00000000..578226e4 --- /dev/null +++ b/_autosummary/axtreme.sampling.ut_sampler.html @@ -0,0 +1,545 @@ + + + + + + + + + axtreme.sampling.ut_sampler - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.sampling.ut_sampler

+

Module for the UTSampler class for sampling a posterior using the Unscented Transform.

+

Functions

+
+ + + + + + +

calculate_sigmas(dim, alpha, beta, kappa_base)

Create the sigma points, and the weight for calculating mean and variance.

+
+

Classes

+
+ + + + + + +

UTSampler([alpha, beta, kappa_base])

Class for sampling a posterior using the Unscented Transform.

+
+
+
+axtreme.sampling.ut_sampler.calculate_sigmas(dim: int, alpha: float, beta: float, kappa_base: float) tuple[Tensor, Tensor, Tensor]
+

Create the sigma points, and the weight for calculating mean and variance.

+
+
Parameters:
+
    +
  • dim – dimensionality of the space to produce sigma points for. +E.g The dimensionality of the output of a GP at a sinlge input point.

  • +
  • alpha – Scaling parameter for the sigma points.

  • +
  • beta – Parameter for the distribution. For Gaussian distributions, beta=2 is optimal.

  • +
  • kappa_base – Base parameter for the sigma points.

  • +
+
+
Returns:
+

A tuple of three tensors where,

+
    +
  1. (m,dim) defines signma points, where +- m: is the number of sigma points generated +- dim: is the dimension of those points

  2. +
  3. (m): weights required to combines these signma points for a mean estimate

  4. +
  5. (m): weights required to combines these signma points for a variance estimate

  6. +
+

+
+
+
+

Todo

+
    +
  • does not currently support correlation between t dimensions.

  • +
  • (ks) - For now using filterpy for UT. Might want to implement our own version

  • +
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.simulator.base.Simulator.html b/_autosummary/axtreme.simulator.base.Simulator.html new file mode 100644 index 00000000..295f274c --- /dev/null +++ b/_autosummary/axtreme.simulator.base.Simulator.html @@ -0,0 +1,514 @@ + + + + + + + + + Simulator - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

Simulator

+
+
+class axtreme.simulator.base.Simulator(*args, **kwargs)
+

Bases: Protocol

+

A protocol for (simulation) models.

+
+
+__init__(*args, **kwargs)
+
+ +

Methods

+
+ + + + + + +

__init__(*args, **kwargs)

+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.simulator.base.html b/_autosummary/axtreme.simulator.base.html new file mode 100644 index 00000000..b001d11b --- /dev/null +++ b/_autosummary/axtreme.simulator.base.html @@ -0,0 +1,481 @@ + + + + + + + + + axtreme.simulator.base - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.simulator.base

+

Define the simulator interface downsteam axtreme components expect.

+

Classes

+
+ + + + + + +

Simulator(*args, **kwargs)

A protocol for (simulation) models.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.simulator.html b/_autosummary/axtreme.simulator.html new file mode 100644 index 00000000..9d20a60d --- /dev/null +++ b/_autosummary/axtreme.simulator.html @@ -0,0 +1,483 @@ + + + + + + + + + axtreme.simulator - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.simulator

+

Modules

+
+ + + + + + + + + +

base

Define the simulator interface downsteam axtreme components expect.

utils

Helper functions for creating vaid simulators.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.simulator.utils.html b/_autosummary/axtreme.simulator.utils.html new file mode 100644 index 00000000..7ffd66a4 --- /dev/null +++ b/_autosummary/axtreme.simulator.utils.html @@ -0,0 +1,553 @@ + + + + + + + + + axtreme.simulator.utils - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.simulator.utils

+

Helper functions for creating vaid simulators.

+

Functions

+
+ + + + + + + + + +

is_valid_simulator(instance, *[, verbose])

Checks that instance conforms to Simulator protocol AND signature definition.

simulator_from_func(func)

Adds n_simulations_per_point functionality to a a function that takes x inputs, and return simulation values.

+
+
+
+axtreme.simulator.utils.is_valid_simulator(instance: object, *, verbose: bool = False) bool
+

Checks that instance conforms to Simulator protocol AND signature definition.

+

This test only works if the instance has type definitions.

+
+

Note

+

By default, isinstance with @runtime_checkable “will check only the presence of the required methods not +their type signatures!”. See @runtime_checkable docs for details.

+
+
+
Parameters:
+
    +
  • instance – will check if this is a valid Simulator.

  • +
  • verbose – If true will provide information regarding why it does not conform.

  • +
+
+
Returns:
+

True if methods and signatures match

+
+
Return type:
+

bool

+
+
+
+

Note

+
    +
  • Briefly looked at override the __instancecheck__ so isinstance would acheive this result

  • +
  • Apprears __instancecheck__ doesn’t get called, would need to investigate why to proceed

  • +
  • Adding this behaviour to protocol would cause it to depart from standard protocol behaviour

  • +
+
+
+ +
+
+axtreme.simulator.utils.simulator_from_func(func: Callable[[ndarray[tuple[int, int], dtype[float64]]], ndarray[tuple[int, int], dtype[float64]]]) Simulator
+

Adds n_simulations_per_point functionality to a a function that takes x inputs, and return simulation values.

+
+
Parameters:
+

func – function which accepts (n,d) x input, and returns (n, m) y output (one response per x point).

+
+
Returns:
+

Function conforming to Simultator interface. Output will always be 3 dimensional +(n_points, n_simulations_per_point, n_targets).

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.distibution_helpers.html b/_autosummary/axtreme.utils.distibution_helpers.html new file mode 100644 index 00000000..9cc5268d --- /dev/null +++ b/_autosummary/axtreme.utils.distibution_helpers.html @@ -0,0 +1,566 @@ + + + + + + + + + axtreme.utils.distibution_helpers - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.distibution_helpers

+

Helper for working with scipy distibutions.

+

Functions

+
+ + + + + + + + + +

distribution_parameter_names_from_scipy(dist)

Collects the parameters required for a scipy rv_continous distibution.

fit_dist_with_uncertainty(data, dist)

Fit a distibution, returning the parameters estimate and Gaussian uncertainty of the fit.

+
+
+
+axtreme.utils.distibution_helpers.distribution_parameter_names_from_scipy(dist: rv_continuous) list[str]
+

Collects the parameters required for a scipy rv_continous distibution.

+

Withing axtreme this is used to determine what a GP should predict.

+
+
Parameters:
+

dist – The distibution to retrieve the parameters for.

+
+
Returns:
+

The distibutiion parameter names, IN THE ORDER they should be passed to calls to this distibution class. +For example:

+
+
    +
  • gumbel_r.pdf(x, loc=0, scale=1) -> order returned [‘loc’,’scale’]

  • +
  • weibull_max.pdf(x, c, loc=0, scale=1) -> order returned [‘c’,’loc’,’scale’]

  • +
+
+

+
+
+
+ +
+
+axtreme.utils.distibution_helpers.fit_dist_with_uncertainty(data: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | bool | int | float | complex | str | bytes | _NestedSequence[bool | int | float | complex | str | bytes], dist: rv_continuous) tuple[ndarray[tuple[int], dtype[float64]], ndarray[tuple[int, int], dtype[float64]]]
+

Fit a distibution, returning the parameters estimate and Gaussian uncertainty of the fit.

+

Results of fitting with Maximum Likelihood give a normal distibution where

+
    +
  • mean:parameter estimate

  • +
  • covariance matrix: Uncertainty in estimate (Inverse Fischer infomation matrix)

  • +
+
+

Note

+

Parameters are returned in tha same order they appear in the fucntion calls of this call. +For example, weibull_max.pdf(x, c, loc=0, scale=1) -> order returned [‘c’,’loc’,’scale’] +This order can be extracted with the helper function distribution_parameter_names_from_scipy

+
+
+
Parameters:
+
    +
  • data (ArrayLike) – 1 dimensional set of data to fit a distibution to.

  • +
  • dist (rv_continuous) – the distribution to be fitted.

  • +
+
+
Returns:
+

(n) parameter mean estimates +covariance: (n,n) covariance matrix of the uncertainty in parameters fitted

+
+
Return type:
+

feature mean

+
+
+
+

Todo

+
    +
  • Some distributions have convergence issues. Currently only allow gumble_r.

  • +
  • Optimisation method needs thorough testing

  • +
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.experiment_utils.html b/_autosummary/axtreme.utils.experiment_utils.html new file mode 100644 index 00000000..be67ba60 --- /dev/null +++ b/_autosummary/axtreme.utils.experiment_utils.html @@ -0,0 +1,506 @@ + + + + + + + + + axtreme.utils.experiment_utils - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.experiment_utils

+

Helpers for working with the Ax Experiment class.

+

Functions

+
+ + + + + + +

input_out_df_from_experiment(exp)

Shows the x and y data in one dataframe.

+
+
+
+axtreme.utils.experiment_utils.input_out_df_from_experiment(exp: Experiment) DataFrame
+

Shows the x and y data in one dataframe.

+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.gradient.html b/_autosummary/axtreme.utils.gradient.html new file mode 100644 index 00000000..962df60a --- /dev/null +++ b/_autosummary/axtreme.utils.gradient.html @@ -0,0 +1,566 @@ + + + + + + + + + axtreme.utils.gradient - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.gradient

+

Helper for gradient assessment.

+

NOTE: currently just used as a helper in tests. Could move their if we do not consider it useful to users

+

Functions

+
+ + + + + + +

is_smooth_1d(x, y[, d1_threshold, ...])

Helper to warn if 1d function is likely not smooth (twice differntiable).

+
+
+
+axtreme.utils.gradient.is_smooth_1d(x: Tensor, y: Tensor, d1_threshold: float = 3.0, d2_threshold: float = 150, *, plot: bool = False, test: bool = True) None | Figure
+

Helper to warn if 1d function is likely not smooth (twice differntiable).

+
+
Parameters:
+
    +
  • x – (n,) points representing the x (input) values of a function

  • +
  • y – (n,) points representing the y (output) values of a function

  • +
  • d1_threshold – Maximum step size allowed in 1st derivative function to be considered smooth.

  • +
  • d2_threshold – Maximum step size allowed in 1st derivative function to be considered smooth.

  • +
  • plot – If true, will plot the first and second derivative functions.

  • +
  • test – is assert statments should be run

  • +
+
+
+
+
Details
+
Smoothness: (defined up to K, the Kth derivative you can take that give a contious funciton over domain)
    +
  • C_0: set of continous functions

  • +
  • +
    C_1 (once differentiable):
      +
    • C_0 can be differentiated

    • +
    • AND the resulting function is continuous (No steps or holes)

    • +
    +
    +
    +
  • +
  • +
+
+
We want C_2 (twice differentiable) for optimisation. As such here we test.
    +
  • +
    if f’(x) is continous.
      +
    • Check if there are not step = not big changes between points.

    • +
    • +
      Knowing the appropriate step threshold is hard, the gradient is easier to think about.
        +
      • Easy way to do this is check if max slope is not exceeded (derivate 2nd)

      • +
      +
      +
      +
    • +
    +
    +
    +
  • +
  • +
    f’’(x) is continous.
      +
    • Check if there are not step = not big changes between points

    • +
    • Easy way to do this is check if max slope is not exceeded (derivate 2nd)

    • +
    +
    +
    +
  • +
+
+
+
+
+

NOTE: The thresholds have been set heuristically. It is recomended to plot your function and establish smoothness, +the use this for regression testing once suitable values have been determined.

+

NOTE: The smaller the step size, the better the estimate of gradient (large and small). See y = sim(50 * x)` with +torch.linspace(0,1,100)` and torch.linspace(0,1,1000)

+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.html b/_autosummary/axtreme.utils.html new file mode 100644 index 00000000..2217f85d --- /dev/null +++ b/_autosummary/axtreme.utils.html @@ -0,0 +1,505 @@ + + + + + + + + + axtreme.utils - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils

+

Utilities for axtreme.

+

Modules

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

distibution_helpers

Helper for working with scipy distibutions.

experiment_utils

Helpers for working with the Ax Experiment class.

gradient

Helper for gradient assessment.

logging

Functions to configure logging for the application.

model_helpers

Utility functions for working with botorch models.

modelbridge_utils

This builds of the utils provided in ax.modelbridge.modelbridge_utils.

numerical_precision

Helpers and documentation for understanding the impacts of numerical precision.

population_estimators

Helpers for understanding the population values expected by estimators.

transforms

The module is used to determine the ax transformations used and create the equivalent botorch transformation.

+
+
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.logging.html b/_autosummary/axtreme.utils.logging.html new file mode 100644 index 00000000..b1cec7d5 --- /dev/null +++ b/_autosummary/axtreme.utils.logging.html @@ -0,0 +1,521 @@ + + + + + + + + + axtreme.utils.logging - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.logging

+

Functions to configure logging for the application.

+

Functions

+
+ + + + + + +

configure_logging([log_level_console, ...])

Configure logging for the application, allowing for both console and file logging.

+
+
+
+axtreme.utils.logging.configure_logging(log_level_console: str = 'WARNING', log_file: Path | None = None, log_level_file: str = 'WARNING') None
+

Configure logging for the application, allowing for both console and file logging.

+

Sets the log levels and formats for the output, ensuring that logs are captured as specified.

+
+
Parameters:
+
    +
  • log_level_console (str, optional) – log level for console output, by default “WARNING”

  • +
  • log_file (Path | None, optional) – log file to be used. If None, file logging is disabled. by default None

  • +
  • log_level_file (str, optional) – log level for file output, by default “WARNING”

  • +
  • Raises

  • +
  • ------

  • +
  • TypeError – if an invalid value for log_level_console or log_level_file is passed

  • +
  • Examples

  • +
  • -------- – configure_logging(log_level_console=”INFO”, log_file=Path(“app.log”), log_level_file=”DEBUG”)

  • +
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.model_helpers.html b/_autosummary/axtreme.utils.model_helpers.html new file mode 100644 index 00000000..7966d1c6 --- /dev/null +++ b/_autosummary/axtreme.utils.model_helpers.html @@ -0,0 +1,554 @@ + + + + + + + + + axtreme.utils.model_helpers - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.model_helpers

+

Utility functions for working with botorch models.

+

Functions

+
+ + + + + + + + + +

get_target_noise_singletaskgp(model)

A helper to extract the training varaince from a botorch model, and return it in a consistent format.

get_training_data_singletaskgp(model)

Extracts the training data from SIngleTaskGP in consistent form.

+
+
+
+axtreme.utils.model_helpers.get_target_noise_singletaskgp(model: SingleTaskGP) Tensor
+

A helper to extract the training varaince from a botorch model, and return it in a consistent format.

+
+
Parameters:
+

model – A SingleTaskGP model.

+
+
Returns:
+

A torch.Tensor of the noise with shape (*b, n,m) where b is an optional batch dimention, n +is the number of observations, m is the number of targets. If homoskedatic noise is used shape will be +(*b, n=1,m).

+
+
Return type:
+

noise (variance)

+
+
+

NOTE: Approach is based on FantasizeMixin.fantasize. +NOTE: Currently unclear if this interface extends to othe type of model.

+
+ +
+
+axtreme.utils.model_helpers.get_training_data_singletaskgp(model: SingleTaskGP) Tensor
+

Extracts the training data from SIngleTaskGP in consistent form.

+

As per Botorch documentation, “SingleTaskGP Modules same training data for all outputs” (BoTorch docs) +As such we are not concerned with batch dimenstion. Gpytorch stores training data in this format:

+
+
    +
  • if m = 1: (*b,n,d)

  • +
  • if m > 1: (*b,m,n,d)

  • +
+
+
+
Parameters:
+

model – the model to collect the training data from.

+
+
Returns:
+

(n,d) A torch.Tensor of the training_inputs

+
+
Return type:
+

training_inputs

+
+
+
+
NOTE: The interface defined here is only available for SingleTaskGPs, as other model can contain different input

data for each batch.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.modelbridge_utils.html b/_autosummary/axtreme.utils.modelbridge_utils.html new file mode 100644 index 00000000..990da73e --- /dev/null +++ b/_autosummary/axtreme.utils.modelbridge_utils.html @@ -0,0 +1,544 @@ + + + + + + + + + axtreme.utils.modelbridge_utils - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.modelbridge_utils

+

This builds of the utils provided in ax.modelbridge.modelbridge_utils.

+

Functions

+
+ + + + + + +

observations_to_arrays(param_names, ...)

Helper method to convert Ax results (Observation) to Numpy arrays of a standard format.

+
+
+
+axtreme.utils.modelbridge_utils.observations_to_arrays(param_names: list[str], outcomes: list[str], observations: list[Observation]) tuple[ndarray[Any, dtype[float64]], ndarray[Any, dtype[float64]], ndarray[Any, dtype[float64]]]
+

Helper method to convert Ax results (Observation) to Numpy arrays of a standard format.

+

This is useful e.g. when converting the output of ax.model_bridge.base.ModelBridge.get_training_data into “x” and +“y” and “covariance” arrays.

+
+
Parameters:
+
    +
  • param_names – List of the parameter names to report, and in what order.

  • +
  • outcomes – list of the metric/target names to report, in this order. +TODO(sw): work out if the order ever changes. If not, we should remove this.

  • +
  • observations – The list of observations to convert.

  • +
+
+
Returns:
+

An (n_observation, n_features) array of features. +- f: An (n_observation, m_metrics) array of prediction means. +- cov: An (n_observation, m_metrics, m_metrics) array of covariance between metric per x point.

+
+
Return type:
+

    +
  • features

  • +
+

+
+
+

Example

+
>>> import numpy as np
+>>> from ax.core.observation import Observation, ObservationData, ObservationFeatures
+>>> X = np.array([[1, 2], [3, 4], [5, 6]])
+>>> Y = np.array([[10], [20], [30]])
+>>> of = [ObservationFeatures(parameters={"x1": x[0], "x2": x[1]}) for x in X]
+>>> od = [ObservationData(metric_names=["y"], means=y, covariance=np.eye(1)) for y in Y]
+>>> observations = [Observation(features=f, data=d) for f, d in zip(of, od)]
+>>> features, f, cov = observations_to_arrays(param_names=["x1", "x2"], outcomes=["y"], observations=observations)
+>>> assert np.array_equal(features, X)
+>>> assert np.array_equal(f, Y)
+>>> # There is only one output per x point. This will have perfect covariance with itself.
+>>> assert np.array_equal(cov, np.ones([3, 1, 1]))
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.numerical_precision.html b/_autosummary/axtreme.utils.numerical_precision.html new file mode 100644 index 00000000..567b8aa6 --- /dev/null +++ b/_autosummary/axtreme.utils.numerical_precision.html @@ -0,0 +1,558 @@ + + + + + + + + + axtreme.utils.numerical_precision - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.numerical_precision

+

Helpers and documentation for understanding the impacts of numerical precision.

+

Functions

+
+ + + + + + +

maximal_representation_error_between_0_1(dtype)

Maximal amount a float can be wrong by, for numbers within the range [0,1).

+
+
+
+axtreme.utils.numerical_precision.maximal_representation_error_between_0_1(dtype: dtype) float
+

Maximal amount a float can be wrong by, for numbers within the range [0,1).

+

NOTE: This is calculated for the range [.5,1). Errors will be smaller for ranges < .5.

+
+
Parameters:
+

dtype – The dtype to calculate the maximal representation error for.

+
+
Returns:
+

The maximal representation error for numbers between 0 and 1.

+
+
+
+
Details:

Mantisa (significant bits) with x explicity bits internally has 1 implict bit added. Effectively this become +1.[x bits] (in binary).

+
+
    +
  • e.g float32 has 24 bits of precision but 23 bits of mantisa

  • +
+
+

Epsilon, the smallest representable number where 1+eps != 1 can be calculated as 2^-x

+
+
    +
  • e.g float32: 2^-23 = 1.19e-7

  • +
+
+

The largest representable number less than 1 is calculated as: 1 - 2^-(x + 1):

+
+
    +
  • e.g float32: 1 - 2^-24 = 0.999999940395355225

  • +
+
+

As such the smallest representable number between [.5,1) is: 2^-(x + 1)

+
+
    +
  • e.g float32: 2^-24 = 5.96e-08

  • +
+
+

Value smaller than the smallest representable number will be rounded to the nearest representable number. As +such the largest representation error for number between [.5,1) is 2^-(x + 1)/2 or 2^-(x_2)

+
+
    +
  • e.g float32: 2^-(23+2) = 2.9802322387695312e-08

  • +
+
+

Resoltuion and Precisions: +- TODO(sw): fill out exactly how these work. These number are ignored for now.

+

Additional information:

+
+
+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.population_estimators.html b/_autosummary/axtreme.utils.population_estimators.html new file mode 100644 index 00000000..65216332 --- /dev/null +++ b/_autosummary/axtreme.utils.population_estimators.html @@ -0,0 +1,626 @@ + + + + + + + + + axtreme.utils.population_estimators - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.population_estimators

+

Helpers for understanding the population values expected by estimators.

+

NOTE: These tool provide indicative/approximate result.

+

Functions

+
+ + + + + + + + + + + + + + + +

estimate_pdf_value_from_sample(sample, x)

Construct a distibution from a sample, and get the pdf value at point x.

plot_dist(dist[, confidence_level, ax])

Plot the distribution PDF over domain mean +- confidence_level * std.

sample_mean_se(samples)

Distibution of the population mean as estimated by this sample.

sample_median_se(samples)

Distibution of the population median as estimated by this sample.

+
+
+
+axtreme.utils.population_estimators.estimate_pdf_value_from_sample(sample: Tensor, x: float) float
+

Construct a distibution from a sample, and get the pdf value at point x.

+

WARNING: This is an approximate method, and results impove with more samples. See testing results below.

+
+
Parameters:
+
    +
  • sample – 1d Samples to construct a pdf from.

  • +
  • x – the point at which to evaluate the pdf.

  • +
+
+
Returns:
+

Estimated pdf value.

+
+
+

Testing results: +The mean returned and the cof have the following behaviour. Full test detail can be run at +tests/utils/test_population_estimators.py : visualise_performance_of_estimate_pdf_value_from_sample

+
+

Number of samples | mean_est/true | Coef |

+

11 | .86 - 1.02 | .25-.30 | +22 | .88 - 1.02 | .18-.20 | +44 | .90 - 1.01 | .14-.16 | +88 | .92 - 1.00 | .11-.13 | +176 | .95 - 1.00 | .05-.10 |

+
+
+ +
+
+axtreme.utils.population_estimators.plot_dist(dist: Distribution, confidence_level: float = 3.0, ax: Axes | None = None, **kwargs: Any) Axes
+

Plot the distribution PDF over domain mean +- confidence_level * std.

+
+
Parameters:
+
    +
  • dist – the distribution to plot the pdf of.

  • +
  • confidence_level – controls the width of the plot

  • +
  • ax – the axes to plot on. If None, will create an x

  • +
  • **kwargs – passed to the plotting method.

  • +
+
+
Returns:
+

Axes with the plot.

+
+
+
+ +
+
+axtreme.utils.population_estimators.sample_mean_se(samples: Tensor) StudentT
+

Distibution of the population mean as estimated by this sample.

+
+

Note

+

The distribution of the sample itself doesn’t matter. The output distibution is not effected by this.

+
+

Use the following link

+

se = sigma / n**.5

+
+
    +
  • Sigma: should be the population standard deviation, but we approximate this with the sample standard deviation

  • +
  • Because of this approximation we use the Student-t distribution

  • +
+
+
+
Parameters:
+

samples – 1d tensor of sample to estimate the population mean from

+
+
Returns:
+

Distribution of the population mean based on the provided sample. Additionally, it provides the 95% confidence +bounds for the estimate, which are typically calculated to fall within a range of 93% to 97% coverage, depending +on sample variability and the assumptions of the calculation method.

+
+
+
+

Todo

+
    +
  • +
    .cdf() raises NotImplementedError for torch implemenation of StudentT. This is annoying

    because this is the best way to check the confidence bounds (using z = (y - mean)/stddev) assumes you +are using a normal distibution rather than a student t distibution. This approximation is considered okay +for n>30)

    +
    +
    +
  • +
+
+
+ +
+
+axtreme.utils.population_estimators.sample_median_se(samples: Tensor) Normal
+

Distibution of the population median as estimated by this sample.

+

Details of this method can be found here.

+
+

Note

+

This function relies on the approximation estimate_pdf_value_from_sample. The approximation can be quite +inaccurate (see the function for details), and as a result this function should be treated as an estimate.

+
+
+

Note

+

The result returned are much more noisey than sample_mean_se.

+
+
+
Parameters:
+

samples – 1d tensor of sample to estimate the population median from

+
+
Returns:
+

Distibution of the population median as estimated by this sample. The 95% bounds (with 50 samples) estimated by +this function typically produce bounds actually between 90%-97%.

+
+
+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_autosummary/axtreme.utils.transforms.html b/_autosummary/axtreme.utils.transforms.html new file mode 100644 index 00000000..371cc4d9 --- /dev/null +++ b/_autosummary/axtreme.utils.transforms.html @@ -0,0 +1,711 @@ + + + + + + + + + axtreme.utils.transforms - axtreme 0.1.1 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark, in light mode + + + + + + + + + + + + + + + Auto light/dark, in dark mode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Skip to content + + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+
+ + + + + Back to top + +
+ +
+ +
+ +
+
+
+

axtreme.utils.transforms

+

The module is used to determine the ax transformations used and create the equivalent botorch transformation.

+

This allows the user to work directly with the Botorch model, while using inputs and outputs in the original space +(e.g the problem space)

+
+

Todo

+

It would be nice to be able to return an identity transform so we don’t have to deal with Nones (sw 2024-11-21).

+
+

Functions

+
+ + + + + + + + + + + + + + + + + + + + + + + + +

ax_to_botorch_transform_input_output(...)

Determines the input and output transforms applied by Ax, and creates the equivalent transforms in botroch.

check_transform_not_applied(transform, ...)

Used to ensure a transform has not been applied.

translate_cast(transform)

Make sure that Cast has not flattned a HierachicalSearchSpace.

translate_derelativize(transform)

Handle Derelativize (relative constraints to non-relative constraints).

translate_ivw(transform)

Handle IVW (inverse variance weight transform).

translate_standardisey(transform, col_names)

Translate ax standardisation into botorch standardisation.

translate_unitx(transform)

Converts a trained UnitX to botorch equivalent.

+
+
+
+axtreme.utils.transforms.ax_to_botorch_transform_input_output(transforms: list[Transform], outcome_names: list[str]) tuple[InputTransform, OutcomeTransform]
+

Determines the input and output transforms applied by Ax, and creates the equivalent transforms in botroch.

+

This allows the botorch model internal to ax (which operates in a standard “model” space), to be used in the problem +space (e.g non-standardised input and output). This is useful when calculating QoIs.

+
+
Parameters:
+
    +
  • transforms – the TRAINED transforms that have been applied by ax. +- Typically found at TorchModelBridge.transforms.

  • +
  • outcome_names – the order of the output columns used to train the internal ax.Model. +- Typically found at TorchModelBridge.outcomes.

  • +
+
+
Returns:
+

    +
  • output_tranform:

  • +
+

+
+
Return type:
+

    +
  • input_transform

  • +
+

+
+
+
+
Using them in the following way allow input and output in the outcome/problem space:
    +
  • Assume: model is a trained`botorch.models`(such as TorchModelBridge.model.surrogate.model)

  • +
  • > model.posterior(input_transform(X), posterior_transform = output_transform.untransform_posterior)

  • +
+
+
+
+

Todo

+
    +
  • +
    Ideally ax_to_botorch_transform_conversion would a config within the root of this module, so it could easily

    be exteneded. This is challenign becuase the ‘translate_standardisey’ function needs the specific +outcome_names of the problem to be passed. This is because ax does not maintain the order of the metrics in +the transform itself (it stores the names/order internally. See +ax.modelbridge.base.ModelBridge._transform_data for details)

    +
    +
    +
  • +
+
+
+ +
+
+axtreme.utils.transforms.check_transform_not_applied(transform: Transform, parameter_names_store: str) tuple[InputTransform | None, OutcomeTransform | None]
+

Used to ensure a transform has not been applied.

+

Many transforms store an internal list of the ax.parameters (input) they should be applied to. +This is determined by that parameter being of a specific type and having specific attributes as checked within the +transform. +This helper function is used to double check the transforms are not being used/applied to anything. This mean a +translation from ax to botorch is not required.

+
+
Parameters:
+
    +
  • transform – the transform to check

  • +
  • parameter_names_store – The attribute on the transform that should be empty (falsey) if the tranform is not +applied to anything.

  • +
+
+
Returns:
+

Input and output transforms required (will be None). Will raise an error if these transformation have actually +been applied.

+
+
+
+

Note

+
+
This should be instantiated with functools.partial, e.g.
>>> from functools import partial
+>>> log_checker = partial(check_not_applied, parameter_names_store="transform_parameters")
+
+
+
+
+
+
+ +
+
+axtreme.utils.transforms.translate_cast(transform: Cast) tuple[InputTransform | None, OutcomeTransform | None]
+

Make sure that Cast has not flattned a HierachicalSearchSpace.

+
+
Cast changes the parameter (e.g RangeParameter), castings the VALUE to the data type it should be.

e.g RangeParameter values should be a float, cast the value to ensure it is a float

+
+
It also deals with HierachicalSearchSpace:
    +
  • +
    (basically this is like a tree that navigates you to a more specific search space
      +
    • e.g if ‘parameter_a’> 2 -> use SearchSpace1

    • +
    +
    +
    +
  • +
  • .flatten_hss flag if this has been used

  • +
+
+
+
+ +
+
+axtreme.utils.transforms.translate_derelativize(transform: Derelativize) tuple[InputTransform | None, OutcomeTransform | None]
+

Handle Derelativize (relative constraints to non-relative constraints).

+

Derelativize transforms optimisation configs and untransforms constraints. As we are only interested in input and +output transformations, this can be ignored.

+
+

Todo

+

Is there a safer way to ensure this is not being used? Difficult because it doesn’t store anything internally

+
+
+

Todo

+

This needs some additional work.

+
+
+ +
+
+axtreme.utils.transforms.translate_ivw(transform: IVW) tuple[InputTransform | None, OutcomeTransform | None]
+

Handle IVW (inverse variance weight transform).

+

IVW is used when at the same location (x), there are multiple measure of the same metric. +It combines these into a single measure of the metric, and passes this on to the botroch model for training +As this is only using for training (transforming the y input to the model), we can ignore this, as we currently +use these transforms for prediction only.

+
+

Note

+

It is hard to tell if this transformation has been applied because no attribute are stored on the object.

+
+
+

Todo

+

Check if botorch supports multiple measure of a single metric at a single point (suspect not) +- if not it is reasonable to ignore this transformation as standard botorch model shouldn’t be using in that way

+
+
+ +
+
+axtreme.utils.transforms.translate_standardisey(transform: StandardizeY, col_names: list[str]) tuple[InputTransform | None, OutcomeTransform | None]
+

Translate ax standardisation into botorch standardisation.

+
+

Note

+

Ax does not maintain the order of the metrics, so need to explicitly pass the order.

+
+

Todo

+

Can there be some work around for this? Would be good not to have to pass constraints.

+
+
+
+

Note

+
+
col_name should be passed using functools.partial
>>> from functools import partial
+>>> standardise_y = partial(translate_standardiseY, col_names=["loc", "scale"])
+
+
+
+
+
+
+
Parameters:
+
    +
  • transform – StandardizeY to translate

  • +
  • col_names – the order of the column in the data being passed in. +This is required to the correct transformation can be applied to the correct column

  • +
+
+
+
+ +
+
+axtreme.utils.transforms.translate_unitx(transform: UnitX) tuple[InputTransform | None, OutcomeTransform | None]
+

Converts a trained UnitX to botorch equivalent.

+

Ax bounds look like this: {‘x1’: (0.0, 2.0), ‘x2’: (0.0, 3.0)}

+

BoTorch bounds look like: tensor([[0., 0.],[2., 3.]])

+
+ +
+ +
+
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/_images/ax_component_diagram.png b/_images/ax_component_diagram.png new file mode 100644 index 00000000..dfe60551 Binary files /dev/null and b/_images/ax_component_diagram.png differ diff --git a/_images/doe_point.png b/_images/doe_point.png new file mode 100644 index 00000000..1f059476 Binary files /dev/null and b/_images/doe_point.png differ diff --git a/_images/erd_smoothness.png b/_images/erd_smoothness.png new file mode 100644 index 00000000..3d5d1f2e Binary files /dev/null and b/_images/erd_smoothness.png differ diff --git a/_images/long_term_response_distribution.png b/_images/long_term_response_distribution.png new file mode 100644 index 00000000..137afc02 Binary files /dev/null and b/_images/long_term_response_distribution.png differ diff --git a/_images/noise_simulator.png b/_images/noise_simulator.png new file mode 100644 index 00000000..191e4916 Binary files /dev/null and b/_images/noise_simulator.png differ diff --git a/_images/qoi_smoothness.png b/_images/qoi_smoothness.png new file mode 100644 index 00000000..617e95ea Binary files /dev/null and b/_images/qoi_smoothness.png differ diff --git a/_images/simulator_non_gaus_noise.png b/_images/simulator_non_gaus_noise.png new file mode 100644 index 00000000..d94dd292 Binary files /dev/null and b/_images/simulator_non_gaus_noise.png differ diff --git a/_images/simulator_normal_noise.png b/_images/simulator_normal_noise.png new file mode 100644 index 00000000..ad3b7438 Binary files /dev/null and b/_images/simulator_normal_noise.png differ diff --git a/_images/surrogate_model_no_uncertainty.png b/_images/surrogate_model_no_uncertainty.png new file mode 100644 index 00000000..28a3a8ca Binary files /dev/null and b/_images/surrogate_model_no_uncertainty.png differ diff --git a/_images/surrogate_model_uncertainty_aware.png b/_images/surrogate_model_uncertainty_aware.png new file mode 100644 index 00000000..94db4d85 Binary files /dev/null and b/_images/surrogate_model_uncertainty_aware.png differ diff --git a/_sources/CHANGELOG.md.txt b/_sources/CHANGELOG.md.txt new file mode 100644 index 00000000..b76750e4 --- /dev/null +++ b/_sources/CHANGELOG.md.txt @@ -0,0 +1,2 @@ +```{include} ../../CHANGELOG.md +``` \ No newline at end of file diff --git a/_sources/LICENSE.md.txt b/_sources/LICENSE.md.txt new file mode 100644 index 00000000..78f2a431 --- /dev/null +++ b/_sources/LICENSE.md.txt @@ -0,0 +1,3 @@ +# LICENSE +```{include} ../../LICENSE +``` \ No newline at end of file diff --git a/_sources/README.md.txt b/_sources/README.md.txt new file mode 100644 index 00000000..16c6b768 --- /dev/null +++ b/_sources/README.md.txt @@ -0,0 +1,2 @@ +```{include} ../../README.md +``` \ No newline at end of file diff --git a/_sources/STYLEGUIDE.md.txt b/_sources/STYLEGUIDE.md.txt new file mode 100644 index 00000000..d5ac6e1c --- /dev/null +++ b/_sources/STYLEGUIDE.md.txt @@ -0,0 +1,2 @@ +```{include} ../../STYLEGUIDE.md +``` \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.acquisition.qoi_look_ahead.QoILookAhead.rst.txt b/_sources/_autosummary/axtreme.acquisition.qoi_look_ahead.QoILookAhead.rst.txt new file mode 100644 index 00000000..3c749b6a --- /dev/null +++ b/_sources/_autosummary/axtreme.acquisition.qoi_look_ahead.QoILookAhead.rst.txt @@ -0,0 +1,80 @@ +QoILookAhead +============ + +.. currentmodule:: axtreme.acquisition.qoi_look_ahead + +.. autoclass:: QoILookAhead + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~QoILookAhead.__init__ + ~QoILookAhead.add_module + ~QoILookAhead.apply + ~QoILookAhead.bfloat16 + ~QoILookAhead.buffers + ~QoILookAhead.children + ~QoILookAhead.compile + ~QoILookAhead.cpu + ~QoILookAhead.cuda + ~QoILookAhead.double + ~QoILookAhead.eval + ~QoILookAhead.extra_repr + ~QoILookAhead.float + ~QoILookAhead.forward + ~QoILookAhead.get_buffer + ~QoILookAhead.get_extra_state + ~QoILookAhead.get_parameter + ~QoILookAhead.get_submodule + ~QoILookAhead.half + ~QoILookAhead.ipu + ~QoILookAhead.load_state_dict + ~QoILookAhead.lookahead + ~QoILookAhead.modules + ~QoILookAhead.named_buffers + ~QoILookAhead.named_children + ~QoILookAhead.named_modules + ~QoILookAhead.named_parameters + ~QoILookAhead.parameters + ~QoILookAhead.register_backward_hook + ~QoILookAhead.register_buffer + ~QoILookAhead.register_forward_hook + ~QoILookAhead.register_forward_pre_hook + ~QoILookAhead.register_full_backward_hook + ~QoILookAhead.register_full_backward_pre_hook + ~QoILookAhead.register_load_state_dict_post_hook + ~QoILookAhead.register_module + ~QoILookAhead.register_parameter + ~QoILookAhead.register_state_dict_pre_hook + ~QoILookAhead.requires_grad_ + ~QoILookAhead.set_X_pending + ~QoILookAhead.set_extra_state + ~QoILookAhead.share_memory + ~QoILookAhead.state_dict + ~QoILookAhead.to + ~QoILookAhead.to_empty + ~QoILookAhead.train + ~QoILookAhead.type + ~QoILookAhead.xpu + ~QoILookAhead.zero_grad + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~QoILookAhead.T_destination + ~QoILookAhead.call_super_init + ~QoILookAhead.dump_patches + ~QoILookAhead.training + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.acquisition.qoi_look_ahead.rst.txt b/_sources/_autosummary/axtreme.acquisition.qoi_look_ahead.rst.txt new file mode 100644 index 00000000..a4408c6a --- /dev/null +++ b/_sources/_autosummary/axtreme.acquisition.qoi_look_ahead.rst.txt @@ -0,0 +1,26 @@ +axtreme.acquisition.qoi\_look\_ahead +==================================== + +.. automodule:: axtreme.acquisition.qoi_look_ahead + :members: + :exclude-members: QoILookAhead, + + + + + .. rubric:: Functions + .. autosummary:: + + average_observational_noise + closest_observational_noise + conditional_update + construct_inputs_qoi_look_ahead + reject_if_batched_model + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + QoILookAhead + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.acquisition.rst.txt b/_sources/_autosummary/axtreme.acquisition.rst.txt new file mode 100644 index 00000000..7a4d2fb3 --- /dev/null +++ b/_sources/_autosummary/axtreme.acquisition.rst.txt @@ -0,0 +1,15 @@ +axtreme.acquisition +=================== + +.. automodule:: axtreme.acquisition + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + qoi_look_ahead diff --git a/_sources/_autosummary/axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d.rst.txt b/_sources/_autosummary/axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d.rst.txt new file mode 100644 index 00000000..23ac7d80 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.batch_invariant_sampler.BatchInvariantSampler2d.rst.txt @@ -0,0 +1,24 @@ +BatchInvariantSampler2d +======================= + +.. currentmodule:: axtreme.data.batch_invariant_sampler + +.. autoclass:: BatchInvariantSampler2d + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~BatchInvariantSampler2d.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.batch_invariant_sampler.rst.txt b/_sources/_autosummary/axtreme.data.batch_invariant_sampler.rst.txt new file mode 100644 index 00000000..082ebabf --- /dev/null +++ b/_sources/_autosummary/axtreme.data.batch_invariant_sampler.rst.txt @@ -0,0 +1,17 @@ +axtreme.data.batch\_invariant\_sampler +====================================== + +.. automodule:: axtreme.data.batch_invariant_sampler + :members: + :exclude-members: BatchInvariantSampler2d, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + BatchInvariantSampler2d + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.dataset.MinimalDataset.rst.txt b/_sources/_autosummary/axtreme.data.dataset.MinimalDataset.rst.txt new file mode 100644 index 00000000..d35041be --- /dev/null +++ b/_sources/_autosummary/axtreme.data.dataset.MinimalDataset.rst.txt @@ -0,0 +1,24 @@ +MinimalDataset +============== + +.. currentmodule:: axtreme.data.dataset + +.. autoclass:: MinimalDataset + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MinimalDataset.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.dataset.rst.txt b/_sources/_autosummary/axtreme.data.dataset.rst.txt new file mode 100644 index 00000000..5b41ca69 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.dataset.rst.txt @@ -0,0 +1,17 @@ +axtreme.data.dataset +==================== + +.. automodule:: axtreme.data.dataset + :members: + :exclude-members: MinimalDataset, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + MinimalDataset + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.fixed_random_sample.FixedRandomSampler.rst.txt b/_sources/_autosummary/axtreme.data.fixed_random_sample.FixedRandomSampler.rst.txt new file mode 100644 index 00000000..20ecf4b6 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.fixed_random_sample.FixedRandomSampler.rst.txt @@ -0,0 +1,31 @@ +FixedRandomSampler +================== + +.. currentmodule:: axtreme.data.fixed_random_sample + +.. autoclass:: FixedRandomSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~FixedRandomSampler.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~FixedRandomSampler.num_samples + ~FixedRandomSampler.data_source + ~FixedRandomSampler.replacement + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.fixed_random_sample.rst.txt b/_sources/_autosummary/axtreme.data.fixed_random_sample.rst.txt new file mode 100644 index 00000000..74311018 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.fixed_random_sample.rst.txt @@ -0,0 +1,17 @@ +axtreme.data.fixed\_random\_sample +================================== + +.. automodule:: axtreme.data.fixed_random_sample + :members: + :exclude-members: FixedRandomSampler, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + FixedRandomSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.importance_dataset.ImportanceAddedWrapper.rst.txt b/_sources/_autosummary/axtreme.data.importance_dataset.ImportanceAddedWrapper.rst.txt new file mode 100644 index 00000000..2622f359 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.importance_dataset.ImportanceAddedWrapper.rst.txt @@ -0,0 +1,29 @@ +ImportanceAddedWrapper +====================== + +.. currentmodule:: axtreme.data.importance_dataset + +.. autoclass:: ImportanceAddedWrapper + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~ImportanceAddedWrapper.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~ImportanceAddedWrapper.datasets + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.importance_dataset.ImportanceIndexWrapper.rst.txt b/_sources/_autosummary/axtreme.data.importance_dataset.ImportanceIndexWrapper.rst.txt new file mode 100644 index 00000000..40ea28c6 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.importance_dataset.ImportanceIndexWrapper.rst.txt @@ -0,0 +1,24 @@ +ImportanceIndexWrapper +====================== + +.. currentmodule:: axtreme.data.importance_dataset + +.. autoclass:: ImportanceIndexWrapper + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~ImportanceIndexWrapper.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.importance_dataset.rst.txt b/_sources/_autosummary/axtreme.data.importance_dataset.rst.txt new file mode 100644 index 00000000..a07d336c --- /dev/null +++ b/_sources/_autosummary/axtreme.data.importance_dataset.rst.txt @@ -0,0 +1,18 @@ +axtreme.data.importance\_dataset +================================ + +.. automodule:: axtreme.data.importance_dataset + :members: + :exclude-members: ImportanceAddedWrapper,ImportanceIndexWrapper, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + ImportanceAddedWrapper + ImportanceIndexWrapper + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.multi_dim_batch_sampler.MultiBatchSampler.rst.txt b/_sources/_autosummary/axtreme.data.multi_dim_batch_sampler.MultiBatchSampler.rst.txt new file mode 100644 index 00000000..4a028a69 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.multi_dim_batch_sampler.MultiBatchSampler.rst.txt @@ -0,0 +1,24 @@ +MultiBatchSampler +================= + +.. currentmodule:: axtreme.data.multi_dim_batch_sampler + +.. autoclass:: MultiBatchSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MultiBatchSampler.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.multi_dim_batch_sampler.rst.txt b/_sources/_autosummary/axtreme.data.multi_dim_batch_sampler.rst.txt new file mode 100644 index 00000000..7a76e343 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.multi_dim_batch_sampler.rst.txt @@ -0,0 +1,17 @@ +axtreme.data.multi\_dim\_batch\_sampler +======================================= + +.. automodule:: axtreme.data.multi_dim_batch_sampler + :members: + :exclude-members: MultiBatchSampler, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + MultiBatchSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.numpy_file_dataset.NumpyFileDataset.rst.txt b/_sources/_autosummary/axtreme.data.numpy_file_dataset.NumpyFileDataset.rst.txt new file mode 100644 index 00000000..cb4017e5 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.numpy_file_dataset.NumpyFileDataset.rst.txt @@ -0,0 +1,24 @@ +NumpyFileDataset +================ + +.. currentmodule:: axtreme.data.numpy_file_dataset + +.. autoclass:: NumpyFileDataset + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~NumpyFileDataset.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.numpy_file_dataset.rst.txt b/_sources/_autosummary/axtreme.data.numpy_file_dataset.rst.txt new file mode 100644 index 00000000..909eb779 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.numpy_file_dataset.rst.txt @@ -0,0 +1,22 @@ +axtreme.data.numpy\_file\_dataset +================================= + +.. automodule:: axtreme.data.numpy_file_dataset + :members: + :exclude-members: NumpyFileDataset, + + + + + .. rubric:: Functions + .. autosummary:: + + collect_np_file + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + NumpyFileDataset + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.rst.txt b/_sources/_autosummary/axtreme.data.rst.txt new file mode 100644 index 00000000..0a8afe54 --- /dev/null +++ b/_sources/_autosummary/axtreme.data.rst.txt @@ -0,0 +1,21 @@ +axtreme.data +============ + +.. automodule:: axtreme.data + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + batch_invariant_sampler + dataset + fixed_random_sample + importance_dataset + multi_dim_batch_sampler + numpy_file_dataset + sizable_sequential_sample diff --git a/_sources/_autosummary/axtreme.data.sizable_sequential_sample.SizableSequentialSampler.rst.txt b/_sources/_autosummary/axtreme.data.sizable_sequential_sample.SizableSequentialSampler.rst.txt new file mode 100644 index 00000000..60e1a53e --- /dev/null +++ b/_sources/_autosummary/axtreme.data.sizable_sequential_sample.SizableSequentialSampler.rst.txt @@ -0,0 +1,30 @@ +SizableSequentialSampler +======================== + +.. currentmodule:: axtreme.data.sizable_sequential_sample + +.. autoclass:: SizableSequentialSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~SizableSequentialSampler.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~SizableSequentialSampler.num_samples + ~SizableSequentialSampler.data_source + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.data.sizable_sequential_sample.rst.txt b/_sources/_autosummary/axtreme.data.sizable_sequential_sample.rst.txt new file mode 100644 index 00000000..0614dc2e --- /dev/null +++ b/_sources/_autosummary/axtreme.data.sizable_sequential_sample.rst.txt @@ -0,0 +1,17 @@ +axtreme.data.sizable\_sequential\_sample +======================================== + +.. automodule:: axtreme.data.sizable_sequential_sample + :members: + :exclude-members: SizableSequentialSampler, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + SizableSequentialSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.distributions.helpers.rst.txt b/_sources/_autosummary/axtreme.distributions.helpers.rst.txt new file mode 100644 index 00000000..f246b9ed --- /dev/null +++ b/_sources/_autosummary/axtreme.distributions.helpers.rst.txt @@ -0,0 +1,15 @@ +axtreme.distributions.helpers +============================= + +.. automodule:: axtreme.distributions.helpers + :members: + + + + .. rubric:: Functions + .. autosummary:: + + approx_mixture_cdf_resolution + dist_cdf_resolution + mixture_cdf_resolution + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.distributions.icdf.rst.txt b/_sources/_autosummary/axtreme.distributions.icdf.rst.txt new file mode 100644 index 00000000..7653f9b2 --- /dev/null +++ b/_sources/_autosummary/axtreme.distributions.icdf.rst.txt @@ -0,0 +1,14 @@ +axtreme.distributions.icdf +========================== + +.. automodule:: axtreme.distributions.icdf + :members: + + + + .. rubric:: Functions + .. autosummary:: + + icdf + icdf_1d + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.distributions.mixture.ApproximateMixture.rst.txt b/_sources/_autosummary/axtreme.distributions.mixture.ApproximateMixture.rst.txt new file mode 100644 index 00000000..852faffb --- /dev/null +++ b/_sources/_autosummary/axtreme.distributions.mixture.ApproximateMixture.rst.txt @@ -0,0 +1,51 @@ +ApproximateMixture +================== + +.. currentmodule:: axtreme.distributions.mixture + +.. autoclass:: ApproximateMixture + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~ApproximateMixture.__init__ + ~ApproximateMixture.cdf + ~ApproximateMixture.entropy + ~ApproximateMixture.enumerate_support + ~ApproximateMixture.expand + ~ApproximateMixture.icdf + ~ApproximateMixture.log_prob + ~ApproximateMixture.perplexity + ~ApproximateMixture.rsample + ~ApproximateMixture.sample + ~ApproximateMixture.sample_n + ~ApproximateMixture.set_default_validate_args + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~ApproximateMixture.arg_constraints + ~ApproximateMixture.batch_shape + ~ApproximateMixture.component_distribution + ~ApproximateMixture.event_shape + ~ApproximateMixture.has_enumerate_support + ~ApproximateMixture.has_rsample + ~ApproximateMixture.mean + ~ApproximateMixture.mixture_distribution + ~ApproximateMixture.mode + ~ApproximateMixture.stddev + ~ApproximateMixture.support + ~ApproximateMixture.variance + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.distributions.mixture.rst.txt b/_sources/_autosummary/axtreme.distributions.mixture.rst.txt new file mode 100644 index 00000000..a991b83c --- /dev/null +++ b/_sources/_autosummary/axtreme.distributions.mixture.rst.txt @@ -0,0 +1,22 @@ +axtreme.distributions.mixture +============================= + +.. automodule:: axtreme.distributions.mixture + :members: + :exclude-members: ApproximateMixture, + + + + + .. rubric:: Functions + .. autosummary:: + + icdf_value_bounds + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + ApproximateMixture + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.distributions.rst.txt b/_sources/_autosummary/axtreme.distributions.rst.txt new file mode 100644 index 00000000..7e98f2b4 --- /dev/null +++ b/_sources/_autosummary/axtreme.distributions.rst.txt @@ -0,0 +1,18 @@ +axtreme.distributions +===================== + +.. automodule:: axtreme.distributions + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + helpers + icdf + mixture + utils diff --git a/_sources/_autosummary/axtreme.distributions.utils.rst.txt b/_sources/_autosummary/axtreme.distributions.utils.rst.txt new file mode 100644 index 00000000..4193ed19 --- /dev/null +++ b/_sources/_autosummary/axtreme.distributions.utils.rst.txt @@ -0,0 +1,15 @@ +axtreme.distributions.utils +=========================== + +.. automodule:: axtreme.distributions.utils + :members: + + + + .. rubric:: Functions + .. autosummary:: + + dist_dtype + index_batch_dist + index_batch_mixture_dist + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.eval.object_logging.rst.txt b/_sources/_autosummary/axtreme.eval.object_logging.rst.txt new file mode 100644 index 00000000..8af5e514 --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.object_logging.rst.txt @@ -0,0 +1,18 @@ +axtreme.eval.object\_logging +============================ + +.. automodule:: axtreme.eval.object_logging + :members: + + + + .. rubric:: Functions + .. autosummary:: + + default_config + get_closest_class_value + nested_content_to_str + public_vars + unpack_object + unpack_object_str_content + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.eval.qoi_helpers.rst.txt b/_sources/_autosummary/axtreme.eval.qoi_helpers.rst.txt new file mode 100644 index 00000000..36586155 --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.qoi_helpers.rst.txt @@ -0,0 +1,16 @@ +axtreme.eval.qoi\_helpers +========================= + +.. automodule:: axtreme.eval.qoi_helpers + :members: + + + + .. rubric:: Functions + .. autosummary:: + + plot_col_histogram + plot_distribution + plot_groups + qoi_ignoring_gp_uncertainty + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.eval.qoi_job.QoIJob.rst.txt b/_sources/_autosummary/axtreme.eval.qoi_job.QoIJob.rst.txt new file mode 100644 index 00000000..a671177f --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.qoi_job.QoIJob.rst.txt @@ -0,0 +1,33 @@ +QoIJob +====== + +.. currentmodule:: axtreme.eval.qoi_job + +.. autoclass:: QoIJob + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~QoIJob.__init__ + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~QoIJob.name + ~QoIJob.model + ~QoIJob.qoi + ~QoIJob.tags + ~QoIJob.metadata + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.eval.qoi_job.QoIJobResult.rst.txt b/_sources/_autosummary/axtreme.eval.qoi_job.QoIJobResult.rst.txt new file mode 100644 index 00000000..472dc5c1 --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.qoi_job.QoIJobResult.rst.txt @@ -0,0 +1,38 @@ +QoIJobResult +============ + +.. currentmodule:: axtreme.eval.qoi_job + +.. autoclass:: QoIJobResult + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~QoIJobResult.__init__ + ~QoIJobResult.from_dict + ~QoIJobResult.from_json + ~QoIJobResult.schema + ~QoIJobResult.to_dict + ~QoIJobResult.to_json + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~QoIJobResult.mean + ~QoIJobResult.var + ~QoIJobResult.samples + ~QoIJobResult.tags + ~QoIJobResult.metadata + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.eval.qoi_job.rst.txt b/_sources/_autosummary/axtreme.eval.qoi_job.rst.txt new file mode 100644 index 00000000..080904a8 --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.qoi_job.rst.txt @@ -0,0 +1,18 @@ +axtreme.eval.qoi\_job +===================== + +.. automodule:: axtreme.eval.qoi_job + :members: + :exclude-members: QoIJob,QoIJobResult, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + QoIJob + QoIJobResult + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.eval.rst.txt b/_sources/_autosummary/axtreme.eval.rst.txt new file mode 100644 index 00000000..8bedd476 --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.rst.txt @@ -0,0 +1,18 @@ +axtreme.eval +============ + +.. automodule:: axtreme.eval + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + object_logging + qoi_helpers + qoi_job + utils diff --git a/_sources/_autosummary/axtreme.eval.utils.rst.txt b/_sources/_autosummary/axtreme.eval.utils.rst.txt new file mode 100644 index 00000000..f087deff --- /dev/null +++ b/_sources/_autosummary/axtreme.eval.utils.rst.txt @@ -0,0 +1,13 @@ +axtreme.eval.utils +================== + +.. automodule:: axtreme.eval.utils + :members: + + + + .. rubric:: Functions + .. autosummary:: + + append_to_json + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.evaluation.EvaluationFunction.rst.txt b/_sources/_autosummary/axtreme.evaluation.EvaluationFunction.rst.txt new file mode 100644 index 00000000..3f453b81 --- /dev/null +++ b/_sources/_autosummary/axtreme.evaluation.EvaluationFunction.rst.txt @@ -0,0 +1,26 @@ +EvaluationFunction +================== + +.. currentmodule:: axtreme.evaluation + +.. autoclass:: EvaluationFunction + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~EvaluationFunction.__init__ + ~EvaluationFunction.post_process_simulation_output + ~EvaluationFunction.run_simulator + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.evaluation.SimulationPointResults.rst.txt b/_sources/_autosummary/axtreme.evaluation.SimulationPointResults.rst.txt new file mode 100644 index 00000000..4038f8bb --- /dev/null +++ b/_sources/_autosummary/axtreme.evaluation.SimulationPointResults.rst.txt @@ -0,0 +1,32 @@ +SimulationPointResults +====================== + +.. currentmodule:: axtreme.evaluation + +.. autoclass:: SimulationPointResults + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~SimulationPointResults.__init__ + ~SimulationPointResults.metric_data + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~SimulationPointResults.metric_names + ~SimulationPointResults.means + ~SimulationPointResults.cov + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.evaluation.rst.txt b/_sources/_autosummary/axtreme.evaluation.rst.txt new file mode 100644 index 00000000..d951b1a9 --- /dev/null +++ b/_sources/_autosummary/axtreme.evaluation.rst.txt @@ -0,0 +1,18 @@ +axtreme.evaluation +================== + +.. automodule:: axtreme.evaluation + :members: + :exclude-members: EvaluationFunction,SimulationPointResults, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + EvaluationFunction + SimulationPointResults + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.experiment.rst.txt b/_sources/_autosummary/axtreme.experiment.rst.txt new file mode 100644 index 00000000..353c1b42 --- /dev/null +++ b/_sources/_autosummary/axtreme.experiment.rst.txt @@ -0,0 +1,18 @@ +axtreme.experiment +================== + +.. automodule:: axtreme.experiment + :members: + + + + .. rubric:: Functions + .. autosummary:: + + add_json_data_to_experiment + add_metric_data_to_experiment + add_simulation_data_to_experiment + add_sobol_points_to_experiment + extract_data_from_experiment_as_json + make_experiment + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.metrics.LocalMetadataMetric.rst.txt b/_sources/_autosummary/axtreme.metrics.LocalMetadataMetric.rst.txt new file mode 100644 index 00000000..7eb338b8 --- /dev/null +++ b/_sources/_autosummary/axtreme.metrics.LocalMetadataMetric.rst.txt @@ -0,0 +1,44 @@ +LocalMetadataMetric +=================== + +.. currentmodule:: axtreme.metrics + +.. autoclass:: LocalMetadataMetric + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~LocalMetadataMetric.__init__ + ~LocalMetadataMetric.bulk_fetch_experiment_data + ~LocalMetadataMetric.bulk_fetch_trial_data + ~LocalMetadataMetric.clone + ~LocalMetadataMetric.deserialize_init_args + ~LocalMetadataMetric.fetch_data_prefer_lookup + ~LocalMetadataMetric.fetch_experiment_data_multi + ~LocalMetadataMetric.fetch_trial_data + ~LocalMetadataMetric.fetch_trial_data_multi + ~LocalMetadataMetric.is_available_while_running + ~LocalMetadataMetric.maybe_raise_deprecation_warning_on_class_methods + ~LocalMetadataMetric.period_of_new_data_after_trial_completion + ~LocalMetadataMetric.serialize_init_args + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~LocalMetadataMetric.db_id + ~LocalMetadataMetric.fetch_multi_group_by_metric + ~LocalMetadataMetric.name + ~LocalMetadataMetric.summary_dict + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.metrics.rst.txt b/_sources/_autosummary/axtreme.metrics.rst.txt new file mode 100644 index 00000000..2cd76b29 --- /dev/null +++ b/_sources/_autosummary/axtreme.metrics.rst.txt @@ -0,0 +1,17 @@ +axtreme.metrics +=============== + +.. automodule:: axtreme.metrics + :members: + :exclude-members: LocalMetadataMetric, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + LocalMetadataMetric + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.plotting.doe.rst.txt b/_sources/_autosummary/axtreme.plotting.doe.rst.txt new file mode 100644 index 00000000..d6aadf4d --- /dev/null +++ b/_sources/_autosummary/axtreme.plotting.doe.rst.txt @@ -0,0 +1,13 @@ +axtreme.plotting.doe +==================== + +.. automodule:: axtreme.plotting.doe + :members: + + + + .. rubric:: Functions + .. autosummary:: + + plot_qoi_estimates + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.plotting.gp_fit.rst.txt b/_sources/_autosummary/axtreme.plotting.gp_fit.rst.txt new file mode 100644 index 00000000..0d3f7fde --- /dev/null +++ b/_sources/_autosummary/axtreme.plotting.gp_fit.rst.txt @@ -0,0 +1,16 @@ +axtreme.plotting.gp\_fit +======================== + +.. automodule:: axtreme.plotting.gp_fit + :members: + + + + .. rubric:: Functions + .. autosummary:: + + plot_1d_model + plot_gp_fits_2d_surface + plot_surface_over_2d_search_space + scatter_plot_training + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.plotting.histogram3d.rst.txt b/_sources/_autosummary/axtreme.plotting.histogram3d.rst.txt new file mode 100644 index 00000000..2cc5feff --- /dev/null +++ b/_sources/_autosummary/axtreme.plotting.histogram3d.rst.txt @@ -0,0 +1,14 @@ +axtreme.plotting.histogram3d +============================ + +.. automodule:: axtreme.plotting.histogram3d + :members: + + + + .. rubric:: Functions + .. autosummary:: + + histogram3d + histogram_surface3d + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.plotting.rst.txt b/_sources/_autosummary/axtreme.plotting.rst.txt new file mode 100644 index 00000000..897be8cb --- /dev/null +++ b/_sources/_autosummary/axtreme.plotting.rst.txt @@ -0,0 +1,17 @@ +axtreme.plotting +================ + +.. automodule:: axtreme.plotting + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + doe + gp_fit + histogram3d diff --git a/_sources/_autosummary/axtreme.qoi.gp_bruteforce.GPBruteForce.rst.txt b/_sources/_autosummary/axtreme.qoi.gp_bruteforce.GPBruteForce.rst.txt new file mode 100644 index 00000000..36f64f59 --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.gp_bruteforce.GPBruteForce.rst.txt @@ -0,0 +1,33 @@ +GPBruteForce +============ + +.. currentmodule:: axtreme.qoi.gp_bruteforce + +.. autoclass:: GPBruteForce + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~GPBruteForce.__init__ + ~GPBruteForce.mean + ~GPBruteForce.posterior_samples_erd_samples + ~GPBruteForce.sample_surrogate + ~GPBruteForce.var + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~GPBruteForce.posterior_sampler + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.qoi.gp_bruteforce.rst.txt b/_sources/_autosummary/axtreme.qoi.gp_bruteforce.rst.txt new file mode 100644 index 00000000..60451840 --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.gp_bruteforce.rst.txt @@ -0,0 +1,17 @@ +axtreme.qoi.gp\_bruteforce +========================== + +.. automodule:: axtreme.qoi.gp_bruteforce + :members: + :exclude-members: GPBruteForce, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + GPBruteForce + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation.rst.txt b/_sources/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation.rst.txt new file mode 100644 index 00000000..1e8a7001 --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.MarginalCDFExtrapolation.rst.txt @@ -0,0 +1,31 @@ +MarginalCDFExtrapolation +======================== + +.. currentmodule:: axtreme.qoi.marginal_cdf_extrapolation + +.. autoclass:: MarginalCDFExtrapolation + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MarginalCDFExtrapolation.__init__ + ~MarginalCDFExtrapolation.mean + ~MarginalCDFExtrapolation.var + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~MarginalCDFExtrapolation.posterior_sampler + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.rst.txt b/_sources/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.rst.txt new file mode 100644 index 00000000..6ec37c97 --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.marginal_cdf_extrapolation.rst.txt @@ -0,0 +1,23 @@ +axtreme.qoi.marginal\_cdf\_extrapolation +======================================== + +.. automodule:: axtreme.qoi.marginal_cdf_extrapolation + :members: + :exclude-members: MarginalCDFExtrapolation, + + + + + .. rubric:: Functions + .. autosummary:: + + acceptable_timestep_error + q_to_qtimestep + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + MarginalCDFExtrapolation + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.qoi.qoi_estimator.QoIEstimator.rst.txt b/_sources/_autosummary/axtreme.qoi.qoi_estimator.QoIEstimator.rst.txt new file mode 100644 index 00000000..a5e8230d --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.qoi_estimator.QoIEstimator.rst.txt @@ -0,0 +1,26 @@ +QoIEstimator +============ + +.. currentmodule:: axtreme.qoi.qoi_estimator + +.. autoclass:: QoIEstimator + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~QoIEstimator.__init__ + ~QoIEstimator.mean + ~QoIEstimator.var + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.qoi.qoi_estimator.rst.txt b/_sources/_autosummary/axtreme.qoi.qoi_estimator.rst.txt new file mode 100644 index 00000000..fe2d4d68 --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.qoi_estimator.rst.txt @@ -0,0 +1,17 @@ +axtreme.qoi.qoi\_estimator +========================== + +.. automodule:: axtreme.qoi.qoi_estimator + :members: + :exclude-members: QoIEstimator, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + QoIEstimator + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.qoi.rst.txt b/_sources/_autosummary/axtreme.qoi.rst.txt new file mode 100644 index 00000000..6162a378 --- /dev/null +++ b/_sources/_autosummary/axtreme.qoi.rst.txt @@ -0,0 +1,17 @@ +axtreme.qoi +=========== + +.. automodule:: axtreme.qoi + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + gp_bruteforce + marginal_cdf_extrapolation + qoi_estimator diff --git a/_sources/_autosummary/axtreme.runner.LocalMetadataRunner.rst.txt b/_sources/_autosummary/axtreme.runner.LocalMetadataRunner.rst.txt new file mode 100644 index 00000000..11b90408 --- /dev/null +++ b/_sources/_autosummary/axtreme.runner.LocalMetadataRunner.rst.txt @@ -0,0 +1,40 @@ +LocalMetadataRunner +=================== + +.. currentmodule:: axtreme.runner + +.. autoclass:: LocalMetadataRunner + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~LocalMetadataRunner.__init__ + ~LocalMetadataRunner.clone + ~LocalMetadataRunner.deserialize_init_args + ~LocalMetadataRunner.poll_available_capacity + ~LocalMetadataRunner.poll_exception + ~LocalMetadataRunner.poll_trial_status + ~LocalMetadataRunner.run + ~LocalMetadataRunner.run_multiple + ~LocalMetadataRunner.serialize_init_args + ~LocalMetadataRunner.stop + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~LocalMetadataRunner.db_id + ~LocalMetadataRunner.run_metadata_report_keys + ~LocalMetadataRunner.staging_required + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.runner.rst.txt b/_sources/_autosummary/axtreme.runner.rst.txt new file mode 100644 index 00000000..00d3f20d --- /dev/null +++ b/_sources/_autosummary/axtreme.runner.rst.txt @@ -0,0 +1,17 @@ +axtreme.runner +============== + +.. automodule:: axtreme.runner + :members: + :exclude-members: LocalMetadataRunner, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + LocalMetadataRunner + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.base.MeanVarPosteriorSampledEstimates.rst.txt b/_sources/_autosummary/axtreme.sampling.base.MeanVarPosteriorSampledEstimates.rst.txt new file mode 100644 index 00000000..3ba61bf8 --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.base.MeanVarPosteriorSampledEstimates.rst.txt @@ -0,0 +1,31 @@ +MeanVarPosteriorSampledEstimates +================================ + +.. currentmodule:: axtreme.sampling.base + +.. autoclass:: MeanVarPosteriorSampledEstimates + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MeanVarPosteriorSampledEstimates.__init__ + ~MeanVarPosteriorSampledEstimates.mean + ~MeanVarPosteriorSampledEstimates.var + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~MeanVarPosteriorSampledEstimates.posterior_sampler + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.base.PosteriorSampler.rst.txt b/_sources/_autosummary/axtreme.sampling.base.PosteriorSampler.rst.txt new file mode 100644 index 00000000..0594251f --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.base.PosteriorSampler.rst.txt @@ -0,0 +1,24 @@ +PosteriorSampler +================ + +.. currentmodule:: axtreme.sampling.base + +.. autoclass:: PosteriorSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~PosteriorSampler.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.base.rst.txt b/_sources/_autosummary/axtreme.sampling.base.rst.txt new file mode 100644 index 00000000..e469889a --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.base.rst.txt @@ -0,0 +1,18 @@ +axtreme.sampling.base +===================== + +.. automodule:: axtreme.sampling.base + :members: + :exclude-members: MeanVarPosteriorSampledEstimates,PosteriorSampler, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + MeanVarPosteriorSampledEstimates + PosteriorSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.independent_sampler.IndependentMCSampler.rst.txt b/_sources/_autosummary/axtreme.sampling.independent_sampler.IndependentMCSampler.rst.txt new file mode 100644 index 00000000..0755410f --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.independent_sampler.IndependentMCSampler.rst.txt @@ -0,0 +1,78 @@ +IndependentMCSampler +==================== + +.. currentmodule:: axtreme.sampling.independent_sampler + +.. autoclass:: IndependentMCSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~IndependentMCSampler.__init__ + ~IndependentMCSampler.add_module + ~IndependentMCSampler.apply + ~IndependentMCSampler.bfloat16 + ~IndependentMCSampler.buffers + ~IndependentMCSampler.children + ~IndependentMCSampler.compile + ~IndependentMCSampler.cpu + ~IndependentMCSampler.cuda + ~IndependentMCSampler.double + ~IndependentMCSampler.eval + ~IndependentMCSampler.extra_repr + ~IndependentMCSampler.float + ~IndependentMCSampler.forward + ~IndependentMCSampler.get_buffer + ~IndependentMCSampler.get_extra_state + ~IndependentMCSampler.get_parameter + ~IndependentMCSampler.get_submodule + ~IndependentMCSampler.half + ~IndependentMCSampler.ipu + ~IndependentMCSampler.load_state_dict + ~IndependentMCSampler.modules + ~IndependentMCSampler.named_buffers + ~IndependentMCSampler.named_children + ~IndependentMCSampler.named_modules + ~IndependentMCSampler.named_parameters + ~IndependentMCSampler.parameters + ~IndependentMCSampler.register_backward_hook + ~IndependentMCSampler.register_buffer + ~IndependentMCSampler.register_forward_hook + ~IndependentMCSampler.register_forward_pre_hook + ~IndependentMCSampler.register_full_backward_hook + ~IndependentMCSampler.register_full_backward_pre_hook + ~IndependentMCSampler.register_load_state_dict_post_hook + ~IndependentMCSampler.register_module + ~IndependentMCSampler.register_parameter + ~IndependentMCSampler.register_state_dict_pre_hook + ~IndependentMCSampler.requires_grad_ + ~IndependentMCSampler.set_extra_state + ~IndependentMCSampler.share_memory + ~IndependentMCSampler.state_dict + ~IndependentMCSampler.to + ~IndependentMCSampler.to_empty + ~IndependentMCSampler.train + ~IndependentMCSampler.type + ~IndependentMCSampler.xpu + ~IndependentMCSampler.zero_grad + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~IndependentMCSampler.T_destination + ~IndependentMCSampler.call_super_init + ~IndependentMCSampler.dump_patches + ~IndependentMCSampler.training + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.independent_sampler.rst.txt b/_sources/_autosummary/axtreme.sampling.independent_sampler.rst.txt new file mode 100644 index 00000000..5b790b5d --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.independent_sampler.rst.txt @@ -0,0 +1,22 @@ +axtreme.sampling.independent\_sampler +===================================== + +.. automodule:: axtreme.sampling.independent_sampler + :members: + :exclude-members: IndependentMCSampler, + + + + + .. rubric:: Functions + .. autosummary:: + + diagonalize_distribution + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + IndependentMCSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.mean_sampler.MeanSampler.rst.txt b/_sources/_autosummary/axtreme.sampling.mean_sampler.MeanSampler.rst.txt new file mode 100644 index 00000000..e92131c8 --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.mean_sampler.MeanSampler.rst.txt @@ -0,0 +1,24 @@ +MeanSampler +=========== + +.. currentmodule:: axtreme.sampling.mean_sampler + +.. autoclass:: MeanSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~MeanSampler.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.mean_sampler.rst.txt b/_sources/_autosummary/axtreme.sampling.mean_sampler.rst.txt new file mode 100644 index 00000000..7404fda6 --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.mean_sampler.rst.txt @@ -0,0 +1,17 @@ +axtreme.sampling.mean\_sampler +============================== + +.. automodule:: axtreme.sampling.mean_sampler + :members: + :exclude-members: MeanSampler, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + MeanSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.normal_independent_sampler.NormalIndependentSampler.rst.txt b/_sources/_autosummary/axtreme.sampling.normal_independent_sampler.NormalIndependentSampler.rst.txt new file mode 100644 index 00000000..a3ac78f0 --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.normal_independent_sampler.NormalIndependentSampler.rst.txt @@ -0,0 +1,78 @@ +NormalIndependentSampler +======================== + +.. currentmodule:: axtreme.sampling.normal_independent_sampler + +.. autoclass:: NormalIndependentSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~NormalIndependentSampler.__init__ + ~NormalIndependentSampler.add_module + ~NormalIndependentSampler.apply + ~NormalIndependentSampler.bfloat16 + ~NormalIndependentSampler.buffers + ~NormalIndependentSampler.children + ~NormalIndependentSampler.compile + ~NormalIndependentSampler.cpu + ~NormalIndependentSampler.cuda + ~NormalIndependentSampler.double + ~NormalIndependentSampler.eval + ~NormalIndependentSampler.extra_repr + ~NormalIndependentSampler.float + ~NormalIndependentSampler.forward + ~NormalIndependentSampler.get_buffer + ~NormalIndependentSampler.get_extra_state + ~NormalIndependentSampler.get_parameter + ~NormalIndependentSampler.get_submodule + ~NormalIndependentSampler.half + ~NormalIndependentSampler.ipu + ~NormalIndependentSampler.load_state_dict + ~NormalIndependentSampler.modules + ~NormalIndependentSampler.named_buffers + ~NormalIndependentSampler.named_children + ~NormalIndependentSampler.named_modules + ~NormalIndependentSampler.named_parameters + ~NormalIndependentSampler.parameters + ~NormalIndependentSampler.register_backward_hook + ~NormalIndependentSampler.register_buffer + ~NormalIndependentSampler.register_forward_hook + ~NormalIndependentSampler.register_forward_pre_hook + ~NormalIndependentSampler.register_full_backward_hook + ~NormalIndependentSampler.register_full_backward_pre_hook + ~NormalIndependentSampler.register_load_state_dict_post_hook + ~NormalIndependentSampler.register_module + ~NormalIndependentSampler.register_parameter + ~NormalIndependentSampler.register_state_dict_pre_hook + ~NormalIndependentSampler.requires_grad_ + ~NormalIndependentSampler.set_extra_state + ~NormalIndependentSampler.share_memory + ~NormalIndependentSampler.state_dict + ~NormalIndependentSampler.to + ~NormalIndependentSampler.to_empty + ~NormalIndependentSampler.train + ~NormalIndependentSampler.type + ~NormalIndependentSampler.xpu + ~NormalIndependentSampler.zero_grad + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~NormalIndependentSampler.T_destination + ~NormalIndependentSampler.call_super_init + ~NormalIndependentSampler.dump_patches + ~NormalIndependentSampler.training + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.normal_independent_sampler.rst.txt b/_sources/_autosummary/axtreme.sampling.normal_independent_sampler.rst.txt new file mode 100644 index 00000000..412c23fa --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.normal_independent_sampler.rst.txt @@ -0,0 +1,17 @@ +axtreme.sampling.normal\_independent\_sampler +============================================= + +.. automodule:: axtreme.sampling.normal_independent_sampler + :members: + :exclude-members: NormalIndependentSampler, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + NormalIndependentSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.rst.txt b/_sources/_autosummary/axtreme.sampling.rst.txt new file mode 100644 index 00000000..389ba21d --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.rst.txt @@ -0,0 +1,19 @@ +axtreme.sampling +================ + +.. automodule:: axtreme.sampling + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + base + independent_sampler + mean_sampler + normal_independent_sampler + ut_sampler diff --git a/_sources/_autosummary/axtreme.sampling.ut_sampler.UTSampler.rst.txt b/_sources/_autosummary/axtreme.sampling.ut_sampler.UTSampler.rst.txt new file mode 100644 index 00000000..8f342102 --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.ut_sampler.UTSampler.rst.txt @@ -0,0 +1,83 @@ +UTSampler +========= + +.. currentmodule:: axtreme.sampling.ut_sampler + +.. autoclass:: UTSampler + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~UTSampler.__init__ + ~UTSampler.add_module + ~UTSampler.apply + ~UTSampler.bfloat16 + ~UTSampler.buffers + ~UTSampler.children + ~UTSampler.compile + ~UTSampler.cpu + ~UTSampler.cuda + ~UTSampler.double + ~UTSampler.eval + ~UTSampler.extra_repr + ~UTSampler.float + ~UTSampler.forward + ~UTSampler.get_buffer + ~UTSampler.get_extra_state + ~UTSampler.get_parameter + ~UTSampler.get_submodule + ~UTSampler.half + ~UTSampler.ipu + ~UTSampler.load_state_dict + ~UTSampler.mean + ~UTSampler.modules + ~UTSampler.named_buffers + ~UTSampler.named_children + ~UTSampler.named_modules + ~UTSampler.named_parameters + ~UTSampler.parameters + ~UTSampler.register_backward_hook + ~UTSampler.register_buffer + ~UTSampler.register_forward_hook + ~UTSampler.register_forward_pre_hook + ~UTSampler.register_full_backward_hook + ~UTSampler.register_full_backward_pre_hook + ~UTSampler.register_load_state_dict_post_hook + ~UTSampler.register_module + ~UTSampler.register_parameter + ~UTSampler.register_state_dict_pre_hook + ~UTSampler.requires_grad_ + ~UTSampler.set_extra_state + ~UTSampler.share_memory + ~UTSampler.state_dict + ~UTSampler.to + ~UTSampler.to_empty + ~UTSampler.train + ~UTSampler.type + ~UTSampler.var + ~UTSampler.xpu + ~UTSampler.zero_grad + + + + + + + .. rubric:: Attributes + .. autosummary:: + + ~UTSampler.T_destination + ~UTSampler.alpha + ~UTSampler.beta + ~UTSampler.call_super_init + ~UTSampler.dump_patches + ~UTSampler.kappa_base + ~UTSampler.training + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.sampling.ut_sampler.rst.txt b/_sources/_autosummary/axtreme.sampling.ut_sampler.rst.txt new file mode 100644 index 00000000..4481e547 --- /dev/null +++ b/_sources/_autosummary/axtreme.sampling.ut_sampler.rst.txt @@ -0,0 +1,22 @@ +axtreme.sampling.ut\_sampler +============================ + +.. automodule:: axtreme.sampling.ut_sampler + :members: + :exclude-members: UTSampler, + + + + + .. rubric:: Functions + .. autosummary:: + + calculate_sigmas + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + UTSampler + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.simulator.base.Simulator.rst.txt b/_sources/_autosummary/axtreme.simulator.base.Simulator.rst.txt new file mode 100644 index 00000000..4a071dcf --- /dev/null +++ b/_sources/_autosummary/axtreme.simulator.base.Simulator.rst.txt @@ -0,0 +1,24 @@ +Simulator +========= + +.. currentmodule:: axtreme.simulator.base + +.. autoclass:: Simulator + :members: + :show-inheritance: + + + + .. automethod:: __init__ + + .. rubric:: Methods + .. autosummary:: + + ~Simulator.__init__ + + + + + + + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.simulator.base.rst.txt b/_sources/_autosummary/axtreme.simulator.base.rst.txt new file mode 100644 index 00000000..6fa9f594 --- /dev/null +++ b/_sources/_autosummary/axtreme.simulator.base.rst.txt @@ -0,0 +1,17 @@ +axtreme.simulator.base +====================== + +.. automodule:: axtreme.simulator.base + :members: + :exclude-members: Simulator, + + + + + .. rubric:: Classes + .. autosummary:: + :toctree: + :template: custom-class.rst + + Simulator + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.simulator.rst.txt b/_sources/_autosummary/axtreme.simulator.rst.txt new file mode 100644 index 00000000..fbff76a6 --- /dev/null +++ b/_sources/_autosummary/axtreme.simulator.rst.txt @@ -0,0 +1,16 @@ +axtreme.simulator +================= + +.. automodule:: axtreme.simulator + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + base + utils diff --git a/_sources/_autosummary/axtreme.simulator.utils.rst.txt b/_sources/_autosummary/axtreme.simulator.utils.rst.txt new file mode 100644 index 00000000..8917002b --- /dev/null +++ b/_sources/_autosummary/axtreme.simulator.utils.rst.txt @@ -0,0 +1,14 @@ +axtreme.simulator.utils +======================= + +.. automodule:: axtreme.simulator.utils + :members: + + + + .. rubric:: Functions + .. autosummary:: + + is_valid_simulator + simulator_from_func + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.distibution_helpers.rst.txt b/_sources/_autosummary/axtreme.utils.distibution_helpers.rst.txt new file mode 100644 index 00000000..6cca5aee --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.distibution_helpers.rst.txt @@ -0,0 +1,14 @@ +axtreme.utils.distibution\_helpers +================================== + +.. automodule:: axtreme.utils.distibution_helpers + :members: + + + + .. rubric:: Functions + .. autosummary:: + + distribution_parameter_names_from_scipy + fit_dist_with_uncertainty + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.experiment_utils.rst.txt b/_sources/_autosummary/axtreme.utils.experiment_utils.rst.txt new file mode 100644 index 00000000..4c4ac8ea --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.experiment_utils.rst.txt @@ -0,0 +1,13 @@ +axtreme.utils.experiment\_utils +=============================== + +.. automodule:: axtreme.utils.experiment_utils + :members: + + + + .. rubric:: Functions + .. autosummary:: + + input_out_df_from_experiment + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.gradient.rst.txt b/_sources/_autosummary/axtreme.utils.gradient.rst.txt new file mode 100644 index 00000000..64a97f67 --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.gradient.rst.txt @@ -0,0 +1,13 @@ +axtreme.utils.gradient +====================== + +.. automodule:: axtreme.utils.gradient + :members: + + + + .. rubric:: Functions + .. autosummary:: + + is_smooth_1d + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.logging.rst.txt b/_sources/_autosummary/axtreme.utils.logging.rst.txt new file mode 100644 index 00000000..efddf61d --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.logging.rst.txt @@ -0,0 +1,13 @@ +axtreme.utils.logging +===================== + +.. automodule:: axtreme.utils.logging + :members: + + + + .. rubric:: Functions + .. autosummary:: + + configure_logging + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.model_helpers.rst.txt b/_sources/_autosummary/axtreme.utils.model_helpers.rst.txt new file mode 100644 index 00000000..a35b55c4 --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.model_helpers.rst.txt @@ -0,0 +1,14 @@ +axtreme.utils.model\_helpers +============================ + +.. automodule:: axtreme.utils.model_helpers + :members: + + + + .. rubric:: Functions + .. autosummary:: + + get_target_noise_singletaskgp + get_training_data_singletaskgp + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.modelbridge_utils.rst.txt b/_sources/_autosummary/axtreme.utils.modelbridge_utils.rst.txt new file mode 100644 index 00000000..aff6f39e --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.modelbridge_utils.rst.txt @@ -0,0 +1,13 @@ +axtreme.utils.modelbridge\_utils +================================ + +.. automodule:: axtreme.utils.modelbridge_utils + :members: + + + + .. rubric:: Functions + .. autosummary:: + + observations_to_arrays + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.numerical_precision.rst.txt b/_sources/_autosummary/axtreme.utils.numerical_precision.rst.txt new file mode 100644 index 00000000..85b93470 --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.numerical_precision.rst.txt @@ -0,0 +1,13 @@ +axtreme.utils.numerical\_precision +================================== + +.. automodule:: axtreme.utils.numerical_precision + :members: + + + + .. rubric:: Functions + .. autosummary:: + + maximal_representation_error_between_0_1 + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.population_estimators.rst.txt b/_sources/_autosummary/axtreme.utils.population_estimators.rst.txt new file mode 100644 index 00000000..727e7591 --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.population_estimators.rst.txt @@ -0,0 +1,16 @@ +axtreme.utils.population\_estimators +==================================== + +.. automodule:: axtreme.utils.population_estimators + :members: + + + + .. rubric:: Functions + .. autosummary:: + + estimate_pdf_value_from_sample + plot_dist + sample_mean_se + sample_median_se + \ No newline at end of file diff --git a/_sources/_autosummary/axtreme.utils.rst.txt b/_sources/_autosummary/axtreme.utils.rst.txt new file mode 100644 index 00000000..6d72aa37 --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.rst.txt @@ -0,0 +1,23 @@ +axtreme.utils +============= + +.. automodule:: axtreme.utils + :members: + + + +.. rubric:: Modules +.. autosummary:: + :toctree: + :template: custom-module.rst + :recursive: + + distibution_helpers + experiment_utils + gradient + logging + model_helpers + modelbridge_utils + numerical_precision + population_estimators + transforms diff --git a/_sources/_autosummary/axtreme.utils.transforms.rst.txt b/_sources/_autosummary/axtreme.utils.transforms.rst.txt new file mode 100644 index 00000000..2f14e45f --- /dev/null +++ b/_sources/_autosummary/axtreme.utils.transforms.rst.txt @@ -0,0 +1,19 @@ +axtreme.utils.transforms +======================== + +.. automodule:: axtreme.utils.transforms + :members: + + + + .. rubric:: Functions + .. autosummary:: + + ax_to_botorch_transform_input_output + check_transform_not_applied + translate_cast + translate_derelativize + translate_ivw + translate_standardisey + translate_unitx + \ No newline at end of file diff --git a/_sources/api.rst.txt b/_sources/api.rst.txt new file mode 100644 index 00000000..3a57bc35 --- /dev/null +++ b/_sources/api.rst.txt @@ -0,0 +1,7 @@ +API Reference +============= + +.. toctree:: + :maxdepth: 4 + + axtreme diff --git a/_sources/axtreme.rst.txt b/_sources/axtreme.rst.txt new file mode 100644 index 00000000..e63a16a1 --- /dev/null +++ b/_sources/axtreme.rst.txt @@ -0,0 +1,34 @@ +axtreme package +================== + +Subpackages +----------- + +.. autosummary:: + :toctree: _autosummary + :template: custom-module.rst + :recursive: + + axtreme.acquisition + axtreme.data + axtreme.distributions + axtreme.eval + axtreme.plotting + axtreme.qoi + axtreme.sampling + axtreme.simulator + axtreme.utils + + +Modules +------- + +.. autosummary:: + :toctree: _autosummary + :template: custom-module.rst + :recursive: + + axtreme.evaluation + axtreme.experiment + axtreme.metrics + axtreme.runner diff --git a/_sources/basic_concepts/basic_concepts.rst.txt b/_sources/basic_concepts/basic_concepts.rst.txt new file mode 100644 index 00000000..d28a87d4 --- /dev/null +++ b/_sources/basic_concepts/basic_concepts.rst.txt @@ -0,0 +1,11 @@ +Basic Concepts +============== +The following are core concepts in the `axtreme` package. A conceptual description is provided below. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + surrogate_model + qoi_estimate + doe diff --git a/_sources/basic_concepts/doe.md.txt b/_sources/basic_concepts/doe.md.txt new file mode 100644 index 00000000..3128b648 --- /dev/null +++ b/_sources/basic_concepts/doe.md.txt @@ -0,0 +1,11 @@ +# Design of Experiments (DoE) + +Adding more data to the surrogate model reduces its uncertainty, which in turn can reduce uncertainty in the QoI. As collecting data is expensive (it requires running the simulator) we want to be judicious about the data points we choose to add. Design of Experiment (also know as Active Learning) techniques can be used to determine which new data point is expected to be the most beneficial (e.g result in the largest reduction on QoI variance). These heuristics often make use of fast approximate methods rather than precise calculations. It is worth noting that the data point that most reduces uncertainty in our calculation is not necessarily where the surrogate has greatest uncertainty. This is because small model inaccuracies in regions important to the calculation can have a far greater impact than large inaccuracies elsewhere. + +The follow example shows 2 possible new data points, the how their addition would impact the ERD estimate. The DoE would aim to pick the purple point, as it produces a more certain estimate of the ERD. + +![axtreme_surrogate_model_uncertainty_aware](img/doe/doe_point.png) + +Within `ax`, DoE is controlled by `AcquisitionFunctions`. These score candidate points based on how much benefit they are expected to provide. Due to the different problem formulation, standard acquisition functions are not suitable for the problems `axtreme` solves. + +Problem specific acquisition functions can be highly performant, but they do not exist for all problems, and often required expert domain and Bayesian optimisation knowledge to develop. `axtreme` instead provides the general purpose acquisition function `QoILookAhead`, which can be used with any `QoIEstimator`. While this acquisition function does not make use of problem and domain specifics, it can be surprisingly performant due to the gradient and GPU support provided by `ax` stack. diff --git a/_sources/basic_concepts/qoi_estimate.md.txt b/_sources/basic_concepts/qoi_estimate.md.txt new file mode 100644 index 00000000..c6c2ee94 --- /dev/null +++ b/_sources/basic_concepts/qoi_estimate.md.txt @@ -0,0 +1,10 @@ +# QoI Estimates +We create a surrogate model in order to better understand the Extreme Response Distribution (ERD). Typically we are interested in a specific quantity of this distribution (e.g the median, or the 90th percentile), which we call the Quantity of Interest (QoI). + +It is important that we can propagate the uncertainty in our surrogate model through to our QoI. The following figure introduced in "Surrogate Model" can help us gain an intuitive understanding of how this is done. + +![axtreme_surrogate_model_uncertainty_aware](img/surrogate_model/surrogate_model_uncertainty_aware.png) + +This diagram shows an uncertainty aware surrogate model. The grey lines represent different functions the surrogate believes could be the true simulator function (e.g The functions that could have generated the data it has seen). The diversity of the grey lines represent the uncertainty that the surrogate model has. A simple way to propagate this uncertainty through to the QoI is to perform the QoI calculation for each of the grey lines. This will give a variety of QoI values, and this distribution captures how the uncertainty in the surrogate propagates through to the QoI. + +The is represented in `axtreme` by the `QoIEstimator` protocol. This takes a surrogate model, from which it samples possible functions (the grey lines), and returns the QoI estimated by each of the possible functions sampled. diff --git a/_sources/basic_concepts/surrogate_model.md.txt b/_sources/basic_concepts/surrogate_model.md.txt new file mode 100644 index 00000000..c0008f31 --- /dev/null +++ b/_sources/basic_concepts/surrogate_model.md.txt @@ -0,0 +1,24 @@ +# Surrogate models: + +Often we work with models (which we will call simulators) that are too slow or expensive for the calculations we would like to use them for. One way to deal with this is to make a faster/cheaper version of the simulator, and use that in place of the expensive model. The faster model is called the "surrogate model". One challenge with using a surrogate model is that it is an imperfect representation of your simulator, and as a result the calculation made with the surrogate can be inaccurate. The degree of inaccuracy can also be hard to estimate, as different regions of the surrogate might have vastly different influence on the calculation (in some regions small error may have a large impact on the calculation, in others regions large errors may have no impact). In order for a surrogate model to be useful in our calculations of the QoI, it needs to be uncertainty aware, and support non-gaussian noise. These are detailed in the following sections. + +## Uncertainty aware surrogate: +Uncertainty aware surrogate models provide an estimate of the simulator output (as does a regular surrogate), and provides information about the models confidence in the prediction (e.g a confidence interval). If the confidence is well calibrated, we can accurately estimate how wrong our surrogate might be, and see what effect this has on our calculation. In `axtreme` we use Gaussian Processes (GP) to provide uncertainty aware surrogate models. Some benefits of GPs are that they work well with small amounts of data (meaning we need little data from the expensive simulator), can incorporate prior knowledge about systems (which is not uncommon in engineering). They are also widely used in Bayesian optimisation, which is useful in the later DoE stage. + +### Surrogate model +![axtreme_surrogate_model_no_uncertainty](img/surrogate_model/surrogate_model_no_uncertainty.png){w=300px} +### Uncertainty aware surrogate mode; +![axtreme_surrogate_model_uncertainty_aware](img/surrogate_model/surrogate_model_uncertainty_aware.png) + + +## Non-Gaussian Noise: +Often simulators are stochastic, meaning for a given input $x$ the output $y$ is stochastic (e.g. there is an output distribution at $x$ and the $y$s are samples of this). The following shows a histogram of the responses seen when running a simulator repeatedly for point $x$. + +![axtreme_noise_simulator](img/surrogate_model/noise_simulator.png) + +GPs estimate Gaussian noise/uncertainty around their predictions (Using other distribution is possible, but becomes intractable). If we use a GP to directly model the output of a simulator, this assumes the output of the simulator is also Gaussian distributed. Often the simulators do not follow a Gaussian distribution, so taking this approach will produce poorly calibrated confidence estimate. +![axtreme_simulator_normal_noise](img/surrogate_model/simulator_normal_noise.png) + +Instead, we can use a number of GPs to model the **parameters** of the response distribution. Here we need to explicitly select the distribution that we believe best captures the simulators response. The distribution can be chosen based on domain knowledge, or by running the simulator repeatedly at a small number of points to get an understanding of the distribution family. + +![axtreme_simulator_non_gaus_noise](img/surrogate_model/simulator_non_gaus_noise.png) diff --git a/_sources/getting_started.rst.txt b/_sources/getting_started.rst.txt new file mode 100644 index 00000000..62dac657 --- /dev/null +++ b/_sources/getting_started.rst.txt @@ -0,0 +1,16 @@ +Getting started +=============== + +Installing axtreme +------------------ + +axtreme can be installed using pip: + +:: + + pip install dnv-axtreme + +Or directly from the source code: +:: + + pip install git+https://github.com/dnv-innersource/TDR_axtreme.git diff --git a/_sources/glossary.md.txt b/_sources/glossary.md.txt new file mode 100644 index 00000000..b488d74e --- /dev/null +++ b/_sources/glossary.md.txt @@ -0,0 +1,36 @@ +# Glossary +## Key terms +- **Extreme Response Distribtuion (ERD):** Distribution of the largest response experienced over a timeframe. e.g distribution of the largest reponse a windturbine will experience in 20 years of operatation. +- **period**: A sample of the environment for the timeframe of interest. e.g 20 years worth of samples of the env dist. + - `n_periods` The number of these periods. + - `period_len`: the number of samples require to create timeframe of interest. + - e.g timeframe is 1 year, and env samples are for 1 day, then `period_len=365.25` +- **environment distribution (env_dist)**: + +## Dimension Notation: +The `ax` stack (`ax`, `botorch`, `gpytorch`, `pytorch`) comprises of a number of libraries, each with their own notation. As `axtreme` interacts with differrent parts of this stack, it is useful to know the different conventions. `axtreme` uses `botorch` tensor notation unless otherwise specifiec. + +### Botorch tensor notation. +key terms that we make use of that we should define: +- Dimension convension used by (botorch)[https://botorch.org/api/models.html#botorch.models.gp_regression.SingleTaskGP] + - `X`: input data + - `batch_shape`: (*b) batch shape. Varying number of dimensions (including 0) + - `n`: input points. + - `m`: target/output dimensionality + - `d`: dimensionality of input points. +- Optimisation: + - `q`: number of candidate points optimised jointly. + - `t`: number of points passed to optimise in parrallel (not optimised jointly) + +### +- The dimension convension used by gpytorch + - (`...`,` b1 x ... x bk`): batch shape + - `n`: input points. + - `t`: target/output dimensionality + - `d`: dimensionality of input points. + +## TODO +Glossary task to be added + +Explain how: +- Multitask in gpytorch can be used with SingleTaskGP diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..4f09d2f0 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,32 @@ +.. axtreme documentation master file, created by + sphinx-quickstart on Tue Sep 3 12:50:10 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +axtreme Documentation +===================== + +.. toctree:: + :maxdepth: 4 + :caption: Contents: + + README + introduction + getting_started + basic_concepts/basic_concepts + usecase_offshorewind + api + technical_details/technical_details + glossary + CHANGELOG + STYLEGUIDE + LICENSE + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/_sources/introduction.md.txt b/_sources/introduction.md.txt new file mode 100644 index 00000000..f8a14948 --- /dev/null +++ b/_sources/introduction.md.txt @@ -0,0 +1,14 @@ +# Introduction +## What is axtreme (Ax for Extremes): +`axtreme` is a toolkit for estimating the long term behaviour (extremes) of expensive, stochastic, black box functions. It does this by creating uncertainty aware surrogate models of the black box function, propagating this uncertainty through to the behaviour being estimated (e.g produce estimates with confidence bounds), and using Active Learning (also know as Design of Experiments (DOE)) to iteratively improve the surrogate model and associated estimates. + +## What problems is it for? +While there are a broad range of applications, development has been motivated by challenges commonly found in Engineering. Specifically, Ultimate Limit State (ULS) calculations often require engineers to understand a structure/design's performance over many years of operation. The models engineers use (FEM etc.) are typically very accurate, but slow, make it challenging to use them over this time frame. An illustrative use case is provided in "Example usecase". + +## Why use it: +Within engineering, probabilistic approaches to these types of problem can offer advantages over traditional methods (for example, demonstrated [here](https://www.sciencedirect.com/science/article/abs/pii/S0951833920300745)). In particular, they can help reduce conservatism in designs. Despite the advantages, probabilistic methods are not widely used, likely due in part to the complexity of implementing them (often requiring specialist knowledge). `axtreme` is designed to reduce this complexity and make probabilistic approaches more accessible, unlocking better understanding of long term behaviour, and potential reductions in excessive conservatism. + +axtreme itself is built on [Ax](https://ax.dev/docs/why-ax.html) and [Botorch](https://botorch.org/docs/introduction). This provides out of the box access to best practice Gaussian Processes (GP), experiment management, auto-differentiation and GPU acceleration. + +## Target Audience: +`axtreme` is intend for users and engineers that are familiar with Python and Tensors. Familiarity with Bayesian Optimisation, Gaussian Processes and Acquisition functions is not assumed. diff --git a/_sources/technical_details/ax_integration.md.txt b/_sources/technical_details/ax_integration.md.txt new file mode 100644 index 00000000..e1ca0420 --- /dev/null +++ b/_sources/technical_details/ax_integration.md.txt @@ -0,0 +1,9 @@ +# Compatibility with `Ax` +`Ax` is a package developed by Meta for orchestration of Bayesian Optimisation. By utilising `Ax`, a large amount of orchestration and book-keeping is automatically handled, minimising developer overhead and providing users with an established and documented interface. While there are a large selection of tools available for maximising a GP, our ULS (detailed in `usecase_offshorewind`) problem does not fit directly into the framework. We do the following to deal with this: +- Define the `Experiment` `Metrics` to be the parameters of the response distribution (e.g location and scale). +- When a `ModelBridge` is instantiated using an `ax` `Experiment` it automatically sets up GPs to track the `Metrics`. +- We customise the Acquisition function in the `ModelBridge` so that it appropriately handles our GPs (Typical acquisition functions try to find the maximum of the GP, but we are interested in a different Quantity) + +The following shows a conceptual overview of the key `ax` components involved. + +![axtreme_ax_component_diagram](img/ax_integration/ax_component_diagram.png) diff --git a/_sources/technical_details/gpbruteforce.md.txt b/_sources/technical_details/gpbruteforce.md.txt new file mode 100644 index 00000000..27fbe5d3 --- /dev/null +++ b/_sources/technical_details/gpbruteforce.md.txt @@ -0,0 +1,22 @@ +# `GPBruteforce` behaviour w.r.t changes in the underlying model. +The `GPBruteforce` QoI output is not smooth w.r.t smooth changes in the model used. This impacts the optimisers that should be used. + +## Details +The `QoILookAhead` acquistion function take a candidate point $x$ and returns a score (`acqusition(x) -> score`). Internally the acquisiton function "fantasizes" what new GP would be produced at candidate point $x$ and the calculates the QoI with the new GP. Is uses the variance of the QoI as the score. As this acquistion function needs to be optimised, it important to understand if the acquisiton function is smooth (is the relationship between $x$ and score smooth). The smoothness is influenced by the steps taken when performing this calculation. + +`x --> new_model --> qoi(new_model) --> var(qoi) --> score` + + +While `QoILookAhead` guarantees the `new_model` is smooth w.r.t $x$, the `GPBruteForce` QoI is **not** smooth w.r.t the `new_model`. As a result the acqusition function is not smooth and cannot be optimised with optimisers that expect 1st or 2nd derivative. The following details why the `GPBruteForce` QoI is **not** smooth w.r.t the `new_model`. + +### ERD smoothness w.r.t model +A single ERD sample is created byt finding the response of each env sample in a period, and taking the max. say `env_samples = [.1,.3,.6,.4]`. Say the new model is built by adding a single new point between [0,1]. For each different new_model, the response for a specific env sample changes. This can be plotted as follows. + +![erd_smoothness](img/gpbruteforce/erd_smoothness.png) + +As the plot shows, even if the `env_samples` responses are smooth w.r.t the model, the ERD sample is not gaurenteed to be. + +### QoI smoothness w.r.t model +A QoI is estimated from ERD samples (typically a seperate estimate is made for each posterior sample). The following plot shows even if the ERD samples are smooth w.r.t the model, the QoI (in this case the median) is not gaurenteed to be. + +![qoi_smoothness](img/gpbruteforce/qoi_smoothness.png) diff --git a/_sources/technical_details/technical_details.rst.txt b/_sources/technical_details/technical_details.rst.txt new file mode 100644 index 00000000..653859fe --- /dev/null +++ b/_sources/technical_details/technical_details.rst.txt @@ -0,0 +1,11 @@ +Technical Details +================= +The following contains in depth information about specific components of `axtreme`. + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + ax_integration + gpbruteforce + diff --git a/_sources/usecase_offshorewind.md.txt b/_sources/usecase_offshorewind.md.txt new file mode 100644 index 00000000..c40cd77f --- /dev/null +++ b/_sources/usecase_offshorewind.md.txt @@ -0,0 +1,48 @@ +# Example Usecase +The following offshore wind usecase is used to introduce the `axtreme` package, as we have found this type of introduction more informative than abstract technical definitions of key package terminology and capabilities: + +## Overview +An offshore wind turbine is being designed to operate for 20 years. The engineers have information about the typical weather conditions (called the environment conditions), and have a slow but accurate stochastic simulator of the response experienced by the turbine in a give weather condition. In order to know their design will survive for the 20 year period they need to know (amongst other things) the Ultimate Limit State (ULS). This is the largest response the wind turbine is experiences in 20 years of operation. + +Because of randomness in the weather and the turbine's response, the largest response experienced in a 20 year period is not a fixed values, and has a distribution. This distribution is called the the Extreme Response Distribution (ERD). The engineers are specifically interested in knowing the median of this distribution (this is called their Quantity of Interest (QoI)). + +![long_term_response_dist](img/usecase_offshorewind/long_term_response_distribution.png) + +The following details the environment samples and simulator. + +### Environment Samples: +The environment represents the factors that effect the wind turbine, and these are used as inputs to the simulator. Typically these are weather conditions such as wind and wave information. The environment distribution then represents how likely it is that a condition will be experience by the wind turbine. + +The environment distribution reports "long-term" conditions. This means it represents the average conditions (e.g wind speed) over an hour. This is different to the instantaneous conditions, which are called "short-term" conditions. Short-term conditions are typically (stochastically) generated within the simulator from the long term conditions. This one of the factors causing stochastic output in the simulator. + +### Wind Turbine Simulator $f:X -> Y$ +This stochastic function predicts the response caused by a given environment condition. +- Input: Takes a "long-term" environment condition $x$ . e.g average wind speed and turbulence. +- Output: The turbines maximum response $y$ during an hour of operation in those conditions. The response is stochastic as the model internally randomly generates an hour on instantaneous weather that satisfies the long term average $x$. As there are many patterns of instantaneous weather, each which may produce different responses, the output is stochastic + +## Possible Solutions: + +### Naive approach: +If the simulator was fast we could use the following process to calculate the QoI: +- Taking one period worth of environment samples. +- Running them through the simulator, creating one period worth of responses. +- Taking the largest responses in that period. + +This produces a single sample of the ERD. The process could be be repeated until enough samples were obtains to estimate the QoI. + +### Traditional Approaches: +Method such as Environment Contouring have been create to approximate the QoI with fewer runs of the simulator. These work better than the Naive approach, but have shortcomings. + + +### `axtreme` approach: +The `axtreme` package deals with this problem by using a fast surrogate model in place of the real simulator when performing the QoI calculations. The process consists of 3 key steps (detailed further in "Basic Concepts"): +1) #### Build an uncertainty-aware Surrogate Model. +Once a small dataset has been created with the simulator (input and output pairs), a surrogate model can be fit to this dataset. For the surrogate to be useful it should: +- Properly capture the (possibly non-Gaussian) randomness in the simulators response. +- Be uncertainty aware: Using a surrogate model introduces uncertainty regarding the quality of the fit. Without knowing this uncertainty, it is difficult to trust the results calculated using the surrogate. + +2) #### Calculate the QoI: +The surrogate model can now be used in place of the simulator to calculate the QoI. It is important that the uncertainty the surrogate has regarding the true model (the simulator) is propagated through to the QoI. + +3) #### Reduce the uncertainty in the QoI: +We can reduce uncertainty in the QoI by adding data to the surrogate (which reduces the surrogates uncertainty). Some data points are more influential in the QoI calculation than others. By using active learning (also called DoE) to identify these regions, uncertainty in the QoI can be reduced with minimal runs of the (expensive) simulator. diff --git a/_static/DNV_logo_RGB.jpg b/_static/DNV_logo_RGB.jpg new file mode 100644 index 00000000..136fe620 Binary files /dev/null and b/_static/DNV_logo_RGB.jpg differ diff --git a/_static/axtreme.svg b/_static/axtreme.svg new file mode 100644 index 00000000..1e02cbed --- /dev/null +++ b/_static/axtreme.svg @@ -0,0 +1 @@ +mypackagelogo svg1224 x 1223 \ No newline at end of file diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..7ebbd6d0 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/debug.css b/_static/debug.css new file mode 100644 index 00000000..74d4aec3 --- /dev/null +++ b/_static/debug.css @@ -0,0 +1,69 @@ +/* + This CSS file should be overridden by the theme authors. It's + meant for debugging and developing the skeleton that this theme provides. +*/ +body { + font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji"; + background: lavender; +} +.sb-announcement { + background: rgb(131, 131, 131); +} +.sb-announcement__inner { + background: black; + color: white; +} +.sb-header { + background: lightskyblue; +} +.sb-header__inner { + background: royalblue; + color: white; +} +.sb-header-secondary { + background: lightcyan; +} +.sb-header-secondary__inner { + background: cornflowerblue; + color: white; +} +.sb-sidebar-primary { + background: lightgreen; +} +.sb-main { + background: blanchedalmond; +} +.sb-main__inner { + background: antiquewhite; +} +.sb-header-article { + background: lightsteelblue; +} +.sb-article-container { + background: snow; +} +.sb-article-main { + background: white; +} +.sb-footer-article { + background: lightpink; +} +.sb-sidebar-secondary { + background: lightgoldenrodyellow; +} +.sb-footer-content { + background: plum; +} +.sb-footer-content__inner { + background: palevioletred; +} +.sb-footer { + background: pink; +} +.sb-footer__inner { + background: salmon; +} +.sb-article { + background: white; +} diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..0398ebb9 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..51cf7f54 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.1.1', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..c7fe6c6f --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/plot_directive.css b/_static/plot_directive.css new file mode 100644 index 00000000..d45593c9 --- /dev/null +++ b/_static/plot_directive.css @@ -0,0 +1,16 @@ +/* + * plot_directive.css + * ~~~~~~~~~~~~ + * + * Stylesheet controlling images created using the `plot` directive within + * Sphinx. + * + * :copyright: Copyright 2020-* by the Matplotlib development team. + * :license: Matplotlib, see LICENSE for details. + * + */ + +img.plot-directive { + border: 0; + max-width: 100%; +} diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..02b4b128 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,258 @@ +.highlight pre { line-height: 125%; } +.highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #a40000 } /* Generic.Deleted */ +.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .ges { color: #000000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #ef2929 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ +.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ +.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ +@media not print { +body[data-theme="dark"] .highlight pre { line-height: 125%; } +body[data-theme="dark"] .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight .hll { background-color: #404040 } +body[data-theme="dark"] .highlight { background: #202020; color: #d0d0d0 } +body[data-theme="dark"] .highlight .c { color: #ababab; font-style: italic } /* Comment */ +body[data-theme="dark"] .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +body[data-theme="dark"] .highlight .esc { color: #d0d0d0 } /* Escape */ +body[data-theme="dark"] .highlight .g { color: #d0d0d0 } /* Generic */ +body[data-theme="dark"] .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */ +body[data-theme="dark"] .highlight .l { color: #d0d0d0 } /* Literal */ +body[data-theme="dark"] .highlight .n { color: #d0d0d0 } /* Name */ +body[data-theme="dark"] .highlight .o { color: #d0d0d0 } /* Operator */ +body[data-theme="dark"] .highlight .x { color: #d0d0d0 } /* Other */ +body[data-theme="dark"] .highlight .p { color: #d0d0d0 } /* Punctuation */ +body[data-theme="dark"] .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */ +body[data-theme="dark"] .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */ +body[data-theme="dark"] .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */ +body[data-theme="dark"] .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ +body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ +body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body[data-theme="dark"] .highlight .gd { color: #ff3a3a } /* Generic.Deleted */ +body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body[data-theme="dark"] .highlight .gr { color: #ff3a3a } /* Generic.Error */ +body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */ +body[data-theme="dark"] .highlight .go { color: #cccccc } /* Generic.Output */ +body[data-theme="dark"] .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +body[data-theme="dark"] .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +body[data-theme="dark"] .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +body[data-theme="dark"] .highlight .gt { color: #ff3a3a } /* Generic.Traceback */ +body[data-theme="dark"] .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ +body[data-theme="dark"] .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ +body[data-theme="dark"] .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ +body[data-theme="dark"] .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */ +body[data-theme="dark"] .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */ +body[data-theme="dark"] .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */ +body[data-theme="dark"] .highlight .ld { color: #d0d0d0 } /* Literal.Date */ +body[data-theme="dark"] .highlight .m { color: #51b2fd } /* Literal.Number */ +body[data-theme="dark"] .highlight .s { color: #ed9d13 } /* Literal.String */ +body[data-theme="dark"] .highlight .na { color: #bbbbbb } /* Name.Attribute */ +body[data-theme="dark"] .highlight .nb { color: #2fbccd } /* Name.Builtin */ +body[data-theme="dark"] .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */ +body[data-theme="dark"] .highlight .no { color: #40ffff } /* Name.Constant */ +body[data-theme="dark"] .highlight .nd { color: #ffa500 } /* Name.Decorator */ +body[data-theme="dark"] .highlight .ni { color: #d0d0d0 } /* Name.Entity */ +body[data-theme="dark"] .highlight .ne { color: #bbbbbb } /* Name.Exception */ +body[data-theme="dark"] .highlight .nf { color: #71adff } /* Name.Function */ +body[data-theme="dark"] .highlight .nl { color: #d0d0d0 } /* Name.Label */ +body[data-theme="dark"] .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */ +body[data-theme="dark"] .highlight .nx { color: #d0d0d0 } /* Name.Other */ +body[data-theme="dark"] .highlight .py { color: #d0d0d0 } /* Name.Property */ +body[data-theme="dark"] .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */ +body[data-theme="dark"] .highlight .nv { color: #40ffff } /* Name.Variable */ +body[data-theme="dark"] .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */ +body[data-theme="dark"] .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */ +body[data-theme="dark"] .highlight .w { color: #666666 } /* Text.Whitespace */ +body[data-theme="dark"] .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */ +body[data-theme="dark"] .highlight .mf { color: #51b2fd } /* Literal.Number.Float */ +body[data-theme="dark"] .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */ +body[data-theme="dark"] .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */ +body[data-theme="dark"] .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */ +body[data-theme="dark"] .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */ +body[data-theme="dark"] .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +body[data-theme="dark"] .highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +body[data-theme="dark"] .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */ +body[data-theme="dark"] .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +body[data-theme="dark"] .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +body[data-theme="dark"] .highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +body[data-theme="dark"] .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +body[data-theme="dark"] .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +body[data-theme="dark"] .highlight .sx { color: #ffa500 } /* Literal.String.Other */ +body[data-theme="dark"] .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +body[data-theme="dark"] .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +body[data-theme="dark"] .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +body[data-theme="dark"] .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */ +body[data-theme="dark"] .highlight .fm { color: #71adff } /* Name.Function.Magic */ +body[data-theme="dark"] .highlight .vc { color: #40ffff } /* Name.Variable.Class */ +body[data-theme="dark"] .highlight .vg { color: #40ffff } /* Name.Variable.Global */ +body[data-theme="dark"] .highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +body[data-theme="dark"] .highlight .vm { color: #40ffff } /* Name.Variable.Magic */ +body[data-theme="dark"] .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */ +@media (prefers-color-scheme: dark) { +body:not([data-theme="light"]) .highlight pre { line-height: 125%; } +body:not([data-theme="light"]) .highlight td.linenos .normal { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos { color: #aaaaaa; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight .hll { background-color: #404040 } +body:not([data-theme="light"]) .highlight { background: #202020; color: #d0d0d0 } +body:not([data-theme="light"]) .highlight .c { color: #ababab; font-style: italic } /* Comment */ +body:not([data-theme="light"]) .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +body:not([data-theme="light"]) .highlight .esc { color: #d0d0d0 } /* Escape */ +body:not([data-theme="light"]) .highlight .g { color: #d0d0d0 } /* Generic */ +body:not([data-theme="light"]) .highlight .k { color: #6ebf26; font-weight: bold } /* Keyword */ +body:not([data-theme="light"]) .highlight .l { color: #d0d0d0 } /* Literal */ +body:not([data-theme="light"]) .highlight .n { color: #d0d0d0 } /* Name */ +body:not([data-theme="light"]) .highlight .o { color: #d0d0d0 } /* Operator */ +body:not([data-theme="light"]) .highlight .x { color: #d0d0d0 } /* Other */ +body:not([data-theme="light"]) .highlight .p { color: #d0d0d0 } /* Punctuation */ +body:not([data-theme="light"]) .highlight .ch { color: #ababab; font-style: italic } /* Comment.Hashbang */ +body:not([data-theme="light"]) .highlight .cm { color: #ababab; font-style: italic } /* Comment.Multiline */ +body:not([data-theme="light"]) .highlight .cp { color: #ff3a3a; font-weight: bold } /* Comment.Preproc */ +body:not([data-theme="light"]) .highlight .cpf { color: #ababab; font-style: italic } /* Comment.PreprocFile */ +body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: italic } /* Comment.Single */ +body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ +body:not([data-theme="light"]) .highlight .gd { color: #ff3a3a } /* Generic.Deleted */ +body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body:not([data-theme="light"]) .highlight .gr { color: #ff3a3a } /* Generic.Error */ +body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ +body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */ +body:not([data-theme="light"]) .highlight .go { color: #cccccc } /* Generic.Output */ +body:not([data-theme="light"]) .highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +body:not([data-theme="light"]) .highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */ +body:not([data-theme="light"]) .highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +body:not([data-theme="light"]) .highlight .gt { color: #ff3a3a } /* Generic.Traceback */ +body:not([data-theme="light"]) .highlight .kc { color: #6ebf26; font-weight: bold } /* Keyword.Constant */ +body:not([data-theme="light"]) .highlight .kd { color: #6ebf26; font-weight: bold } /* Keyword.Declaration */ +body:not([data-theme="light"]) .highlight .kn { color: #6ebf26; font-weight: bold } /* Keyword.Namespace */ +body:not([data-theme="light"]) .highlight .kp { color: #6ebf26 } /* Keyword.Pseudo */ +body:not([data-theme="light"]) .highlight .kr { color: #6ebf26; font-weight: bold } /* Keyword.Reserved */ +body:not([data-theme="light"]) .highlight .kt { color: #6ebf26; font-weight: bold } /* Keyword.Type */ +body:not([data-theme="light"]) .highlight .ld { color: #d0d0d0 } /* Literal.Date */ +body:not([data-theme="light"]) .highlight .m { color: #51b2fd } /* Literal.Number */ +body:not([data-theme="light"]) .highlight .s { color: #ed9d13 } /* Literal.String */ +body:not([data-theme="light"]) .highlight .na { color: #bbbbbb } /* Name.Attribute */ +body:not([data-theme="light"]) .highlight .nb { color: #2fbccd } /* Name.Builtin */ +body:not([data-theme="light"]) .highlight .nc { color: #71adff; text-decoration: underline } /* Name.Class */ +body:not([data-theme="light"]) .highlight .no { color: #40ffff } /* Name.Constant */ +body:not([data-theme="light"]) .highlight .nd { color: #ffa500 } /* Name.Decorator */ +body:not([data-theme="light"]) .highlight .ni { color: #d0d0d0 } /* Name.Entity */ +body:not([data-theme="light"]) .highlight .ne { color: #bbbbbb } /* Name.Exception */ +body:not([data-theme="light"]) .highlight .nf { color: #71adff } /* Name.Function */ +body:not([data-theme="light"]) .highlight .nl { color: #d0d0d0 } /* Name.Label */ +body:not([data-theme="light"]) .highlight .nn { color: #71adff; text-decoration: underline } /* Name.Namespace */ +body:not([data-theme="light"]) .highlight .nx { color: #d0d0d0 } /* Name.Other */ +body:not([data-theme="light"]) .highlight .py { color: #d0d0d0 } /* Name.Property */ +body:not([data-theme="light"]) .highlight .nt { color: #6ebf26; font-weight: bold } /* Name.Tag */ +body:not([data-theme="light"]) .highlight .nv { color: #40ffff } /* Name.Variable */ +body:not([data-theme="light"]) .highlight .ow { color: #6ebf26; font-weight: bold } /* Operator.Word */ +body:not([data-theme="light"]) .highlight .pm { color: #d0d0d0 } /* Punctuation.Marker */ +body:not([data-theme="light"]) .highlight .w { color: #666666 } /* Text.Whitespace */ +body:not([data-theme="light"]) .highlight .mb { color: #51b2fd } /* Literal.Number.Bin */ +body:not([data-theme="light"]) .highlight .mf { color: #51b2fd } /* Literal.Number.Float */ +body:not([data-theme="light"]) .highlight .mh { color: #51b2fd } /* Literal.Number.Hex */ +body:not([data-theme="light"]) .highlight .mi { color: #51b2fd } /* Literal.Number.Integer */ +body:not([data-theme="light"]) .highlight .mo { color: #51b2fd } /* Literal.Number.Oct */ +body:not([data-theme="light"]) .highlight .sa { color: #ed9d13 } /* Literal.String.Affix */ +body:not([data-theme="light"]) .highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */ +body:not([data-theme="light"]) .highlight .sc { color: #ed9d13 } /* Literal.String.Char */ +body:not([data-theme="light"]) .highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */ +body:not([data-theme="light"]) .highlight .sd { color: #ed9d13 } /* Literal.String.Doc */ +body:not([data-theme="light"]) .highlight .s2 { color: #ed9d13 } /* Literal.String.Double */ +body:not([data-theme="light"]) .highlight .se { color: #ed9d13 } /* Literal.String.Escape */ +body:not([data-theme="light"]) .highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */ +body:not([data-theme="light"]) .highlight .si { color: #ed9d13 } /* Literal.String.Interpol */ +body:not([data-theme="light"]) .highlight .sx { color: #ffa500 } /* Literal.String.Other */ +body:not([data-theme="light"]) .highlight .sr { color: #ed9d13 } /* Literal.String.Regex */ +body:not([data-theme="light"]) .highlight .s1 { color: #ed9d13 } /* Literal.String.Single */ +body:not([data-theme="light"]) .highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */ +body:not([data-theme="light"]) .highlight .bp { color: #2fbccd } /* Name.Builtin.Pseudo */ +body:not([data-theme="light"]) .highlight .fm { color: #71adff } /* Name.Function.Magic */ +body:not([data-theme="light"]) .highlight .vc { color: #40ffff } /* Name.Variable.Class */ +body:not([data-theme="light"]) .highlight .vg { color: #40ffff } /* Name.Variable.Global */ +body:not([data-theme="light"]) .highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +body:not([data-theme="light"]) .highlight .vm { color: #40ffff } /* Name.Variable.Magic */ +body:not([data-theme="light"]) .highlight .il { color: #51b2fd } /* Literal.Number.Integer.Long */ +} +} \ No newline at end of file diff --git a/_static/scripts/furo-extensions.js b/_static/scripts/furo-extensions.js new file mode 100644 index 00000000..e69de29b diff --git a/_static/scripts/furo.js b/_static/scripts/furo.js new file mode 100644 index 00000000..0abb2afa --- /dev/null +++ b/_static/scripts/furo.js @@ -0,0 +1,3 @@ +/*! For license information please see furo.js.LICENSE.txt */ +(()=>{var t={856:function(t,e,n){var o,r;r=void 0!==n.g?n.g:"undefined"!=typeof window?window:this,o=function(){return function(t){"use strict";var e={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},n=function(t,e,n){if(n.settings.events){var o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e.dispatchEvent(o)}},o=function(t){var e=0;if(t.offsetParent)for(;t;)e+=t.offsetTop,t=t.offsetParent;return e>=0?e:0},r=function(t){t&&t.sort((function(t,e){return o(t.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},l=function(t,e){var n=t[t.length-1];if(function(t,e){return!(!s()||!c(t.content,e,!0))}(n,e))return n;for(var o=t.length-1;o>=0;o--)if(c(t[o].content,e))return t[o]},a=function(t,e){if(e.nested&&t.parentNode){var n=t.parentNode.closest("li");n&&(n.classList.remove(e.nestedClass),a(n,e))}},i=function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.remove(e.navClass),t.content.classList.remove(e.contentClass),a(o,e),n("gumshoeDeactivate",o,{link:t.nav,content:t.content,settings:e}))}},u=function(t,e){if(e.nested){var n=t.parentNode.closest("li");n&&(n.classList.add(e.nestedClass),u(n,e))}};return function(o,c){var s,a,d,f,m,v={setup:function(){s=document.querySelectorAll(o),a=[],Array.prototype.forEach.call(s,(function(t){var e=document.getElementById(decodeURIComponent(t.hash.substr(1)));e&&a.push({nav:t,content:e})})),r(a)},detect:function(){var t=l(a,m);t?d&&t.content===d.content||(i(d,m),function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.add(e.navClass),t.content.classList.add(e.contentClass),u(o,e),n("gumshoeActivate",o,{link:t.nav,content:t.content,settings:e}))}}(t,m),d=t):d&&(i(d,m),d=null)}},h=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame(v.detect)},g=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame((function(){r(a),v.detect()}))};return v.destroy=function(){d&&i(d,m),t.removeEventListener("scroll",h,!1),m.reflow&&t.removeEventListener("resize",g,!1),a=null,s=null,d=null,f=null,m=null},m=function(){var t={};return Array.prototype.forEach.call(arguments,(function(e){for(var n in e){if(!e.hasOwnProperty(n))return;t[n]=e[n]}})),t}(e,c||{}),v.setup(),v.detect(),t.addEventListener("scroll",h,!1),m.reflow&&t.addEventListener("resize",g,!1),v}}(r)}.apply(e,[]),void 0===o||(t.exports=o)}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=n(856),e=n.n(t),o=null,r=null,c=document.documentElement.scrollTop;const s=64;function l(){const t=localStorage.getItem("theme")||"auto";var e;"light"!==(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"auto"===t?"light":"light"==t?"dark":"auto":"auto"===t?"dark":"dark"==t?"light":"auto")&&"dark"!==e&&"auto"!==e&&(console.error(`Got invalid theme mode: ${e}. Resetting to auto.`),e="auto"),document.body.dataset.theme=e,localStorage.setItem("theme",e),console.log(`Changed to ${e} mode.`)}function a(){!function(){const t=document.getElementsByClassName("theme-toggle");Array.from(t).forEach((t=>{t.addEventListener("click",l)}))}(),function(){let t=0,e=!1;window.addEventListener("scroll",(function(n){t=window.scrollY,e||(window.requestAnimationFrame((function(){var n;(function(t){const e=Math.floor(r.getBoundingClientRect().top);console.log(`headerTop: ${e}`),0==e&&t!=e?r.classList.add("scrolled"):r.classList.remove("scrolled")})(n=t),function(t){tc&&document.documentElement.classList.remove("show-back-to-top"),c=t}(n),function(t){null!==o&&(0==t?o.scrollTo(0,0):Math.ceil(t)>=Math.floor(document.documentElement.scrollHeight-window.innerHeight)?o.scrollTo(0,o.scrollHeight):document.querySelector(".scroll-current"))}(n),e=!1})),e=!0)})),window.scroll()}(),null!==o&&new(e())(".toc-tree a",{reflow:!0,recursive:!0,navClass:"scroll-current",offset:()=>{let t=parseFloat(getComputedStyle(document.documentElement).fontSize);return r.getBoundingClientRect().height+2.5*t+1}})}document.addEventListener("DOMContentLoaded",(function(){document.body.parentNode.classList.remove("no-js"),r=document.querySelector("header"),o=document.querySelector(".toc-scroll"),a()}))})()})(); +//# sourceMappingURL=furo.js.map \ No newline at end of file diff --git a/_static/scripts/furo.js.LICENSE.txt b/_static/scripts/furo.js.LICENSE.txt new file mode 100644 index 00000000..1632189c --- /dev/null +++ b/_static/scripts/furo.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! + * gumshoejs v5.1.2 (patched by @pradyunsg) + * A simple, framework-agnostic scrollspy script. + * (c) 2019 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/gumshoe + */ diff --git a/_static/scripts/furo.js.map b/_static/scripts/furo.js.map new file mode 100644 index 00000000..80ea12b8 --- /dev/null +++ b/_static/scripts/furo.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/furo.js","mappings":";iCAAA,MAQWA,SAWS,IAAX,EAAAC,EACH,EAAAA,EACkB,oBAAXC,OACLA,OACAC,KAbO,EAAF,WACP,OAaJ,SAAUD,GACR,aAMA,IAAIE,EAAW,CAEbC,SAAU,SACVC,aAAc,SAGdC,QAAQ,EACRC,YAAa,SAGbC,OAAQ,EACRC,QAAQ,EAGRC,QAAQ,GA6BNC,EAAY,SAAUC,EAAMC,EAAMC,GAEpC,GAAKA,EAAOC,SAASL,OAArB,CAGA,IAAIM,EAAQ,IAAIC,YAAYL,EAAM,CAChCM,SAAS,EACTC,YAAY,EACZL,OAAQA,IAIVD,EAAKO,cAAcJ,EAVgB,CAWrC,EAOIK,EAAe,SAAUR,GAC3B,IAAIS,EAAW,EACf,GAAIT,EAAKU,aACP,KAAOV,GACLS,GAAYT,EAAKW,UACjBX,EAAOA,EAAKU,aAGhB,OAAOD,GAAY,EAAIA,EAAW,CACpC,EAMIG,EAAe,SAAUC,GACvBA,GACFA,EAASC,MAAK,SAAUC,EAAOC,GAG7B,OAFcR,EAAaO,EAAME,SACnBT,EAAaQ,EAAMC,UACF,EACxB,CACT,GAEJ,EAwCIC,EAAW,SAAUlB,EAAME,EAAUiB,GACvC,IAAIC,EAASpB,EAAKqB,wBACd1B,EAnCU,SAAUO,GAExB,MAA+B,mBAApBA,EAASP,OACX2B,WAAWpB,EAASP,UAItB2B,WAAWpB,EAASP,OAC7B,CA2Be4B,CAAUrB,GACvB,OAAIiB,EAEAK,SAASJ,EAAOD,OAAQ,KACvB/B,EAAOqC,aAAeC,SAASC,gBAAgBC,cAG7CJ,SAASJ,EAAOS,IAAK,KAAOlC,CACrC,EAMImC,EAAa,WACf,OACEC,KAAKC,KAAK5C,EAAOqC,YAAcrC,EAAO6C,cAnCjCF,KAAKG,IACVR,SAASS,KAAKC,aACdV,SAASC,gBAAgBS,aACzBV,SAASS,KAAKE,aACdX,SAASC,gBAAgBU,aACzBX,SAASS,KAAKP,aACdF,SAASC,gBAAgBC,aAkC7B,EAmBIU,EAAY,SAAUzB,EAAUX,GAClC,IAAIqC,EAAO1B,EAASA,EAAS2B,OAAS,GACtC,GAbgB,SAAUC,EAAMvC,GAChC,SAAI4B,MAAgBZ,EAASuB,EAAKxB,QAASf,GAAU,GAEvD,CAUMwC,CAAYH,EAAMrC,GAAW,OAAOqC,EACxC,IAAK,IAAII,EAAI9B,EAAS2B,OAAS,EAAGG,GAAK,EAAGA,IACxC,GAAIzB,EAASL,EAAS8B,GAAG1B,QAASf,GAAW,OAAOW,EAAS8B,EAEjE,EAOIC,EAAmB,SAAUC,EAAK3C,GAEpC,GAAKA,EAAST,QAAWoD,EAAIC,WAA7B,CAGA,IAAIC,EAAKF,EAAIC,WAAWE,QAAQ,MAC3BD,IAGLA,EAAGE,UAAUC,OAAOhD,EAASR,aAG7BkD,EAAiBG,EAAI7C,GAV0B,CAWjD,EAOIiD,EAAa,SAAUC,EAAOlD,GAEhC,GAAKkD,EAAL,CAGA,IAAIL,EAAKK,EAAMP,IAAIG,QAAQ,MACtBD,IAGLA,EAAGE,UAAUC,OAAOhD,EAASX,UAC7B6D,EAAMnC,QAAQgC,UAAUC,OAAOhD,EAASV,cAGxCoD,EAAiBG,EAAI7C,GAGrBJ,EAAU,oBAAqBiD,EAAI,CACjCM,KAAMD,EAAMP,IACZ5B,QAASmC,EAAMnC,QACff,SAAUA,IAjBM,CAmBpB,EAOIoD,EAAiB,SAAUT,EAAK3C,GAElC,GAAKA,EAAST,OAAd,CAGA,IAAIsD,EAAKF,EAAIC,WAAWE,QAAQ,MAC3BD,IAGLA,EAAGE,UAAUM,IAAIrD,EAASR,aAG1B4D,EAAeP,EAAI7C,GAVS,CAW9B,EA6LA,OA1JkB,SAAUsD,EAAUC,GAKpC,IACIC,EAAU7C,EAAU8C,EAASC,EAAS1D,EADtC2D,EAAa,CAUjBA,MAAmB,WAEjBH,EAAWhC,SAASoC,iBAAiBN,GAGrC3C,EAAW,GAGXkD,MAAMC,UAAUC,QAAQC,KAAKR,GAAU,SAAUjB,GAE/C,IAAIxB,EAAUS,SAASyC,eACrBC,mBAAmB3B,EAAK4B,KAAKC,OAAO,KAEjCrD,GAGLJ,EAAS0D,KAAK,CACZ1B,IAAKJ,EACLxB,QAASA,GAEb,IAGAL,EAAaC,EACf,EAKAgD,OAAoB,WAElB,IAAIW,EAASlC,EAAUzB,EAAUX,GAG5BsE,EASDb,GAAWa,EAAOvD,UAAY0C,EAAQ1C,UAG1CkC,EAAWQ,EAASzD,GAzFT,SAAUkD,EAAOlD,GAE9B,GAAKkD,EAAL,CAGA,IAAIL,EAAKK,EAAMP,IAAIG,QAAQ,MACtBD,IAGLA,EAAGE,UAAUM,IAAIrD,EAASX,UAC1B6D,EAAMnC,QAAQgC,UAAUM,IAAIrD,EAASV,cAGrC8D,EAAeP,EAAI7C,GAGnBJ,EAAU,kBAAmBiD,EAAI,CAC/BM,KAAMD,EAAMP,IACZ5B,QAASmC,EAAMnC,QACff,SAAUA,IAjBM,CAmBpB,CAqEIuE,CAASD,EAAQtE,GAGjByD,EAAUa,GAfJb,IACFR,EAAWQ,EAASzD,GACpByD,EAAU,KAchB,GAMIe,EAAgB,SAAUvE,GAExByD,GACFxE,EAAOuF,qBAAqBf,GAI9BA,EAAUxE,EAAOwF,sBAAsBf,EAAWgB,OACpD,EAMIC,EAAgB,SAAU3E,GAExByD,GACFxE,EAAOuF,qBAAqBf,GAI9BA,EAAUxE,EAAOwF,uBAAsB,WACrChE,EAAaC,GACbgD,EAAWgB,QACb,GACF,EAkDA,OA7CAhB,EAAWkB,QAAU,WAEfpB,GACFR,EAAWQ,EAASzD,GAItBd,EAAO4F,oBAAoB,SAAUN,GAAe,GAChDxE,EAASN,QACXR,EAAO4F,oBAAoB,SAAUF,GAAe,GAItDjE,EAAW,KACX6C,EAAW,KACXC,EAAU,KACVC,EAAU,KACV1D,EAAW,IACb,EAOEA,EA3XS,WACX,IAAI+E,EAAS,CAAC,EAOd,OANAlB,MAAMC,UAAUC,QAAQC,KAAKgB,WAAW,SAAUC,GAChD,IAAK,IAAIC,KAAOD,EAAK,CACnB,IAAKA,EAAIE,eAAeD,GAAM,OAC9BH,EAAOG,GAAOD,EAAIC,EACpB,CACF,IACOH,CACT,CAkXeK,CAAOhG,EAAUmE,GAAW,CAAC,GAGxCI,EAAW0B,QAGX1B,EAAWgB,SAGXzF,EAAOoG,iBAAiB,SAAUd,GAAe,GAC7CxE,EAASN,QACXR,EAAOoG,iBAAiB,SAAUV,GAAe,GAS9CjB,CACT,CAOF,CArcW4B,CAAQvG,EAChB,UAFM,SAEN,uBCXDwG,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaE,QAGrB,IAAIC,EAASN,EAAyBE,GAAY,CAGjDG,QAAS,CAAC,GAOX,OAHAE,EAAoBL,GAAU1B,KAAK8B,EAAOD,QAASC,EAAQA,EAAOD,QAASJ,GAGpEK,EAAOD,OACf,CCrBAJ,EAAoBO,EAAKF,IACxB,IAAIG,EAASH,GAAUA,EAAOI,WAC7B,IAAOJ,EAAiB,QACxB,IAAM,EAEP,OADAL,EAAoBU,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,CAAM,ECLdR,EAAoBU,EAAI,CAACN,EAASQ,KACjC,IAAI,IAAInB,KAAOmB,EACXZ,EAAoBa,EAAED,EAAYnB,KAASO,EAAoBa,EAAET,EAASX,IAC5EqB,OAAOC,eAAeX,EAASX,EAAK,CAAEuB,YAAY,EAAMC,IAAKL,EAAWnB,IAE1E,ECNDO,EAAoBxG,EAAI,WACvB,GAA0B,iBAAf0H,WAAyB,OAAOA,WAC3C,IACC,OAAOxH,MAAQ,IAAIyH,SAAS,cAAb,EAChB,CAAE,MAAOC,GACR,GAAsB,iBAAX3H,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCAxBuG,EAAoBa,EAAI,CAACrB,EAAK6B,IAAUP,OAAOzC,UAAUqB,eAAenB,KAAKiB,EAAK6B,4CCK9EC,EAAY,KACZC,EAAS,KACTC,EAAgBzF,SAASC,gBAAgByF,UAC7C,MAAMC,EAAmB,GA8EzB,SAASC,IACP,MAAMC,EAAeC,aAAaC,QAAQ,UAAY,OAZxD,IAAkBC,EACH,WADGA,EAaItI,OAAOuI,WAAW,gCAAgCC,QAI/C,SAAjBL,EACO,QACgB,SAAhBA,EACA,OAEA,OAIU,SAAjBA,EACO,OACgB,QAAhBA,EACA,QAEA,SA9BoB,SAATG,GAA4B,SAATA,IACzCG,QAAQC,MAAM,2BAA2BJ,yBACzCA,EAAO,QAGThG,SAASS,KAAK4F,QAAQC,MAAQN,EAC9BF,aAAaS,QAAQ,QAASP,GAC9BG,QAAQK,IAAI,cAAcR,UA0B5B,CAkDA,SAASnC,KART,WAEE,MAAM4C,EAAUzG,SAAS0G,uBAAuB,gBAChDrE,MAAMsE,KAAKF,GAASlE,SAASqE,IAC3BA,EAAI9C,iBAAiB,QAAS8B,EAAe,GAEjD,CAGEiB,GA9CF,WAEE,IAAIC,EAA6B,EAC7BC,GAAU,EAEdrJ,OAAOoG,iBAAiB,UAAU,SAAUuB,GAC1CyB,EAA6BpJ,OAAOsJ,QAE/BD,IACHrJ,OAAOwF,uBAAsB,WAzDnC,IAAuB+D,GAxDvB,SAAgCA,GAC9B,MAAMC,EAAY7G,KAAK8G,MAAM3B,EAAO7F,wBAAwBQ,KAE5DgG,QAAQK,IAAI,cAAcU,KACT,GAAbA,GAAkBD,GAAaC,EACjC1B,EAAOjE,UAAUM,IAAI,YAErB2D,EAAOjE,UAAUC,OAAO,WAE5B,EAgDE4F,CADqBH,EA0DDH,GAvGtB,SAAmCG,GAC7BA,EAAYtB,EACd3F,SAASC,gBAAgBsB,UAAUC,OAAO,oBAEtCyF,EAAYxB,EACdzF,SAASC,gBAAgBsB,UAAUM,IAAI,oBAC9BoF,EAAYxB,GACrBzF,SAASC,gBAAgBsB,UAAUC,OAAO,oBAG9CiE,EAAgBwB,CAClB,CAoCEI,CAA0BJ,GAlC5B,SAA6BA,GACT,OAAd1B,IAKa,GAAb0B,EACF1B,EAAU+B,SAAS,EAAG,GAGtBjH,KAAKC,KAAK2G,IACV5G,KAAK8G,MAAMnH,SAASC,gBAAgBS,aAAehD,OAAOqC,aAE1DwF,EAAU+B,SAAS,EAAG/B,EAAU7E,cAGhBV,SAASuH,cAAc,mBAc3C,CAKEC,CAAoBP,GAwDdF,GAAU,CACZ,IAEAA,GAAU,EAEd,IACArJ,OAAO+J,QACT,CA6BEC,GA1BkB,OAAdnC,GAKJ,IAAI,IAAJ,CAAY,cAAe,CACzBrH,QAAQ,EACRyJ,WAAW,EACX9J,SAAU,iBACVI,OAAQ,KACN,IAAI2J,EAAMhI,WAAWiI,iBAAiB7H,SAASC,iBAAiB6H,UAChE,OAAOtC,EAAO7F,wBAAwBoI,OAAS,IAAMH,EAAM,CAAC,GAiBlE,CAcA5H,SAAS8D,iBAAiB,oBAT1B,WACE9D,SAASS,KAAKW,WAAWG,UAAUC,OAAO,SAE1CgE,EAASxF,SAASuH,cAAc,UAChChC,EAAYvF,SAASuH,cAAc,eAEnC1D,GACF","sources":["webpack:///./src/furo/assets/scripts/gumshoe-patched.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./src/furo/assets/scripts/furo.js"],"sourcesContent":["/*!\n * gumshoejs v5.1.2 (patched by @pradyunsg)\n * A simple, framework-agnostic scrollspy script.\n * (c) 2019 Chris Ferdinandi\n * MIT License\n * http://github.com/cferdinandi/gumshoe\n */\n\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], function () {\n return factory(root);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(root);\n } else {\n root.Gumshoe = factory(root);\n }\n})(\n typeof global !== \"undefined\"\n ? global\n : typeof window !== \"undefined\"\n ? window\n : this,\n function (window) {\n \"use strict\";\n\n //\n // Defaults\n //\n\n var defaults = {\n // Active classes\n navClass: \"active\",\n contentClass: \"active\",\n\n // Nested navigation\n nested: false,\n nestedClass: \"active\",\n\n // Offset & reflow\n offset: 0,\n reflow: false,\n\n // Event support\n events: true,\n };\n\n //\n // Methods\n //\n\n /**\n * Merge two or more objects together.\n * @param {Object} objects The objects to merge together\n * @returns {Object} Merged values of defaults and options\n */\n var extend = function () {\n var merged = {};\n Array.prototype.forEach.call(arguments, function (obj) {\n for (var key in obj) {\n if (!obj.hasOwnProperty(key)) return;\n merged[key] = obj[key];\n }\n });\n return merged;\n };\n\n /**\n * Emit a custom event\n * @param {String} type The event type\n * @param {Node} elem The element to attach the event to\n * @param {Object} detail Any details to pass along with the event\n */\n var emitEvent = function (type, elem, detail) {\n // Make sure events are enabled\n if (!detail.settings.events) return;\n\n // Create a new event\n var event = new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n detail: detail,\n });\n\n // Dispatch the event\n elem.dispatchEvent(event);\n };\n\n /**\n * Get an element's distance from the top of the Document.\n * @param {Node} elem The element\n * @return {Number} Distance from the top in pixels\n */\n var getOffsetTop = function (elem) {\n var location = 0;\n if (elem.offsetParent) {\n while (elem) {\n location += elem.offsetTop;\n elem = elem.offsetParent;\n }\n }\n return location >= 0 ? location : 0;\n };\n\n /**\n * Sort content from first to last in the DOM\n * @param {Array} contents The content areas\n */\n var sortContents = function (contents) {\n if (contents) {\n contents.sort(function (item1, item2) {\n var offset1 = getOffsetTop(item1.content);\n var offset2 = getOffsetTop(item2.content);\n if (offset1 < offset2) return -1;\n return 1;\n });\n }\n };\n\n /**\n * Get the offset to use for calculating position\n * @param {Object} settings The settings for this instantiation\n * @return {Float} The number of pixels to offset the calculations\n */\n var getOffset = function (settings) {\n // if the offset is a function run it\n if (typeof settings.offset === \"function\") {\n return parseFloat(settings.offset());\n }\n\n // Otherwise, return it as-is\n return parseFloat(settings.offset);\n };\n\n /**\n * Get the document element's height\n * @private\n * @returns {Number}\n */\n var getDocumentHeight = function () {\n return Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.offsetHeight,\n document.body.clientHeight,\n document.documentElement.clientHeight,\n );\n };\n\n /**\n * Determine if an element is in view\n * @param {Node} elem The element\n * @param {Object} settings The settings for this instantiation\n * @param {Boolean} bottom If true, check if element is above bottom of viewport instead\n * @return {Boolean} Returns true if element is in the viewport\n */\n var isInView = function (elem, settings, bottom) {\n var bounds = elem.getBoundingClientRect();\n var offset = getOffset(settings);\n if (bottom) {\n return (\n parseInt(bounds.bottom, 10) <\n (window.innerHeight || document.documentElement.clientHeight)\n );\n }\n return parseInt(bounds.top, 10) <= offset;\n };\n\n /**\n * Check if at the bottom of the viewport\n * @return {Boolean} If true, page is at the bottom of the viewport\n */\n var isAtBottom = function () {\n if (\n Math.ceil(window.innerHeight + window.pageYOffset) >=\n getDocumentHeight()\n )\n return true;\n return false;\n };\n\n /**\n * Check if the last item should be used (even if not at the top of the page)\n * @param {Object} item The last item\n * @param {Object} settings The settings for this instantiation\n * @return {Boolean} If true, use the last item\n */\n var useLastItem = function (item, settings) {\n if (isAtBottom() && isInView(item.content, settings, true)) return true;\n return false;\n };\n\n /**\n * Get the active content\n * @param {Array} contents The content areas\n * @param {Object} settings The settings for this instantiation\n * @return {Object} The content area and matching navigation link\n */\n var getActive = function (contents, settings) {\n var last = contents[contents.length - 1];\n if (useLastItem(last, settings)) return last;\n for (var i = contents.length - 1; i >= 0; i--) {\n if (isInView(contents[i].content, settings)) return contents[i];\n }\n };\n\n /**\n * Deactivate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var deactivateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested || !nav.parentNode) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Remove the active class\n li.classList.remove(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n deactivateNested(li, settings);\n };\n\n /**\n * Deactivate a nav and content area\n * @param {Object} items The nav item and content to deactivate\n * @param {Object} settings The settings for this instantiation\n */\n var deactivate = function (items, settings) {\n // Make sure there are items to deactivate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Remove the active class from the nav and content\n li.classList.remove(settings.navClass);\n items.content.classList.remove(settings.contentClass);\n\n // Deactivate any parent navs in a nested navigation\n deactivateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeDeactivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Activate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var activateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Add the active class\n li.classList.add(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n activateNested(li, settings);\n };\n\n /**\n * Activate a nav and content area\n * @param {Object} items The nav item and content to activate\n * @param {Object} settings The settings for this instantiation\n */\n var activate = function (items, settings) {\n // Make sure there are items to activate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Add the active class to the nav and content\n li.classList.add(settings.navClass);\n items.content.classList.add(settings.contentClass);\n\n // Activate any parent navs in a nested navigation\n activateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeActivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Create the Constructor object\n * @param {String} selector The selector to use for navigation items\n * @param {Object} options User options and settings\n */\n var Constructor = function (selector, options) {\n //\n // Variables\n //\n\n var publicAPIs = {};\n var navItems, contents, current, timeout, settings;\n\n //\n // Methods\n //\n\n /**\n * Set variables from DOM elements\n */\n publicAPIs.setup = function () {\n // Get all nav items\n navItems = document.querySelectorAll(selector);\n\n // Create contents array\n contents = [];\n\n // Loop through each item, get it's matching content, and push to the array\n Array.prototype.forEach.call(navItems, function (item) {\n // Get the content for the nav item\n var content = document.getElementById(\n decodeURIComponent(item.hash.substr(1)),\n );\n if (!content) return;\n\n // Push to the contents array\n contents.push({\n nav: item,\n content: content,\n });\n });\n\n // Sort contents by the order they appear in the DOM\n sortContents(contents);\n };\n\n /**\n * Detect which content is currently active\n */\n publicAPIs.detect = function () {\n // Get the active content\n var active = getActive(contents, settings);\n\n // if there's no active content, deactivate and bail\n if (!active) {\n if (current) {\n deactivate(current, settings);\n current = null;\n }\n return;\n }\n\n // If the active content is the one currently active, do nothing\n if (current && active.content === current.content) return;\n\n // Deactivate the current content and activate the new content\n deactivate(current, settings);\n activate(active, settings);\n\n // Update the currently active content\n current = active;\n };\n\n /**\n * Detect the active content on scroll\n * Debounced for performance\n */\n var scrollHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(publicAPIs.detect);\n };\n\n /**\n * Update content sorting on resize\n * Debounced for performance\n */\n var resizeHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(function () {\n sortContents(contents);\n publicAPIs.detect();\n });\n };\n\n /**\n * Destroy the current instantiation\n */\n publicAPIs.destroy = function () {\n // Undo DOM changes\n if (current) {\n deactivate(current, settings);\n }\n\n // Remove event listeners\n window.removeEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.removeEventListener(\"resize\", resizeHandler, false);\n }\n\n // Reset variables\n contents = null;\n navItems = null;\n current = null;\n timeout = null;\n settings = null;\n };\n\n /**\n * Initialize the current instantiation\n */\n var init = function () {\n // Merge user options into defaults\n settings = extend(defaults, options || {});\n\n // Setup variables based on the current DOM\n publicAPIs.setup();\n\n // Find the currently active content\n publicAPIs.detect();\n\n // Setup event listeners\n window.addEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.addEventListener(\"resize\", resizeHandler, false);\n }\n };\n\n //\n // Initialize and return the public APIs\n //\n\n init();\n return publicAPIs;\n };\n\n //\n // Return the Constructor\n //\n\n return Constructor;\n },\n);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import Gumshoe from \"./gumshoe-patched.js\";\n\n////////////////////////////////////////////////////////////////////////////////\n// Scroll Handling\n////////////////////////////////////////////////////////////////////////////////\nvar tocScroll = null;\nvar header = null;\nvar lastScrollTop = document.documentElement.scrollTop;\nconst GO_TO_TOP_OFFSET = 64;\n\nfunction scrollHandlerForHeader(positionY) {\n const headerTop = Math.floor(header.getBoundingClientRect().top);\n\n console.log(`headerTop: ${headerTop}`);\n if (headerTop == 0 && positionY != headerTop) {\n header.classList.add(\"scrolled\");\n } else {\n header.classList.remove(\"scrolled\");\n }\n}\n\nfunction scrollHandlerForBackToTop(positionY) {\n if (positionY < GO_TO_TOP_OFFSET) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n } else {\n if (positionY < lastScrollTop) {\n document.documentElement.classList.add(\"show-back-to-top\");\n } else if (positionY > lastScrollTop) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n }\n }\n lastScrollTop = positionY;\n}\n\nfunction scrollHandlerForTOC(positionY) {\n if (tocScroll === null) {\n return;\n }\n\n // top of page.\n if (positionY == 0) {\n tocScroll.scrollTo(0, 0);\n } else if (\n // bottom of page.\n Math.ceil(positionY) >=\n Math.floor(document.documentElement.scrollHeight - window.innerHeight)\n ) {\n tocScroll.scrollTo(0, tocScroll.scrollHeight);\n } else {\n // somewhere in the middle.\n const current = document.querySelector(\".scroll-current\");\n if (current == null) {\n return;\n }\n\n // https://github.com/pypa/pip/issues/9159 This breaks scroll behaviours.\n // // scroll the currently \"active\" heading in toc, into view.\n // const rect = current.getBoundingClientRect();\n // if (0 > rect.top) {\n // current.scrollIntoView(true); // the argument is \"alignTop\"\n // } else if (rect.bottom > window.innerHeight) {\n // current.scrollIntoView(false);\n // }\n }\n}\n\nfunction scrollHandler(positionY) {\n scrollHandlerForHeader(positionY);\n scrollHandlerForBackToTop(positionY);\n scrollHandlerForTOC(positionY);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Theme Toggle\n////////////////////////////////////////////////////////////////////////////////\nfunction setTheme(mode) {\n if (mode !== \"light\" && mode !== \"dark\" && mode !== \"auto\") {\n console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);\n mode = \"auto\";\n }\n\n document.body.dataset.theme = mode;\n localStorage.setItem(\"theme\", mode);\n console.log(`Changed to ${mode} mode.`);\n}\n\nfunction cycleThemeOnce() {\n const currentTheme = localStorage.getItem(\"theme\") || \"auto\";\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\n if (prefersDark) {\n // Auto (dark) -> Light -> Dark\n if (currentTheme === \"auto\") {\n setTheme(\"light\");\n } else if (currentTheme == \"light\") {\n setTheme(\"dark\");\n } else {\n setTheme(\"auto\");\n }\n } else {\n // Auto (light) -> Dark -> Light\n if (currentTheme === \"auto\") {\n setTheme(\"dark\");\n } else if (currentTheme == \"dark\") {\n setTheme(\"light\");\n } else {\n setTheme(\"auto\");\n }\n }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Setup\n////////////////////////////////////////////////////////////////////////////////\nfunction setupScrollHandler() {\n // Taken from https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event\n let last_known_scroll_position = 0;\n let ticking = false;\n\n window.addEventListener(\"scroll\", function (e) {\n last_known_scroll_position = window.scrollY;\n\n if (!ticking) {\n window.requestAnimationFrame(function () {\n scrollHandler(last_known_scroll_position);\n ticking = false;\n });\n\n ticking = true;\n }\n });\n window.scroll();\n}\n\nfunction setupScrollSpy() {\n if (tocScroll === null) {\n return;\n }\n\n // Scrollspy -- highlight table on contents, based on scroll\n new Gumshoe(\".toc-tree a\", {\n reflow: true,\n recursive: true,\n navClass: \"scroll-current\",\n offset: () => {\n let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return header.getBoundingClientRect().height + 2.5 * rem + 1;\n },\n });\n}\n\nfunction setupTheme() {\n // Attach event handlers for toggling themes\n const buttons = document.getElementsByClassName(\"theme-toggle\");\n Array.from(buttons).forEach((btn) => {\n btn.addEventListener(\"click\", cycleThemeOnce);\n });\n}\n\nfunction setup() {\n setupTheme();\n setupScrollHandler();\n setupScrollSpy();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Main entrypoint\n////////////////////////////////////////////////////////////////////////////////\nfunction main() {\n document.body.parentNode.classList.remove(\"no-js\");\n\n header = document.querySelector(\"header\");\n tocScroll = document.querySelector(\".toc-scroll\");\n\n setup();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", main);\n"],"names":["root","g","window","this","defaults","navClass","contentClass","nested","nestedClass","offset","reflow","events","emitEvent","type","elem","detail","settings","event","CustomEvent","bubbles","cancelable","dispatchEvent","getOffsetTop","location","offsetParent","offsetTop","sortContents","contents","sort","item1","item2","content","isInView","bottom","bounds","getBoundingClientRect","parseFloat","getOffset","parseInt","innerHeight","document","documentElement","clientHeight","top","isAtBottom","Math","ceil","pageYOffset","max","body","scrollHeight","offsetHeight","getActive","last","length","item","useLastItem","i","deactivateNested","nav","parentNode","li","closest","classList","remove","deactivate","items","link","activateNested","add","selector","options","navItems","current","timeout","publicAPIs","querySelectorAll","Array","prototype","forEach","call","getElementById","decodeURIComponent","hash","substr","push","active","activate","scrollHandler","cancelAnimationFrame","requestAnimationFrame","detect","resizeHandler","destroy","removeEventListener","merged","arguments","obj","key","hasOwnProperty","extend","setup","addEventListener","factory","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","n","getter","__esModule","d","a","definition","o","Object","defineProperty","enumerable","get","globalThis","Function","e","prop","tocScroll","header","lastScrollTop","scrollTop","GO_TO_TOP_OFFSET","cycleThemeOnce","currentTheme","localStorage","getItem","mode","matchMedia","matches","console","error","dataset","theme","setItem","log","buttons","getElementsByClassName","from","btn","setupTheme","last_known_scroll_position","ticking","scrollY","positionY","headerTop","floor","scrollHandlerForHeader","scrollHandlerForBackToTop","scrollTo","querySelector","scrollHandlerForTOC","scroll","setupScrollHandler","recursive","rem","getComputedStyle","fontSize","height"],"sourceRoot":""} \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 00000000..2c774d17 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/skeleton.css b/_static/skeleton.css new file mode 100644 index 00000000..467c878c --- /dev/null +++ b/_static/skeleton.css @@ -0,0 +1,296 @@ +/* Some sane resets. */ +html { + height: 100%; +} + +body { + margin: 0; + min-height: 100%; +} + +/* All the flexbox magic! */ +body, +.sb-announcement, +.sb-content, +.sb-main, +.sb-container, +.sb-container__inner, +.sb-article-container, +.sb-footer-content, +.sb-header, +.sb-header-secondary, +.sb-footer { + display: flex; +} + +/* These order things vertically */ +body, +.sb-main, +.sb-article-container { + flex-direction: column; +} + +/* Put elements in the center */ +.sb-header, +.sb-header-secondary, +.sb-container, +.sb-content, +.sb-footer, +.sb-footer-content { + justify-content: center; +} +/* Put elements at the ends */ +.sb-article-container { + justify-content: space-between; +} + +/* These elements grow. */ +.sb-main, +.sb-content, +.sb-container, +article { + flex-grow: 1; +} + +/* Because padding making this wider is not fun */ +article { + box-sizing: border-box; +} + +/* The announcements element should never be wider than the page. */ +.sb-announcement { + max-width: 100%; +} + +.sb-sidebar-primary, +.sb-sidebar-secondary { + flex-shrink: 0; + width: 17rem; +} + +.sb-announcement__inner { + justify-content: center; + + box-sizing: border-box; + height: 3rem; + + overflow-x: auto; + white-space: nowrap; +} + +/* Sidebars, with checkbox-based toggle */ +.sb-sidebar-primary, +.sb-sidebar-secondary { + position: fixed; + height: 100%; + top: 0; +} + +.sb-sidebar-primary { + left: -17rem; + transition: left 250ms ease-in-out; +} +.sb-sidebar-secondary { + right: -17rem; + transition: right 250ms ease-in-out; +} + +.sb-sidebar-toggle { + display: none; +} +.sb-sidebar-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + + transition: width 0ms ease 250ms, height 0ms ease 250ms, opacity 250ms ease; + + opacity: 0; + background-color: rgba(0, 0, 0, 0.54); +} + +#sb-sidebar-toggle--primary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--primary"], +#sb-sidebar-toggle--secondary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--secondary"] { + width: 100%; + height: 100%; + opacity: 1; + transition: width 0ms ease, height 0ms ease, opacity 250ms ease; +} + +#sb-sidebar-toggle--primary:checked ~ .sb-container .sb-sidebar-primary { + left: 0; +} +#sb-sidebar-toggle--secondary:checked ~ .sb-container .sb-sidebar-secondary { + right: 0; +} + +/* Full-width mode */ +.drop-secondary-sidebar-for-full-width-content + .hide-when-secondary-sidebar-shown { + display: none !important; +} +.drop-secondary-sidebar-for-full-width-content .sb-sidebar-secondary { + display: none !important; +} + +/* Mobile views */ +.sb-page-width { + width: 100%; +} + +.sb-article-container, +.sb-footer-content__inner, +.drop-secondary-sidebar-for-full-width-content .sb-article, +.drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 100vw; +} + +.sb-article, +.match-content-width { + padding: 0 1rem; + box-sizing: border-box; +} + +@media (min-width: 32rem) { + .sb-article, + .match-content-width { + padding: 0 2rem; + } +} + +/* Tablet views */ +@media (min-width: 42rem) { + .sb-article-container { + width: auto; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 42rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 46rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 46rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 50rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 50rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Tablet views */ +@media (min-width: 59rem) { + .sb-sidebar-secondary { + position: static; + } + .hide-when-secondary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 63rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 67rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Desktop views */ +@media (min-width: 76rem) { + .sb-sidebar-primary { + position: static; + } + .hide-when-primary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} + +/* Full desktop views */ +@media (min-width: 80rem) { + .sb-article, + .match-content-width { + width: 46rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } +} + +@media (min-width: 84rem) { + .sb-article, + .match-content-width { + width: 50rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } +} + +@media (min-width: 88rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-page-width { + width: 88rem; + } +} diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/styles/furo-extensions.css b/_static/styles/furo-extensions.css new file mode 100644 index 00000000..82295876 --- /dev/null +++ b/_static/styles/furo-extensions.css @@ -0,0 +1,2 @@ +#furo-sidebar-ad-placement{padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)}#furo-sidebar-ad-placement .ethical-sidebar{background:var(--color-background-secondary);border:none;box-shadow:none}#furo-sidebar-ad-placement .ethical-sidebar:hover{background:var(--color-background-hover)}#furo-sidebar-ad-placement .ethical-sidebar a{color:var(--color-foreground-primary)}#furo-sidebar-ad-placement .ethical-callout a{color:var(--color-foreground-secondary)!important}#furo-readthedocs-versions{background:transparent;display:block;position:static;width:100%}#furo-readthedocs-versions .rst-versions{background:#1a1c1e}#furo-readthedocs-versions .rst-current-version{background:var(--color-sidebar-item-background);cursor:unset}#furo-readthedocs-versions .rst-current-version:hover{background:var(--color-sidebar-item-background)}#furo-readthedocs-versions .rst-current-version .fa-book{color:var(--color-foreground-primary)}#furo-readthedocs-versions>.rst-other-versions{padding:0}#furo-readthedocs-versions>.rst-other-versions small{opacity:1}#furo-readthedocs-versions .injected .rst-versions{position:unset}#furo-readthedocs-versions:focus-within,#furo-readthedocs-versions:hover{box-shadow:0 0 0 1px var(--color-sidebar-background-border)}#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:hover .rst-current-version{background:#1a1c1e;font-size:inherit;height:auto;line-height:inherit;padding:12px;text-align:right}#furo-readthedocs-versions:focus-within .rst-current-version .fa-book,#furo-readthedocs-versions:hover .rst-current-version .fa-book{color:#fff;float:left}#furo-readthedocs-versions:focus-within .fa-caret-down,#furo-readthedocs-versions:hover .fa-caret-down{display:none}#furo-readthedocs-versions:focus-within .injected,#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:focus-within .rst-other-versions,#furo-readthedocs-versions:hover .injected,#furo-readthedocs-versions:hover .rst-current-version,#furo-readthedocs-versions:hover .rst-other-versions{display:block}#furo-readthedocs-versions:focus-within>.rst-current-version,#furo-readthedocs-versions:hover>.rst-current-version{display:none}.highlight:hover button.copybtn{color:var(--color-code-foreground)}.highlight button.copybtn{align-items:center;background-color:var(--color-code-background);border:none;color:var(--color-background-item);cursor:pointer;height:1.25em;right:.5rem;top:.625rem;transition:color .3s,opacity .3s;width:1.25em}.highlight button.copybtn:hover{background-color:var(--color-code-background);color:var(--color-brand-content)}.highlight button.copybtn:after{background-color:transparent;color:var(--color-code-foreground);display:none}.highlight button.copybtn.success{color:#22863a;transition:color 0ms}.highlight button.copybtn.success:after{display:block}.highlight button.copybtn svg{padding:0}body{--sd-color-primary:var(--color-brand-primary);--sd-color-primary-highlight:var(--color-brand-content);--sd-color-primary-text:var(--color-background-primary);--sd-color-shadow:rgba(0,0,0,.05);--sd-color-card-border:var(--color-card-border);--sd-color-card-border-hover:var(--color-brand-content);--sd-color-card-background:var(--color-card-background);--sd-color-card-text:var(--color-foreground-primary);--sd-color-card-header:var(--color-card-marginals-background);--sd-color-card-footer:var(--color-card-marginals-background);--sd-color-tabs-label-active:var(--color-brand-content);--sd-color-tabs-label-hover:var(--color-foreground-muted);--sd-color-tabs-label-inactive:var(--color-foreground-muted);--sd-color-tabs-underline-active:var(--color-brand-content);--sd-color-tabs-underline-hover:var(--color-foreground-border);--sd-color-tabs-underline-inactive:var(--color-background-border);--sd-color-tabs-overline:var(--color-background-border);--sd-color-tabs-underline:var(--color-background-border)}.sd-tab-content{box-shadow:0 -2px var(--sd-color-tabs-overline),0 1px var(--sd-color-tabs-underline)}.sd-card{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)}.sd-shadow-sm{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-md{box-shadow:0 .3rem .75rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-lg{box-shadow:0 .6rem 1.5rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-card-hover:hover{transform:none}.sd-cards-carousel{gap:.25rem;padding:.25rem}body{--tabs--label-text:var(--color-foreground-muted);--tabs--label-text--hover:var(--color-foreground-muted);--tabs--label-text--active:var(--color-brand-content);--tabs--label-text--active--hover:var(--color-brand-content);--tabs--label-background:transparent;--tabs--label-background--hover:transparent;--tabs--label-background--active:transparent;--tabs--label-background--active--hover:transparent;--tabs--padding-x:0.25em;--tabs--margin-x:1em;--tabs--border:var(--color-background-border);--tabs--label-border:transparent;--tabs--label-border--hover:var(--color-foreground-muted);--tabs--label-border--active:var(--color-brand-content);--tabs--label-border--active--hover:var(--color-brand-content)}[role=main] .container{max-width:none;padding-left:0;padding-right:0}.shadow.docutils{border:none;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)!important}.sphinx-bs .card{background-color:var(--color-background-secondary);color:var(--color-foreground)} +/*# sourceMappingURL=furo-extensions.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo-extensions.css.map b/_static/styles/furo-extensions.css.map new file mode 100644 index 00000000..c26eac7f --- /dev/null +++ b/_static/styles/furo-extensions.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo-extensions.css","mappings":"AAGA,2BACE,oFACA,4CAKE,6CAHA,YACA,eAEA,CACA,kDACE,yCAEF,8CACE,sCAEJ,8CACE,kDAEJ,2BAGE,uBACA,cAHA,gBACA,UAEA,CAGA,yCACE,mBAEF,gDAEE,gDADA,YACA,CACA,sDACE,gDACF,yDACE,sCAEJ,+CACE,UACA,qDACE,UAGF,mDACE,eAEJ,yEAEE,4DAEA,mHASE,mBAPA,kBAEA,YADA,oBAGA,aADA,gBAIA,CAEA,qIAEE,WADA,UACA,CAEJ,uGACE,aAEF,iUAGE,cAEF,mHACE,aC1EJ,gCACE,mCAEF,0BAEE,mBAUA,8CACA,YAFA,mCAKA,eAZA,cAIA,YADA,YAYA,iCAdA,YAcA,CAEA,gCAEE,8CADA,gCACA,CAEF,gCAGE,6BADA,mCADA,YAEA,CAEF,kCAEE,cADA,oBACA,CACA,wCACE,cAEJ,8BACE,UCzCN,KAEE,6CAA8C,CAC9C,uDAAwD,CACxD,uDAAwD,CAGxD,iCAAsC,CAGtC,+CAAgD,CAChD,uDAAwD,CACxD,uDAAwD,CACxD,oDAAqD,CACrD,6DAA8D,CAC9D,6DAA8D,CAG9D,uDAAwD,CACxD,yDAA0D,CAC1D,4DAA6D,CAC7D,2DAA4D,CAC5D,8DAA+D,CAC/D,iEAAkE,CAClE,uDAAwD,CACxD,wDAAyD,CAG3D,gBACE,qFAGF,SACE,6EAEF,cACE,uFAEF,cACE,uFAEF,cACE,uFAGF,qBACE,eAEF,mBACE,WACA,eChDF,KACE,gDAAiD,CACjD,uDAAwD,CACxD,qDAAsD,CACtD,4DAA6D,CAC7D,oCAAqC,CACrC,2CAA4C,CAC5C,4CAA6C,CAC7C,mDAAoD,CACpD,wBAAyB,CACzB,oBAAqB,CACrB,6CAA8C,CAC9C,gCAAiC,CACjC,yDAA0D,CAC1D,uDAAwD,CACxD,8DAA+D,CCbjE,uBACE,eACA,eACA,gBAGF,iBACE,YACA,+EAGF,iBACE,mDACA","sources":["webpack:///./src/furo/assets/styles/extensions/_readthedocs.sass","webpack:///./src/furo/assets/styles/extensions/_copybutton.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-design.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-inline-tabs.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-panels.sass"],"sourcesContent":["// This file contains the styles used for tweaking how ReadTheDoc's embedded\n// contents would show up inside the theme.\n\n#furo-sidebar-ad-placement\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n .ethical-sidebar\n // Remove the border and box-shadow.\n border: none\n box-shadow: none\n // Manage the background colors.\n background: var(--color-background-secondary)\n &:hover\n background: var(--color-background-hover)\n // Ensure the text is legible.\n a\n color: var(--color-foreground-primary)\n\n .ethical-callout a\n color: var(--color-foreground-secondary) !important\n\n#furo-readthedocs-versions\n position: static\n width: 100%\n background: transparent\n display: block\n\n // Make the background color fit with the theme's aesthetic.\n .rst-versions\n background: rgb(26, 28, 30)\n\n .rst-current-version\n cursor: unset\n background: var(--color-sidebar-item-background)\n &:hover\n background: var(--color-sidebar-item-background)\n .fa-book\n color: var(--color-foreground-primary)\n\n > .rst-other-versions\n padding: 0\n small\n opacity: 1\n\n .injected\n .rst-versions\n position: unset\n\n &:hover,\n &:focus-within\n box-shadow: 0 0 0 1px var(--color-sidebar-background-border)\n\n .rst-current-version\n // Undo the tweaks done in RTD's CSS\n font-size: inherit\n line-height: inherit\n height: auto\n text-align: right\n padding: 12px\n\n // Match the rest of the body\n background: #1a1c1e\n\n .fa-book\n float: left\n color: white\n\n .fa-caret-down\n display: none\n\n .rst-current-version,\n .rst-other-versions,\n .injected\n display: block\n\n > .rst-current-version\n display: none\n",".highlight\n &:hover button.copybtn\n color: var(--color-code-foreground)\n\n button.copybtn\n // Align things correctly\n align-items: center\n\n height: 1.25em\n width: 1.25em\n\n top: 0.625rem // $code-spacing-vertical\n right: 0.5rem\n\n // Make it look better\n color: var(--color-background-item)\n background-color: var(--color-code-background)\n border: none\n\n // Change to cursor to make it obvious that you can click on it\n cursor: pointer\n\n // Transition smoothly, for aesthetics\n transition: color 300ms, opacity 300ms\n\n &:hover\n color: var(--color-brand-content)\n background-color: var(--color-code-background)\n\n &::after\n display: none\n color: var(--color-code-foreground)\n background-color: transparent\n\n &.success\n transition: color 0ms\n color: #22863a\n &::after\n display: block\n\n svg\n padding: 0\n","body\n // Colors\n --sd-color-primary: var(--color-brand-primary)\n --sd-color-primary-highlight: var(--color-brand-content)\n --sd-color-primary-text: var(--color-background-primary)\n\n // Shadows\n --sd-color-shadow: rgba(0, 0, 0, 0.05)\n\n // Cards\n --sd-color-card-border: var(--color-card-border)\n --sd-color-card-border-hover: var(--color-brand-content)\n --sd-color-card-background: var(--color-card-background)\n --sd-color-card-text: var(--color-foreground-primary)\n --sd-color-card-header: var(--color-card-marginals-background)\n --sd-color-card-footer: var(--color-card-marginals-background)\n\n // Tabs\n --sd-color-tabs-label-active: var(--color-brand-content)\n --sd-color-tabs-label-hover: var(--color-foreground-muted)\n --sd-color-tabs-label-inactive: var(--color-foreground-muted)\n --sd-color-tabs-underline-active: var(--color-brand-content)\n --sd-color-tabs-underline-hover: var(--color-foreground-border)\n --sd-color-tabs-underline-inactive: var(--color-background-border)\n --sd-color-tabs-overline: var(--color-background-border)\n --sd-color-tabs-underline: var(--color-background-border)\n\n// Tabs\n.sd-tab-content\n box-shadow: 0 -2px var(--sd-color-tabs-overline), 0 1px var(--sd-color-tabs-underline)\n\n// Shadows\n.sd-card // Have a shadow by default\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n.sd-shadow-sm\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-md\n box-shadow: 0 0.3rem 0.75rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-lg\n box-shadow: 0 0.6rem 1.5rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Cards\n.sd-card-hover:hover // Don't change scale on hover\n transform: none\n\n.sd-cards-carousel // Have a bit of gap in the carousel by default\n gap: 0.25rem\n padding: 0.25rem\n","// This file contains styles to tweak sphinx-inline-tabs to work well with Furo.\n\nbody\n --tabs--label-text: var(--color-foreground-muted)\n --tabs--label-text--hover: var(--color-foreground-muted)\n --tabs--label-text--active: var(--color-brand-content)\n --tabs--label-text--active--hover: var(--color-brand-content)\n --tabs--label-background: transparent\n --tabs--label-background--hover: transparent\n --tabs--label-background--active: transparent\n --tabs--label-background--active--hover: transparent\n --tabs--padding-x: 0.25em\n --tabs--margin-x: 1em\n --tabs--border: var(--color-background-border)\n --tabs--label-border: transparent\n --tabs--label-border--hover: var(--color-foreground-muted)\n --tabs--label-border--active: var(--color-brand-content)\n --tabs--label-border--active--hover: var(--color-brand-content)\n","// This file contains styles to tweak sphinx-panels to work well with Furo.\n\n// sphinx-panels includes Bootstrap 4, which uses .container which can conflict\n// with docutils' `.. container::` directive.\n[role=\"main\"] .container\n max-width: initial\n padding-left: initial\n padding-right: initial\n\n// Make the panels look nicer!\n.shadow.docutils\n border: none\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Make panel colors respond to dark mode\n.sphinx-bs .card\n background-color: var(--color-background-secondary)\n color: var(--color-foreground)\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/_static/styles/furo.css b/_static/styles/furo.css new file mode 100644 index 00000000..05a56b17 --- /dev/null +++ b/_static/styles/furo.css @@ -0,0 +1,2 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,p,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;background:var(--color-background-primary);border:0!important;color:var(--color-foreground-primary);white-space:nowrap!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-stack--headings:var(--font-stack);--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8,');--icon-pencil:url('data:image/svg+xml;charset=utf-8,');--icon-abstract:url('data:image/svg+xml;charset=utf-8,');--icon-info:url('data:image/svg+xml;charset=utf-8,');--icon-flame:url('data:image/svg+xml;charset=utf-8,');--icon-question:url('data:image/svg+xml;charset=utf-8,');--icon-warning:url('data:image/svg+xml;charset=utf-8,');--icon-failure:url('data:image/svg+xml;charset=utf-8,');--icon-spark:url('data:image/svg+xml;charset=utf-8,');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#6b6f76;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#0a4bff;--color-brand-content:#2757dd;--color-brand-visited:#872ee0;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-api-added:#21632c;--color-api-added-border:#38a84d;--color-api-changed:#046172;--color-api-changed-border:#06a1bc;--color-api-deprecated:#605706;--color-api-deprecated-border:#f0d90f;--color-api-removed:#b30000;--color-api-removed-border:#ff5c5c;--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link--hover:var(--color-brand-content);--color-link-underline--hover:var(--color-foreground-border);--color-link--visited:var(--color-brand-visited);--color-link-underline--visited:var(--color-background-border);--color-link--visited--hover:var(--color-brand-visited);--color-link-underline--visited--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#cfd0d0;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:block}@media(prefers-color-scheme:dark){body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-dark{display:block}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:none}}body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-family:var(--font-stack--headings);font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:visited{color:var(--color-link--visited);text-decoration-color:var(--color-link-underline--visited)}a:visited:hover{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link:hover:visited{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{height:100%}.skip-to-content,body,html{background:var(--color-background-primary);color:var(--color-foreground-primary)}.skip-to-content{border-radius:1rem;left:.25rem;padding:1rem;position:fixed;top:.25rem;transform:translateY(-200%);transition:transform .3s ease-in-out;z-index:40}.skip-to-content:focus-within{transform:translateY(0)}article{background:var(--color-content-background);color:var(--color-content-foreground);overflow-wrap:break-word}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{display:flex}.theme-toggle{background:transparent;border:none;cursor:pointer;display:flex;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1.25rem;width:1.25rem}.theme-toggle-header{align-items:center;display:flex;justify-content:center}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1.5rem;width:1.5rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg,.content-icon-container .view-this-page svg{color:inherit;height:1.25rem;width:1.25rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{height:1rem;width:1rem;fill:currentColor;display:inline-block}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.content{margin-left:auto;margin-right:auto;padding:0 1em}}@media(max-width:63em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.theme-toggle-header,.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.5rem;width:1.5rem}:target{scroll-margin-top:calc(var(--header-height) + 2.5rem)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}}@media(max-width:48em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){article[role=main] aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}.admonition p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}.admonition p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:4.25rem}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}div.deprecated,div.versionadded,div.versionchanged,div.versionremoved{border-left:.1875rem solid;border-radius:.125rem;padding-left:.75rem}div.deprecated p,div.versionadded p,div.versionchanged p,div.versionremoved p{margin-bottom:.125rem;margin-top:.125rem}div.versionadded{border-color:var(--color-api-added-border)}div.versionadded .versionmodified{color:var(--color-api-added)}div.versionchanged{border-color:var(--color-api-changed-border)}div.versionchanged .versionmodified{color:var(--color-api-changed)}div.deprecated{border-color:var(--color-api-deprecated-border)}div.deprecated .versionmodified{color:var(--color-api-deprecated)}div.versionremoved{border-color:var(--color-api-removed-border)}div.versionremoved .versionmodified{color:var(--color-api-removed)}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);padding:.1em .2em}pre.literal-block .sig-inline,pre.literal-block code.literal{font-size:inherit;padding:0}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>:not(span),div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}[role=main] .table-wrapper.container{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:2.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(2.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(2.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover);color:var(--color-sidebar-link-text)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23607D8B' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Cpath stroke='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree a.reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling. Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right} +/*# sourceMappingURL=furo.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo.css.map b/_static/styles/furo.css.map new file mode 100644 index 00000000..3ecc3715 --- /dev/null +++ b/_static/styles/furo.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo.css","mappings":"AAAA,2EAA2E,CAU3E,KACE,gBAAiB,CACjB,6BACF,CASA,KACE,QACF,CAMA,KACE,aACF,CAOA,GACE,aAAc,CACd,cACF,CAUA,GACE,sBAAuB,CACvB,QAAS,CACT,gBACF,CAOA,IACE,+BAAiC,CACjC,aACF,CASA,EACE,4BACF,CAOA,YACE,kBAAmB,CACnB,yBAA0B,CAC1B,gCACF,CAMA,SAEE,kBACF,CAOA,cAGE,+BAAiC,CACjC,aACF,CAeA,QAEE,aAAc,CACd,aAAc,CACd,iBAAkB,CAClB,uBACF,CAEA,IACE,aACF,CAEA,IACE,SACF,CASA,IACE,iBACF,CAUA,sCAKE,mBAAoB,CACpB,cAAe,CACf,gBAAiB,CACjB,QACF,CAOA,aAEE,gBACF,CAOA,cAEE,mBACF,CAMA,gDAIE,yBACF,CAMA,wHAIE,iBAAkB,CAClB,SACF,CAMA,4GAIE,6BACF,CAMA,SACE,0BACF,CASA,OACE,qBAAsB,CACtB,aAAc,CACd,aAAc,CACd,cAAe,CACf,SAAU,CACV,kBACF,CAMA,SACE,uBACF,CAMA,SACE,aACF,CAOA,6BAEE,qBAAsB,CACtB,SACF,CAMA,kFAEE,WACF,CAOA,cACE,4BAA6B,CAC7B,mBACF,CAMA,yCACE,uBACF,CAOA,6BACE,yBAA0B,CAC1B,YACF,CASA,QACE,aACF,CAMA,QACE,iBACF,CAiBA,kBACE,YACF,CCvVA,aAcE,kEACE,uBAOF,WACE,iDAMF,kCACE,wBAEF,qCAEE,uBADA,uBACA,CAEF,SACE,wBAtBA,CCpBJ,iBAGE,qBAEA,sBACA,0BAFA,oBAHA,4BACA,oBAKA,6BAIA,2CAFA,mBACA,sCAFA,4BAGA,CAEF,gBACE,aCTF,KCGE,mHAEA,wGAEA,wCAAyC,CAEzC,wBAAyB,CACzB,wBAAyB,CACzB,4BAA6B,CAC7B,yBAA0B,CAC1B,2BAA4B,CAG5B,sDAAuD,CACvD,gDAAiD,CACjD,wDAAyD,CAGzD,0CAA2C,CAC3C,gDAAiD,CACjD,gDAAiD,CAKjD,gCAAiC,CACjC,sCAAuC,CAGvC,2CAA4C,CAG5C,uCAAwC,CCjCxC,+FAGA,uBAAwB,CAGxB,iCAAkC,CAClC,kCAAmC,CAEnC,+BAAgC,CAChC,sCAAuC,CACvC,sCAAuC,CACvC,qGAIA,mDAAoD,CAEpD,mCAAoC,CACpC,8CAA+C,CAC/C,gDAAiD,CACjD,kCAAmC,CACnC,6DAA8D,CAG9D,6BAA8B,CAC9B,6BAA8B,CAC9B,+BAAgC,CAChC,kCAAmC,CACnC,kCAAmC,CCPjC,+jBCYA,iqCAZF,iaCVA,8KAOA,4SAWA,4SAUA,0CACA,gEAGA,0CAGA,gEAGA,yCACA,+DAIA,4CACA,kEAGA,wCAUA,8DACA,uCAGA,4DACA,sCACA,2DAGA,4CACA,kEACA,uCAGA,6DACA,2GAGA,sHAEA,yFAEA,+CACA,+EAGA,4MAOA,gCACA,sHAIA,kCACA,uEACA,gEACA,4DACA,kEAGA,2DACA,sDACA,0CACA,8CACA,wGAGA,0BACA,iCAGA,+DACA,+BACA,sCACA,+DAEA,kGACA,oCACA,yDACA,sCL7HF,kCAEA,sDAIA,0CK2HE,kEAIA,oDACA,sDAGA,oCACA,oEAEA,0DACA,qDAIA,oDACA,6DAIA,iEAIA,2DAIA,2DAGA,4DACA,gEAIA,gEAEA,gFAEA,oNASA,qDLxKE,gFAGE,4DAIF,oEKkHF,yEAEA,6DAGA,0DAEA,uDACA,qDACA,wDAIA,6DAIA,yDACA,2DAIA,uCAGA,wCACA,sDAGA,+CAGA,6DAEA,iDACA,+DAEA,wDAEA,sEAMA,0DACA,sBACA,mEL9JI,wEAEA,iCACE,+BAMN,wEAGA,iCACE,kFAEA,uEAIF,gEACE,8BAGF,qEMvDA,sCAKA,wFAKA,iCAIA,0BAWA,iCACA,4BACA,mCAGA,+BAEA,sCACA,4BAEA,mCAEA,sCAKA,sDAIA,gCAEA,gEAQF,wCAME,sBACA,kCAKA,uBAEA,gEAIA,2BAIA,mCAEA,qCACA,iCAGE,+BACA,wEAEE,iCACA,kFAGF,6BACA,0CACF,kCAEE,8BACE,8BACA,qEAEE,sCACA,wFCnFN,iCAGF,2DAEE,4BACA,oCAGA,mIAGA,4HACE,gEAMJ,+CAGE,sBACA,yCAEF,uBAEE,sEAKA,gDACA,kEAGA,iFAGE,YAGF,EACA,4HAQF,mBACE,6BACA,mBACA,wCACA,wCACA,2CAIA,eAGA,mBAKE,mBAGA,CAJA,uCACA,iBAFF,gBACE,CAKE,mBACA,mBAGJ,oBAIF,+BAGE,kDACA,OADA,kBAGA,CAFA,gBAEA,mBACA,oBAEA,sCACA,OAGF,cAHE,WAGF,GAEE,oBACA,CAHF,gBAGE,CC9Gc,YDiHd,+CAIF,SAEE,CAPF,UACE,wBAMA,4BAEA,GAGA,uBACA,CAJA,yBAGA,CACA,iDAKA,2CAGA,2DAQA,iBACA,uCAGA,kEAKE,SAKJ,8BACE,yDACA,2BAEA,oBACA,8BAEA,yDAEE,4BAEJ,uCACE,CACA,iEAGA,CAEA,wCACE,uBACA,kDAEA,0DAEE,CAJF,oBAIE,0GAWN,aACE,CAHA,YAGA,4HASA,+CAGF,sBACE,WACA,WAQA,4BAFF,0CAEE,CARA,qCAsBA,CAdA,iBAEA,kBACE,aADF,4BACE,WAMF,2BAGF,qCAEE,CAXE,UAWF,+BAGA,uBAEA,SAEA,0CAIE,CANF,qCAEA,CAIE,2DACE,gBAIN,+CAIA,CAEA,kDAKE,CAPF,8BAEA,CAOE,YACA,CAjBI,2BAGN,CAHM,WAcJ,UAGA,CAEA,2GAIF,iCAGE,8BAIA,qBACA,oBACF,uBAOI,0CAIA,CATF,6DAKE,CALF,sBASE,qCAKF,CACE,cACA,CAFF,sBAEE,CACA,+BAEA,qBAEE,WAKN,aACE,sCAGA,mBAEA,6BAMA,kCACA,CAJA,sBACA,aAEA,CAJA,eACA,MAIA,2FAEA,UAGA,YACA,sBACE,8BAEA,CALF,aACA,WAIE,OACA,oBAEF,uBACE,WAEF,YAFE,UAEF,eAgBA,kBACE,CAhBA,qDAQF,qCAGF,CAGI,YACF,CAJF,2BAGI,CAEA,eACA,qBAGA,mEAEA,qBACA,8BAIA,kBADF,kBACE,yBAEJ,oCAGI,qDAIJ,+BAGI,oCAEA,+CAQF,4CACE,yBACF,2BAOE,sBACA,CAHA,WACA,CAFF,cACE,CAJA,YAGF,CAEE,SAEA,mBAGA,kDAEE,CAJF,cAEA,cAEE,sBAEA,mBADA,YACA,uBACA,mDACE,CADF,YACE,iDAEA,uCAEN,+DAOE,mBADF,sBACE,mBAGF,aACE,sCAIA,aADF,WACE,CAKF,SACE,CAHJ,kBAEE,CAJE,gBAEJ,CAHI,iBAMA,yFAKA,aACA,eACA,cElbJ,iBAEE,aADA,iBACA,6BAEA,kCAEA,SACA,UAIA,gCACA,CALA,SAEA,SAEA,CAJA,0EAEA,CAFA,OAKA,CAGA,mDACE,iBAGF,gCACE,CADF,UACE,aAEJ,iCAEE,CAFF,UAEE,wCAEA,WACA,WADA,UACA,CACA,4CAGA,MACA,CADA,KACA,wCACA,UAGA,CAJA,UAIA,6DAUA,0CACE,CAFF,mBAEE,wEACA,CAVA,YACA,CAMF,mBAJE,OAOA,gBAJJ,gCACE,CANE,cACA,CAHA,oBACA,CAGA,QAGJ,CAII,0BACA,CADA,UACA,wCAEJ,kBACE,0DACA,gCACE,kBACA,CADA,YACA,oEACA,2CAMF,mDAII,CALN,YACE,CANE,cAKJ,CACE,iBAII,kEACA,yCACE,kDACA,yDACE,+CACA,uBANN,CAMM,+BANN,uCACE,qDACA,4BAEE,mBADA,0CACA,CADA,qBACA,0DACE,wCACA,sGALJ,oCACA,sBACE,kBAFF,UAEE,2CACA,wFACE,cACA,kEANN,uBACE,iDACA,CADA,UACA,0DACE,wDAEE,iEACA,qEANN,sCACE,CAGE,iBAHF,gBAGE,qBACE,CAJJ,uBACA,gDACE,wDACA,6DAHF,2CACA,CADA,gBACA,eACE,CAGE,sBANN,8BACE,CAII,iBAFF,4DACA,WACE,YADF,uCACE,6EACA,2BANN,8CACE,kDACA,0CACE,8BACA,yFACE,sBACA,sFALJ,mEACA,sBACE,kEACA,6EACE,uCACA,kEALJ,qGAEE,kEACA,6EACE,uCACA,kEALJ,8CACA,uDACE,sEACA,2EACE,sCACA,iEALJ,mGACA,qCACE,oDACA,0DACE,6GACA,gDAGR,yDCrEA,sEACE,CACA,6GACE,gEACF,iGAIF,wFACE,qDAGA,mGAEE,2CAEF,4FACE,gCACF,wGACE,8DAEE,6FAIA,iJAKN,6GACE,gDAKF,yDACA,qCAGA,6BACA,kBACA,qDAKA,oCAEA,+DAGA,2CAGE,oDAIA,oEAEE,qBAGJ,wDAEE,uCAEF,kEAGA,8CAEA,uDAIF,gEAIE,6BACA,gEAIA,+CACE,0EAIF,sDAEE,+DAGF,sCACA,8BACE,oCAEJ,wBACE,4FAEE,gBAEJ,yGAGI,kBAGJ,CCnHE,2MCFF,oBAGE,wGAKA,iCACE,CADF,wBACE,8GAQA,mBCjBJ,2GAIE,mBACA,6HAMA,YACE,mIAYF,eACA,CAHF,YAGE,4FAGE,8BAKF,uBAkBE,sCACA,CADA,qBAbA,wCAIA,CALF,8BACE,CADF,gBAKE,wCACA,CAOA,kDACA,CACA,kCAKF,6BAGA,4CACE,kDACA,eAGF,cACE,aACA,iBACA,yBACA,8BACA,WAGJ,2BACE,cAGA,+BACA,CAHA,eAGA,wCACA,YACA,iBACA,uEAGA,0BACA,2CAEA,8EAGI,qBACA,CAFF,kBAEE,kBAGN,0CAGE,mCAGA,4BAIA,gEACE,qCACA,8BAEA,gBACA,+CACA,iCAEF,iCAEE,gEACA,qCAGF,8BAEE,+BAIA,yCAEE,qBADA,gBACA,yBAKF,eACA,CAFF,YACE,CACA,iBACA,qDAEA,mDCvIJ,2FAOE,iCACA,CAEA,eACA,CAHA,kBAEA,CAFA,wBAGA,8BACA,eACE,CAFF,YAEE,0BACA,8CAGA,oBACE,oCAGA,kBACE,8DAEA,iBAEN,UACE,8BAIJ,+CAEE,qDAEF,kDAIE,YAEF,CAFE,YAEF,CCpCE,mFADA,kBAKE,CAJF,IAGA,aACE,mCAGA,iDACE,+BAEJ,wBAEE,mBAMA,6CAEF,CAJE,mBAEA,CAEF,kCAGE,CARF,kBACE,CAHA,eAUA,YACA,mBACA,CADA,UACA,wCC9BF,oBDkCE,wBCnCJ,uCACE,+BACA,+DACA,sBAGA,qBCDA,6CAIE,CAPF,uBAGA,CDGE,oBACF,yDAEE,CCDE,2CAGF,CAJA,kCACE,CDJJ,YACE,CAIA,eCTF,CDKE,uBCMA,gCACE,YAEF,oCAEE,wBACA,0BAIF,iBAEA,cADF,UACE,uBAEA,iCAEA,wCAEA,6CAMA,CAYF,gCATI,4BASJ,CAZE,mCAEE,iCAUJ,4BAGE,4DADA,+BACA,CAHF,qBAGE,sCACE,OAEF,iBAHA,SAGA,iHACE,2DAKF,CANA,8EAMA,uSAEE,kBAEF,+FACE,yCCjEJ,WACA,yBAGA,uBACA,gBAEA,uCAIA,CAJA,iCAIA,uCAGA,UACE,gBACA,qBAEA,0CClBJ,gBACE,KAGF,qBACE,YAGF,CAHE,cAGF,gCAEE,mBACA,iEAEA,oCACA,wCAEA,sBACA,WAEA,CAFA,YAEA,8EAEA,mCAFA,iBAEA,6BAIA,wEAKA,sDAIE,CARF,mDAIA,CAIE,cAEF,8CAIA,oBAFE,iBAEF,8CAGE,eAEF,CAFE,YAEF,OAEE,kBAGJ,CAJI,eACA,CAFF,mBAKF,yCCjDE,oBACA,CAFA,iBAEA,uCAKE,iBACA,qCAGA,mBCZJ,CDWI,gBCXJ,6BAEE,eACA,sBAGA,eAEA,sBACA,oDACA,iGAMA,gBAFE,YAEF,8FAME,iJCnBF,YACA,gNAWE,gDAEF,iSAaE,kBACE,gHAKF,oCACE,eACF,CADE,UACF,8CACE,gDACF,wCACE,oBCxCJ,oBAEF,6BACE,QACE,kDAGF,yBACE,kDAmBA,kDAEF,CAhBA,+CAaA,CAbA,oBAaA,0FACE,CADF,gGAfF,cACE,gBACA,CAaA,0BAGA,mQACE,gBAGF,oMACE,iBACA,CAFF,eACE,CADF,gBAEE,aAGJ,iCAEE,CAFF,wCAEE,wBAUE,+VAIE,uEAHA,2BAGA,wXAKJ,iDAGF,CARM,+CACE,iDAIN,CALI,gBAQN,mHACE,gBAGF,2DACE,0EAOA,0EAGF,gBAEE,6DC/EA,kDACA,gCACA,qDAGA,qBACA,qDCFA,cACA,eAEA,yBAGF,sBAEE,iBACA,sNAWA,iBACE,kBACA,wRAgBA,kBAEA,iOAgBA,uCACE,uEAEA,kBAEF,qUAuBE,iDAIJ,CACA,geCxFF,4BAEE,CAQA,6JACA,iDAIA,sEAGA,mDAOF,iDAGE,4DAIA,8CACA,qDAEE,eAFF,cAEE,oBAEF,uBAFE,kCAGA,eACA,iBACA,mBAIA,mDACA,CAHA,uCAEA,CAJA,0CACA,CAIA,gBAJA,gBACA,oBADA,gBAIA,wBAEJ,gBAGE,6BACA,YAHA,iBAGA,gCACA,iEAEA,6CACA,sDACA,0BADA,wBACA,0BACA,oIAIA,mBAFA,YAEA,qBACA,0CAIE,uBAEF,CAHA,yBACE,CAEF,iDACE,mFAKJ,oCACE,CANE,aAKJ,CACE,qEAIA,YAFA,WAEA,CAHA,aACA,CAEA,gBACE,4BACA,sBADA,aACA,gCAMF,oCACA,yDACA,2CAEA,qBAGE,kBAEA,CACA,mCAIF,CARE,YACA,CAOF,iCAEE,CAPA,oBACA,CAQA,oBACE,uDAEJ,sDAGA,CAHA,cAGA,0BACE,oDAIA,oCACA,4BACA,sBAGA,cAEA,oFAGA,sBAEA,yDACE,CAIF,iBAJE,wBAIF,6CAHE,6CAKA,eACA,aACA,CADA,cACA,yCAGJ,kBACE,CAKA,iDAEA,CARF,aACE,4CAGA,kBAIA,wEAGA,wDAGA,kCAOA,iDAGA,CAPF,WAEE,sCAEA,CAJF,2CACE,CAMA,qCACA,+BARF,kBACE,qCAOA,iBAsBA,sBACE,CAvBF,WAKA,CACE,0DAIF,CALA,uDACE,CANF,sBAqBA,4CACA,CALA,gRAIA,YAEE,6CAEN,mCAEE,+CASA,6EAIA,4BChNA,SDmNA,qFCnNA,gDACA,sCAGA,qCACA,sDACA,CAKA,kDAGA,CARA,0CAQA,kBAGA,YACA,sBACA,iBAFA,gBADF,YACE,CAHA,SAKA,kBAEA,SAFA,iBAEA,uEAGA,CAEE,6CAFF,oCAgBI,CAdF,yBACE,qBACF,CAGF,oBACE,CAIF,WACE,CALA,2CAGA,uBACF,CACE,mFAGE,CALF,qBAEA,UAGE,gCAIF,sDAEA,CALE,oCAKF,yCC7CJ,oCACE,CD+CA,yXAQE,sCCrDJ,wCAGA,oCACE","sources":["webpack:///./node_modules/normalize.css/normalize.css","webpack:///./src/furo/assets/styles/base/_print.sass","webpack:///./src/furo/assets/styles/base/_screen-readers.sass","webpack:///./src/furo/assets/styles/base/_theme.sass","webpack:///./src/furo/assets/styles/variables/_fonts.scss","webpack:///./src/furo/assets/styles/variables/_spacing.scss","webpack:///./src/furo/assets/styles/variables/_icons.scss","webpack:///./src/furo/assets/styles/variables/_admonitions.scss","webpack:///./src/furo/assets/styles/variables/_colors.scss","webpack:///./src/furo/assets/styles/base/_typography.sass","webpack:///./src/furo/assets/styles/_scaffold.sass","webpack:///./src/furo/assets/styles/variables/_layout.scss","webpack:///./src/furo/assets/styles/content/_admonitions.sass","webpack:///./src/furo/assets/styles/content/_api.sass","webpack:///./src/furo/assets/styles/content/_blocks.sass","webpack:///./src/furo/assets/styles/content/_captions.sass","webpack:///./src/furo/assets/styles/content/_code.sass","webpack:///./src/furo/assets/styles/content/_footnotes.sass","webpack:///./src/furo/assets/styles/content/_images.sass","webpack:///./src/furo/assets/styles/content/_indexes.sass","webpack:///./src/furo/assets/styles/content/_lists.sass","webpack:///./src/furo/assets/styles/content/_math.sass","webpack:///./src/furo/assets/styles/content/_misc.sass","webpack:///./src/furo/assets/styles/content/_rubrics.sass","webpack:///./src/furo/assets/styles/content/_sidebar.sass","webpack:///./src/furo/assets/styles/content/_tables.sass","webpack:///./src/furo/assets/styles/content/_target.sass","webpack:///./src/furo/assets/styles/content/_gui-labels.sass","webpack:///./src/furo/assets/styles/components/_footer.sass","webpack:///./src/furo/assets/styles/components/_sidebar.sass","webpack:///./src/furo/assets/styles/components/_table_of_contents.sass","webpack:///./src/furo/assets/styles/_shame.sass"],"sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","// This file contains styles for managing print media.\n\n////////////////////////////////////////////////////////////////////////////////\n// Hide elements not relevant to print media.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Hide icon container.\n .content-icon-container\n display: none !important\n\n // Hide showing header links if hovering over when printing.\n .headerlink\n display: none !important\n\n // Hide mobile header.\n .mobile-header\n display: none !important\n\n // Hide navigation links.\n .related-pages\n display: none !important\n\n////////////////////////////////////////////////////////////////////////////////\n// Tweaks related to decolorization.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Apply a border around code which no longer have a color background.\n .highlight\n border: 0.1pt solid var(--color-foreground-border)\n\n////////////////////////////////////////////////////////////////////////////////\n// Avoid page break in some relevant cases.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n ul, ol, dl, a, table, pre, blockquote, p\n page-break-inside: avoid\n\n h1, h2, h3, h4, h5, h6, img, figure, caption\n page-break-inside: avoid\n page-break-after: avoid\n\n ul, ol, dl\n page-break-before: avoid\n",".visually-hidden\n position: absolute !important\n width: 1px !important\n height: 1px !important\n padding: 0 !important\n margin: -1px !important\n overflow: hidden !important\n clip: rect(0,0,0,0) !important\n white-space: nowrap !important\n border: 0 !important\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n:-moz-focusring\n outline: auto\n","// This file serves as the \"skeleton\" of the theming logic.\n//\n// This contains the bulk of the logic for handling dark mode, color scheme\n// toggling and the handling of color-scheme-specific hiding of elements.\n\nbody\n @include fonts\n @include spacing\n @include icons\n @include admonitions\n @include default-admonition(#651fff, \"abstract\")\n @include default-topic(#14B8A6, \"pencil\")\n\n @include colors\n\n.only-light\n display: block !important\nhtml body .only-dark\n display: none !important\n\n// Ignore dark-mode hints if print media.\n@media not print\n // Enable dark-mode, if requested.\n body[data-theme=\"dark\"]\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n // Enable dark mode, unless explicitly told to avoid.\n @media (prefers-color-scheme: dark)\n body:not([data-theme=\"light\"])\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n//\n// Theme toggle presentation\n//\nbody[data-theme=\"auto\"]\n .theme-toggle svg.theme-icon-when-auto-light\n display: block\n\n @media (prefers-color-scheme: dark)\n .theme-toggle svg.theme-icon-when-auto-dark\n display: block\n .theme-toggle svg.theme-icon-when-auto-light\n display: none\n\nbody[data-theme=\"dark\"]\n .theme-toggle svg.theme-icon-when-dark\n display: block\n\nbody[data-theme=\"light\"]\n .theme-toggle svg.theme-icon-when-light\n display: block\n","// Fonts used by this theme.\n//\n// There are basically two things here -- using the system font stack and\n// defining sizes for various elements in %ages. We could have also used `em`\n// but %age is easier to reason about for me.\n\n@mixin fonts {\n // These are adapted from https://systemfontstack.com/\n --font-stack: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --font-stack--monospace: \"SFMono-Regular\", Menlo, Consolas, Monaco,\n Liberation Mono, Lucida Console, monospace;\n --font-stack--headings: var(--font-stack);\n\n --font-size--normal: 100%;\n --font-size--small: 87.5%;\n --font-size--small--2: 81.25%;\n --font-size--small--3: 75%;\n --font-size--small--4: 62.5%;\n\n // Sidebar\n --sidebar-caption-font-size: var(--font-size--small--2);\n --sidebar-item-font-size: var(--font-size--small);\n --sidebar-search-input-font-size: var(--font-size--small);\n\n // Table of Contents\n --toc-font-size: var(--font-size--small--3);\n --toc-font-size--mobile: var(--font-size--normal);\n --toc-title-font-size: var(--font-size--small--4);\n\n // Admonitions\n //\n // These aren't defined in terms of %ages, since nesting these is permitted.\n --admonition-font-size: 0.8125rem;\n --admonition-title-font-size: 0.8125rem;\n\n // Code\n --code-font-size: var(--font-size--small--2);\n\n // API\n --api-font-size: var(--font-size--small);\n}\n","// Spacing for various elements on the page\n//\n// If the user wants to tweak things in a certain way, they are permitted to.\n// They also have to deal with the consequences though!\n\n@mixin spacing {\n // Header!\n --header-height: calc(\n var(--sidebar-item-line-height) + 4 * #{var(--sidebar-item-spacing-vertical)}\n );\n --header-padding: 0.5rem;\n\n // Sidebar\n --sidebar-tree-space-above: 1.5rem;\n --sidebar-caption-space-above: 1rem;\n\n --sidebar-item-line-height: 1rem;\n --sidebar-item-spacing-vertical: 0.5rem;\n --sidebar-item-spacing-horizontal: 1rem;\n --sidebar-item-height: calc(\n var(--sidebar-item-line-height) + 2 *#{var(--sidebar-item-spacing-vertical)}\n );\n\n --sidebar-expander-width: var(--sidebar-item-height); // be square\n\n --sidebar-search-space-above: 0.5rem;\n --sidebar-search-input-spacing-vertical: 0.5rem;\n --sidebar-search-input-spacing-horizontal: 0.5rem;\n --sidebar-search-input-height: 1rem;\n --sidebar-search-icon-size: var(--sidebar-search-input-height);\n\n // Table of Contents\n --toc-title-padding: 0.25rem 0;\n --toc-spacing-vertical: 1.5rem;\n --toc-spacing-horizontal: 1.5rem;\n --toc-item-spacing-vertical: 0.4rem;\n --toc-item-spacing-horizontal: 1rem;\n}\n","// Expose theme icons as CSS variables.\n\n$icons: (\n // Adapted from tabler-icons\n // url: https://tablericons.com/\n \"search\":\n url('data:image/svg+xml;charset=utf-8,'),\n // Factored out from mkdocs-material on 24-Aug-2020.\n // url: https://squidfunk.github.io/mkdocs-material/reference/admonitions/\n \"pencil\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"abstract\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"info\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"flame\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"question\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"warning\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"failure\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"spark\":\n url('data:image/svg+xml;charset=utf-8,')\n);\n\n@mixin icons {\n @each $name, $glyph in $icons {\n --icon-#{$name}: #{$glyph};\n }\n}\n","// Admonitions\n\n// Structure of these is:\n// admonition-class: color \"icon-name\";\n//\n// The colors are translated into CSS variables below. The icons are\n// used directly in the main declarations to set the `mask-image` in\n// the title.\n\n// prettier-ignore\n$admonitions: (\n // Each of these has an reST directives for it.\n \"caution\": #ff9100 \"spark\",\n \"warning\": #ff9100 \"warning\",\n \"danger\": #ff5252 \"spark\",\n \"attention\": #ff5252 \"warning\",\n \"error\": #ff5252 \"failure\",\n \"hint\": #00c852 \"question\",\n \"tip\": #00c852 \"info\",\n \"important\": #00bfa5 \"flame\",\n \"note\": #00b0ff \"pencil\",\n \"seealso\": #448aff \"info\",\n \"admonition-todo\": #808080 \"pencil\"\n);\n\n@mixin default-admonition($color, $icon-name) {\n --color-admonition-title: #{$color};\n --color-admonition-title-background: #{rgba($color, 0.2)};\n\n --icon-admonition-default: var(--icon-#{$icon-name});\n}\n\n@mixin default-topic($color, $icon-name) {\n --color-topic-title: #{$color};\n --color-topic-title-background: #{rgba($color, 0.2)};\n\n --icon-topic-default: var(--icon-#{$icon-name});\n}\n\n@mixin admonitions {\n @each $name, $values in $admonitions {\n --color-admonition-title--#{$name}: #{nth($values, 1)};\n --color-admonition-title-background--#{$name}: #{rgba(\n nth($values, 1),\n 0.2\n )};\n }\n}\n","// Colors used throughout this theme.\n//\n// The aim is to give the user more control. Thus, instead of hard-coding colors\n// in various parts of the stylesheet, the approach taken is to define all\n// colors as CSS variables and reusing them in all the places.\n//\n// `colors-dark` depends on `colors` being included at a lower specificity.\n\n@mixin colors {\n --color-problematic: #b30000;\n\n // Base Colors\n --color-foreground-primary: black; // for main text and headings\n --color-foreground-secondary: #5a5c63; // for secondary text\n --color-foreground-muted: #6b6f76; // for muted text\n --color-foreground-border: #878787; // for content borders\n\n --color-background-primary: white; // for content\n --color-background-secondary: #f8f9fb; // for navigation + ToC\n --color-background-hover: #efeff4ff; // for navigation-item hover\n --color-background-hover--transparent: #efeff400;\n --color-background-border: #eeebee; // for UI borders\n --color-background-item: #ccc; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #0a4bff;\n --color-brand-content: #2757dd;\n --color-brand-visited: #872ee0;\n\n // API documentation\n --color-api-background: var(--color-background-hover--transparent);\n --color-api-background-hover: var(--color-background-hover);\n --color-api-overall: var(--color-foreground-secondary);\n --color-api-name: var(--color-problematic);\n --color-api-pre-name: var(--color-problematic);\n --color-api-paren: var(--color-foreground-secondary);\n --color-api-keyword: var(--color-foreground-primary);\n\n --color-api-added: #21632c;\n --color-api-added-border: #38a84d;\n --color-api-changed: #046172;\n --color-api-changed-border: #06a1bc;\n --color-api-deprecated: #605706;\n --color-api-deprecated-border: #f0d90f;\n --color-api-removed: #b30000;\n --color-api-removed-border: #ff5c5c;\n\n --color-highlight-on-target: #ffffcc;\n\n // Inline code background\n --color-inline-code-background: var(--color-background-secondary);\n\n // Highlighted text (search)\n --color-highlighted-background: #ddeeff;\n --color-highlighted-text: var(--color-foreground-primary);\n\n // GUI Labels\n --color-guilabel-background: #ddeeff80;\n --color-guilabel-border: #bedaf580;\n --color-guilabel-text: var(--color-foreground-primary);\n\n // Admonitions!\n --color-admonition-background: transparent;\n\n //////////////////////////////////////////////////////////////////////////////\n // Everything below this should be one of:\n // - var(...)\n // - *-gradient(...)\n // - special literal values (eg: transparent, none)\n //////////////////////////////////////////////////////////////////////////////\n\n // Tables\n --color-table-header-background: var(--color-background-secondary);\n --color-table-border: var(--color-background-border);\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: transparent;\n --color-card-marginals-background: var(--color-background-secondary);\n\n // Header\n --color-header-background: var(--color-background-primary);\n --color-header-border: var(--color-background-border);\n --color-header-text: var(--color-foreground-primary);\n\n // Sidebar (left)\n --color-sidebar-background: var(--color-background-secondary);\n --color-sidebar-background-border: var(--color-background-border);\n\n --color-sidebar-brand-text: var(--color-foreground-primary);\n --color-sidebar-caption-text: var(--color-foreground-muted);\n --color-sidebar-link-text: var(--color-foreground-secondary);\n --color-sidebar-link-text--top-level: var(--color-brand-primary);\n\n --color-sidebar-item-background: var(--color-sidebar-background);\n --color-sidebar-item-background--current: var(\n --color-sidebar-item-background\n );\n --color-sidebar-item-background--hover: linear-gradient(\n 90deg,\n var(--color-background-hover--transparent) 0%,\n var(--color-background-hover) var(--sidebar-item-spacing-horizontal),\n var(--color-background-hover) 100%\n );\n\n --color-sidebar-item-expander-background: transparent;\n --color-sidebar-item-expander-background--hover: var(\n --color-background-hover\n );\n\n --color-sidebar-search-text: var(--color-foreground-primary);\n --color-sidebar-search-background: var(--color-background-secondary);\n --color-sidebar-search-background--focus: var(--color-background-primary);\n --color-sidebar-search-border: var(--color-background-border);\n --color-sidebar-search-icon: var(--color-foreground-muted);\n\n // Table of Contents (right)\n --color-toc-background: var(--color-background-primary);\n --color-toc-title-text: var(--color-foreground-muted);\n --color-toc-item-text: var(--color-foreground-secondary);\n --color-toc-item-text--hover: var(--color-foreground-primary);\n --color-toc-item-text--active: var(--color-brand-primary);\n\n // Actual page contents\n --color-content-foreground: var(--color-foreground-primary);\n --color-content-background: transparent;\n\n // Links\n --color-link: var(--color-brand-content);\n --color-link-underline: var(--color-background-border);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline--hover: var(--color-foreground-border);\n\n --color-link--visited: var(--color-brand-visited);\n --color-link-underline--visited: var(--color-background-border);\n --color-link--visited--hover: var(--color-brand-visited);\n --color-link-underline--visited--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #cfd0d0; // for main text and headings\n --color-foreground-secondary: #9ca0a5; // for secondary text\n --color-foreground-muted: #81868d; // for muted text\n --color-foreground-border: #666666; // for content borders\n\n --color-background-primary: #131416; // for content\n --color-background-secondary: #1a1c1e; // for navigation + ToC\n --color-background-hover: #1e2124ff; // for navigation-item hover\n --color-background-hover--transparent: #1e212400;\n --color-background-border: #303335; // for UI borders\n --color-background-item: #444; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #3d94ff;\n --color-brand-content: #5ca5ff;\n --color-brand-visited: #b27aeb;\n\n // Highlighted text (search)\n --color-highlighted-background: #083563;\n\n // GUI Labels\n --color-guilabel-background: #08356380;\n --color-guilabel-border: #13395f80;\n\n // API documentation\n --color-api-keyword: var(--color-foreground-secondary);\n --color-highlight-on-target: #333300;\n\n --color-api-added: #3db854;\n --color-api-added-border: #267334;\n --color-api-changed: #09b0ce;\n --color-api-changed-border: #056d80;\n --color-api-deprecated: #b1a10b;\n --color-api-deprecated-border: #6e6407;\n --color-api-removed: #ff7575;\n --color-api-removed-border: #b03b3b;\n\n // Admonitions\n --color-admonition-background: #18181a;\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: #18181a;\n --color-card-marginals-background: var(--color-background-hover);\n}\n","// This file contains the styling for making the content throughout the page,\n// including fonts, paragraphs, headings and spacing among these elements.\n\nbody\n font-family: var(--font-stack)\npre,\ncode,\nkbd,\nsamp\n font-family: var(--font-stack--monospace)\n\n// Make fonts look slightly nicer.\nbody\n -webkit-font-smoothing: antialiased\n -moz-osx-font-smoothing: grayscale\n\n// Line height from Bootstrap 4.1\narticle\n line-height: 1.5\n\n//\n// Headings\n//\nh1,\nh2,\nh3,\nh4,\nh5,\nh6\n line-height: 1.25\n font-family: var(--font-stack--headings)\n font-weight: bold\n\n border-radius: 0.5rem\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n margin-left: -0.5rem\n margin-right: -0.5rem\n padding-left: 0.5rem\n padding-right: 0.5rem\n\n + p\n margin-top: 0\n\nh1\n font-size: 2.5em\n margin-top: 1.75rem\n margin-bottom: 1rem\nh2\n font-size: 2em\n margin-top: 1.75rem\nh3\n font-size: 1.5em\nh4\n font-size: 1.25em\nh5\n font-size: 1.125em\nh6\n font-size: 1em\n\nsmall\n opacity: 75%\n font-size: 80%\n\n// Paragraph\np\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n\n// Horizontal rules\nhr.docutils\n height: 1px\n padding: 0\n margin: 2rem 0\n background-color: var(--color-background-border)\n border: 0\n\n.centered\n text-align: center\n\n// Links\na\n text-decoration: underline\n\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n &:visited\n color: var(--color-link--visited)\n text-decoration-color: var(--color-link-underline--visited)\n &:hover\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &.muted-link\n color: inherit\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &:visited\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\n","// This file contains the styles for the overall layouting of the documentation\n// skeleton, including the responsive changes as well as sidebar toggles.\n//\n// This is implemented as a mobile-last design, which isn't ideal, but it is\n// reasonably good-enough and I got pretty tired by the time I'd finished this\n// to move the rules around to fix this. Shouldn't take more than 3-4 hours,\n// if you know what you're doing tho.\n\n// HACK: Not all browsers account for the scrollbar width in media queries.\n// This results in horizontal scrollbars in the breakpoint where we go\n// from displaying everything to hiding the ToC. We accomodate for this by\n// adding a bit of padding to the TOC drawer, disabling the horizontal\n// scrollbar and allowing the scrollbars to cover the padding.\n// https://www.456bereastreet.com/archive/201301/media_query_width_and_vertical_scrollbars/\n\n// HACK: Always having the scrollbar visible, prevents certain browsers from\n// causing the content to stutter horizontally between taller-than-viewport and\n// not-taller-than-viewport pages.\n\nhtml\n overflow-x: hidden\n overflow-y: scroll\n scroll-behavior: smooth\n\n.sidebar-scroll, .toc-scroll, article[role=main] *\n // Override Firefox scrollbar style\n scrollbar-width: thin\n scrollbar-color: var(--color-foreground-border) transparent\n\n // Override Chrome scrollbar styles\n &::-webkit-scrollbar\n width: 0.25rem\n height: 0.25rem\n &::-webkit-scrollbar-thumb\n background-color: var(--color-foreground-border)\n border-radius: 0.125rem\n\n//\n// Overalls\n//\nhtml,\nbody\n height: 100%\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\n.skip-to-content\n position: fixed\n padding: 1rem\n border-radius: 1rem\n left: 0.25rem\n top: 0.25rem\n z-index: 40\n background: var(--color-background-primary)\n color: var(--color-foreground-primary)\n\n transform: translateY(-200%)\n transition: transform 300ms ease-in-out\n\n &:focus-within\n transform: translateY(0%)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n overflow-wrap: break-word\n\n.page\n display: flex\n // fill the viewport for pages with little content.\n min-height: 100%\n\n.mobile-header\n width: 100%\n height: var(--header-height)\n background-color: var(--color-header-background)\n color: var(--color-header-text)\n border-bottom: 1px solid var(--color-header-border)\n\n // Looks like sub-script/super-script have this, and we need this to\n // be \"on top\" of those.\n z-index: 10\n\n // We don't show the header on large screens.\n display: none\n\n // Add shadow when scrolled\n &.scrolled\n border-bottom: none\n box-shadow: 0 0 0.2rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.4rem rgba(0, 0, 0, 0.2)\n\n .header-center\n a\n color: var(--color-header-text)\n text-decoration: none\n\n.main\n display: flex\n flex: 1\n\n// Sidebar (left) also covers the entire left portion of screen.\n.sidebar-drawer\n box-sizing: border-box\n\n border-right: 1px solid var(--color-sidebar-background-border)\n background: var(--color-sidebar-background)\n\n display: flex\n justify-content: flex-end\n // These next two lines took me two days to figure out.\n width: calc((100% - #{$full-width}) / 2 + #{$sidebar-width})\n min-width: $sidebar-width\n\n// Scroll-along sidebars\n.sidebar-container,\n.toc-drawer\n box-sizing: border-box\n width: $sidebar-width\n\n.toc-drawer\n background: var(--color-toc-background)\n // See HACK described on top of this document\n padding-right: 1rem\n\n.sidebar-sticky,\n.toc-sticky\n position: sticky\n top: 0\n height: min(100%, 100vh)\n height: 100vh\n\n display: flex\n flex-direction: column\n\n.sidebar-scroll,\n.toc-scroll\n flex-grow: 1\n flex-shrink: 1\n\n overflow: auto\n scroll-behavior: smooth\n\n// Central items.\n.content\n padding: 0 $content-padding\n width: $content-width\n\n display: flex\n flex-direction: column\n justify-content: space-between\n\n.icon\n display: inline-block\n height: 1rem\n width: 1rem\n svg\n width: 100%\n height: 100%\n\n//\n// Accommodate announcement banner\n//\n.announcement\n background-color: var(--color-announcement-background)\n color: var(--color-announcement-text)\n\n height: var(--header-height)\n display: flex\n align-items: center\n overflow-x: auto\n & + .page\n min-height: calc(100% - var(--header-height))\n\n.announcement-content\n box-sizing: border-box\n padding: 0.5rem\n min-width: 100%\n white-space: nowrap\n text-align: center\n\n a\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-announcement-text)\n\n &:hover\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-link--hover)\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for theme\n////////////////////////////////////////////////////////////////////////////////\n.no-js .theme-toggle-container // don't show theme toggle if there's no JS\n display: none\n\n.theme-toggle-container\n display: flex\n\n.theme-toggle\n display: flex\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n height: 1.25rem\n width: 1.25rem\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n display: flex\n align-items: center\n justify-content: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for elements\n////////////////////////////////////////////////////////////////////////////////\n.toc-overlay-icon, .nav-overlay-icon\n display: none\n cursor: pointer\n\n .icon\n color: var(--color-foreground-secondary)\n height: 1.5rem\n width: 1.5rem\n\n.toc-header-icon, .nav-overlay-icon\n // for when we set display: flex\n justify-content: center\n align-items: center\n\n.toc-content-icon\n height: 1.5rem\n width: 1.5rem\n\n.content-icon-container\n float: right\n display: flex\n margin-top: 1.5rem\n margin-left: 1rem\n margin-bottom: 1rem\n gap: 0.5rem\n\n .edit-this-page, .view-this-page\n svg\n color: inherit\n height: 1.25rem\n width: 1.25rem\n\n.sidebar-toggle\n position: absolute\n display: none\n// \n.sidebar-toggle[name=\"__toc\"]\n left: 20px\n.sidebar-toggle:checked\n left: 40px\n// \n\n.overlay\n position: fixed\n top: 0\n width: 0\n height: 0\n\n transition: width 0ms, height 0ms, opacity 250ms ease-out\n\n opacity: 0\n background-color: rgba(0, 0, 0, 0.54)\n.sidebar-overlay\n z-index: 20\n.toc-overlay\n z-index: 40\n\n// Keep things on top and smooth.\n.sidebar-drawer\n z-index: 30\n transition: left 250ms ease-in-out\n.toc-drawer\n z-index: 50\n transition: right 250ms ease-in-out\n\n// Show the Sidebar\n#__navigation:checked\n & ~ .sidebar-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .sidebar-drawer\n top: 0\n left: 0\n // Show the toc sidebar\n#__toc:checked\n & ~ .toc-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .toc-drawer\n top: 0\n right: 0\n\n////////////////////////////////////////////////////////////////////////////////\n// Back to top\n////////////////////////////////////////////////////////////////////////////////\n.back-to-top\n text-decoration: none\n\n display: none\n position: fixed\n left: 0\n top: 1rem\n padding: 0.5rem\n padding-right: 0.75rem\n border-radius: 1rem\n font-size: 0.8125rem\n\n background: var(--color-background-primary)\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), #6b728080 0px 0px 1px 0px\n\n z-index: 10\n\n margin-left: 50%\n transform: translateX(-50%)\n svg\n height: 1rem\n width: 1rem\n fill: currentColor\n display: inline-block\n\n span\n margin-left: 0.25rem\n\n .show-back-to-top &\n display: flex\n align-items: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Responsive layouting\n////////////////////////////////////////////////////////////////////////////////\n// Make things a bit bigger on bigger screens.\n@media (min-width: $full-width + $sidebar-width)\n html\n font-size: 110%\n\n@media (max-width: $full-width)\n // Collapse \"toc\" into the icon.\n .toc-content-icon\n display: flex\n .toc-drawer\n position: fixed\n height: 100vh\n top: 0\n right: -$sidebar-width\n border-left: 1px solid var(--color-background-muted)\n .toc-tree\n border-left: none\n font-size: var(--toc-font-size--mobile)\n\n // Accomodate for a changed content width.\n .sidebar-drawer\n width: calc((100% - #{$full-width - $sidebar-width}) / 2 + #{$sidebar-width})\n\n@media (max-width: $content-padded-width + $sidebar-width)\n // Center the page\n .content\n margin-left: auto\n margin-right: auto\n padding: 0 $content-padding--small\n\n@media (max-width: $content-padded-width--small + $sidebar-width)\n // Collapse \"navigation\".\n .nav-overlay-icon\n display: flex\n .sidebar-drawer\n position: fixed\n height: 100vh\n width: $sidebar-width\n\n top: 0\n left: -$sidebar-width\n\n // Swap which icon is visible.\n .toc-header-icon, .theme-toggle-header\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\n\n // Show the header.\n .mobile-header\n position: sticky\n top: 0\n display: flex\n justify-content: space-between\n align-items: center\n\n .header-left,\n .header-right\n display: flex\n height: var(--header-height)\n padding: 0 var(--header-padding)\n label\n height: 100%\n width: 100%\n user-select: none\n\n .nav-overlay-icon .icon,\n .theme-toggle svg\n height: 1.5rem\n width: 1.5rem\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: calc(var(--header-height) + 2.5rem)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n\n@media (max-width: $content-width + 2* $content-padding--small)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n article[role=main] aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","// Overall Layout Variables\n//\n// Because CSS variables can't be used in media queries. The fact that this\n// makes the layout non-user-configurable is a good thing.\n$content-padding: 3em;\n$content-padding--small: 1em;\n$content-width: 46em;\n$sidebar-width: 15em;\n$content-padded-width: $content-width + 2 * $content-padding;\n$content-padded-width--small: $content-width + 2 * $content-padding--small;\n$full-width: $content-padded-width + 2 * $sidebar-width;\n","//\n// The design here is strongly inspired by mkdocs-material.\n.admonition, .topic\n margin: 1rem auto\n padding: 0 0.5rem 0.5rem 0.5rem\n\n background: var(--color-admonition-background)\n\n border-radius: 0.2rem\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n font-size: var(--admonition-font-size)\n\n overflow: hidden\n page-break-inside: avoid\n\n // First element should have no margin, since the title has it.\n > :nth-child(2)\n margin-top: 0\n\n // Last item should have no margin, since we'll control that w/ padding\n > :last-child\n margin-bottom: 0\n\n.admonition p.admonition-title,\np.topic-title\n position: relative\n margin: 0 -0.5rem 0.5rem\n padding-left: 2rem\n padding-right: .5rem\n padding-top: .4rem\n padding-bottom: .4rem\n\n font-weight: 500\n font-size: var(--admonition-title-font-size)\n line-height: 1.3\n\n // Our fancy icon\n &::before\n content: \"\"\n position: absolute\n left: 0.5rem\n width: 1rem\n height: 1rem\n\n// Default styles\np.admonition-title\n background-color: var(--color-admonition-title-background)\n &::before\n background-color: var(--color-admonition-title)\n mask-image: var(--icon-admonition-default)\n mask-repeat: no-repeat\n\np.topic-title\n background-color: var(--color-topic-title-background)\n &::before\n background-color: var(--color-topic-title)\n mask-image: var(--icon-topic-default)\n mask-repeat: no-repeat\n\n//\n// Variants\n//\n.admonition\n border-left: 0.2rem solid var(--color-admonition-title)\n\n @each $type, $value in $admonitions\n &.#{$type}\n border-left-color: var(--color-admonition-title--#{$type})\n > .admonition-title\n background-color: var(--color-admonition-title-background--#{$type})\n &::before\n background-color: var(--color-admonition-title--#{$type})\n mask-image: var(--icon-#{nth($value, 2)})\n\n.admonition-todo > .admonition-title\n text-transform: uppercase\n","// This file stylizes the API documentation (stuff generated by autodoc). It's\n// deeply nested due to how autodoc structures the HTML without enough classes\n// to select the relevant items.\n\n// API docs!\ndl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)\n // Tweak the spacing of all the things!\n dd\n margin-left: 2rem\n > :first-child\n margin-top: 0.125rem\n > :last-child\n margin-bottom: 0.75rem\n\n // This is used for the arguments\n .field-list\n margin-bottom: 0.75rem\n\n // \"Headings\" (like \"Parameters\" and \"Return\")\n > dt\n text-transform: uppercase\n font-size: var(--font-size--small)\n\n dd:empty\n margin-bottom: 0.5rem\n dd > ul\n margin-left: -1.2rem\n > li\n > p:nth-child(2)\n margin-top: 0\n // When the last-empty-paragraph follows a paragraph, it doesn't need\n // to augument the existing spacing.\n > p + p:last-child:empty\n margin-top: 0\n margin-bottom: 0\n\n // Colorize the elements\n > dt\n color: var(--color-api-overall)\n\n.sig:not(.sig-inline)\n font-weight: bold\n\n font-size: var(--api-font-size)\n font-family: var(--font-stack--monospace)\n\n margin-left: -0.25rem\n margin-right: -0.25rem\n padding-top: 0.25rem\n padding-bottom: 0.25rem\n padding-right: 0.5rem\n\n // These are intentionally em, to properly match the font size.\n padding-left: 3em\n text-indent: -2.5em\n\n border-radius: 0.25rem\n\n background: var(--color-api-background)\n transition: background 100ms ease-out\n\n &:hover\n background: var(--color-api-background-hover)\n\n // adjust the size of the [source] link on the right.\n a.reference\n .viewcode-link\n font-weight: normal\n width: 4.25rem\n\nem.property\n font-style: normal\n &:first-child\n color: var(--color-api-keyword)\n.sig-name\n color: var(--color-api-name)\n.sig-prename\n font-weight: normal\n color: var(--color-api-pre-name)\n.sig-paren\n color: var(--color-api-paren)\n.sig-param\n font-style: normal\n\ndiv.versionadded,\ndiv.versionchanged,\ndiv.deprecated,\ndiv.versionremoved\n border-left: 0.1875rem solid\n border-radius: 0.125rem\n\n padding-left: 0.75rem\n\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\ndiv.versionadded\n border-color: var(--color-api-added-border)\n .versionmodified\n color: var(--color-api-added)\n\ndiv.versionchanged\n border-color: var(--color-api-changed-border)\n .versionmodified\n color: var(--color-api-changed)\n\ndiv.deprecated\n border-color: var(--color-api-deprecated-border)\n .versionmodified\n color: var(--color-api-deprecated)\n\ndiv.versionremoved\n border-color: var(--color-api-removed-border)\n .versionmodified\n color: var(--color-api-removed)\n\n// Align the [docs] and [source] to the right.\n.viewcode-link, .viewcode-back\n float: right\n text-align: right\n",".line-block\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n .line-block\n margin-top: 0rem\n margin-bottom: 0rem\n padding-left: 1rem\n","// Captions\narticle p.caption,\ntable > caption,\n.code-block-caption\n font-size: var(--font-size--small)\n text-align: center\n\n// Caption above a TOCTree\n.toctree-wrapper.compound\n .caption, :not(.caption) > .caption-text\n font-size: var(--font-size--small)\n text-transform: uppercase\n\n text-align: initial\n margin-bottom: 0\n\n > ul\n margin-top: 0\n margin-bottom: 0\n","// Inline code\ncode.literal, .sig-inline\n background: var(--color-inline-code-background)\n border-radius: 0.2em\n // Make the font smaller, and use padding to recover.\n font-size: var(--font-size--small--2)\n padding: 0.1em 0.2em\n\n pre.literal-block &\n font-size: inherit\n padding: 0\n\n p &\n border: 1px solid var(--color-background-border)\n\n.sig-inline\n font-family: var(--font-stack--monospace)\n\n// Code and Literal Blocks\n$code-spacing-vertical: 0.625rem\n$code-spacing-horizontal: 0.875rem\n\n// Wraps every literal block + line numbers.\ndiv[class*=\" highlight-\"],\ndiv[class^=\"highlight-\"]\n margin: 1em 0\n display: flex\n\n .table-wrapper\n margin: 0\n padding: 0\n\npre\n margin: 0\n padding: 0\n overflow: auto\n\n // Needed to have more specificity than pygments' \"pre\" selector. :(\n article[role=\"main\"] .highlight &\n line-height: 1.5\n\n &.literal-block,\n .highlight &\n font-size: var(--code-font-size)\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n // Make it look like all the other blocks.\n &.literal-block\n margin-top: 1rem\n margin-bottom: 1rem\n\n border-radius: 0.2rem\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n\n// All code is always contained in this.\n.highlight\n width: 100%\n border-radius: 0.2rem\n\n // Make line numbers and prompts un-selectable.\n .gp, span.linenos\n user-select: none\n pointer-events: none\n\n // Expand the line-highlighting.\n .hll\n display: block\n margin-left: -$code-spacing-horizontal\n margin-right: -$code-spacing-horizontal\n padding-left: $code-spacing-horizontal\n padding-right: $code-spacing-horizontal\n\n/* Make code block captions be nicely integrated */\n.code-block-caption\n display: flex\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n border-radius: 0.25rem\n border-bottom-left-radius: 0\n border-bottom-right-radius: 0\n font-weight: 300\n border-bottom: 1px solid\n\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n border-color: var(--color-background-border)\n\n + div[class]\n margin-top: 0\n pre\n border-top-left-radius: 0\n border-top-right-radius: 0\n\n// When `html_codeblock_linenos_style` is table.\n.highlighttable\n width: 100%\n display: block\n tbody\n display: block\n\n tr\n display: flex\n\n // Line numbers\n td.linenos\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n padding: $code-spacing-vertical $code-spacing-horizontal\n padding-right: 0\n border-top-left-radius: 0.2rem\n border-bottom-left-radius: 0.2rem\n\n .linenodiv\n padding-right: $code-spacing-horizontal\n font-size: var(--code-font-size)\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n\n // Actual code\n td.code\n padding: 0\n display: block\n flex: 1\n overflow: hidden\n\n .highlight\n border-top-left-radius: 0\n border-bottom-left-radius: 0\n\n// When `html_codeblock_linenos_style` is inline.\n.highlight\n span.linenos\n display: inline-block\n padding-left: 0\n padding-right: $code-spacing-horizontal\n margin-right: $code-spacing-horizontal\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n","// Inline Footnote Reference\n.footnote-reference\n font-size: var(--font-size--small--4)\n vertical-align: super\n\n// Definition list, listing the content of each note.\n// docutils <= 0.17\ndl.footnote.brackets\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\n display: grid\n grid-template-columns: max-content auto\n dt\n margin: 0\n > .fn-backref\n margin-left: 0.25rem\n\n &:after\n content: \":\"\n\n .brackets\n &:before\n content: \"[\"\n &:after\n content: \"]\"\n\n dd\n margin: 0\n padding: 0 1rem\n\n// docutils >= 0.18\naside.footnote\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\naside.footnote > span,\ndiv.citation > span\n float: left\n font-weight: 500\n padding-right: 0.25rem\n\naside.footnote > *:not(span),\ndiv.citation > p\n margin-left: 2rem\n","//\n// Figures\n//\nimg\n box-sizing: border-box\n max-width: 100%\n height: auto\n\narticle\n figure, .figure\n border-radius: 0.2rem\n\n margin: 0\n :last-child\n margin-bottom: 0\n\n .align-left\n float: left\n clear: left\n margin: 0 1rem 1rem\n\n .align-right\n float: right\n clear: right\n margin: 0 1rem 1rem\n\n .align-default,\n .align-center\n display: block\n text-align: center\n margin-left: auto\n margin-right: auto\n\n // WELL, table needs to be stylised like a table.\n table.align-default\n display: table\n text-align: initial\n",".genindex-jumpbox, .domainindex-jumpbox\n border-top: 1px solid var(--color-background-border)\n border-bottom: 1px solid var(--color-background-border)\n padding: 0.25rem\n\n.genindex-section, .domainindex-section\n h2\n margin-top: 0.75rem\n margin-bottom: 0.5rem\n ul\n margin-top: 0\n margin-bottom: 0\n","ul,\nol\n padding-left: 1.2rem\n\n // Space lists out like paragraphs\n margin-top: 1rem\n margin-bottom: 1rem\n // reduce margins within li.\n li\n > p:first-child\n margin-top: 0.25rem\n margin-bottom: 0.25rem\n\n > p:last-child\n margin-top: 0.25rem\n\n > ul,\n > ol\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n\nol\n &.arabic\n list-style: decimal\n &.loweralpha\n list-style: lower-alpha\n &.upperalpha\n list-style: upper-alpha\n &.lowerroman\n list-style: lower-roman\n &.upperroman\n list-style: upper-roman\n\n// Don't space lists out when they're \"simple\" or in a `.. toctree::`\n.simple,\n.toctree-wrapper\n li\n > ul,\n > ol\n margin-top: 0\n margin-bottom: 0\n\n// Definition Lists\n.field-list,\n.option-list,\ndl:not([class]),\ndl.simple,\ndl.footnote,\ndl.glossary\n dt\n font-weight: 500\n margin-top: 0.25rem\n + dt\n margin-top: 0\n\n .classifier::before\n content: \":\"\n margin-left: 0.2rem\n margin-right: 0.2rem\n\n dd\n > p:first-child,\n ul\n margin-top: 0.125rem\n\n ul\n margin-bottom: 0.125rem\n",".math-wrapper\n width: 100%\n overflow-x: auto\n\ndiv.math\n position: relative\n text-align: center\n\n .headerlink,\n &:focus .headerlink\n display: none\n\n &:hover .headerlink\n display: inline-block\n\n span.eqno\n position: absolute\n right: 0.5rem\n top: 50%\n transform: translate(0, -50%)\n z-index: 1\n","// Abbreviations\nabbr[title]\n cursor: help\n\n// \"Problematic\" content, as identified by Sphinx\n.problematic\n color: var(--color-problematic)\n\n// Keyboard / Mouse \"instructions\"\nkbd:not(.compound)\n margin: 0 0.2rem\n padding: 0 0.2rem\n border-radius: 0.2rem\n border: 1px solid var(--color-foreground-border)\n color: var(--color-foreground-primary)\n vertical-align: text-bottom\n\n font-size: var(--font-size--small--3)\n display: inline-block\n\n box-shadow: 0 0.0625rem 0 rgba(0, 0, 0, 0.2), inset 0 0 0 0.125rem var(--color-background-primary)\n\n background-color: var(--color-background-secondary)\n\n// Blockquote\nblockquote\n border-left: 4px solid var(--color-background-border)\n background: var(--color-background-secondary)\n\n margin-left: 0\n margin-right: 0\n padding: 0.5rem 1rem\n\n .attribution\n font-weight: 600\n text-align: right\n\n &.pull-quote,\n &.highlights\n font-size: 1.25em\n\n &.epigraph,\n &.pull-quote\n border-left-width: 0\n border-radius: 0.5rem\n\n &.highlights\n border-left-width: 0\n background: transparent\n\n// Center align embedded-in-text images\np .reference img\n vertical-align: middle\n","p.rubric\n line-height: 1.25\n font-weight: bold\n font-size: 1.125em\n\n // For Numpy-style documentation that's got rubrics within it.\n // https://github.com/pradyunsg/furo/discussions/505\n dd &\n line-height: inherit\n font-weight: inherit\n\n font-size: var(--font-size--small)\n text-transform: uppercase\n","article .sidebar\n float: right\n clear: right\n width: 30%\n\n margin-left: 1rem\n margin-right: 0\n\n border-radius: 0.2rem\n background-color: var(--color-background-secondary)\n border: var(--color-background-border) 1px solid\n\n > *\n padding-left: 1rem\n padding-right: 1rem\n\n > ul, > ol // lists need additional padding, because bullets.\n padding-left: 2.2rem\n\n .sidebar-title\n margin: 0\n padding: 0.5rem 1rem\n border-bottom: var(--color-background-border) 1px solid\n\n font-weight: 500\n\n// TODO: subtitle\n// TODO: dedicated variables?\n","[role=main] .table-wrapper.container\n width: 100%\n overflow-x: auto\n margin-top: 1rem\n margin-bottom: 0.5rem\n padding: 0.2rem 0.2rem 0.75rem\n\ntable.docutils\n border-radius: 0.2rem\n border-spacing: 0\n border-collapse: collapse\n\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n th\n background: var(--color-table-header-background)\n\n td,\n th\n // Space things out properly\n padding: 0 0.25rem\n\n // Get the borders looking just-right.\n border-left: 1px solid var(--color-table-border)\n border-right: 1px solid var(--color-table-border)\n border-bottom: 1px solid var(--color-table-border)\n\n p\n margin: 0.25rem\n\n &:first-child\n border-left: none\n &:last-child\n border-right: none\n\n // MyST-parser tables set these classes for control of column alignment\n &.text-left\n text-align: left\n &.text-right\n text-align: right\n &.text-center\n text-align: center\n",":target\n scroll-margin-top: 2.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(2.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(2.8rem + var(--header-height))\n\n// Permalinks\n.headerlink\n font-weight: 100\n user-select: none\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ndl dt,\np.caption,\nfigcaption p,\ntable > caption,\n.code-block-caption\n > .headerlink\n margin-left: 0.5rem\n visibility: hidden\n &:hover > .headerlink\n visibility: visible\n\n // Don't change to link-like, if someone adds the contents directive.\n > .toc-backref\n color: inherit\n text-decoration-line: none\n\n// Figure and table captions are special.\nfigure:hover > figcaption > p > .headerlink,\ntable:hover > caption > .headerlink\n visibility: visible\n\n:target >, // Regular section[id] style anchors\nspan:target ~ // Non-regular span[id] style \"extra\" anchors\n h1,\n h2,\n h3,\n h4,\n h5,\n h6\n &:nth-of-type(1)\n background-color: var(--color-highlight-on-target)\n // .headerlink\n // visibility: visible\n code.literal\n background-color: transparent\n\ntable:target > caption,\nfigure:target\n background-color: var(--color-highlight-on-target)\n\n// Inline page contents\n.this-will-duplicate-information-and-it-is-still-useful-here li :target\n background-color: var(--color-highlight-on-target)\n\n// Code block permalinks\n.literal-block-wrapper:target .code-block-caption\n background-color: var(--color-highlight-on-target)\n\n// When a definition list item is selected\n//\n// There isn't really an alternative to !important here, due to the\n// high-specificity of API documentation's selector.\ndt:target\n background-color: var(--color-highlight-on-target) !important\n\n// When a footnote reference is selected\n.footnote > dt:target + dd,\n.footnote-reference:target\n background-color: var(--color-highlight-on-target)\n",".guilabel\n background-color: var(--color-guilabel-background)\n border: 1px solid var(--color-guilabel-border)\n color: var(--color-guilabel-text)\n\n padding: 0 0.3em\n border-radius: 0.5em\n font-size: 0.9em\n","// This file contains the styles used for stylizing the footer that's shown\n// below the content.\n\nfooter\n font-size: var(--font-size--small)\n display: flex\n flex-direction: column\n\n margin-top: 2rem\n\n// Bottom of page information\n.bottom-of-page\n display: flex\n align-items: center\n justify-content: space-between\n\n margin-top: 1rem\n padding-top: 1rem\n padding-bottom: 1rem\n\n color: var(--color-foreground-secondary)\n border-top: 1px solid var(--color-background-border)\n\n line-height: 1.5\n\n @media (max-width: $content-width)\n text-align: center\n flex-direction: column-reverse\n gap: 0.25rem\n\n .left-details\n font-size: var(--font-size--small)\n\n .right-details\n display: flex\n flex-direction: column\n gap: 0.25rem\n text-align: right\n\n .icons\n display: flex\n justify-content: flex-end\n gap: 0.25rem\n font-size: 1rem\n\n a\n text-decoration: none\n\n svg,\n img\n font-size: 1.125rem\n height: 1em\n width: 1em\n\n// Next/Prev page information\n.related-pages\n a\n display: flex\n align-items: center\n\n text-decoration: none\n &:hover .page-info .title\n text-decoration: underline\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n svg.furo-related-icon,\n svg.furo-related-icon > use\n flex-shrink: 0\n\n color: var(--color-foreground-border)\n\n width: 0.75rem\n height: 0.75rem\n margin: 0 0.5rem\n\n &.next-page\n max-width: 50%\n\n float: right\n clear: right\n text-align: right\n\n &.prev-page\n max-width: 50%\n\n float: left\n clear: left\n\n svg\n transform: rotate(180deg)\n\n.page-info\n display: flex\n flex-direction: column\n overflow-wrap: anywhere\n\n .next-page &\n align-items: flex-end\n\n .context\n display: flex\n align-items: center\n\n padding-bottom: 0.1rem\n\n color: var(--color-foreground-muted)\n font-size: var(--font-size--small)\n text-decoration: none\n","// This file contains the styles for the contents of the left sidebar, which\n// contains the navigation tree, logo, search etc.\n\n////////////////////////////////////////////////////////////////////////////////\n// Brand on top of the scrollable tree.\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-brand\n display: flex\n flex-direction: column\n flex-shrink: 0\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n text-decoration: none\n\n.sidebar-brand-text\n color: var(--color-sidebar-brand-text)\n overflow-wrap: break-word\n margin: var(--sidebar-item-spacing-vertical) 0\n font-size: 1.5rem\n\n.sidebar-logo-container\n margin: var(--sidebar-item-spacing-vertical) 0\n\n.sidebar-logo\n margin: 0 auto\n display: block\n max-width: 100%\n\n////////////////////////////////////////////////////////////////////////////////\n// Search\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-search-container\n display: flex\n align-items: center\n margin-top: var(--sidebar-search-space-above)\n\n position: relative\n\n background: var(--color-sidebar-search-background)\n &:hover,\n &:focus-within\n background: var(--color-sidebar-search-background--focus)\n\n &::before\n content: \"\"\n position: absolute\n left: var(--sidebar-item-spacing-horizontal)\n width: var(--sidebar-search-icon-size)\n height: var(--sidebar-search-icon-size)\n\n background-color: var(--color-sidebar-search-icon)\n mask-image: var(--icon-search)\n\n.sidebar-search\n box-sizing: border-box\n\n border: none\n border-top: 1px solid var(--color-sidebar-search-border)\n border-bottom: 1px solid var(--color-sidebar-search-border)\n\n padding-top: var(--sidebar-search-input-spacing-vertical)\n padding-bottom: var(--sidebar-search-input-spacing-vertical)\n padding-right: var(--sidebar-search-input-spacing-horizontal)\n padding-left: calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size))\n\n width: 100%\n\n color: var(--color-sidebar-search-foreground)\n background: transparent\n z-index: 10\n\n &:focus\n outline: none\n\n &::placeholder\n font-size: var(--sidebar-search-input-font-size)\n\n//\n// Hide Search Matches link\n//\n#searchbox .highlight-link\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0\n margin: 0\n text-align: center\n\n a\n color: var(--color-sidebar-search-icon)\n font-size: var(--font-size--small--2)\n\n////////////////////////////////////////////////////////////////////////////////\n// Structure/Skeleton of the navigation tree (left)\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-tree\n font-size: var(--sidebar-item-font-size)\n margin-top: var(--sidebar-tree-space-above)\n margin-bottom: var(--sidebar-item-spacing-vertical)\n\n ul\n padding: 0\n margin-top: 0\n margin-bottom: 0\n\n display: flex\n flex-direction: column\n\n list-style: none\n\n li\n position: relative\n margin: 0\n\n > ul\n margin-left: var(--sidebar-item-spacing-horizontal)\n\n .icon\n color: var(--color-sidebar-link-text)\n\n .reference\n box-sizing: border-box\n color: var(--color-sidebar-link-text)\n\n // Fill the parent.\n display: inline-block\n line-height: var(--sidebar-item-line-height)\n text-decoration: none\n\n // Don't allow long words to cause wrapping.\n overflow-wrap: anywhere\n\n height: 100%\n width: 100%\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n &:hover\n color: var(--color-sidebar-link-text)\n background: var(--color-sidebar-item-background--hover)\n\n // Add a nice little \"external-link\" arrow here.\n &.external::after\n content: url('data:image/svg+xml,')\n margin: 0 0.25rem\n vertical-align: middle\n color: var(--color-sidebar-link-text)\n\n // Make the current page reference bold.\n .current-page > .reference\n font-weight: bold\n\n label\n position: absolute\n top: 0\n right: 0\n height: var(--sidebar-item-height)\n width: var(--sidebar-expander-width)\n\n cursor: pointer\n user-select: none\n\n display: flex\n justify-content: center\n align-items: center\n\n .caption, :not(.caption) > .caption-text\n font-size: var(--sidebar-caption-font-size)\n color: var(--color-sidebar-caption-text)\n\n font-weight: bold\n text-transform: uppercase\n\n margin: var(--sidebar-caption-space-above) 0 0 0\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n // If it has children, add a bit more padding to wrap the content to avoid\n // overlapping with the